1 /******************************************************************************
2 *
3 * Module Name: ascase - Source conversion - lower/upper case utilities
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2023, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
29 *
30 * NO WARRANTY
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
42 */
43
44 #include "acpisrc.h"
45
46 /* Local prototypes */
47
48 void
49 AsUppercaseTokens (
50 char *Buffer,
51 char *PrefixString);
52
53
54 /******************************************************************************
55 *
56 * FUNCTION: AsLowerCaseString
57 *
58 * DESCRIPTION: LowerCase all instances of a target string with a replacement
59 * string. Returns count of the strings replaced.
60 *
61 ******************************************************************************/
62
63 int
AsLowerCaseString(char * Target,char * Buffer)64 AsLowerCaseString (
65 char *Target,
66 char *Buffer)
67 {
68 char *SubString1;
69 char *SubString2;
70 char *SubBuffer;
71 int TargetLength;
72 int LowerCaseCount = 0;
73 int i;
74
75
76 TargetLength = strlen (Target);
77
78 SubBuffer = Buffer;
79 SubString1 = Buffer;
80
81 while (SubString1)
82 {
83 /* Find the target string */
84
85 SubString1 = strstr (SubBuffer, Target);
86 if (!SubString1)
87 {
88 return (LowerCaseCount);
89 }
90
91 /*
92 * Check for translation escape string -- means to ignore
93 * blocks of code while replacing
94 */
95 if (Gbl_IgnoreTranslationEscapes)
96 {
97 SubString2 = NULL;
98 }
99 else
100 {
101 SubString2 = strstr (SubBuffer, AS_START_IGNORE);
102 }
103
104 if ((SubString2) &&
105 (SubString2 < SubString1))
106 {
107 /* Find end of the escape block starting at "Substring2" */
108
109 SubString2 = strstr (SubString2, AS_STOP_IGNORE);
110 if (!SubString2)
111 {
112 /* Didn't find terminator */
113
114 return (LowerCaseCount);
115 }
116
117 /* Move buffer to end of escape block and continue */
118
119 SubBuffer = SubString2;
120 }
121
122 /* Do the actual replace if the target was found */
123
124 else
125 {
126 if (!AsMatchExactWord (SubString1, TargetLength))
127 {
128 SubBuffer = SubString1 + 1;
129 continue;
130 }
131
132 for (i = 0; i < TargetLength; i++)
133 {
134 SubString1[i] = (char) tolower ((int) SubString1[i]);
135 }
136
137 SubBuffer = SubString1 + TargetLength;
138
139 if ((Gbl_WidenDeclarations) && (!Gbl_StructDefs))
140 {
141 if ((SubBuffer[0] == ' ') && (SubBuffer[1] == ' '))
142 {
143 AsInsertData (SubBuffer, " ", 8);
144 }
145 }
146
147 LowerCaseCount++;
148 }
149 }
150
151 return (LowerCaseCount);
152 }
153
154
155 /******************************************************************************
156 *
157 * FUNCTION: AsMixedCaseToUnderscores
158 *
159 * DESCRIPTION: Converts mixed case identifiers to underscored identifiers.
160 * for example,
161 *
162 * ThisUsefullyNamedIdentifier becomes:
163 *
164 * this_usefully_named_identifier
165 *
166 ******************************************************************************/
167
168 void
AsMixedCaseToUnderscores(char * Buffer,char * Filename)169 AsMixedCaseToUnderscores (
170 char *Buffer,
171 char *Filename)
172 {
173 UINT32 Length;
174 char *SubBuffer = Buffer;
175 char *TokenEnd;
176 char *TokenStart = NULL;
177 char *SubString;
178 UINT32 LineNumber = 1;
179 UINT32 Count;
180
181
182 /*
183 * Examine the entire buffer (contains the entire file)
184 * We are only interested in these tokens:
185 * Escape sequences - ignore entire sequence
186 * Single-quoted constants - ignore
187 * Quoted strings - ignore entire string
188 * Translation escape - starts with /,*,!
189 * Decimal and hex numeric constants - ignore entire token
190 * Entire uppercase token - ignore, it is a macro or define
191 * Starts with underscore, then a lowercase or digit: convert
192 */
193 while (*SubBuffer)
194 {
195 if (*SubBuffer == '\n')
196 {
197 LineNumber++;
198 SubBuffer++;
199 continue;
200 }
201
202 /* Ignore standard escape sequences (\n, \r, etc.) Not Hex or Octal escapes */
203
204 if (*SubBuffer == '\\')
205 {
206 SubBuffer += 2;
207 continue;
208 }
209
210 /* Ignore single-quoted characters */
211
212 if (*SubBuffer == '\'')
213 {
214 SubBuffer += 3;
215 continue;
216 }
217
218 /* Ignore standard double-quoted strings */
219
220 if (*SubBuffer == '"')
221 {
222 SubBuffer++;
223 Count = 0;
224 while (*SubBuffer != '"')
225 {
226 Count++;
227 if ((!*SubBuffer) ||
228 (Count > 8192))
229 {
230 printf ("Found an unterminated quoted string!, line %u: %s\n",
231 LineNumber, Filename);
232 return;
233 }
234
235 /* Handle escape sequences */
236
237 if (*SubBuffer == '\\')
238 {
239 SubBuffer++;
240 }
241
242 SubBuffer++;
243 }
244
245 SubBuffer++;
246 continue;
247 }
248
249 /*
250 * Check for translation escape string. It means to ignore
251 * blocks of code during this code conversion.
252 */
253 if ((SubBuffer[0] == '/') &&
254 (SubBuffer[1] == '*') &&
255 (SubBuffer[2] == '!'))
256 {
257 SubBuffer = strstr (SubBuffer, "!*/");
258 if (!SubBuffer)
259 {
260 printf ("Found an unterminated translation escape!, line %u: %s\n",
261 LineNumber, Filename);
262 return;
263 }
264
265 continue;
266 }
267
268 /* Ignore anything that starts with a number (0-9) */
269
270 if (isdigit ((int) *SubBuffer))
271 {
272 /* Ignore hex constants */
273
274 if ((SubBuffer[0] == '0') &&
275 ((SubBuffer[1] == 'x') || (SubBuffer[1] == 'X')))
276 {
277 SubBuffer += 2;
278 }
279
280 /* Skip over all digits, both decimal and hex */
281
282 while (isxdigit ((int) *SubBuffer))
283 {
284 SubBuffer++;
285 }
286 TokenStart = NULL;
287 continue;
288 }
289
290 /*
291 * Check for fully upper case identifiers. These are usually macros
292 * or defines. Allow decimal digits and embedded underscores.
293 */
294 if (isupper ((int) *SubBuffer))
295 {
296 SubString = SubBuffer + 1;
297 while ((isupper ((int) *SubString)) ||
298 (isdigit ((int) *SubString)) ||
299 (*SubString == '_'))
300 {
301 SubString++;
302 }
303
304 /*
305 * For the next character, anything other than a lower case
306 * means that the identifier has terminated, and contains
307 * exclusively Uppers/Digits/Underscores. Ignore the entire
308 * identifier.
309 */
310 if (!islower ((int) *SubString))
311 {
312 SubBuffer = SubString + 1;
313 continue;
314 }
315 }
316
317 /*
318 * These forms may indicate an identifier that can be converted:
319 * <UpperCase><LowerCase> (Ax)
320 * <UpperCase><Number> (An)
321 */
322 if (isupper ((int) SubBuffer[0]) &&
323 ((islower ((int) SubBuffer[1])) || isdigit ((int) SubBuffer[1])))
324 {
325 TokenStart = SubBuffer;
326 SubBuffer++;
327
328 while (1)
329 {
330 /* Walk over the lower case letters and decimal digits */
331
332 while (islower ((int) *SubBuffer) ||
333 isdigit ((int) *SubBuffer))
334 {
335 SubBuffer++;
336 }
337
338 /* Check for end of line or end of token */
339
340 if (*SubBuffer == '\n')
341 {
342 LineNumber++;
343 break;
344 }
345
346 if (*SubBuffer == ' ')
347 {
348 /* Check for form "Axx - " in a parameter header description */
349
350 while (*SubBuffer == ' ')
351 {
352 SubBuffer++;
353 }
354
355 SubBuffer--;
356 if ((SubBuffer[1] == '-') &&
357 (SubBuffer[2] == ' '))
358 {
359 if (TokenStart)
360 {
361 *TokenStart = (char) tolower ((int) *TokenStart);
362 }
363 }
364 break;
365 }
366
367 /*
368 * Ignore these combinations:
369 * <Letter><Digit><UpperCase>
370 * <Digit><Digit><UpperCase>
371 * <Underscore><Digit><UpperCase>
372 */
373 if (isdigit ((int) *SubBuffer))
374 {
375 if (isalnum ((int) *(SubBuffer-1)) ||
376 *(SubBuffer-1) == '_')
377 {
378 break;
379 }
380 }
381
382 /* Ignore token if next character is not uppercase or digit */
383
384 if (!isupper ((int) *SubBuffer) &&
385 !isdigit ((int) *SubBuffer))
386 {
387 break;
388 }
389
390 /*
391 * Form <UpperCase><LowerCaseLetters><UpperCase> (AxxB):
392 * Convert leading character of the token to lower case
393 */
394 if (TokenStart)
395 {
396 *TokenStart = (char) tolower ((int) *TokenStart);
397 TokenStart = NULL;
398 }
399
400 /* Find the end of this identifier (token) */
401
402 TokenEnd = SubBuffer - 1;
403 while ((isalnum ((int) *TokenEnd)) ||
404 (*TokenEnd == '_'))
405 {
406 TokenEnd++;
407 }
408
409 SubString = TokenEnd;
410 Length = 0;
411
412 while (*SubString != '\n')
413 {
414 /*
415 * If we have at least two trailing spaces, we can get rid of
416 * one to make up for the newly inserted underscore. This will
417 * help preserve the alignment of the text
418 */
419 if ((SubString[0] == ' ') &&
420 (SubString[1] == ' '))
421 {
422 Length = SubString - SubBuffer - 1;
423 break;
424 }
425
426 SubString++;
427 }
428
429 if (!Length)
430 {
431 Length = strlen (&SubBuffer[0]);
432 }
433
434 /*
435 * Within this identifier, convert this pair of letters that
436 * matches the form:
437 *
438 * <LowerCase><UpperCase>
439 * to
440 * <LowerCase><Underscore><LowerCase>
441 */
442 Gbl_MadeChanges = TRUE;
443
444 /* Insert the underscore */
445
446 memmove (&SubBuffer[1], &SubBuffer[0], Length + 1);
447 SubBuffer[0] = '_';
448
449 /*
450 * If we have <UpperCase><UpperCase>, leave them as-is
451 * Enables transforms like:
452 * LocalFADT -> local_FADT
453 */
454 if (isupper ((int) SubBuffer[2]))
455 {
456 SubBuffer += 1;
457 break;
458 }
459
460 /* Lower case the original upper case letter */
461
462 SubBuffer[1] = (char) tolower ((int) SubBuffer[1]);
463 SubBuffer += 2;
464 }
465 }
466
467 SubBuffer++;
468 }
469 }
470
471
472 /******************************************************************************
473 *
474 * FUNCTION: AsLowerCaseIdentifiers
475 *
476 * DESCRIPTION: Converts mixed case identifiers to lower case. Leaves comments,
477 * quoted strings, and all-upper-case macros alone.
478 *
479 ******************************************************************************/
480
481 void
AsLowerCaseIdentifiers(char * Buffer)482 AsLowerCaseIdentifiers (
483 char *Buffer)
484 {
485 char *SubBuffer = Buffer;
486
487
488 while (*SubBuffer)
489 {
490 /*
491 * Check for translation escape string -- means to ignore
492 * blocks of code while replacing
493 */
494 if ((SubBuffer[0] == '/') &&
495 (SubBuffer[1] == '*') &&
496 (SubBuffer[2] == '!'))
497 {
498 SubBuffer = strstr (SubBuffer, "!*/");
499 if (!SubBuffer)
500 {
501 return;
502 }
503 }
504
505 /* Ignore comments */
506
507 if ((SubBuffer[0] == '/') &&
508 (SubBuffer[1] == '*'))
509 {
510 SubBuffer = strstr (SubBuffer, "*/");
511 if (!SubBuffer)
512 {
513 return;
514 }
515
516 SubBuffer += 2;
517 }
518
519 /* Ignore quoted strings */
520
521 if ((SubBuffer[0] == '\"') && (SubBuffer[1] != '\''))
522 {
523 SubBuffer++;
524
525 /* Find the closing quote */
526
527 while (SubBuffer[0])
528 {
529 /* Ignore escaped quote characters */
530
531 if (SubBuffer[0] == '\\')
532 {
533 SubBuffer++;
534 }
535 else if (SubBuffer[0] == '\"')
536 {
537 SubBuffer++;
538 break;
539 }
540
541 SubBuffer++;
542 }
543 }
544
545 if (!SubBuffer[0])
546 {
547 return;
548 }
549
550 /*
551 * Only lower case if we have an upper followed by a lower
552 * This leaves the all-uppercase things (macros, etc.) intact
553 */
554 if ((isupper ((int) SubBuffer[0])) &&
555 (islower ((int) SubBuffer[1])))
556 {
557 Gbl_MadeChanges = TRUE;
558 *SubBuffer = (char) tolower ((int) *SubBuffer);
559 }
560
561 SubBuffer++;
562 }
563 }
564
565
566 /******************************************************************************
567 *
568 * FUNCTION: AsUppercaseTokens
569 *
570 * DESCRIPTION: Force to uppercase all tokens that begin with the prefix string.
571 * used to convert mixed-case macros and constants to uppercase.
572 *
573 ******************************************************************************/
574
575 void
AsUppercaseTokens(char * Buffer,char * PrefixString)576 AsUppercaseTokens (
577 char *Buffer,
578 char *PrefixString)
579 {
580 char *SubBuffer;
581 char *TokenEnd;
582 char *SubString;
583 int i;
584 UINT32 Length;
585
586
587 SubBuffer = Buffer;
588
589 while (SubBuffer)
590 {
591 SubBuffer = strstr (SubBuffer, PrefixString);
592 if (SubBuffer)
593 {
594 TokenEnd = SubBuffer;
595 while ((isalnum ((int) *TokenEnd)) || (*TokenEnd == '_'))
596 {
597 TokenEnd++;
598 }
599
600 for (i = 0; i < (TokenEnd - SubBuffer); i++)
601 {
602 if ((islower ((int) SubBuffer[i])) &&
603 (isupper ((int) SubBuffer[i+1])))
604 {
605
606 SubString = TokenEnd;
607 Length = 0;
608
609 while (*SubString != '\n')
610 {
611 if ((SubString[0] == ' ') &&
612 (SubString[1] == ' '))
613 {
614 Length = SubString - &SubBuffer[i] - 2;
615 break;
616 }
617
618 SubString++;
619 }
620
621 if (!Length)
622 {
623 Length = strlen (&SubBuffer[i+1]);
624 }
625
626 memmove (&SubBuffer[i+2], &SubBuffer[i+1], (Length+1));
627 SubBuffer[i+1] = '_';
628 i +=2;
629 TokenEnd++;
630 }
631 }
632
633 for (i = 0; i < (TokenEnd - SubBuffer); i++)
634 {
635 SubBuffer[i] = (char) toupper ((int) SubBuffer[i]);
636 }
637
638 SubBuffer = TokenEnd;
639 }
640 }
641 }
642