FreeCalypso > hg > ueda-linux
diff ueda/libuschem/rdschem_lex.c @ 0:cd92449fdb51
initial import of ueda and ifctf-part-lib from ifctfvax CVS
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 20 Jul 2015 00:24:37 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ueda/libuschem/rdschem_lex.c Mon Jul 20 00:24:37 2015 +0000 @@ -0,0 +1,205 @@ +/* + * token lexer for the schematic parser + */ + +#include <sys/types.h> +#include <stdio.h> +#include <ctype.h> +#include <strings.h> +#include "schemstruct.h" +#include "parserint.h" + +extern char *malloc(); + +extern struct schem_parse_state schem_parse_state; + +static +my_getchar() +{ + register int c; + + c = getc(schem_parse_state.file); + if (c < 0) + return(c); + if (!isascii(c)) { + rdschem_error("non-ASCII character"); + exit(1); + } + if (iscntrl(c) && c != '\n' && c != '\t') { + rdschem_error("invalid control character"); + exit(1); + } + return(c); +} + +rdschem_token() +{ + register int c; + register char *cp; + register int len; + static char delims[] = "\n\"%(),;={}"; + + if (c = schem_parse_state.pushback_token) { + schem_parse_state.pushback_token = 0; + return(c); + } +loop: c = my_getchar(); + switch (c) { + case EOF: + return(0); + case ' ': + case '\t': + goto loop; + case '"': + yylex_qstr(); + return(QSTRING); + case '%': + do + c = my_getchar(); + while (c != EOF && c != '\n'); + if (c == EOF) + return(0); + /* FALL THRU */ + case '\n': + schem_parse_state.lineno++; + goto loop; + case '(': + case ')': + case ',': + case ';': + case '=': + case '{': + case '}': + return(c); + } + cp = schem_parse_state.string; + *cp++ = c; + for (len = 1; ; ) { + c = my_getchar(); + if (c == EOF || c == ' ' || c == '\t') + break; + if (index(delims, c)) { + ungetc(c, schem_parse_state.file); + break; + } + if (len >= MAXSTRING) + rdschem_error("text token is too long"); + *cp++ = c; + len++; + } + *cp = '\0'; + return(STRING); +} + +static +yylex_qstr() +{ + register int c; + register char *cp; + register int len; + + cp = schem_parse_state.string; + for (len = 0; ; ) { + c = my_getchar(); + if (c == EOF || c == '\n') +unterm: rdschem_error("unterminated quoted string"); + if (c == '"') + break; + if (c == '\\') { + c = my_getchar(); + if (c == EOF || c == '\n') + goto unterm; + } + if (len >= MAXSTRING) + rdschem_error("quoted string is too long"); + *cp++ = c; + len++; + } + *cp = '\0'; +} + +struct graphblock * +rdschem_graphblock(type) +{ + struct graphblock *blk; + register int c, n; + + blk = (struct graphblock *) malloc(sizeof(struct graphblock)); + if (!blk) { + perror("malloc"); + exit(1); + } + blk->type = type; + blk->lineno = schem_parse_state.lineno; + c = my_getchar(); + if (c == EOF) +badeof: rdschem_error("EOF in a graphical block"); + if (c == '\n') + schem_parse_state.lineno++; + else + ungetc(c, schem_parse_state.file); + blk->offset = ftell(schem_parse_state.file); + + for (n = 0; n >= 0; ) { + c = my_getchar(); + switch (c) { + case EOF: + goto badeof; + case '%': + for (;;) { + c = my_getchar(); + if (c == EOF) + goto badeof; + if (c == '\n') + break; + } + /* FALL THRU */ + case '\n': + schem_parse_state.lineno++; + continue; + case '(': + skip_over_ps_string(); + continue; + case ')': + rdschem_error("unmatched \')\' in a graphical block"); + case '{': + n++; + continue; + case '}': + n--; + continue; + } + } + blk->length = ftell(schem_parse_state.file) - blk->offset - 1; + return(blk); +} + +static +skip_over_ps_string() +{ + register int c, n; + + for (n = 1; n > 0; ) { + c = my_getchar(); + switch (c) { + case EOF: +badeof: rdschem_error("EOF in a PS string in a graphical block"); + case '\n': + schem_parse_state.lineno++; + continue; + case '(': + n++; + continue; + case ')': + n--; + continue; + case '\\': + c = my_getchar(); + if (c == EOF) + goto badeof; + if (c == '\n') + schem_parse_state.lineno++; + continue; + } + } +}