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
/******************************************************************************
37
*
38
* parse-paste.c: HyperDoc routines for paste-in areas.
39
*
40
* Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993.
41
*
42
****************************************************************************/
43
44
#include "openaxiom-c-macros.h"
45
#include "debug.h"
46
#include "halloc.h"
47
#include "sockio.h"
48
#include "parse.h"
49
#include "hyper.h"
50
#include "display.h"
51
#include "group.h"
52
#include "lex.h"
53
54
static void load_patch(PatchStore * patch);
55
56
short int gInPaste;
57
58
59
void
60
parse_paste()
61
{
62
TextNode *pn = curr_node;
63
PasteNode *paste;
64
SourceInputKind where;
65
66
if (gParserRegion != Scrolling) {
67
fprintf(stderr, "(HyperDoc) Paste areas are only allowed in the scrolling area:");
68
print_page_and_filename();
69
jump();
70
}
71
gInPaste++;
72
73
/* now I need to get the name */
74
get_token();
75
if (token.type != openaxiom_Lbrace_token) {
76
fprintf(stderr, "(HyperDoc) A paste area needs a name:\n");
77
print_next_ten_tokens();
78
print_page_and_filename();
79
jump();
80
}
81
pn->data.text = alloc_string(get_input_string());
82
pn->type = openaxiom_Paste_token;
83
84
/*
85
* now see if there is already an entry in the hash_table for this thing,
86
* if not create it and put it there.
87
*/
88
paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, pn->data.text);
89
if (paste == 0) {
90
paste = alloc_paste_node(pn->data.text);
91
hash_insert(gWindow->fPasteHashTable, (char *)paste, paste->name);
92
}
93
else if (paste->haspaste) {
94
fprintf(stderr, "(HyperDoc) Tried to redefine paste area %s\n", paste->name);
95
print_page_and_filename();
96
/* jump(); */
97
}
98
paste->haspaste = 1;
99
paste->paste_item = current_item();
100
get_token();
101
if (token.type == openaxiom_Lsquarebrace_token) {
102
/* user wishes to specify a where to send the command */
103
where = get_where();
104
if (where == SourceInputKind::Error) {
105
paste->where = where;
106
fprintf(stderr, "(HyperDoc) \\begin{paste} was expecting [lisp|unix|ht]\n");
107
print_next_ten_tokens();
108
print_page_and_filename();
109
jump();
110
}
111
else
112
paste->where = where;
113
get_token();
114
}
115
else
116
paste->where = SourceInputKind::File;
117
118
/* now try to get the command argument or page name */
119
if (token.type != openaxiom_Lbrace_token) {
120
paste->where = { };
121
fprintf(stderr, "(HyperDoc) \\begin{paste} was expecting an argument\n");
122
print_next_ten_tokens();
123
print_page_and_filename();
124
jump();
125
}
126
paste->arg_node = alloc_node();
127
curr_node = paste->arg_node;
128
parse_HyperDoc();
129
curr_node->type = openaxiom_Endarg_token;
130
131
gWindow->fDisplayedWindow = gWindow->fScrollWindow;
132
133
/* Now try to find the displaying text */
134
pn->next = alloc_node();
135
curr_node = pn->next;
136
parse_HyperDoc();
137
curr_node->type = openaxiom_Endpaste_token;
138
paste->end_node = curr_node;
139
140
paste->begin_node = pn;
141
gInPaste--;
142
}
143
144
void
145
parse_pastebutton()
146
{
147
PasteNode *paste;
148
TextNode *pb;
149
150
/*
151
* this routine parse a \pastebutton expression. The syntax is
152
* \pastebutton{name}
153
*/
154
pb = curr_node;
155
pb->type = openaxiom_Pastebutton_token;
156
157
/* first thing I should do is get the name */
158
get_token();
159
if (token.type != openaxiom_Lbrace_token) {
160
fprintf(stderr, "(HyperDoc) \\pastebutton needs a name\n");
161
print_page_and_filename();
162
print_next_ten_tokens();
163
jump();
164
}
165
pb->data.text = alloc_string(get_input_string());
166
167
/*
168
* now I should see if the paste area has already been parsed, and if not
169
* I should create a spot in the hash table for it
170
*/
171
paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, pb->data.text);
172
if (paste == 0) {
173
paste = alloc_paste_node(pb->data.text);
174
hash_insert(gWindow->fPasteHashTable,(char *) paste, paste->name);
175
}
176
else if (paste->hasbutton) {
177
fprintf(stderr, "(HyperDoc) Tried to redefine paste area %s\n", paste->name);
178
print_page_and_filename();
179
/* jump(); */
180
}
181
paste->hasbutton = 1;
182
183
/* Now we need to parse the HyperDoc and for the displayed text */
184
185
get_token();
186
if (token.type != openaxiom_Lbrace_token) {
187
fprintf(stderr, "(HyperDoc) \\pastebutton was expecting a { \n");
188
print_page_and_filename();
189
print_next_ten_tokens();
190
jump();
191
}
192
pb->next = alloc_node();
193
curr_node = pb->next;
194
parse_HyperDoc();
195
curr_node->type = openaxiom_Endpastebutton_token;
196
197
/* once that is done I need only make the window for this link */
198
pb->link = make_paste_window(paste);
199
}
200
201
202
/*
203
* this routine is responsible for parsing a patch from a file. To do this I
204
* guess er will init_scanner, then parse, the parsed piece of text
205
* will replace the current PasteNode which will be squashed down to
206
* nothing, and then discarded.
207
*/
208
209
HyperDocPage *
210
parse_patch(PasteNode *paste)
211
{
212
TextNode *new_paste;
213
TextNode *end_node;
214
TextNode *begin_node;
215
TextNode *arg_node;
216
TextNode *old;
217
TextNode *next_node;
218
InputItem *paste_item = paste->paste_item;
219
SourceInputKind where = paste->where;
220
GroupItem *g = paste->group;
221
ItemStack *is = paste->item_stack;
222
PatchStore *patch;
223
char *patch_name;
224
int ret_value = 1;
225
226
/* prepare to throw away the current paste node */
227
end_node = paste->end_node;
228
next_node = end_node->next;
229
begin_node = paste->begin_node;
230
arg_node = paste->arg_node;
231
old = begin_node->next;
232
233
/* now read the new stuff and add it in between all this stuff */
234
235
switch (where) {
236
case SourceInputKind::File:
237
patch_name = print_to_string(arg_node);
238
patch = (PatchStore *) hash_find(gWindow->fPatchHashTable, patch_name);
239
if (!patch) {
240
fprintf(stderr, "(HyperDoc) Unknown patch name %s\n", patch_name);
241
BeepAtTheUser();
242
return 0;
243
}
244
if (!patch->loaded)
245
load_patch(patch);
246
input_type = SourceInputKind::String;
247
input_string = patch->string;
248
break;
249
case SourceInputKind::SpadSocket:
250
input_type = SourceInputKind::SpadSocket;
251
ret_value = issue_serverpaste(arg_node);
252
if (ret_value < 0) {
253
paste->where = where;
254
paste->end_node = end_node;
255
paste->arg_node = arg_node;
256
paste->group = g;
257
paste->item_stack = is;
258
paste->haspaste = 1;
259
return 0;
260
}
261
break;
262
case SourceInputKind::UnixFD:
263
input_type = SourceInputKind::UnixFD;
264
issue_unixpaste(arg_node);
265
break;
266
default:
267
fprintf(stderr, "(HyperDoc) \\parsebutton error: Unknown where\n");
268
exit(-1);
269
break;
270
}
271
272
paste->where = { };
273
paste->end_node = paste->arg_node = paste->begin_node = 0;
274
paste->group = 0;
275
paste->item_stack = 0;
276
paste->haspaste = 0;
277
paste->paste_item = 0;
278
279
280
/* set the jump buffer in case it is needed */
281
if (setjmp(jmpbuf)) {
282
/*** OOOPS, an error occurred ****/
283
fprintf(stderr, "(HyperDoc) Had an error parsing a patch: Goodbye!\n");
284
exit(-1);
285
}
286
287
288
end_node->next = 0;
289
free_node(old, 1);
290
291
init_parse_patch(gWindow->page);
292
init_paste_item(paste_item);
293
get_token();
294
if (token.type != openaxiom_Patch_token) {
295
fprintf(stderr, "(HyperDoc) Pastebutton %s was expecting a patch\n",
296
paste->name);
297
jump();
298
}
299
if (input_type == SourceInputKind::String) {
300
get_token();
301
if (token.type != openaxiom_Lbrace_token) {
302
token_name(token.type);
303
fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer);
304
print_page_and_filename();
305
jump();
306
}
307
308
get_token();
309
if (token.type != openaxiom_Word_token) {
310
token_name(token.type);
311
fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer);
312
print_page_and_filename();
313
jump();
314
}
315
316
get_token();
317
if (token.type != openaxiom_Rbrace_token) {
318
token_name(token.type);
319
fprintf(stderr, "(HyperDoc) Unexpected %s \n", ebuffer);
320
print_page_and_filename();
321
jump();
322
}
323
}
324
new_paste = alloc_node();
325
curr_node = new_paste;
326
parse_HyperDoc();
327
328
/* Once I am back, I need only reallign all the text structures */
329
curr_node->type = openaxiom_Noop_token;
330
curr_node->next = next_node;
331
begin_node->next = new_paste;
332
begin_node->type = openaxiom_Noop_token;
333
free(begin_node->data.text);
334
begin_node->data.text = 0;
335
336
gWindow->fDisplayedWindow = gWindow->fScrollWindow;
337
338
repaste_item();
339
340
paste_page(begin_node);
341
342
/* so now I should just be able to disappear */
343
return gWindow->page;
344
}
345
346
static void
347
load_patch(PatchStore *patch)
348
{
349
long start_fpos;
350
int size = 0;
351
int limsize;
352
char *trace;
353
354
355
save_scanner_state();
356
cfile = find_fp(patch->fpos);
357
358
init_scanner();
359
360
/** First thing I should do is make sure that the name is correct ***/
361
start_fpos = fpos;
362
get_expected_token(openaxiom_Patch_token);
363
get_expected_token(openaxiom_Lbrace_token);
364
get_expected_token(openaxiom_Word_token);
365
if (strcmp(token.id, patch->name)) {
366
/** WOW, Somehow I had the location of the wrong macro **/
367
fprintf(stderr, "(HyperDoc) Expected patch name %s: got instead %s in load_patch\n",
368
patch->name, token.id);
369
jump();
370
}
371
get_expected_token(openaxiom_Rbrace_token);
372
373
scan_HyperDoc();
374
fseek(cfile, patch->fpos.pos + start_fpos, 0);
375
limsize = fpos - start_fpos + 1;
376
patch->string = (char *) halloc((limsize + 1) * sizeof(char), "Patch String");
377
for (size = 1, trace = patch->string; size < limsize; size++)
378
*trace++ = getc(cfile);
379
*trace = '\0';
380
patch->loaded = 1;
381
restore_scanner_state();
382
}
383
384
385
386