dev/c/tex_parser/tex_table.c

472 lines
10 KiB
C

#include "tex_table.h"
#include <string.h>
#include <ctype.h>
#include "tex_table_tags.h"
#include "zalloc_ext.h"
#include "zalloc.h"
#include "c_const.h"
/* only for debug */
#define __TEX_TABLE_DEBUG 0
#include <stdio.h>
int parse_table(const char *table_source, size_t len, struct table_s *table, struct xerror_s *error)
{
error->code = 0;
error->message = NULL;
if (!len)
len = strlen(table_source);
enum where_e
{
IN_UNDEF = 0, // undefined place
IN_COMMENT, // any comment
IN_TAG, // any tag
IN_TAG_UNKNOWN, // unknown tag
IN_SPACE, // space, \tag { for example
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};
char *tag = NULL;
size_t i = 0;
size_t tex_level = 0;
for (i = 0; i < len; i++) {
/* stack checking */
if (tex_level + 1 == MAX_TEX_STACK_LEVEL) {
error->code = (int)i;
error->message = "stack overflow";
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 = (int)i;
error->message = "unexpected symbol (IN_UDEF)";
return error->code;
}
break;
case IN_COMMENT:
if (c == '\r' || c == '\n') {
where_stack[tex_level--] = IN_UNDEF;
}
break;
case IN_TAG:
if (isalnum(c)) {
tag = zalloc_append8_str(tag, c);
} else if (!tag && (c == '\\' || c == ',' || c == '%')) { // newline tag or \,
where_stack[tex_level--] = IN_UNDEF;
} else if (!tag) {
error->code = (int)i;
error->message = "empty tag (IN_TAG)";
return error->code;
} else {
if (!strcmp(tag, TEX_TAG_BEGIN)) {
where_stack[tex_level] = IN_TAG_BEGIN;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_CLINE)) {
where_stack[tex_level] = IN_TAG_CLINE;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_END)) {
where_stack[tex_level] = IN_TAG_END;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_ENDFOOT)) {
where_stack[tex_level] = IN_TAG_ENDFOOT;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_ENDHEAD)) {
where_stack[tex_level] = IN_TAG_ENDHEAD;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_HLINE)) {
where_stack[tex_level] = IN_TAG_HLINE;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_HSPACE)) {
where_stack[tex_level] = IN_TAG_HSPACE;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_MULTICOLUMN)) {
where_stack[tex_level] = IN_TAG_MULTICOLUMN;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_MULTIROW)) {
where_stack[tex_level] = IN_TAG_MULTIROW;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_TABULARNEWLINE)) {
where_stack[tex_level] = IN_TAG_TABULARNEWLINE;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (!strcmp(tag, TEX_TAG_SLASH)) {
where_stack[tex_level] = IN_TAG_SLASH;
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
} else if (c == '%') {
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG_UNKNOWN;
where_stack[++tex_level] = IN_COMMENT;
} else if (c == '{' || c == '[') {
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG_UNKNOWN;
where_stack[++tex_level] = IN_TAGPARM;
} else if (isspace(c)) { // \tag { for example
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG_UNKNOWN;
where_stack[++tex_level] = IN_SPACE;
} else { // unknown tag
#ifdef __TEX_TABLE_DEBUG
printf("\\%s\n", tag);
#endif
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG_UNKNOWN;
}
if (c == '\\')
i--;
}
break;
case IN_SPACE:
if (isspace(c)) {
} else {
where_stack[tex_level--] = IN_UNDEF;
i--;
}
break;
case IN_TAGPARM:
if (c == '{' || c == '[') { // tag params
where_stack[++tex_level] = IN_TAGPARM;
} else if (c == '}' || c == ']') { // end tag params
where_stack[tex_level--] = IN_UNDEF;
} else if (c == '\\') { // new tag
tag = zfree_null(tag);
where_stack[++tex_level] = IN_TAG;
} else if (isspace(c)) {
where_stack[++tex_level] = IN_SPACE;
} else if (c == '%') {
where_stack[++tex_level] = IN_COMMENT;
} else if (isgraph(c) || c < 0) {
} else {
error->code = (int)i;
error->message = "unexpected symbol (IN_TAGPARM)";
return error->code;
}
break;
case IN_TAG_UNKNOWN:
if (c == '{' || c == '[') { // tag params
where_stack[++tex_level] = IN_TAGPARM;
} else if (c == '\\') { // new tag
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG;
} else if (c == '%') {
where_stack[++tex_level] = IN_COMMENT;
} else if (isspace(c)) {
where_stack[++tex_level] = IN_SPACE;
} else if (c == '}') {
where_stack[tex_level--] = IN_UNDEF;
} else if (isgraph(c) || c < 0) {
} else {
error->code = (int)i;
error->message = "unexpected symbol (IN_TAG_UNKNOWN)";
return error->code;
}
break;
case IN_TAG_BEGIN:
if (c == '{' || c == '[') { // tag params
where_stack[++tex_level] = IN_TAGPARM;
} else if (c == '\\') { // new tag
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG;
} else if (c == '%') {
where_stack[++tex_level] = IN_COMMENT;
} else if (isspace(c)) {
where_stack[++tex_level] = IN_SPACE;
} else if (c == '}') {
where_stack[tex_level--] = IN_UNDEF;
} else if (isalnum(c) || c == '#') {
} else {
error->code = (int)i;
error->message = "unexpected symbol (IN_TAG_BEGIN)";
return error->code;
}
break;
case IN_TAG_CLINE:
if (c == '{' || c == '[') { // tag params
where_stack[++tex_level] = IN_TAGPARM;
} else if (c == '\\') { // new tag
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG;
} else if (c == '%') {
where_stack[++tex_level] = IN_COMMENT;
} else if (isspace(c)) {
where_stack[++tex_level] = IN_SPACE;
} else if (c == '}') {
where_stack[tex_level--] = IN_UNDEF;
} else if (isgraph(c) || c < 0) {
} else {
error->code = (int)i;
error->message = "unexpected symbol (IN_TAG_UNKNOWN)";
return error->code;
}
break;
case IN_TAG_END:
if (c == '{' || c == '[') { // tag params
where_stack[++tex_level] = IN_TAGPARM;
} else if (c == '\\') { // new tag
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG;
} else if (c == '%') {
where_stack[++tex_level] = IN_COMMENT;
} else if (isspace(c)) {
where_stack[++tex_level] = IN_SPACE;
} else if (c == '}') {
where_stack[tex_level--] = IN_UNDEF;
} else if (isgraph(c) || c < 0) {
} else {
error->code = (int)i;
error->message = "unexpected symbol (IN_TAG_UNKNOWN)";
return error->code;
}
break;
case IN_TAG_ENDFOOT:
break;
case IN_TAG_ENDHEAD:
break;
case IN_TAG_HLINE:
where_stack[tex_level--] = IN_UNDEF;
break;
case IN_TAG_HSPACE:
break;
case IN_TAG_MULTICOLUMN:
if (c == '{' || c == '[') { // tag params
where_stack[++tex_level] = IN_TAGPARM;
} else if (c == '\\') { // new tag
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG;
} else if (c == '%') {
where_stack[++tex_level] = IN_COMMENT;
} else if (isspace(c)) {
where_stack[++tex_level] = IN_SPACE;
} else if (c == '}') {
where_stack[tex_level--] = IN_UNDEF;
} else if (isalnum(c) || c == '#') {
} else {
error->code = (int)i;
error->message = "unexpected symbol (IN_TAG_MULTICOLUMN)";
return error->code;
}
break;
case IN_TAG_MULTIROW:
if (c == '{' || c == '[') { // tag params
where_stack[++tex_level] = IN_TAGPARM;
} else if (c == '\\') { // new tag
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG;
} else if (c == '%') {
where_stack[++tex_level] = IN_COMMENT;
} else if (isspace(c)) {
where_stack[++tex_level] = IN_SPACE;
} else if (c == '}') {
where_stack[tex_level--] = IN_UNDEF;
} else if (isgraph(c) || c < 0) {
} else {
error->code = (int)i;
error->message = "unexpected symbol (IN_TAG_MULTIROW)";
return error->code;
}
break;
case IN_TAG_TABULARNEWLINE:
if (c == '{' || c == '[') { // tag params
where_stack[++tex_level] = IN_TAGPARM;
} else if (c == '\\') { // new tag
tag = zfree_null(tag);
where_stack[tex_level] = IN_TAG;
} else if (c == '%') {
where_stack[++tex_level] = IN_COMMENT;
} else if (isspace(c)) {
where_stack[++tex_level] = IN_SPACE;
} else if (c == '}') {
where_stack[tex_level--] = IN_UNDEF;
} else if (isalnum(c) || c == '#') {
} else {
error->code = (int)i;
error->message = "unexpected symbol (IN_TAG_TABULARNEWLINE)";
return error->code;
}
break;
case IN_TAG_SLASH:
break;
case IN_FORMULA:
break;
case IN_LONGTABLE:
break;
default:
error->code = (int)i;
error->message = "unknown error";
return error->code;
break;
}
}
table->id = "Drossel1.Table1";
return 0;
}