build: depend on gnulib's calloc-gnu, not calloc
[cppi.git] / src / cppi.l
blob144911e60bdf638272b08423a80d6e924d51ee94
1 /* flex-lexer for cppi
2    Copyright (C) 1997-2019 Free Software Foundation, Inc.
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17 %option noyywrap
18 %top{
19 /* config.h must precede flex's inclusion of <stdio.h>
20    in order for its _GNU_SOURCE definition to take effect.  */
21 #include "config.h"
22 #include "system.h"
27 /* When output is inhibited, exit with status:
28    0 if all's ok
29    1 if indentation is wrong, or if text follows #else/#endif
30    2 if #if/#endif mismatch
31    3 if file error
32    */
34 #ifndef FLEX_SCANNER
35 # error This scanner must be made using flex, not lex.
36 #endif
38 #include <assert.h>
40 #include <sys/types.h>
41 #include <getopt.h>
43 #define _(msgid) gettext (msgid)
44 #define N_(msgid) msgid
46 #include "cpp.h"
47 #include "error.h"
48 #include "obstack.h"
49 #include "xstrtol.h"
51 /* The official name of this program (e.g., no `g' prefix).  */
52 #define PROGRAM_NAME "cppi"
54 #define AUTHORS "Jim Meyering"
56 #define obstack_chunk_alloc malloc
57 #define obstack_chunk_free free
59 #ifdef MY_DEBUG
60 # define PUT2(x,y) do { putchar (x); putchar (y); } while (0)
61 #else
62 # define PUT2(x,y) /* empty */
63 #endif
65 #undef YY_DECL
66 #define YY_DECL static int cpp_i (const char *in_file)
68 #undef isblank
69 #define isblank(c) ((c) == ' ' || (c) == '\t')
71 #define MY_ECHO do { if (!inhibit_output) ECHO; } while (0)
73 #define OPENER_STACK_HEIGHT \
74   (obstack_object_size (&opener_stack) / sizeof (struct KL_pair))
76 /* An entry on the stack of opener (keyword/line_number) specs.  */
77 struct KL_pair
79   /* The type of cpp directive opening a block: one of
80      EIC_IF, EIC_IFDEF, EIC_IFNDEF.  */
81   enum Eic_type opener_type;
83   /* The line number of the directive.  */
84   unsigned int line_number;
87 enum
89   EXIT_NOT_PROPERLY_INDENTED = 1,
90   EXIT_STRING_TOO_LONG = 1,
91   EXIT_LEX_ERROR = 2,
92   EXIT_FILE_ERROR = 3
95 /* A stack of cpp-opener-directive-spec/line-number pairs.
96    This lets us report the line numbers of any unmatched #if,
97    #ifdef, or #ifndef directives.  */
98 static struct obstack opener_stack;
100 /* Current nesting level.  */
101 static int i_depth;
103 /* Initial indentation nesting depth.  May be negative.
104    Use a value of -1 to cause code (usually header files) to be indented
105    one level less than otherwise.  This is useful if you don't want file-
106    enclosing ifdefs (e.g., #ifdef FOO_H/#define FOO_H/ ... #endif) to
107    cause every enclosed cpp directive to have at least one space between
108    the `#' and the cpp keyword.  */
109 static int initial_i_depth;
111 /* Nonzero means don't generate diagnostics about indentation, and print
112    to stdout only the names of files that aren't properly indented.  */
113 static int list_files_only;
115 /* Set to non-zero to enable ANSI-conformance check
116    (text after #else or #endif is non-ANSI).  */
117 static int ansi_check = 0;
119 /* Set to non-zero to inhibit non-error output.  */
120 static int inhibit_output = 0;
122 /* The maximum length of a double-quoted string.  Set to zero
123    to indicate there is no limit.  */
124 static unsigned long int max_string_length = 0;
126 static char *default_file_list[] = {(char *) "-", NULL};
128 static struct option const long_options[] =
130   {"ansi", no_argument, NULL, 'a'},
131   {"check", no_argument, NULL, 'c'},
132   {"list-files-only", no_argument, NULL, 'l'},
133   {"max-string-length", required_argument, NULL, 'm'},
134   {GETOPT_HELP_OPTION_DECL},
135   {GETOPT_VERSION_OPTION_DECL},
136   {NULL, 0, NULL, 0}
139 static void gobble_define (unsigned int *);
140 static void gobble_c_comment (const char *, unsigned int *);
141 static void gobble_line (unsigned int *);
143 /* Include gperf-generated hash function.  */
144 #include "cpp-cond.c"
146 #if __GNUC__ && ! __STRICT_ANSI__
147 /* this use of a statement-expression works only with gcc.  */
148 # define INPUT_AND_ECHO()                       \
149  ({                                             \
150    int _c_ = input ();                          \
151    if (_c_ != EOF && !inhibit_output)           \
152      fputc (_c_, yyout);                        \
153    _c_;                                         \
154  })
155 #else
156 /* Although the above is a macro, this function definition must
157    follow the declaration of inhibit_output, above.  */
158 static int input (void);
159 static int
160 INPUT_AND_ECHO (void)
162   int _c_ = input ();
163   if (_c_ != EOF && !inhibit_output)
164     fputc (_c_, yyout);
165   return _c_;
167 #endif
169 /* PREFIX is the cpp line from beginning of line to end of the keyword
170    following the `#'.  */
172 static enum Eic_type
173 lookup_cpp_keyword (const char *prefix, size_t len, const char **kw)
175   /* Find the beginning of the keyword.  */
176   const char *p;
177   for (p = prefix; ; ++p, --len)
178     {
179       switch (*p)
180         {
181         case '#':
182         case ' ':
183         case '\t':
184           break;
186         default:
187           {
188             struct KW const *ent = cpp_cond_lookup (p, len);
189             *kw = p;
190             return (ent ? ent->code : EIC_OTHER);
191           }
192         }
193       assert (len > 0);
194     }
197 static inline struct KL_pair
198 kth_entry (unsigned int k)
200   struct KL_pair *s = (struct KL_pair *) obstack_base (&opener_stack);
201   assert (k < OPENER_STACK_HEIGHT);
202   return s[k];
205 static inline void
206 pop (void)
208   int pair_size = sizeof (struct KL_pair);
209   assert (OPENER_STACK_HEIGHT > 0);
210   obstack_blank_fast (&opener_stack, -pair_size);
213 static inline void
214 push (enum Eic_type opener_type, unsigned int line_number)
216   struct KL_pair pair;
217   pair.opener_type = opener_type;
218   pair.line_number = line_number;
220   obstack_grow (&opener_stack, &pair, sizeof (struct KL_pair));
223 static int
224 emit_or_check (enum Eic_type type, const char *text, const char *other)
226   int fail = 1;
228   if (inhibit_output)
229     {
230       int n;
231       int depth = (i_depth < 0 ? 0 : i_depth);
232       if ((text[0] == '#'
233            && (n = strspn (text + 1, " ")) == depth
234            && !isblank (text[1 + n]))
235           /* This allows pragmas to have exactly one space before the `#'.
236              E.g., ` #pragma alloca' or ` #  pragma alloca' .  */
237           || (text[0] == ' '
238               && text[1] == '#'
239               && type == EIC_PRAGMA
240               && (n = strspn (text + 2, " ")) == depth - 1
241               && text[n + 2] == 'p'))
242         {
243           fail = 0;
244         }
245     }
246   else
247     {
248       int i;
249       const char *dir = (type == EIC_OTHER ? other : directive[type]);
250       int space_first = (type == EIC_PRAGMA && text[0] == ' ');
252       if (space_first)
253         {
254           fputc (' ', yyout);
255           fputc ('#', yyout);
256           for (i = 0; i < i_depth - 1; i++)
257             fputc (' ', yyout);
258         }
259       else
260         {
261           fputc ('#', yyout);
262           for (i = 0; i < i_depth; i++)
263             fputc (' ', yyout);
264         }
266       fputs (dir, yyout);
268       fail = 0;
269     }
271   return fail;
274 static enum Eic_type
275 emit_indented_cpp (char const *in_file, unsigned int line_number,
276                    char const *text, size_t len, int *fail)
278   const char *keyword;
279   enum Eic_type t = lookup_cpp_keyword (text, len, &keyword);
281   *fail = 0;
283   switch (t)
284     {
285     case EIC_IF:
286     case EIC_IFDEF:
287     case EIC_IFNDEF:
288       /* Maintain a stack of (keyword, line number) pairs to better
289          report any `unterminated #if...' errors.  Put a new pair
290          on the stack.  */
291       push (t, line_number);
293       *fail = emit_or_check (t, yytext, keyword);
294       ++i_depth;
295       break;
297     case EIC_ELSE:
298     case EIC_ELIF:
299       if (i_depth <= initial_i_depth)
300         {
301           if (!list_files_only)
302             {
303               error (0, 0, _("%s: line %d: found #%s without matching #if"),
304                      in_file, line_number, directive[t]);
305             }
306           i_depth = 0;
307           emit_or_check (t, yytext, keyword);
308           *fail = 2;
309         }
310       else
311         {
312           --i_depth;
313           *fail = emit_or_check (t, yytext, keyword);
314           ++i_depth;
315         }
316       break;
318     case EIC_ENDIF:
319       if (i_depth <= initial_i_depth)
320         {
321           if (!list_files_only)
322             {
323               error (0, 0, _("%s: line %d: found #%s without matching #if"),
324                      in_file, line_number, directive[t]);
325             }
326           i_depth = initial_i_depth + 1;
327           *fail = 2;
328         }
329       else
330         {
331           /* We've just found an #endif.  Pop off and discard the
332              keyword,line-number pair that's on the top of the stack.
333              That pair identifies the matching #if, #ifdef, or #ifndef.  */
334           pop ();
335         }
337       --i_depth;
338       {
339         int tf = emit_or_check (t, yytext, keyword);
340         if (tf > *fail)
341           *fail = tf;
342       }
343       break;
345     case EIC_PRAGMA:
346     case EIC_DEFINE:
347     case EIC_OTHER:
348       *fail = emit_or_check (t, yytext, keyword);
349       break;
351     case EIC_INVALID:
352     default:
353       abort ();
354     }
356   if (*fail == EXIT_NOT_PROPERLY_INDENTED)
357     {
358       if (!list_files_only)
359         error (0, 0, _("%s: line %d: not properly indented"),
360                in_file, line_number);
361     }
363   return t;
368 w [a-zA-Z_]
369 b [^a-zA-Z_\n]
374   /* This section contains dcls and code that is local to the
375      scanning routine.  */
377   /* Current line number -- for diagnostics and errors.  */
378   unsigned int lineno = 1;
380   int lex_fail = 0;
382   obstack_init (&opener_stack);
384   initial_i_depth = 0;
385   i_depth = initial_i_depth;
389 "/*"        {
390   PUT2 ('[', '\0');
391   MY_ECHO;
392   gobble_c_comment (in_file, &lineno);
393   PUT2 ('\0', ']');
396 "//"        {
397   MY_ECHO;
398   gobble_line (&lineno);
401 "'"\\?"\"'" {
402   /* We need this rule so that the double quote in the character literal,
403      '"' (also written as '\"'), is not interpreted as a string opener.  */
404   MY_ECHO;
407 "'\\"/"\"" {
408   /* This rule is included to make flex's scanner more efficient
409      by avoiding backup states.  */
410   MY_ECHO;
412 "'\\"    { /* Likewise.  */ MY_ECHO;}
413 "'"/"\"" { /* Likewise.  */ MY_ECHO; }
415 "\"" {
416   register int c;
417   int start_lineno = lineno;
419   /* Count consecutive backslashes.  We'll need this number when
420      a string of them immediately precedes a double quote.  */
421   size_t n_backslashes = 0;
422   size_t string_length = 0;
423   int fail = 0;
425   PUT2 ('[', '\0');
426   MY_ECHO;
428   while (1)
429     {
430       c = INPUT_AND_ECHO ();
432       if (c == EOF)
433         {
434           error (0, 0, _("%s: line %d: EOF in string"),
435                  in_file, start_lineno);
436           fail = EXIT_LEX_ERROR;
437           break;
438         }
440       /* If the number of preceding backslashes is even, then this is
441          an unescaped double quote, and it marks the end of the string.  */
442       if (c == '"' && n_backslashes % 2 == 0)
443         break;
445       n_backslashes = (c == '\\' ? n_backslashes + 1 : 0);
447       /* Some compilers (irix4's cc) impose a limit on the length of a
448          double quoted string.  It's probably a limit on the length of
449          the actual value of the string, rather than on the number of
450          bytes between `"'s in the source, but I'm not sure it's worth
451          the trouble of computing the former.  */
452       ++string_length;
454       if (c == '\n')
455         ++lineno;
456     }
458   PUT2 ('\0', ']');
460   if (0 < max_string_length && max_string_length < string_length)
461     {
462       error (0, 0, _("%s: line %d: string (%lu) longer than maximum of %lu"),
463              in_file, start_lineno, (unsigned long) string_length,
464              (unsigned long) max_string_length);
465       if (fail == 0)
466         lex_fail = EXIT_STRING_TOO_LONG;
467     }
469   if (fail)
470     lex_fail = 1;
473 ^[ \t]*#[ \t]*[a-zA-Z0-9_]+   {
474   enum Eic_type t;
475   int fail;
477   t = emit_indented_cpp (in_file, lineno, yytext, yyleng, &fail);
479   if (t == EIC_IF || t == EIC_IFNDEF || t == EIC_ELIF || t == EIC_DEFINE)
480     {
481       int c;
482       if (inhibit_output)
483         {
484           /* Make sure there's exactly one space after this directive.  */
485           c = input ();
486           if (c != ' ' || ((c = input ()) == ' ' || c == '\t' || c == EOF))
487             {
488               if (!list_files_only)
489                 {
490                   error (0, 0, _("%s: line %d: not properly formatted;\n\
491 there must be exactly one SPACE character after each\n\
492 #if, #elif, and #define directive"),
493                          in_file, lineno);
494                 }
495               if (fail < 1)
496                 fail = 1;
497             }
498         }
499       else
500         {
501           /* Squeeze multiple spaces and tabs after an #if or #elif
502              directive to a single space.  */
503           fputc (' ', yyout);
504           while ((c = input ()) == ' ' || c == '\t')
505             {
506               /* empty */
507             }
508         }
509       unput (c);
510       if (t == EIC_DEFINE)
511         {
512           gobble_define (&lineno);
513         }
514     }
515   else if (ansi_check && (t == EIC_ELSE || t == EIC_ENDIF))
516     {
517       /* If requested, make sure there's nothing after an #else or #endif.  */
518       int found_non_ansi = 0;
519       int cpp_directive_lineno = lineno;
520       int c;
521       while ((c = INPUT_AND_ECHO ()) != EOF)
522         {
523           if (isblank (c))
524             continue;
525           if (c == '/')
526             {
527               c = INPUT_AND_ECHO ();
528               if (c == EOF)
529                 break;
530               if (c == '*')
531                 {
532                   gobble_c_comment (in_file, &lineno);
533                   continue;
534                 }
535               if (c == '/')
536                 {
537                   gobble_line (&lineno);
538                   break;
539                 }
541               /* else, fall through to next if-stmt */
542             }
544           if (c == '\n')
545             {
546               ++lineno;
547               break;
548             }
550           /* We've found a token after an #else or #endif.
551              Continue reading to end of line.  */
552           found_non_ansi = 1;
553         }
555       if (found_non_ansi)
556         {
557           if (!list_files_only)
558             error (0, 0,
559               _("%s: line %d: text following `#%s' violates ANSI standard"),
560                    in_file, cpp_directive_lineno,
561                    (t == EIC_ELSE ? "else" : "endif"));
562           if (fail < 1)
563             fail = 1;
564         }
565     }
567   if (fail > lex_fail)
568     lex_fail = fail;
570 ^[ \t]*#[ \t]*            { MY_ECHO; }
571 ^[ \t]*                   { MY_ECHO; }
573 \n                        { MY_ECHO; ++lineno; }
574 .                         { MY_ECHO; }
576 <<EOF>> {
577   if (i_depth != initial_i_depth)
578     {
579       if (!list_files_only)
580         {
581           /* Iterate the opener stack from bottom to top, giving a
582              diagnostic per unterminated #if* directive.
583              Torture this code with a command like this:
584              $ yes '#if FOO' |head -600 |cppi -c */
585           unsigned int i;
586           for (i = 0; i < OPENER_STACK_HEIGHT; i++)
587             {
588               struct KL_pair x = kth_entry (i);
589               error (0, 0, _("%s: line %d: unterminated #%s"),
590                      in_file, x.line_number, directive[x.opener_type]);
591             }
592         }
594       lex_fail = EXIT_LEX_ERROR;
595     }
597   return lex_fail;
602 static int
603 cpp_indent (const char *in_file)
605   FILE *in = NULL;
606   int fail;
608   if (STREQ (in_file, "-"))
609     {
610       yyin = stdin;
611       in_file = "standard input";
612     }
613   else
614     {
615       if ((in = fopen (in_file, "r")) == NULL)
616         {
617           error (EXIT_FILE_ERROR, errno, "%s", in_file);
618         }
619       yyin = in;
620     }
622   fail = cpp_i (in_file);
624   obstack_free (&opener_stack, NULL);
626   if (in && fclose (in) == EOF)
627     error (EXIT_FILE_ERROR, errno, "%s", in_file);
629   return fail;
632 static void usage (int status) ATTRIBUTE_NORETURN;
633 static void
634 usage (int status)
636   if (status != 0)
637     {
638       fprintf (stderr, "Try `%s --help' for more information.\n",
639                program_name);
640     }
641   else
642     {
643       printf (_("\
644 Usage: %s [FILE]\n\
645   or:  %s -c [OPTION] [FILE]...\n\
646 "), program_name, program_name);
647       fputs (_("\
649 Indent the C preprocessor directives in FILE to reflect their nesting\n\
650 and ensure that there is exactly one space character between each #if,\n\
651 #elif, #define directive and the following token, and write the result\n\
652 "), stdout);
653       fputs (_("\
654 to standard output.  The number of spaces between the `#' and the following\n\
655 directive must correspond to the level of nesting of that directive.\n\
656 With no FILE, or when FILE is -, read standard input.\n\
657 "), stdout);
658       fputs (_("\
660   -a, --ansi             when checking, fail if text follows #else or #endif\n\
661   -c, --check            set exit code, but don't produce any output\n\
662   -l, --list-files-only  don't generate diagnostics about indentation;\n\
663                          print to stdout only the names of files that\n\
664                          are not properly indented\n\
665 "), stdout);
666       fputs (_("\
667   -m, --max-string-length=LENGTH\n\
668                          fail if there is a double-quoted string longer\n\
669                          than LENGTH;  if LENGTH is 0 (the default),\n\
670                          then there is no limit\n\
671 "), stdout);
672       fputs (HELP_OPTION_DESCRIPTION, stdout);
673       fputs (VERSION_OPTION_DESCRIPTION, stdout);
674       fputs (_("\n\
675 With the -c option, don't write to stdout.  Instead, check the\n\
676 indentation of the specified files giving diagnostics for preprocessor\n\
677 lines that aren't properly indented or are otherwise invalid.\n\
678 "), stdout);
679       fputs (_("\
681 Note that --ansi without --check does not correct the problem of\n\
682 non-ANSI text following #else and #endif directives.\n\
683 "), stdout);
684       fputs (_("\
686 The exit code will be one of these:\n\
687   0  all directives properly indented\n\
688   1  some cpp directive(s) improperly indented, or\n\
689      text follows #else/#endif (enabled with --check --ansi), or\n\
690      a double-quoted string is longer than the specified maximum\n\
691   2  #if/#endif mismatch, EOF in comment or string\n\
692   3  file (e.g. open/read/write) error\n\
693 "), stdout);
694       fputs (_("\
696 A pragma directive may have its `#' indented.\n\
697 "), stdout);
698       printf (_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
699     }
700   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
703 /* Read the body of a #define directive (echoing or not, as appropriate).
704    That is, read up to and including the first unescaped newline (or EOF).
705    This is necessary because otherwise, we could mistakenly interpret the
706    stringification of a macro argument as a cpp directive.  */
708 static void
709 gobble_define (unsigned int *line_number)
711   int c;
712   int backslash_count = 0;
713   while ((c = INPUT_AND_ECHO ()) != EOF)
714     {
715       if (c == '\n')
716         {
717           ++(*line_number);
718           if (backslash_count % 2 == 0)
719             break;
720         }
722       if (c == '\\')
723         ++backslash_count;
724       else
725         backslash_count = 0;
726     }
729 /* We've read the C comment opener.  Read up to and including
730    the closing delimiter.  */
732 static void
733 gobble_c_comment (const char *in_file, unsigned int *line_number)
735   int start_lineno = *line_number;
736   for ( ; ; )
737     {
738       int c;
739       while ((c = INPUT_AND_ECHO ()) != '*' && c != EOF)
740         {
741           if (c == '\n')
742             ++(*line_number);
743         }
745       if (c == '*')
746         {
747           while ((c = INPUT_AND_ECHO ()) == '*')
748             ;
749           if (c == '/')
750             break;    /* found the end */
751           if (c == '\n')
752             ++(*line_number);
753         }
755       if (c == EOF)
756         {
757           error (EXIT_LEX_ERROR, 0, _("%s: line %d: EOF in comment"),
758                  in_file, start_lineno);
759           break;
760         }
761     }
764 /* Read up to and including any newline.  */
766 static void
767 gobble_line (unsigned int *line_number)
769   int c;
770   while ((c = INPUT_AND_ECHO ()) != EOF)
771     {
772       if (c == '\n')
773         {
774           ++(*line_number);
775           break;
776         }
777     }
781 main (int argc, char **argv)
783   int i;
784   int max_err;
785   char **file_list;
786   int c;
787   int fail = 0;
789   set_program_name (argv[0]);
790   setlocale (LC_ALL, "");
791   bindtextdomain (PACKAGE, LOCALEDIR);
792   textdomain (PACKAGE);
794   atexit (close_stdout);
796   while ((c = getopt_long (argc, argv, "aclm:", long_options, NULL)) != -1)
797     {
798       switch (c)
799         {
800         case 0:
801           break;
803         case 'a':
804           ansi_check = 1;
805           break;
807         case 'c':
808           inhibit_output = 1;
809           break;
811         case 'l':
812           inhibit_output = 1;
813           list_files_only = 1;
814           break;
816         case 'm':
817           if (xstrtoul (optarg, NULL, 0, &max_string_length, NULL)
818               != LONGINT_OK)
819             {
820               error (0, 0, _("invalid maximum string length %s"), optarg);
821               fail = 1;
822             }
823           break;
825         case_GETOPT_HELP_CHAR;
827         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
829         default:
830           usage (EXIT_LEX_ERROR);
831           break;
832         }
833     }
835   if (fail)
836     exit (EXIT_FAILURE);
838   if (!inhibit_output && argc - optind > 2)
839     {
840       error (0, 0, _("too many arguments"));
841       usage (EXIT_FAILURE);
842     }
844   file_list = (optind == argc ? default_file_list : argv + optind);
846   max_err = 0;
847   for (i = 0; file_list[i]; i++)
848     {
849       int err;
851       err = cpp_indent (file_list[i]);
852       if (err > max_err)
853         max_err = err;
855       if (err && list_files_only)
856         puts (file_list[i]);
857     }
859   exit (max_err);
863   Local Variables:
864   mode: c
865   End: