winnt-more-makefile-fixes-for-cvs-head-20010906
[openafs.git] / src / config / mc.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #define MAXLINELEN      1024
11 #define MAXTOKLEN       100
12 #include <sys/param.h>
13 #include <sys/types.h>
14 #include <sys/file.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17
18 #define TOK_DONTUSE 1 /* Don't copy if match and this flag is set. */
19 struct token {
20     struct token *next;
21     char *key;
22     int flags;
23 };
24
25 /* free token list returned by parseLine */
26 static int FreeTokens(alist)
27     register struct token *alist; {
28     register struct token *nlist;
29     for(; alist; alist = nlist) {
30         nlist = alist->next;
31         free(alist->key);
32         free(alist);
33     }
34     return 0;
35 }
36
37 #define space(x)    ((x) == ' ' || (x) == '\t' || (x) == '<' || (x) == '>')
38 static int ParseLine(aline, alist)
39     char *aline;
40     struct token **alist; {
41     char tbuffer[MAXTOKLEN+1];
42     register char *tptr = NULL;
43     int inToken;
44     struct token *first, *last;
45     register struct token *ttok;
46     register int tc;
47     int dontUse = 0;
48     
49     inToken = 0;        /* not copying token chars at start */
50     first = (struct token *) 0;
51     last = (struct token *) 0;
52     while (1) {
53         tc = *aline++;
54         if (tc == 0 || space(tc)) {    /* terminating null gets us in here, too */
55             if (inToken) {
56                 inToken = 0;    /* end of this token */
57                 if ( !tptr )
58                     return -1; /* should never get here */
59                 else
60                     *tptr++ = 0;
61                 ttok = (struct token *) malloc(sizeof(struct token));
62                 ttok->next = (struct token *) 0;
63                 if (dontUse) {
64                     ttok->key = (char *) malloc(strlen(tbuffer));
65                     strcpy(ttok->key, tbuffer+1);
66                     ttok->flags = TOK_DONTUSE;
67                     dontUse = 0;
68                 }
69                 else {
70                     ttok->key = (char *) malloc(strlen(tbuffer)+1);
71                     strcpy(ttok->key, tbuffer);
72                     ttok->flags = 0;
73                 }
74                 if (last) {
75                     last->next = ttok;
76                     last = ttok;
77                 }
78                 else last = ttok;
79                 if (!first) first = ttok;
80             }
81         }
82         else {
83             /* an alpha character */
84             if (!inToken) {
85                 if (tc == '-') {
86                     dontUse = 1;
87                 }
88                 tptr = tbuffer;
89                 inToken = 1;
90             }
91             if (tptr - tbuffer >= MAXTOKLEN) return -1;   /* token too long */
92             *tptr++ = tc;
93         }
94         if (tc == 0) {
95             /* last token flushed 'cause space(0) --> true */
96             if (last) last->next = (struct token *) 0;
97             *alist = first;
98             return 0;
99         }
100     }
101 }
102 /* read a line into a buffer, putting in null termination and stopping on appropriate
103     end of line char.  Returns 0 at eof, > 0 at normal line end, and < 0 on error */
104 static int GetLine(afile, abuffer, amax)
105     FILE *afile;
106     int amax;
107     register char *abuffer; {
108     register int tc;
109     int first;
110
111     first = 1;
112     while (1) {
113         tc = getc(afile);
114         if (first && tc < 0) return 0;
115         first = 0;
116         if (tc <= 0 || tc == '\012') {
117             if (amax > 0) *abuffer++ = 0;
118             return (amax > 0? 1 : -1);
119         }
120         if (amax > 0) {
121             /* keep reading to end of line so next one isn't bogus */
122             *abuffer++ = tc;
123             amax--;
124         }
125     }
126 }
127
128 int mc_copy(ain, aout, alist)
129     register FILE *ain;
130     register FILE *aout;
131     char *alist[]; {
132     char tbuffer[MAXLINELEN];
133     struct token *tokens;
134     register char **tp;
135     register struct token *tt;
136     register int code;
137     int copying;
138     int done;
139
140     copying = 1;        /* start off copying data */
141     while (1) {
142         /* copy lines, handling modes appropriately */
143         code = GetLine(ain, tbuffer, MAXLINELEN);
144         if (code <= 0) break;
145         /* otherwise process the line */
146         if (tbuffer[0] == '<') {
147             /* interpret the line as a set of options, any one of which will cause us
148                 to start copying the data again. */
149             code = ParseLine(tbuffer, &tokens);
150             if (code != 0) return -1;
151             copying = 0;
152             done = 0;
153             for(tp = alist; (!done) && (*tp != (char *)0) ; tp++) {
154                 for(tt = tokens; tt; tt=tt->next) {
155                     if (!strcmp(*tp, tt->key)) {
156                         /* Need to search all tokens in case a dont use
157                          * flag is set. But we can stop on the first
158                          * don't use.
159                          */
160                         if (tt->flags & TOK_DONTUSE) {
161                             copying = 0;
162                             done = 1;
163                             break;
164                         }
165                         else {
166                             copying = 1;
167                         }
168                     }
169                 }
170             }
171             FreeTokens(tokens);
172         }
173         else {
174             /* just copy the line */
175             if (copying) {
176                 fwrite(tbuffer, 1, strlen(tbuffer), aout);
177                 putc('\n', aout);
178             }
179         }
180     }
181     return 0;
182 }