00001
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <errno.h>
00007 #include <string.h>
00008 #include "pair.h"
00009 #include "lexer.h"
00010 #include "template.h"
00011 #include "translator.h"
00012 #include "parser.h"
00013
00017 #define EVAL(expr, err) if (expr) { errno = err; perror(pcerr); iret = EXIT_FAILURE; goto cleanup; }
00018
00021 #define ALLOC(str, vector) EVAL((str = (char *) realloc(str, vector + sizeof('\0'))) == NULL, ENOMEM)
00022
00025 #define STRCAT(stra, strb) ALLOC(stra, strlen(stra) + strlen(strb)); strcat(stra, strb)
00026
00030 #define STRSUB(stra, strb, offset) ALLOC(stra, offset); sprintf(stra, "%.*s", offset, strb)
00031
00033 #define NONE(a) a = (char *) malloc(0)
00034
00038 int parse(char *pcin)
00039 {
00040 int i, iret = EXIT_SUCCESS;
00041 const char *pcmaskbase = "<[[:space:]]*?(%s)+?(.*?)>(.*?)</\\%d>";
00042 const char *pcdiv = "|";
00043 const char *pcerr = "parser.c parse()";
00044 char NONE(*pcmaskelement), NONE(*pcmask);
00045
00046
00047 EVAL(template(&te) != EXIT_SUCCESS, PARSE_ERR);
00048
00049
00050 for (i = 0; i < te.i; i++) {
00051 STRCAT(pcmaskelement, (te.pten + i)->pcclass);
00052 STRCAT(pcmaskelement, pcdiv);
00053 }
00054
00055
00056 *(pcmaskelement + strlen(pcmaskelement) - strlen(pcdiv)) = '\0';
00057
00058
00059 ALLOC(pcmask, strlen(pcmaskelement) + strlen(pcmaskbase));
00060 sprintf(pcmask, pcmaskbase, pcmaskelement, PARSE_ELEMENT);
00061
00062
00063
00064 EVAL(lex(pcin, pcmask, parsetag) != EXIT_SUCCESS, EINVAL);
00065
00066 cleanup:
00067 templatefree(&te);
00068 free(pcmaskelement);
00069 free(pcmask);
00070 return iret;
00071 }
00072
00075 void parsetag(char *pc)
00076 {
00077 int i, ire, aisub[PARSE_ARGS * PARSE_VECTOR], iret;
00078 pcre *pre;
00079 const char *pcre;
00080 const char *pcmask = "^<[[:space:]]*([^[:space:]]+)(.*?)>(.*)<";
00081 const char *pcerr = "parser.c parsetag()";
00082 char NONE(*pcclass), NONE(*pcpairs), NONE(*pccontent);
00083 pair_t pa;
00084
00085 EVAL((pre = pcre_compile(pcmask, PARSE_OPT, &pcre, &ire, NULL)) == NULL, EINVAL);
00086 EVAL(pcre_exec(pre, NULL, pc, strlen(pc), 0, 0, aisub, 12) < PARSE_MATCH, EINVAL);
00087 STRSUB(pcclass, pc + aisub[PARSE_CLASS * PARSE_ARG + PARSE_BEGIN], aisub[PARSE_CLASS * PARSE_ARG + PARSE_END] - aisub[PARSE_CLASS * PARSE_ARG + PARSE_BEGIN]);
00088 STRSUB(pcpairs, pc + aisub[PARSE_PAIRS * PARSE_ARG + PARSE_BEGIN], aisub[PARSE_PAIRS * PARSE_ARG + PARSE_END] - aisub[PARSE_PAIRS * PARSE_ARG + PARSE_BEGIN]);
00089 STRSUB(pccontent, pc + aisub[PARSE_CONTENT * PARSE_ARG + PARSE_BEGIN], aisub[PARSE_CONTENT * PARSE_ARG + PARSE_END] - aisub[PARSE_CONTENT * PARSE_ARG + PARSE_BEGIN]);
00090
00091
00092 PAIRNEW(pa);
00093
00094 addpair(pcclass, pccontent, &pa);
00095
00096 for (i = 0; i < te.i; i++) {
00097 if (strcmp(pcclass, (te.pten + i)->pcclass) == 0) {
00098 translate((te.pten + i)->pcdigest, &pa);
00099 }
00100 }
00101
00102 cleanup:
00103 free(pcclass);
00104 free(pcpairs);
00105 free(pccontent);
00106 }