1 /* ----------------------------------------------------------------------------
\r
3 * Purpose : input routine to create a Tree from an input file
\r
4 * ----------------------------------------------------------------------------
\r
14 char *EnvNm; /* Stores name of current Envir file */
\r
15 static int tokDepth = 0; /* Depth in tree of current token */
\r
16 static int prevTokDepth; /* Depth in tree of prev token */
\r
18 static void SaveSubtree();
\r
20 /* ----------------------------------------------------------------------------
\r
22 * GetNextToken() reads the next token from the file indicated by 'fp' and
\r
23 * returns a token. If the token is TOKEN_LABEL, the lexeme is returned
\r
24 * in 'lexeme'. If memory could not be allocated for 'lexeme', it is NULL.
\r
26 * The following tokens are supported:
\r
28 * - TOKEN_LABEL: a string of characters, up to 'TOKEN-MAXSIZ'
\r
29 * characters, delimited by number of leading spaces and newlines.
\r
30 * If a label has more than this number of characters, the rest are
\r
34 * ----------------------------------------------------------------------------
\r
38 GetNextToken(fp, lexeme)
\r
42 static char lexbuf[INPUT_BUFSIZ];
\r
43 register char *curbuf = lexbuf;
\r
44 register int charct = 0;
\r
48 prevTokDepth = tokDepth;
\r
53 /* skip over leading whitespace */
\r
69 *lexeme = strdup(lexbuf);
\r
70 return (TOKEN_LABEL);
\r
75 /* check for buffer overflow */
\r
76 if (charct >= TOKEN_MAXSIZ)
\r
79 *lexeme = strdup(lexbuf);
\r
80 /* since buffer is full, skip over remaining chars */
\r
82 while (c != '\n' && c != EOF)
\r
86 return (TOKEN_LABEL);
\r
95 /* ----------------------------------------------------------------------------
\r
97 * SetNodeLabelAndValue() sets the label text of the specified node and
\r
98 * stores any string value following the label and preceded by a "^^"
\r
101 * ----------------------------------------------------------------------------
\r
105 SetNodeLabelAndValue(node, label_and_value)
\r
107 char *label_and_value;
\r
111 if (val = strstr(label_and_value, "^^"))
\r
113 /* Set node value to string following ^^ delimiter. */
\r
114 node->value = val+2;
\r
115 /* Erase value from input string, leaving only label. */
\r
119 { node->value = NULL; }
\r
120 SetNodeLabel(node, label_and_value);
\r
124 /* ----------------------------------------------------------------------------
\r
126 * ReadTreeFromFile() takes a filename argument and constructs
\r
127 * a Tree from the labels in the file. If a tree could be constructed,
\r
128 * even partially, it is returned by the function. NULL is returned if
\r
129 * the file could not be opened or there was insufficient memory for
\r
130 * creating the tree.
\r
132 * ----------------------------------------------------------------------------
\r
136 ReadTreeFromFile(fname, error)
\r
141 int inside_list = 0; /* for semantic checking */
\r
142 int first_child = TRUE;
\r
147 Tree *tree = NULL; /* the return value of this function */
\r
148 Tree *parent = NULL; /* parent of 'node' */
\r
149 Tree *node; /* current node */
\r
150 Tree *new_node; /* new node to add after current node */
\r
154 infile = fopen(fname, "r");
\r
155 if (infile == NULL)
\r
157 *error = ERR_OPENFAIL;
\r
161 /* first line of file is Envir file name, save */
\r
162 token = GetNextToken(infile, &label);
\r
163 if (token == TOKEN_EOF)
\r
165 *error = ERR_EMPTYFILE;
\r
169 else if (token == TOKEN_LABEL)
\r
173 *error = ERR_MEMALLOC;
\r
177 EnvNm = strdup(label);
\r
180 /* set up root node */
\r
181 token = GetNextToken(infile, &label);
\r
182 if (token == TOKEN_EOF)
\r
184 *error = ERR_EMPTYFILE;
\r
188 else if (token == TOKEN_LABEL)
\r
192 *error = ERR_MEMALLOC;
\r
199 *error = ERR_MEMALLOC;
\r
204 SetNodeLabelAndValue(tree, label);
\r
205 tree->parent = NULL;
\r
210 *error = ERR_NOROOT;
\r
215 /* add children and siblings */
\r
218 token = GetNextToken(infile, &label);
\r
219 if (token == TOKEN_EOF)
\r
222 if (tokDepth > prevTokDepth) /* then new subtree */
\r
225 first_child = TRUE;
\r
228 else if (tokDepth < prevTokDepth) /* then end of subtree */
\r
231 *error = ERR_NOBEGIN;
\r
236 while (tokDepth < inside_list)
\r
239 node = node->parent;
\r
240 parent = node->parent;
\r
245 *error = ERR_MEMALLOC;
\r
249 if (parent == NULL)
\r
251 *error = ERR_MANYROOT;
\r
258 new_node = MakeNode();
\r
259 if (new_node == NULL)
\r
261 *error = ERR_MEMALLOC;
\r
266 SetNodeLabelAndValue(new_node, label);
\r
267 new_node->parent = parent;
\r
271 new_node->parent->child = new_node;
\r
272 first_child = FALSE;
\r
275 node->sibling = new_node;
\r
279 * printf("%3d tok: '%s'; tokDepth: %d; prevTokDepth: %d; inside_list: %d\n",
\r
280 * NumNodes, node->label.text, tokDepth, prevTokDepth, inside_list);
\r
289 /* ----------------------------------------------------------------------------
\r
291 * SaveTreeToFile() takes a tree and saves it to a file specified by 'fname.'
\r
292 * If the file could not be opened for writing, False is returned. Otherwise,
\r
293 * True is returned.
\r
295 * ----------------------------------------------------------------------------
\r
298 SaveTreeToFile(tree, fname)
\r
304 outfile = fopen(fname, "w");
\r
305 if (outfile == NULL)
\r
308 fprintf(outfile, "%s\n", EnvNm); /* Save Env File Name */
\r
309 fprintf(outfile, "%s\n", tree->label.text);
\r
311 SaveSubtree(tree->child, 0, outfile);
\r
318 /* ----------------------------------------------------------------------------
\r
320 * SaveSubtree() is the recursive procedure that supports SaveTreeToFile().
\r
322 * ----------------------------------------------------------------------------
\r
326 SaveSubtree(tree, level, fp)
\r
334 for ( ; tree ; tree = tree->sibling)
\r
336 for (i = 0 ; i < level ; i++)
\r
341 fprintf(fp, "%s\n", tree->label.text);
\r
343 SaveSubtree(tree->child, level, fp);
\r