comparison pkg-src/tree-x/input.c @ 167:85ec50267440 r20-3b10

Import from CVS: tag r20-3b10
author cvs
date Mon, 13 Aug 2007 09:45:46 +0200
parents 0132846995bd
children 15872534500d
comparison
equal deleted inserted replaced
166:7a77eb660975 167:85ec50267440
4 * ---------------------------------------------------------------------------- 4 * ----------------------------------------------------------------------------
5 */ 5 */
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 #include <string.h> 8 #include <string.h>
9 #include <stdlib.h>
9 #include "defs.h" 10 #include "defs.h"
10 #include "tree.h" 11 #include "tree.h"
11 #include "input.h" 12 #include "input.h"
13 #include "dbl.h"
14 #include "intf.h"
12 15
13 char *EnvNm; /* Stores name of current Envir file */ 16 char *EnvNm; /* Stores name of current Envir file */
14 static int tokDepth = 0; /* Depth in tree of current token */ 17 static int tokDepth = 0; /* Depth in tree of current token */
15 static int prevTokDepth; /* Depth in tree of prev token */ 18 static int prevTokDepth; /* Depth in tree of prev token */
16 19
17 static void SaveSubtree(); 20 static void SaveSubtree(Tree *tree, int level, FILE *fp);
18 21
19 /* ---------------------------------------------------------------------------- 22 /* ----------------------------------------------------------------------------
20 * 23 *
21 * GetNextToken() reads the next token from the file indicated by 'fp' and 24 * GetNextToken() reads the next token from the file indicated by 'fp' and
22 * returns a token. If the token is TOKEN_LABEL, the lexeme is returned 25 * returns a token. If the token is TOKEN_LABEL, the lexeme is returned
23 * in 'lexeme'. If memory could not be allocated for 'lexeme', it is NULL. 26 * in 'lexeme'. If memory could not be allocated for 'lexeme', it is NULL.
24 * 27 *
25 * The following tokens are supported: 28 * The following tokens are supported:
26 * 29 *
27 * - TOKEN_LABEL: a string of characters, up to 'TOKEN-MAXSIZ' 30 * - TOKEN_LABEL: a string of characters, up to 'TOKEN-MAXSIZ'
28 * characters, delimited by number of leading spaces and newlines. 31 * characters, delimited by number of leading spaces and newlines.
29 * If a label has more than this number of characters, the rest are 32 * If a label has more than this number of characters, the rest are
30 * ignored. 33 * ignored.
31 * - TOKEN_EOF 34 * - TOKEN_EOF
32 * 35 *
33 * ---------------------------------------------------------------------------- 36 * ----------------------------------------------------------------------------
34 */ 37 */
35 38
36 int 39 static int
37 GetNextToken(fp, lexeme) 40 GetNextToken(FILE *fp, char **lexeme)
38 FILE *fp;
39 char **lexeme;
40 { 41 {
41 static char lexbuf[INPUT_BUFSIZ]; 42 static char lexbuf[INPUT_BUFSIZ];
42 register char *curbuf = lexbuf; 43 register char *curbuf = lexbuf;
43 register int charct = 0; 44 register int charct = 0;
44 register int c; 45 register int c;
45 int done = FALSE; 46 int done = FALSE;
46 47
47 prevTokDepth = tokDepth; 48 prevTokDepth = tokDepth;
48 tokDepth = 0; 49 tokDepth = 0;
49 50
50 c = getc(fp); 51 c = getc(fp);
51 52
52 /* skip over leading whitespace */ 53 /* skip over leading whitespace */
53 while (c == ' ') 54 while (c == ' ')
54 { 55 {
55 tokDepth++; 56 tokDepth++;
56 c = getc(fp); 57 c = getc(fp);
57 } 58 }
58 tokDepth /= 2; 59 tokDepth /= 2;
59 60
60 while (1) 61 while (1)
61 { 62 {
62 switch (c) 63 switch (c)
63 { 64 {
64 case EOF: 65 case EOF:
65 return (TOKEN_EOF); 66 return (TOKEN_EOF);
66 case '\n': 67 case '\n':
67 *curbuf = '\0'; 68 *curbuf = '\0';
68 *lexeme = strdup(lexbuf); 69 *lexeme = strdup(lexbuf);
69 return (TOKEN_LABEL); 70 return (TOKEN_LABEL);
70 break;
71 default: 71 default:
72 *curbuf++ = c; 72 *curbuf++ = c;
73 charct++; 73 charct++;
74 /* check for buffer overflow */ 74 /* check for buffer overflow */
75 if (charct >= TOKEN_MAXSIZ) 75 if (charct >= TOKEN_MAXSIZ)
90 } 90 }
91 } 91 }
92 92
93 93
94 /* ---------------------------------------------------------------------------- 94 /* ----------------------------------------------------------------------------
95 * 95 *
96 * SetNodeLabelAndValue() sets the label text of the specified node and 96 * SetNodeLabelAndValue() sets the label text of the specified node and
97 * stores any string value following the label and preceded by a "^^" 97 * stores any string value following the label and preceded by a "^^"
98 * delimiter. 98 * delimiter.
99 * 99 *
100 * ---------------------------------------------------------------------------- 100 * ----------------------------------------------------------------------------
101 */ 101 */
102 102
103 void 103 void
104 SetNodeLabelAndValue(node, label_and_value) 104 SetNodeLabelAndValue(Tree *node, char *label_and_value)
105 Tree *node;
106 char *label_and_value;
107 { 105 {
108 char* val; 106 char* val;
109 107
110 if (val = strstr(label_and_value, "^^")) 108 if ((val = strstr(label_and_value, "^^")))
111 { 109 {
112 /* Set node value to string following ^^ delimiter. */ 110 /* Set node value to string following ^^ delimiter. */
113 node->value = val+2; 111 node->value = val+2;
114 /* Erase value from input string, leaving only label. */ 112 /* Erase value from input string, leaving only label. */
115 *val = '\0'; 113 *val = '\0';
119 SetNodeLabel(node, label_and_value); 117 SetNodeLabel(node, label_and_value);
120 } 118 }
121 119
122 120
123 /* ---------------------------------------------------------------------------- 121 /* ----------------------------------------------------------------------------
124 * 122 *
125 * ReadTreeFromFile() takes a filename argument and constructs 123 * ReadTreeFromFile() takes a filename argument and constructs
126 * a Tree from the labels in the file. If a tree could be constructed, 124 * a Tree from the labels in the file. If a tree could be constructed,
127 * even partially, it is returned by the function. NULL is returned if 125 * even partially, it is returned by the function. NULL is returned if
128 * the file could not be opened or there was insufficient memory for 126 * the file could not be opened or there was insufficient memory for
129 * creating the tree. 127 * creating the tree.
130 * 128 *
131 * ---------------------------------------------------------------------------- 129 * ----------------------------------------------------------------------------
132 */ 130 */
133 131
134 Tree* 132 Tree*
135 ReadTreeFromFile(fname, error) 133 ReadTreeFromFile(char *fname, ErrCode *error)
136 char *fname;
137 ErrCode *error;
138 { 134 {
139 FILE *infile; 135 FILE *infile;
140 int inside_list = 0; /* for semantic checking */ 136 int inside_list = 0; /* for semantic checking */
141 int first_child = TRUE; 137 int first_child = TRUE;
142 138
143 int token; 139 int token;
144 char *label; 140 char *label;
145 141
146 Tree *tree = NULL; /* the return value of this function */ 142 Tree *tree = NULL; /* the return value of this function */
147 Tree *parent = NULL; /* parent of 'node' */ 143 Tree *parent = NULL; /* parent of 'node' */
148 Tree *node; /* current node */ 144 Tree *node; /* current node */
149 Tree *new_node; /* new node to add after current node */ 145 Tree *new_node; /* new node to add after current node */
150 146
151 *error = ERR_NONE; 147 *error = ERR_NONE;
152 148
153 infile = fopen(fname, "r"); 149 infile = fopen(fname, "r");
154 if (infile == NULL) 150 if (infile == NULL)
155 { 151 {
156 *error = ERR_OPENFAIL; 152 *error = ERR_OPENFAIL;
157 return (NULL); 153 return (NULL);
158 } 154 }
159 155
160 /* first line of file is Envir file name, save */ 156 /* first line of file is Envir file name, save */
161 token = GetNextToken(infile, &label); 157 token = GetNextToken(infile, &label);
162 if (token == TOKEN_EOF) 158 if (token == TOKEN_EOF)
163 { 159 {
164 *error = ERR_EMPTYFILE; 160 *error = ERR_EMPTYFILE;
173 fclose(infile); 169 fclose(infile);
174 return (NULL); 170 return (NULL);
175 } 171 }
176 EnvNm = strdup(label); 172 EnvNm = strdup(label);
177 } 173 }
178 174
179 /* set up root node */ 175 /* set up root node */
180 token = GetNextToken(infile, &label); 176 token = GetNextToken(infile, &label);
181 if (token == TOKEN_EOF) 177 if (token == TOKEN_EOF)
182 { 178 {
183 *error = ERR_EMPTYFILE; 179 *error = ERR_EMPTYFILE;
208 { 204 {
209 *error = ERR_NOROOT; 205 *error = ERR_NOROOT;
210 fclose(infile); 206 fclose(infile);
211 return (NULL); 207 return (NULL);
212 } 208 }
213 209
214 /* add children and siblings */ 210 /* add children and siblings */
215 while (1) 211 while (1)
216 { 212 {
217 token = GetNextToken(infile, &label); 213 token = GetNextToken(infile, &label);
218 if (token == TOKEN_EOF) 214 if (token == TOKEN_EOF)
219 break; 215 break;
220 216
221 if (tokDepth > prevTokDepth) /* then new subtree */ 217 if (tokDepth > prevTokDepth) /* then new subtree */
222 { 218 {
223 inside_list++; 219 inside_list++;
224 first_child = TRUE; 220 first_child = TRUE;
225 parent = node; 221 parent = node;
236 { 232 {
237 inside_list--; 233 inside_list--;
238 node = node->parent; 234 node = node->parent;
239 parent = node->parent; 235 parent = node->parent;
240 } 236 }
241 237
242 if (label == NULL) 238 if (label == NULL)
243 { 239 {
244 *error = ERR_MEMALLOC; 240 *error = ERR_MEMALLOC;
245 fclose(infile); 241 fclose(infile);
246 return (tree); 242 return (tree);
262 free(label); 258 free(label);
263 return (tree); 259 return (tree);
264 } 260 }
265 SetNodeLabelAndValue(new_node, label); 261 SetNodeLabelAndValue(new_node, label);
266 new_node->parent = parent; 262 new_node->parent = parent;
267 263
268 if (first_child) 264 if (first_child)
269 { 265 {
270 new_node->parent->child = new_node; 266 new_node->parent->child = new_node;
271 first_child = FALSE; 267 first_child = FALSE;
272 } 268 }
273 else 269 else
274 node->sibling = new_node; 270 node->sibling = new_node;
275 271
276 node = new_node; 272 node = new_node;
277 /* 273 /*
278 * printf("%3d tok: '%s'; tokDepth: %d; prevTokDepth: %d; inside_list: %d\n", 274 * printf("%3d tok: '%s'; tokDepth: %d; prevTokDepth: %d; inside_list: %d\n",
279 * NumNodes, node->label.text, tokDepth, prevTokDepth, inside_list); 275 * NumNodes, node->label.text, tokDepth, prevTokDepth, inside_list);
280 */ 276 */
284 return (tree); 280 return (tree);
285 } 281 }
286 282
287 283
288 /* ---------------------------------------------------------------------------- 284 /* ----------------------------------------------------------------------------
289 * 285 *
290 * SaveTreeToFile() takes a tree and saves it to a file specified by 'fname.' 286 * SaveTreeToFile() takes a tree and saves it to a file specified by 'fname.'
291 * If the file could not be opened for writing, False is returned. Otherwise, 287 * If the file could not be opened for writing, False is returned. Otherwise,
292 * True is returned. 288 * True is returned.
293 * 289 *
294 * ---------------------------------------------------------------------------- 290 * ----------------------------------------------------------------------------
295 */ 291 */
296 292
297 SaveTreeToFile(tree, fname) 293 int
298 Tree *tree; 294 SaveTreeToFile(Tree *tree, char *fname)
299 char *fname;
300 { 295 {
301 FILE *outfile; 296 FILE *outfile;
302 297
303 outfile = fopen(fname, "w"); 298 outfile = fopen(fname, "w");
304 if (outfile == NULL) 299 if (outfile == NULL)
305 return (FALSE); 300 return (FALSE);
306 301
307 fprintf(outfile, "%s\n", EnvNm); /* Save Env File Name */ 302 fprintf(outfile, "%s\n", EnvNm); /* Save Env File Name */
308 fprintf(outfile, "%s\n", tree->label.text); 303 fprintf(outfile, "%s\n", tree->label.text);
309 if (tree->child) 304 if (tree->child)
310 SaveSubtree(tree->child, 0, outfile); 305 SaveSubtree(tree->child, 0, outfile);
311 306
312 fclose(outfile); 307 fclose(outfile);
313 return (TRUE); 308 return (TRUE);
314 } 309 }
315 310
316 311
317 /* ---------------------------------------------------------------------------- 312 /* ----------------------------------------------------------------------------
318 * 313 *
319 * SaveSubtree() is the recursive procedure that supports SaveTreeToFile(). 314 * SaveSubtree() is the recursive procedure that supports SaveTreeToFile().
320 * 315 *
321 * ---------------------------------------------------------------------------- 316 * ----------------------------------------------------------------------------
322 */ 317 */
323 318
324 static void 319 static void
325 SaveSubtree(tree, level, fp) 320 SaveSubtree(Tree *tree, int level, FILE *fp)
326 Tree *tree;
327 int level;
328 FILE *fp;
329 { 321 {
330 int i; 322 int i;
331 323
332 level++; 324 level++;
333 for ( ; tree ; tree = tree->sibling) 325 for ( ; tree ; tree = tree->sibling)
334 { 326 {
335 for (i = 0 ; i < level ; i++) 327 for (i = 0 ; i < level ; i++)
336 { 328 {
341 if (tree->child) 333 if (tree->child)
342 SaveSubtree(tree->child, level, fp); 334 SaveSubtree(tree->child, level, fp);
343 } 335 }
344 level--; 336 level--;
345 } 337 }
346
347