1 /******************************************************************************
2  *
3  * Module Name: ascase - Source conversion - lower/upper case utilities
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include "acpisrc.h"
153 
154 /* Local prototypes */
155 
156 void
157 AsUppercaseTokens (
158     char                    *Buffer,
159     char                    *PrefixString);
160 
161 
162 /******************************************************************************
163  *
164  * FUNCTION:    AsLowerCaseString
165  *
166  * DESCRIPTION: LowerCase all instances of a target string with a replacement
167  *              string. Returns count of the strings replaced.
168  *
169  ******************************************************************************/
170 
171 int
172 AsLowerCaseString (
173     char                    *Target,
174     char                    *Buffer)
175 {
176     char                    *SubString1;
177     char                    *SubString2;
178     char                    *SubBuffer;
179     int                     TargetLength;
180     int                     LowerCaseCount = 0;
181     int                     i;
182 
183 
184     TargetLength = strlen (Target);
185 
186     SubBuffer = Buffer;
187     SubString1 = Buffer;
188 
189     while (SubString1)
190     {
191         /* Find the target string */
192 
193         SubString1 = strstr (SubBuffer, Target);
194         if (!SubString1)
195         {
196             return (LowerCaseCount);
197         }
198 
199         /*
200          * Check for translation escape string -- means to ignore
201          * blocks of code while replacing
202          */
203         if (Gbl_IgnoreTranslationEscapes)
204         {
205             SubString2 = NULL;
206         }
207         else
208         {
209             SubString2 = strstr (SubBuffer, AS_START_IGNORE);
210         }
211 
212         if ((SubString2) &&
213             (SubString2 < SubString1))
214         {
215             /* Find end of the escape block starting at "Substring2" */
216 
217             SubString2 = strstr (SubString2, AS_STOP_IGNORE);
218             if (!SubString2)
219             {
220                 /* Didn't find terminator */
221 
222                 return (LowerCaseCount);
223             }
224 
225             /* Move buffer to end of escape block and continue */
226 
227             SubBuffer = SubString2;
228         }
229 
230         /* Do the actual replace if the target was found */
231 
232         else
233         {
234             if (!AsMatchExactWord (SubString1, TargetLength))
235             {
236                 SubBuffer = SubString1 + 1;
237                 continue;
238             }
239 
240             for (i = 0; i < TargetLength; i++)
241             {
242                 SubString1[i] = (char) tolower ((int) SubString1[i]);
243             }
244 
245             SubBuffer = SubString1 + TargetLength;
246 
247             if ((Gbl_WidenDeclarations) && (!Gbl_StructDefs))
248             {
249                 if ((SubBuffer[0] == ' ') && (SubBuffer[1] == ' '))
250                 {
251                     AsInsertData (SubBuffer, "        ", 8);
252                 }
253             }
254 
255             LowerCaseCount++;
256         }
257     }
258 
259     return (LowerCaseCount);
260 }
261 
262 
263 /******************************************************************************
264  *
265  * FUNCTION:    AsMixedCaseToUnderscores
266  *
267  * DESCRIPTION: Converts mixed case identifiers to underscored identifiers.
268  *              for example,
269  *
270  *              ThisUsefullyNamedIdentifier   becomes:
271  *
272  *              this_usefully_named_identifier
273  *
274  ******************************************************************************/
275 
276 void
277 AsMixedCaseToUnderscores (
278     char                    *Buffer,
279     char                    *Filename)
280 {
281     UINT32                  Length;
282     char                    *SubBuffer = Buffer;
283     char                    *TokenEnd;
284     char                    *TokenStart = NULL;
285     char                    *SubString;
286     UINT32                  LineNumber = 1;
287     UINT32                  Count;
288 
289 
290     /*
291      * Examine the entire buffer (contains the entire file)
292      * We are only interested in these tokens:
293      *      Escape sequences - ignore entire sequence
294      *      Single-quoted constants - ignore
295      *      Quoted strings - ignore entire string
296      *      Translation escape - starts with /,*,!
297      *      Decimal and hex numeric constants - ignore entire token
298      *      Entire uppercase token - ignore, it is a macro or define
299      *      Starts with underscore, then a lowercase or digit: convert
300      */
301     while (*SubBuffer)
302     {
303         if (*SubBuffer == '\n')
304         {
305             LineNumber++;
306             SubBuffer++;
307             continue;
308         }
309 
310         /* Ignore standard escape sequences (\n, \r, etc.)  Not Hex or Octal escapes */
311 
312         if (*SubBuffer == '\\')
313         {
314             SubBuffer += 2;
315             continue;
316         }
317 
318         /* Ignore single-quoted characters */
319 
320         if (*SubBuffer == '\'')
321         {
322             SubBuffer += 3;
323             continue;
324         }
325 
326         /* Ignore standard double-quoted strings */
327 
328         if (*SubBuffer == '"')
329         {
330             SubBuffer++;
331             Count = 0;
332             while (*SubBuffer != '"')
333             {
334                 Count++;
335                 if ((!*SubBuffer) ||
336                      (Count > 8192))
337                 {
338                     printf ("Found an unterminated quoted string!, line %u: %s\n",
339                         LineNumber, Filename);
340                     return;
341                 }
342 
343                 /* Handle escape sequences */
344 
345                 if (*SubBuffer == '\\')
346                 {
347                     SubBuffer++;
348                 }
349 
350                 SubBuffer++;
351             }
352 
353             SubBuffer++;
354             continue;
355         }
356 
357         /*
358          * Check for translation escape string. It means to ignore
359          * blocks of code during this code conversion.
360          */
361         if ((SubBuffer[0] == '/') &&
362             (SubBuffer[1] == '*') &&
363             (SubBuffer[2] == '!'))
364         {
365             SubBuffer = strstr (SubBuffer, "!*/");
366             if (!SubBuffer)
367             {
368                 printf ("Found an unterminated translation escape!, line %u: %s\n",
369                     LineNumber, Filename);
370                 return;
371             }
372 
373             continue;
374         }
375 
376         /* Ignore anything that starts with a number (0-9) */
377 
378         if (isdigit ((int) *SubBuffer))
379         {
380             /* Ignore hex constants */
381 
382             if ((SubBuffer[0] == '0') &&
383                ((SubBuffer[1] == 'x') || (SubBuffer[1] == 'X')))
384             {
385                 SubBuffer += 2;
386             }
387 
388             /* Skip over all digits, both decimal and hex */
389 
390             while (isxdigit ((int) *SubBuffer))
391             {
392                 SubBuffer++;
393             }
394             TokenStart = NULL;
395             continue;
396         }
397 
398         /*
399          * Check for fully upper case identifiers. These are usually macros
400          * or defines. Allow decimal digits and embedded underscores.
401          */
402         if (isupper ((int) *SubBuffer))
403         {
404             SubString = SubBuffer + 1;
405             while ((isupper ((int) *SubString)) ||
406                    (isdigit ((int) *SubString)) ||
407                    (*SubString == '_'))
408             {
409                 SubString++;
410             }
411 
412             /*
413              * For the next character, anything other than a lower case
414              * means that the identifier has terminated, and contains
415              * exclusively Uppers/Digits/Underscores. Ignore the entire
416              * identifier.
417              */
418             if (!islower ((int) *SubString))
419             {
420                 SubBuffer = SubString + 1;
421                 continue;
422             }
423         }
424 
425         /*
426          * These forms may indicate an identifier that can be converted:
427          *      <UpperCase><LowerCase> (Ax)
428          *      <UpperCase><Number> (An)
429          */
430         if (isupper ((int) SubBuffer[0]) &&
431           ((islower ((int) SubBuffer[1])) || isdigit ((int) SubBuffer[1])))
432         {
433             TokenStart = SubBuffer;
434             SubBuffer++;
435 
436             while (1)
437             {
438                 /* Walk over the lower case letters and decimal digits */
439 
440                 while (islower ((int) *SubBuffer) ||
441                        isdigit ((int) *SubBuffer))
442                 {
443                     SubBuffer++;
444                 }
445 
446                 /* Check for end of line or end of token */
447 
448                 if (*SubBuffer == '\n')
449                 {
450                     LineNumber++;
451                     break;
452                 }
453 
454                 if (*SubBuffer == ' ')
455                 {
456                     /* Check for form "Axx - " in a parameter header description */
457 
458                     while (*SubBuffer == ' ')
459                     {
460                         SubBuffer++;
461                     }
462 
463                     SubBuffer--;
464                     if ((SubBuffer[1] == '-') &&
465                         (SubBuffer[2] == ' '))
466                     {
467                         if (TokenStart)
468                         {
469                             *TokenStart = (char) tolower ((int) *TokenStart);
470                         }
471                     }
472                     break;
473                 }
474 
475                 /*
476                  * Ignore these combinations:
477                  *      <Letter><Digit><UpperCase>
478                  *      <Digit><Digit><UpperCase>
479                  *      <Underscore><Digit><UpperCase>
480                  */
481                 if (isdigit ((int) *SubBuffer))
482                 {
483                     if (isalnum ((int) *(SubBuffer-1)) ||
484                         *(SubBuffer-1) == '_')
485                     {
486                         break;
487                     }
488                 }
489 
490                 /* Ignore token if next character is not uppercase or digit */
491 
492                 if (!isupper ((int) *SubBuffer) &&
493                     !isdigit ((int) *SubBuffer))
494                 {
495                     break;
496                 }
497 
498                 /*
499                  * Form <UpperCase><LowerCaseLetters><UpperCase> (AxxB):
500                  * Convert leading character of the token to lower case
501                  */
502                 if (TokenStart)
503                 {
504                     *TokenStart = (char) tolower ((int) *TokenStart);
505                     TokenStart = NULL;
506                 }
507 
508                 /* Find the end of this identifier (token) */
509 
510                 TokenEnd = SubBuffer - 1;
511                 while ((isalnum ((int) *TokenEnd)) ||
512                        (*TokenEnd == '_'))
513                 {
514                     TokenEnd++;
515                 }
516 
517                 SubString = TokenEnd;
518                 Length = 0;
519 
520                 while (*SubString != '\n')
521                 {
522                     /*
523                      * If we have at least two trailing spaces, we can get rid of
524                      * one to make up for the newly inserted underscore. This will
525                      * help preserve the alignment of the text
526                      */
527                     if ((SubString[0] == ' ') &&
528                         (SubString[1] == ' '))
529                     {
530                         Length = SubString - SubBuffer - 1;
531                         break;
532                     }
533 
534                     SubString++;
535                 }
536 
537                 if (!Length)
538                 {
539                     Length = strlen (&SubBuffer[0]);
540                 }
541 
542                 /*
543                  * Within this identifier, convert this pair of letters that
544                  * matches the form:
545                  *
546                  *      <LowerCase><UpperCase>
547                  * to
548                  *      <LowerCase><Underscore><LowerCase>
549                  */
550                 Gbl_MadeChanges = TRUE;
551 
552                 /* Insert the underscore */
553 
554                 memmove (&SubBuffer[1], &SubBuffer[0], Length + 1);
555                 SubBuffer[0] = '_';
556 
557                 /*
558                  * If we have <UpperCase><UpperCase>, leave them as-is
559                  * Enables transforms like:
560                  *      LocalFADT -> local_FADT
561                  */
562                 if (isupper ((int) SubBuffer[2]))
563                 {
564                     SubBuffer += 1;
565                     break;
566                 }
567 
568                 /* Lower case the original upper case letter */
569 
570                 SubBuffer[1] = (char) tolower ((int) SubBuffer[1]);
571                 SubBuffer += 2;
572             }
573         }
574 
575         SubBuffer++;
576     }
577 }
578 
579 
580 /******************************************************************************
581  *
582  * FUNCTION:    AsLowerCaseIdentifiers
583  *
584  * DESCRIPTION: Converts mixed case identifiers to lower case. Leaves comments,
585  *              quoted strings, and all-upper-case macros alone.
586  *
587  ******************************************************************************/
588 
589 void
590 AsLowerCaseIdentifiers (
591     char                    *Buffer)
592 {
593     char                    *SubBuffer = Buffer;
594 
595 
596     while (*SubBuffer)
597     {
598         /*
599          * Check for translation escape string -- means to ignore
600          * blocks of code while replacing
601          */
602         if ((SubBuffer[0] == '/') &&
603             (SubBuffer[1] == '*') &&
604             (SubBuffer[2] == '!'))
605         {
606             SubBuffer = strstr (SubBuffer, "!*/");
607             if (!SubBuffer)
608             {
609                 return;
610             }
611         }
612 
613         /* Ignore comments */
614 
615         if ((SubBuffer[0] == '/') &&
616             (SubBuffer[1] == '*'))
617         {
618             SubBuffer = strstr (SubBuffer, "*/");
619             if (!SubBuffer)
620             {
621                 return;
622             }
623 
624             SubBuffer += 2;
625         }
626 
627         /* Ignore quoted strings */
628 
629         if ((SubBuffer[0] == '\"') && (SubBuffer[1] != '\''))
630         {
631             SubBuffer++;
632 
633             /* Find the closing quote */
634 
635             while (SubBuffer[0])
636             {
637                 /* Ignore escaped quote characters */
638 
639                 if (SubBuffer[0] == '\\')
640                 {
641                     SubBuffer++;
642                 }
643                 else if (SubBuffer[0] == '\"')
644                 {
645                     SubBuffer++;
646                     break;
647                 }
648 
649                 SubBuffer++;
650             }
651         }
652 
653         if (!SubBuffer[0])
654         {
655             return;
656         }
657 
658         /*
659          * Only lower case if we have an upper followed by a lower
660          * This leaves the all-uppercase things (macros, etc.) intact
661          */
662         if ((isupper ((int) SubBuffer[0])) &&
663             (islower ((int) SubBuffer[1])))
664         {
665             Gbl_MadeChanges = TRUE;
666             *SubBuffer = (char) tolower ((int) *SubBuffer);
667         }
668 
669         SubBuffer++;
670     }
671 }
672 
673 
674 /******************************************************************************
675  *
676  * FUNCTION:    AsUppercaseTokens
677  *
678  * DESCRIPTION: Force to uppercase all tokens that begin with the prefix string.
679  *              used to convert mixed-case macros and constants to uppercase.
680  *
681  ******************************************************************************/
682 
683 void
684 AsUppercaseTokens (
685     char                    *Buffer,
686     char                    *PrefixString)
687 {
688     char                    *SubBuffer;
689     char                    *TokenEnd;
690     char                    *SubString;
691     int                     i;
692     UINT32                  Length;
693 
694 
695     SubBuffer = Buffer;
696 
697     while (SubBuffer)
698     {
699         SubBuffer = strstr (SubBuffer, PrefixString);
700         if (SubBuffer)
701         {
702             TokenEnd = SubBuffer;
703             while ((isalnum ((int) *TokenEnd)) || (*TokenEnd == '_'))
704             {
705                 TokenEnd++;
706             }
707 
708             for (i = 0; i < (TokenEnd - SubBuffer); i++)
709             {
710                 if ((islower ((int) SubBuffer[i])) &&
711                     (isupper ((int) SubBuffer[i+1])))
712                 {
713 
714                     SubString = TokenEnd;
715                     Length = 0;
716 
717                     while (*SubString != '\n')
718                     {
719                         if ((SubString[0] == ' ') &&
720                             (SubString[1] == ' '))
721                         {
722                             Length = SubString - &SubBuffer[i] - 2;
723                             break;
724                         }
725 
726                         SubString++;
727                     }
728 
729                     if (!Length)
730                     {
731                         Length = strlen (&SubBuffer[i+1]);
732                     }
733 
734                     memmove (&SubBuffer[i+2], &SubBuffer[i+1], (Length+1));
735                     SubBuffer[i+1] = '_';
736                     i +=2;
737                     TokenEnd++;
738                 }
739             }
740 
741             for (i = 0; i < (TokenEnd - SubBuffer); i++)
742             {
743                 SubBuffer[i] = (char) toupper ((int) SubBuffer[i]);
744             }
745 
746             SubBuffer = TokenEnd;
747         }
748     }
749 }
750