Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/*
2
Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.
3
All rights reserved.
4
Copyright (C) 2007-2010, Gabriel Dos Reis.
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
- Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
14
- Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the following disclaimer in
16
the documentation and/or other materials provided with the
17
distribution.
18
19
- Neither the name of The Numerical Algorithms Group Ltd. nor the
20
names of its contributors may be used to endorse or promote products
21
derived from this software without specific prior written permission.
22
23
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
#include "openaxiom-c-macros.h"
37
#include "debug.h"
38
#include "halloc.h"
39
#include "sockio.h"
40
#include "parse.h"
41
#include "hyper.h"
42
#include "lex.h"
43
44
static char * load_macro(MacroStore * macro);
45
static void get_parameter_strings(int number , char * macro_name);
46
47
/* #define DEBUG 1 */
48
49
/*
50
* This routine keeps scanning until it reaches it pops off 1 more
51
* right brace then left brace
52
*/
53
void
54
scan_HyperDoc()
55
{
56
HDWindow *twin = gWindow;
57
int ret_val;
58
int number_of_left_braces = 1;
59
60
gWindow = NULL;
61
while (number_of_left_braces) {
62
ret_val = get_token();
63
if (ret_val == EOF && number_of_left_braces) {
64
fprintf(stderr, "Scan_Hypertex: Unexpected End of File\n");
65
longjmp(jmpbuf, 1);
66
}
67
switch (token.type) {
68
case openaxiom_Page_token:
69
fprintf(stderr, "scan_HyperDoc: Unexpected Page Declaration\n");
70
break;
71
case openaxiom_NewCommand_token:
72
fprintf(stderr, "scan_HyperDoc: Unexpected Macro Declaration\n");
73
break;
74
case openaxiom_Lbrace_token:
75
number_of_left_braces++;
76
break;
77
case openaxiom_Endpatch_token:
78
case openaxiom_Rbrace_token:
79
number_of_left_braces--;
80
break;
81
default:
82
break;
83
}
84
}
85
gWindow = twin;
86
}
87
88
int
89
number(const char *str)
90
{
91
const char *t = str;
92
93
while (*t)
94
if (!isdigit(*t++))
95
return 0;
96
return 1;
97
}
98
99
/* Parse a given macro given the pointer to the unlaoded macro ** */
100
101
static char *
102
load_macro(MacroStore *macro)
103
{
104
int ret_val;
105
long start_fpos;
106
int size = 0;
107
char *trace;
108
char *macro_buff;
109
110
save_scanner_state();
111
cfile = find_fp(macro->fpos);
112
113
114
init_scanner();
115
116
/** First thing I should do is make sure that the name is correct ***/
117
get_expected_token(openaxiom_NewCommand_token);
118
get_expected_token(openaxiom_Lbrace_token);
119
get_expected_token(openaxiom_Macro_token);
120
if (strcmp(token.id, macro->name)) {
121
/** WOW, Somehow I had the location of the wrong macro **/
122
fprintf(stderr, "Expected macro name %s got insted %s in load_macro\n",
123
macro->name, token.id);
124
longjmp(jmpbuf, 1);
125
}
126
get_expected_token(openaxiom_Rbrace_token);
127
128
/** Next I should check to see if I have any parameters **/
129
get_token();
130
if (token.type == openaxiom_Lsquarebrace_token) {
131
/** The person is telling me the number of macros he is going to use **/
132
get_expected_token(openaxiom_Word_token);
133
if (!number(token.id)) {
134
fprintf(stderr, "load_macro: Expected A Value Instead Got %s\n",
135
token.id);
136
longjmp(jmpbuf, 1);
137
}
138
/** if it is a number, then I should store it in the parameter number
139
member of the macro structure **/
140
macro->number_parameters = atoi(token.id);
141
#ifdef DEBUG
142
fprintf(stderr,
143
"The number of parameters is %d\n", macro->number_parameters);
144
#endif
145
get_expected_token(openaxiom_Rsquarebrace_token);
146
get_token();
147
}
148
else
149
macro->number_parameters = 0;
150
151
/*** Now I should be able to check the token, and insure that I have read
152
a leftbrace, then the string will follow ****/
153
if (token.type != openaxiom_Lbrace_token) {
154
/** The macro is not in a group, uh oh **/
155
fprintf(stderr, "load_macro:Expected a Left Brace got type %d\n",
156
token.type);
157
longjmp(jmpbuf, 1);
158
}
159
start_fpos = fpos;
160
scan_HyperDoc();
161
ret_val = fseek(cfile, macro->fpos.pos + start_fpos, 0);
162
size = fpos - start_fpos;
163
macro_buff = (char *) halloc((size + 1) * sizeof(char), "Macro_buf");
164
for (size = 0, trace = macro_buff; size < fpos - (start_fpos) - 1; size++)
165
*trace++ = getc(cfile);
166
*trace = '\0';
167
macro->loaded = 1;
168
restore_scanner_state();
169
return macro_buff;
170
}
171
172
173
/** Here are the functions and declarations for the parameter stack **/
174
ParameterList parameters = NULL;
175
176
ParameterList
177
init_parameter_elem(int number)
178
{
179
ParameterList parms;
180
int count;
181
182
/** allocate the space neeeded **/
183
parms = (ParameterList) halloc(sizeof(struct parameter_list_type),
184
"ParameterList");
185
/** now allocate the memeory for the pointers to the parameters **/
186
if (number) {
187
parms->list = (char **) halloc(number * sizeof(char *), "Parameter List");
188
189
/** initialize my pointers **/
190
for (count = 0; count < number; count++)
191
(parms->list)[count] = NULL;
192
}
193
parms->number = number;
194
return parms;
195
}
196
197
int
198
push_parameters(ParameterList parms)
199
{
200
201
if (parms == NULL) {
202
fprintf(stderr, "Tried pushing a null list onto the parameter stack\n");
203
longjmp(jmpbuf, 1);
204
}
205
206
parms->next = parameters;
207
parameters = parms;
208
return 1;
209
}
210
int
211
pop_parameters()
212
{
213
/** Simply pops the top of the parameter list, being good and freeing
214
all the memory **/
215
ParameterList old;
216
int count;
217
218
if (!parameters) {
219
return 0;
220
}
221
222
old = parameters;
223
parameters = old->next;
224
225
/** Free the parameter text and pointers **/
226
if (old->number >0) {
227
for (count = 0; count < old->number; count++)
228
if ( (old->list)[count] ) free((char *) (old->list)[count]);
229
free(old->list);
230
}
231
232
free(old); /** free the parameter **/
233
234
return 1;
235
}
236
237
int
238
parse_macro()
239
{
240
241
/*
242
* This routine loads a macro if needed, and then parses it from the
243
* string
244
*/
245
MacroStore *macro;
246
int s;
247
248
curr_node->type = openaxiom_Macro_token;
249
curr_node->space = token.id[-1];
250
curr_node->next = alloc_node();
251
curr_node = curr_node->next;
252
macro = (MacroStore *) hash_find(gWindow->fMacroHashTable, token.id);
253
if (macro != NULL) {
254
if (!macro->loaded)
255
macro->macro_string = load_macro(macro);
256
get_parameter_strings(macro->number_parameters, macro->name);
257
parse_from_string(macro->macro_string);
258
if (gEndedPage) {
259
s = curr_node->type;
260
curr_node->type = openaxiom_Endmacro_token;
261
curr_node->next = alloc_node();
262
curr_node = curr_node->next;
263
curr_node->type = s;
264
}
265
else
266
curr_node->type = openaxiom_Endmacro_token;
267
if (pop_parameters())
268
return 1;
269
else {
270
fprintf(stderr,
271
"parse_macro: Tried to pop an empty parameter stack\n");
272
longjmp(jmpbuf, 1);
273
}
274
}
275
else {
276
fprintf(stderr, "parse_macro: Unknown keyword %s\n", token.id);
277
longjmp(jmpbuf, 1);
278
}
279
}
280
281
#define numeric(c) ((c >= '0' && c <= '9')?1:0)
282
283
static void
284
get_parameter_strings(int number,char * macro_name)
285
{
286
static char buffer[4096];
287
char *buffer_pntr;
288
int count;
289
int lbrace_counter;
290
char c;
291
int size;
292
ParameterList parms = init_parameter_elem(number);
293
int pnum;
294
char pnum_chars[5];
295
int pc;
296
297
if (!number) { /* nothing to be done */
298
push_parameters(parms);
299
return;
300
}
301
for (count = 0; count < number; count++) {
302
get_token();
303
if (token.type != openaxiom_Lbrace_token) {
304
/** The macro is not in a group, uh oh **/
305
fprintf(stderr, "Wrong number of arguments to the macro %s\n",
306
macro_name);
307
jump();
308
}
309
for (lbrace_counter = 1, buffer_pntr = buffer;
310
lbrace_counter;) {
311
switch (c = get_char()) {
312
case EOF:
313
fprintf(stderr, "GetParameterStrings: Unexpected EOF\n");
314
longjmp(jmpbuf, 1);
315
case '}':
316
lbrace_counter--;
317
if (lbrace_counter)
318
*buffer_pntr++ = c;
319
break;
320
case '{':
321
lbrace_counter++;
322
*buffer_pntr++ = c;
323
break;
324
case '#':
325
/* uh oh, I have a parameter reference inside a parameter */
326
/* get the number */
327
if (parameters == NULL) {
328
*buffer_pntr++ = c;
329
break;
330
}
331
if (
332
((buffer_pntr > buffer + 1) &&
333
*(buffer_pntr - 1) == '\\' &&
334
*(buffer_pntr - 2) != '\\') ||
335
((buffer_pntr > buffer) &&
336
*(buffer_pntr - 1) == '\\')) {
337
/* I had a \# */
338
*buffer_pntr++ = c;
339
}
340
else {
341
c = get_char();
342
for (pc = 0; numeric(c); pc++) {
343
pnum_chars[pc] = c;
344
c = get_char();
345
}
346
unget_char(c);
347
pnum_chars[pc] = '\0';
348
pnum = atoi(pnum_chars);
349
pc = 0;
350
/* Now copy the parameter */
351
while ((parameters->list)[pnum - 1][pc] != '\0')
352
*buffer_pntr++ = (parameters->list)[pnum - 1][pc++];
353
}
354
break;
355
default:
356
*buffer_pntr++ = c;
357
break;
358
}
359
}
360
*buffer_pntr = '\0';
361
/*** Now add it to the current parameter list **/
362
size = strlen(buffer) + 1;
363
parms->list[count] = (char *) halloc(size, "Parameter Strings");
364
strcpy(parms->list[count], buffer);
365
}
366
push_parameters(parms);
367
return ;
368
}
369
void
370
parse_parameters()
371
{
372
int value;
373
374
if (!number(token.id)) {
375
fprintf(stderr,
376
"Parse_parameter: Error Expected a number, got %s instead\n", token.id);
377
longjmp(jmpbuf, 1);
378
}
379
380
if ((value = atoi(token.id)) > parameters->number) {
381
/** had a bad parameter number **/
382
fprintf(stderr,
383
"Parse_parameter: Had a bad parameter number %d\n", value);
384
longjmp(jmpbuf, 1);
385
}
386
387
parse_from_string((parameters->list)[value - 1]);
388
curr_node->type = openaxiom_Endparameter_token;
389
return;
390
}
391
392