aboutsummaryrefslogtreecommitdiffstats
path: root/src/man/preproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/man/preproc.c')
-rw-r--r--src/man/preproc.c146
1 files changed, 146 insertions, 0 deletions
diff --git a/src/man/preproc.c b/src/man/preproc.c
new file mode 100644
index 000000000..34a49d335
--- /dev/null
+++ b/src/man/preproc.c
@@ -0,0 +1,146 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <assert.h>
5
6#define MAXBUF 4096
7#define MAXMACROS 64
8static char *macro[MAXMACROS] = {NULL};
9
10static void add_macro(char *m) {
11 assert(m);
12 int i;
13 for (i = 0; i < MAXMACROS && macro[i]; i++);
14 if (i == MAXMACROS) {
15 fprintf(stderr, "Error: maximum number of marcros (%d) exceeded\n", MAXMACROS);
16 exit(1);
17 }
18
19 macro[i] = m;
20}
21
22static char *find_macro(char *m) {
23 assert(m);
24 int i = 0;
25 while (i < MAXMACROS && macro[i]) {
26 if (strcmp(macro[i], m) == 0)
27 return m;
28 i++;
29 }
30
31 return NULL;
32}
33
34static void usage(void) {
35 printf("Simple preprocessor for man pages. It supports:\n");
36 printf("\t#if 0 ... #endif\n");
37 printf("\t#ifdef macro ... #endif\n");
38 printf("Usage: preproc [--help] [-Dmacro] manpage.txt\n");
39 return;
40}
41
42
43int main(int argc, char **argv) {
44 if (argc == 1) {
45 fprintf(stderr, "Error: no files/arguments provided\n");
46 usage();
47 exit(1);
48 }
49
50 int i;
51 for (i = 1; i < argc; i++) {
52 if (strncmp(argv[i], "-D", 2) == 0)
53 add_macro(argv[i] + 2);
54 else if (strcmp(argv[i], "--help") == 0) {
55 usage();
56 return 0;
57 }
58 else if (*argv[i] == '-') {
59 fprintf(stderr, "Error: invalid argument %s\n", argv[i]);
60 exit(1);
61 }
62 else
63 break;
64 }
65
66 char *ptr = strstr(argv[i], ".txt");
67 if (!ptr || strlen(ptr) != 4) {
68 fprintf(stderr, "Error: input file needs to have a .txt extension\n"),
69 exit(1);
70 }
71
72 FILE *fp = fopen(argv[i], "r");
73 if (!fp) {
74 fprintf(stderr, "Error: cannot open %s\n", argv[i]);
75 exit(1);
76 }
77 char *outfile = strdup(argv[i]);
78 if (!outfile)
79 goto errout;
80 ptr = strstr(outfile, ".txt");
81 assert(ptr);
82 strcpy(ptr, ".man");
83 FILE *fpout = fopen(outfile, "w");
84 if (!fpout)
85 goto errout;
86
87 char buf[MAXBUF];
88 int disabled = 0;
89 int enabled = 0;
90 int line = 0;;
91 while (fgets(buf, MAXBUF, fp)) {
92 line++;
93 if (disabled && strncmp(buf, "#if", 3) == 0) {
94 fprintf(stderr, "Error %d: already in a #if block on line %d\n", __LINE__, line);
95 exit(1);
96 }
97 if ((!disabled && !enabled) && strncmp(buf, "#endif", 6) == 0) {
98 fprintf(stderr, "Error %d: unmatched #endif on line %d\n", __LINE__, line);
99 exit(1);
100 }
101
102 char *ptr = strchr(buf, '\n');
103 if (ptr)
104 *ptr = '\0';
105
106 if (strncmp(buf, "#if 0", 5) == 0) {
107 disabled = 1;
108 continue;
109 }
110 if (strncmp(buf, "#ifdef", 6) == 0) {
111 char *ptr = buf + 6;
112 if (*ptr != ' ' && *ptr != '\t') {
113 fprintf(stderr, "Error %d: invalid macro on line %d\n", __LINE__, line);
114 exit(1);
115 }
116
117 while (*ptr == ' ' || *ptr == '\t')
118 ptr++;
119
120 if (!find_macro(ptr))
121 disabled = 1;
122 else
123 enabled = 1;
124 continue;
125 }
126
127 if (strncmp(buf, "#endif", 6) == 0) {
128 disabled = 0;
129 enabled = 1;
130 continue;
131 }
132
133 if (!disabled) {
134// printf("%s\n", buf);
135 fprintf(fpout, "%s\n", buf);
136 }
137 }
138 fclose(fp);
139
140 return 0;
141
142errout:
143 fclose(fp);
144 fprintf(stderr, "Error: cannot open output file\n");
145 exit(1);
146}