#include "tex_table.h" #include #include #include "tex_table_tags.h" #include "zalloc_ext.h" #include "zalloc.h" #include "c_const.h" /* unnecessary includes */ #include enum tex_parse_err { TEX_PARSING_NOERROR = 0, TEX_PARSING_ERROR_UNDEF, TEX_PARSING_ERROR_STACKOVERFLOW }; char * const TEX_PARSING_ERROR_UNDEF_STR = "unknown parsing error"; char * const TEX_PARSING_ERROR_STACKOVERFLOW_STR = "parser stack overflow"; int parse_table(const char *table_source, size_t len, struct table_s *table, struct xerror_s *error) { char *tag = NULL;/*, *brpar = NULL;*/ size_t i = 0; if (!len) len = strlen(table_source); enum where_e { IN_UNDEF = 0, // undefined place IN_COMMENT, // any comment IN_TAG, // any tag IN_TAGPARM, // in \tag{} curly braces IN_TAG_BEGIN, IN_TAG_CLINE, IN_TAG_END, IN_TAG_ENDFOOT, IN_TAG_ENDHEAD, IN_TAG_HLINE, IN_TAG_HSPACE, IN_TAG_MULTICOLUMN, IN_TAG_MULTIROW, IN_TAG_TABULARNEWLINE, IN_TAG_SLASH, IN_FORMULA, // in $...$ IN_LONGTABLE, // in longtable } where_stack[MAX_TEX_STACK_LEVEL] = {IN_UNDEF}; size_t tex_level = 0; for (i = 0; i < len; i++) { /* stack checking */ if (tex_level + 1 == MAX_TEX_STACK_LEVEL) { error->code = TEX_PARSING_ERROR_STACKOVERFLOW; error->message = TEX_PARSING_ERROR_STACKOVERFLOW_STR; return error->code; } /* read one character from input stream */ char c = table_source[i]; /* looking at where_stack and encountered character */ switch (where_stack[tex_level]) { case IN_UNDEF: if (c == '\\') { tag = zfree_null(tag); where_stack[++tex_level] = IN_TAG; } else if (c == '%') { where_stack[++tex_level] = IN_COMMENT; } else { error->code = TEX_PARSING_ERROR_UNDEF; error->message = TEX_PARSING_ERROR_UNDEF_STR; return error->code; } break; case IN_COMMENT: if (c == '\r' || c == '\n') { where_stack[tex_level--] = IN_UNDEF; } break; case IN_TAG: if (islower(c) || isdigit(c) || (!tag && c == '\\')) { // test for char, digit and newline tag "\\" tag = zalloc_append8_str(tag, c); } else { if (!tag) { error->code = TEX_PARSING_ERROR_UNDEF; error->message = TEX_PARSING_ERROR_UNDEF_STR; return error->code; } else if (!strcmp(tag, TEX_TAG_BEGIN)) { where_stack[tex_level] = IN_TAG_BEGIN; } else if (!strcmp(tag, TEX_TAG_CLINE)) { where_stack[tex_level] = IN_TAG_CLINE; } else if (!strcmp(tag, TEX_TAG_END)) { where_stack[tex_level] = IN_TAG_END; } else if (!strcmp(tag, TEX_TAG_ENDFOOT)) { where_stack[tex_level] = IN_TAG_ENDFOOT; } else if (!strcmp(tag, TEX_TAG_ENDHEAD)) { where_stack[tex_level] = IN_TAG_ENDHEAD; } else if (!strcmp(tag, TEX_TAG_HLINE)) { where_stack[tex_level] = IN_TAG_HLINE; } else if (!strcmp(tag, TEX_TAG_HSPACE)) { where_stack[tex_level] = IN_TAG_HSPACE; } else if (!strcmp(tag, TEX_TAG_MULTICOLUMN)) { where_stack[tex_level] = IN_TAG_MULTICOLUMN; } else if (!strcmp(tag, TEX_TAG_MULTIROW)) { where_stack[tex_level] = IN_TAG_MULTIROW; } else if (!strcmp(tag, TEX_TAG_TABULARNEWLINE)) { where_stack[tex_level] = IN_TAG_TABULARNEWLINE; } else if (!strcmp(tag, TEX_TAG_SLASH)) { where_stack[tex_level] = IN_TAG_SLASH; } } break; case IN_TAGPARM: if (c == '{') { // tag params where_stack[++tex_level] = IN_TAGPARM; } else if (c == '}') { // end tag params where_stack[tex_level--] = IN_UNDEF; } else if (c == '\\') { // new tag where_stack[++tex_level] = IN_TAG; } else if (isprint(c)) { //~ brpar = zalloc_append8_str(brpar, c); // ??????? } else { error->code = TEX_PARSING_ERROR_UNDEF; error->message = TEX_PARSING_ERROR_UNDEF_STR; return error->code; } break; case IN_TAG_BEGIN: if (c == '{') { // tag params where_stack[++tex_level] = IN_TAGPARM; } else if (c == '\\') { // new tag where_stack[tex_level] = IN_TAG; if (FALSE) { // longtable } } else if (isspace(c)) { } else { error->code = TEX_PARSING_ERROR_UNDEF; error->message = TEX_PARSING_ERROR_UNDEF_STR; return error->code; } break; case IN_TAG_CLINE: break; case IN_TAG_END: break; case IN_TAG_ENDFOOT: break; case IN_TAG_ENDHEAD: break; case IN_TAG_HLINE: break; case IN_TAG_HSPACE: break; case IN_TAG_MULTICOLUMN: break; case IN_TAG_MULTIROW: break; case IN_TAG_TABULARNEWLINE: break; case IN_TAG_SLASH: break; case IN_FORMULA: break; case IN_LONGTABLE: break; default: error->code = TEX_PARSING_ERROR_UNDEF; error->message = TEX_PARSING_ERROR_UNDEF_STR; return error->code; break; } } table->id = "Drossel1.Table1"; error->message = NULL; return 0; }