]> mj.ucw.cz Git - eval.git/blob - src/pedant.c
Ignore src/syscall-table.h.
[eval.git] / src / pedant.c
1 /*
2  *      A Pedantic Check of Text Input/Output File Syntax
3  *
4  *      (c) 2005--2007 Martin Mares <mj@ucw.cz>
5  */
6
7 #include <stdio.h>
8 #include <stdarg.h>
9 #include <stdlib.h>
10 #include <getopt.h>
11
12 static int max = -1;
13 static int no_stats;
14 static int line = 1;
15 static int warn_total, warn_shown;
16
17 static void warn(char *msg, ...)
18 {
19 #define NUM_TYPES 16
20   static char *seen[NUM_TYPES];
21   static int cnt[NUM_TYPES];
22   int type = 0;
23
24   va_list args;
25   va_start(args, msg);
26
27   warn_total++;
28   if (max >= 0)
29     {
30       for (type=0; type < NUM_TYPES && seen[type] && seen[type] != msg; type++)
31         ;
32       if (type >= NUM_TYPES)
33         goto done;
34       seen[type] = msg;
35       if (cnt[type]++ >= max)
36         goto done;
37     }
38   warn_shown++;
39   printf("Line %d: ", line);
40   vprintf(msg, args);
41   putchar('\n');
42 done:
43   va_end(args);
44 }
45
46 static void check(void)
47 {
48   int pos = 0;
49   int maxlen = 0;
50   int lastlen = -1;
51   int space = 0;
52   int c;
53   while ((c = getchar()) >= 0)
54     {
55       if (c == '\n')
56         {
57           if (space)
58             warn("Trailing spaces");
59           if (line == 1 && !pos)
60             warn("Leading empty line");
61           if (maxlen < pos)
62             maxlen = pos;
63           if (!lastlen && !pos)
64             warn("Consecutive empty lines");
65           lastlen = pos;
66           line++;
67           pos = space = 0;
68         }
69       else
70         {
71           if (c == ' ')
72             {
73               if (!pos)
74                 warn("Leading spaces");
75               if (space == 1)
76                 warn("Consecutive spaces");
77               space++;
78             }
79           else
80             {
81               space = 0;
82               if (c < ' ' || c >= 0x7f)
83                 warn("Invalid character 0x%02x", c);
84             }
85           pos++;
86         }
87     }
88   if (pos)
89     warn("Incomplete line at the end of file");
90   else if (!lastlen)
91     {
92       line--;
93       warn("Trailing empty line");
94       line++;
95     }
96   if (warn_shown < warn_total)
97     printf("(and %d more warnings)\n", warn_total - warn_shown);
98   if (!no_stats)
99     printf("Found %d lines, the longest has %d chars\n", line-1, maxlen);
100 }
101
102 static void usage(void)
103 {
104   fprintf(stderr, "Usage: pedant [-m <max>] [-s]\n");
105   exit(1);
106 }
107
108 int main(int argc, char **argv)
109 {
110   int opt;
111   while ((opt = getopt(argc, argv, "m:s")) >= 0)
112     switch (opt)
113       {
114       case 'm':
115         max = atoi(optarg);
116         break;
117       case 's':
118         no_stats++;
119         break;
120       default:
121         usage();
122       }
123   if (optind < argc)
124     usage();
125
126   check();
127   return 0;
128 }