Merge branch 'master' into work
[xcircuit.git] / pp.c
blobf17156acb8872ba559fb10df72f9d6efe17b38ea
1 /*--------------------------------------------------------------*/
2 /* pp.c -- */
3 /* */
4 /* This helper program emulates m4 pre-processor behavior. */
5 /* */
6 /* As of July 2006, XCircuit no longer uses m4, having replaced */
7 /* it with "sed" scripts. However, since this C code was */
8 /* written to bypass the lack of "m4" under Windows, it is */
9 /* still required to bypass the lack of "sed" under Windows. */
10 /* The "m4" emulation is maintained. However, the m4 files */
11 /* have been rewritten to remove the awkward "ifelse" syntax, */
12 /* which has been replaced with a simpler "<variable_name>" */
13 /* at the beginning of each variable-dependent line. This */
14 /* program also handles those situations. */
15 /*--------------------------------------------------------------*/
17 #include <stdio.h>
18 #include <string.h>
20 typedef struct _pattern {
21 char *pattern;
22 char *string;
23 struct _pattern *next;
24 } pattern;
26 pattern* parse_args(int* argc, char ***argv)
28 int i, len = 0;
29 pattern *p = (pattern*)malloc(sizeof(pattern));
31 p->pattern = "`eval'";
32 p->string = "eval";
33 p->next = NULL;
35 for (i=1; i<(*argc); i++) {
36 if (strncmp((*argv)[i], "-D", 2) == 0) {
37 char *c = strchr((*argv)[i], '=');
38 pattern *new_p;
39 if (c == NULL) {
40 printf("Invalid argument: %s\n", (*argv[i]));
41 exit(-1);
43 new_p = (pattern*)malloc(sizeof(pattern));
44 new_p->next = p;
45 p = new_p;
46 c[0] = '\0';
47 p->pattern = strdup((*argv)[i]+2);
48 if (c[1] == '"') {
49 char *c2;
50 c += 2;
51 c2 = strchr(c, '"');
52 if (c2 != NULL)
53 c2[0] = '\0';
54 } else {
55 char *c2;
56 c++;
57 c2 = strchr(c, ' ');
58 if (c2 != NULL)
59 c2[0] = '\0';
61 p->string = strdup(c);
62 /*fprintf(stderr, "%s -> %s\n", p->pattern, p->string);*/
63 len++;
67 *argc -= len+1;
68 *argv += len+1;
70 return p;
73 int main(int argc, char **argv)
75 char buffer[4096];
76 char buffer2[4096];
77 char *c;
78 int i;
79 pattern *patterns, *p;
80 FILE *fin;
82 patterns = parse_args(&argc, &argv);
84 if (argc > 0) {
85 fin = fopen(argv[0], "r");
86 if (fin == NULL) {
87 printf("Unable to open file: %s\n", argv[0]);
88 exit(-1);
91 else
92 fin = stdin;
94 while (1) {
95 if (fgets(buffer, 4096, fin) == 0)
96 exit(0);
97 p = patterns;
98 while (p) {
99 while ((c = strstr(buffer, p->pattern)) != NULL) {
100 c[0] = '\0';
102 /* Handle variable-dependent lines */
103 if (c == buffer && !strcmp(p->string, "1")) {
104 strcpy(buffer2, c + strlen(p->pattern) + 1);
105 strcpy(buffer, buffer2);
107 else if (c == buffer && !strcmp(p->string, "0")) {
108 p = NULL;
109 break;
111 else {
112 strcpy(buffer2, buffer);
113 strcat(buffer2, p->string);
114 strcat(buffer2, c + strlen(p->pattern));
115 strcpy(buffer, buffer2);
118 if (p == NULL) break;
119 p = p->next;
121 if (buffer[0] != '\0')
122 printf("%s", buffer);
125 if (argc > 0)
126 fclose(fin);
128 return 0;