Mercurial > hg > xemacs-beta
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 |
