#include "openaxiom-c-macros.h"
#include "debug.h"
#include "halloc.h"
#include "sockio.h"
#include "parse.h"
#include "hyper.h"
#include "lex.h"
static char * load_macro(MacroStore * macro);
static void get_parameter_strings(int number , char * macro_name);
void
scan_HyperDoc()
{
HDWindow *twin = gWindow;
int ret_val;
int number_of_left_braces = 1;
gWindow = NULL;
while (number_of_left_braces) {
ret_val = get_token();
if (ret_val == EOF && number_of_left_braces) {
fprintf(stderr, "Scan_Hypertex: Unexpected End of File\n");
longjmp(jmpbuf, 1);
}
switch (token.type) {
case openaxiom_Page_token:
fprintf(stderr, "scan_HyperDoc: Unexpected Page Declaration\n");
break;
case openaxiom_NewCommand_token:
fprintf(stderr, "scan_HyperDoc: Unexpected Macro Declaration\n");
break;
case openaxiom_Lbrace_token:
number_of_left_braces++;
break;
case openaxiom_Endpatch_token:
case openaxiom_Rbrace_token:
number_of_left_braces--;
break;
default:
break;
}
}
gWindow = twin;
}
int
number(const char *str)
{
const char *t = str;
while (*t)
if (!isdigit(*t++))
return 0;
return 1;
}
static char *
load_macro(MacroStore *macro)
{
int ret_val;
long start_fpos;
int size = 0;
char *trace;
char *macro_buff;
save_scanner_state();
cfile = find_fp(macro->fpos);
init_scanner();
get_expected_token(openaxiom_NewCommand_token);
get_expected_token(openaxiom_Lbrace_token);
get_expected_token(openaxiom_Macro_token);
if (strcmp(token.id, macro->name)) {
fprintf(stderr, "Expected macro name %s got insted %s in load_macro\n",
macro->name, token.id);
longjmp(jmpbuf, 1);
}
get_expected_token(openaxiom_Rbrace_token);
get_token();
if (token.type == openaxiom_Lsquarebrace_token) {
get_expected_token(openaxiom_Word_token);
if (!number(token.id)) {
fprintf(stderr, "load_macro: Expected A Value Instead Got %s\n",
token.id);
longjmp(jmpbuf, 1);
}
macro->number_parameters = atoi(token.id);
#ifdef DEBUG
fprintf(stderr,
"The number of parameters is %d\n", macro->number_parameters);
#endif
get_expected_token(openaxiom_Rsquarebrace_token);
get_token();
}
else
macro->number_parameters = 0;
if (token.type != openaxiom_Lbrace_token) {
fprintf(stderr, "load_macro:Expected a Left Brace got type %d\n",
token.type);
longjmp(jmpbuf, 1);
}
start_fpos = fpos;
scan_HyperDoc();
ret_val = fseek(cfile, macro->fpos.pos + start_fpos, 0);
size = fpos - start_fpos;
macro_buff = (char *) halloc((size + 1) * sizeof(char), "Macro_buf");
for (size = 0, trace = macro_buff; size < fpos - (start_fpos) - 1; size++)
*trace++ = getc(cfile);
*trace = '\0';
macro->loaded = 1;
restore_scanner_state();
return macro_buff;
}
ParameterList parameters = NULL;
ParameterList
init_parameter_elem(int number)
{
ParameterList parms;
int count;
parms = (ParameterList) halloc(sizeof(struct parameter_list_type),
"ParameterList");
if (number) {
parms->list = (char **) halloc(number * sizeof(char *), "Parameter List");
for (count = 0; count < number; count++)
(parms->list)[count] = NULL;
}
parms->number = number;
return parms;
}
int
push_parameters(ParameterList parms)
{
if (parms == NULL) {
fprintf(stderr, "Tried pushing a null list onto the parameter stack\n");
longjmp(jmpbuf, 1);
}
parms->next = parameters;
parameters = parms;
return 1;
}
int
pop_parameters()
{
ParameterList old;
int count;
if (!parameters) {
return 0;
}
old = parameters;
parameters = old->next;
if (old->number >0) {
for (count = 0; count < old->number; count++)
if ( (old->list)[count] ) free((char *) (old->list)[count]);
free(old->list);
}
free(old);
return 1;
}
int
parse_macro()
{
MacroStore *macro;
int s;
curr_node->type = openaxiom_Macro_token;
curr_node->space = token.id[-1];
curr_node->next = alloc_node();
curr_node = curr_node->next;
macro = (MacroStore *) hash_find(gWindow->fMacroHashTable, token.id);
if (macro != NULL) {
if (!macro->loaded)
macro->macro_string = load_macro(macro);
get_parameter_strings(macro->number_parameters, macro->name);
parse_from_string(macro->macro_string);
if (gEndedPage) {
s = curr_node->type;
curr_node->type = openaxiom_Endmacro_token;
curr_node->next = alloc_node();
curr_node = curr_node->next;
curr_node->type = s;
}
else
curr_node->type = openaxiom_Endmacro_token;
if (pop_parameters())
return 1;
else {
fprintf(stderr,
"parse_macro: Tried to pop an empty parameter stack\n");
longjmp(jmpbuf, 1);
}
}
else {
fprintf(stderr, "parse_macro: Unknown keyword %s\n", token.id);
longjmp(jmpbuf, 1);
}
}
#define numeric(c) ((c >= '0' && c <= '9')?1:0)
static void
get_parameter_strings(int number,char * macro_name)
{
static char buffer[4096];
char *buffer_pntr;
int count;
int lbrace_counter;
char c;
int size;
ParameterList parms = init_parameter_elem(number);
int pnum;
char pnum_chars[5];
int pc;
if (!number) {
push_parameters(parms);
return;
}
for (count = 0; count < number; count++) {
get_token();
if (token.type != openaxiom_Lbrace_token) {
fprintf(stderr, "Wrong number of arguments to the macro %s\n",
macro_name);
jump();
}
for (lbrace_counter = 1, buffer_pntr = buffer;
lbrace_counter;) {
switch (c = get_char()) {
case EOF:
fprintf(stderr, "GetParameterStrings: Unexpected EOF\n");
longjmp(jmpbuf, 1);
case '}':
lbrace_counter--;
if (lbrace_counter)
*buffer_pntr++ = c;
break;
case '{':
lbrace_counter++;
*buffer_pntr++ = c;
break;
case '#':
if (parameters == NULL) {
*buffer_pntr++ = c;
break;
}
if (
((buffer_pntr > buffer + 1) &&
*(buffer_pntr - 1) == '\\' &&
*(buffer_pntr - 2) != '\\') ||
((buffer_pntr > buffer) &&
*(buffer_pntr - 1) == '\\')) {
*buffer_pntr++ = c;
}
else {
c = get_char();
for (pc = 0; numeric(c); pc++) {
pnum_chars[pc] = c;
c = get_char();
}
unget_char(c);
pnum_chars[pc] = '\0';
pnum = atoi(pnum_chars);
pc = 0;
while ((parameters->list)[pnum - 1][pc] != '\0')
*buffer_pntr++ = (parameters->list)[pnum - 1][pc++];
}
break;
default:
*buffer_pntr++ = c;
break;
}
}
*buffer_pntr = '\0';
size = strlen(buffer) + 1;
parms->list[count] = (char *) halloc(size, "Parameter Strings");
strcpy(parms->list[count], buffer);
}
push_parameters(parms);
return ;
}
void
parse_parameters()
{
int value;
if (!number(token.id)) {
fprintf(stderr,
"Parse_parameter: Error Expected a number, got %s instead\n", token.id);
longjmp(jmpbuf, 1);
}
if ((value = atoi(token.id)) > parameters->number) {
fprintf(stderr,
"Parse_parameter: Had a bad parameter number %d\n", value);
longjmp(jmpbuf, 1);
}
parse_from_string((parameters->list)[value - 1]);
curr_node->type = openaxiom_Endparameter_token;
return;
}