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 reversed.
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
* mem.c: HyperDoc Memory Management Routines.
39
*
40
* Copyright The Numerical Algorithms Group Limited 1991, 1992, 1993.
41
*
42
****************************************************************************/
43
44
#include "debug.h"
45
#include "halloc.h"
46
#include "sockio.h"
47
#include "hyper.h"
48
#include "group.h"
49
#include "event.h"
50
#include "parse.h"
51
52
static void free_cond(CondNode * cond);
53
static void free_depend(SpadcomDepend * sd);
54
static void free_lines(LineStruct * lines);
55
static void dont_free(void * link);
56
static void free_if_non_NULL(void * p);
57
static void free_input_box(InputBox * box);
58
static void free_paste(PasteNode * paste , short des);
59
static void free_pastearea(TextNode * node , short des);
60
static void free_pastebutton(TextNode * node , short des);
61
static void free_radio_boxes(RadioBoxes * radio);
62
63
64
extern HashTable init_page_hash;
65
extern HashTable init_macro_hash;
66
extern HashTable init_patch_hash;
67
68
69
static void
70
free_if_non_NULL(void *p)
71
{
72
if (p){
73
free(p);
74
}
75
}
76
77
78
/* allocate an HDWindow Structure and initialize it */
79
80
HDWindow *
81
alloc_hd_window()
82
{
83
HDWindow *w = (HDWindow *) halloc(sizeof(HDWindow), "HDWindow");
84
/*char haslisp[10];*/
85
86
w->fMemoStack = (HyperDocPage **)
87
halloc(MaxMemoDepth * sizeof(HyperDocPage *), "Memo Stack");
88
w->fDownLinkStack = (HyperDocPage **)
89
halloc(MaxDownlinkDepth * sizeof(HyperDocPage *), "downlink stack");
90
w->fDownLinkStackTop =
91
(int *) halloc(MaxDownlinkDepth * sizeof(int), "top downlink stack");
92
w->fAxiomFrame = 0;
93
init_page_structs(w);
94
95
/* Now I initialize the hash tables for the page */
96
w->fCondHashTable = (HashTable *) halloc(sizeof(HashTable), "cond hash");
97
hash_init(
98
w->fCondHashTable,
99
CondHashSize,
100
(EqualFunction) string_equal,
101
(HashcodeFunction) string_hash);
102
103
w->fPasteHashTable = (HashTable *) halloc(sizeof(HashTable), "paste hash");
104
hash_init(
105
w->fPasteHashTable,
106
PasteHashSize,
107
(EqualFunction) string_equal,
108
(HashcodeFunction) string_hash);
109
w->fPageHashTable = hash_copy_table(&init_page_hash);
110
w->fPatchHashTable = hash_copy_table(&init_patch_hash);
111
w->fMacroHashTable = hash_copy_table(&init_macro_hash);
112
113
gWindow = w;
114
/*sprintf(haslisp, "%1d\0", MenuServerOpened);*/
115
make_special_pages(w->fPageHashTable);
116
w->fDisplayedCursor = 0;
117
return w;
118
}
119
120
void
121
free_hd_window(HDWindow *w)
122
{
123
if (w) {
124
free(w->fMemoStack);
125
free(w->fDownLinkStack);
126
free(w->fDownLinkStackTop);
127
/*
128
free(w->fWindowHashTable); will be taken care of by freeing
129
free_hash(w->fPageHashTable, free_page); below
130
cf free_page
131
*/
132
free_hash(w->fMacroHashTable, (FreeFunction)dont_free);
133
free_hash(w->fPasteHashTable, (FreeFunction)dont_free);
134
free_hash(w->fPatchHashTable, (FreeFunction)dont_free);
135
136
free_hash(w->fCondHashTable, (FreeFunction)free_cond);
137
free_hash(w->fPageHashTable, (FreeFunction)free_page);
138
free(w->fPageHashTable);
139
free(w->fPatchHashTable);
140
free(w->fMacroHashTable);
141
XFreeGC(gXDisplay, w->fStandardGC);
142
XFreeGC(gXDisplay, w->fInputGC);
143
XFreeGC(gXDisplay, w->fCursorGC);
144
XFreeGC(gXDisplay, w->fControlGC);
145
free(w);
146
}
147
}
148
149
150
/* Allocate an empty text node */
151
152
TextNode *
153
alloc_node()
154
{
155
TextNode *temp_node;
156
157
temp_node = (TextNode *) halloc(sizeof(TextNode), "Text Node");
158
temp_node->type = 0;
159
temp_node->space = 0;
160
temp_node->height = 0;
161
temp_node->width = 0;
162
temp_node->x = -1;
163
temp_node->y = -1;
164
temp_node->data.node = NULL;
165
temp_node->next = NULL;
166
temp_node->link = NULL;
167
temp_node->image.pm = 0;
168
return temp_node;
169
}
170
171
void
172
free_node(TextNode *node, short int des)
173
{
174
175
if (node == NULL)
176
return;
177
178
switch (node->type) {
179
case openaxiom_Paste_token:
180
free_pastearea(node, des);
181
free_node(node->next, des);
182
break;
183
case openaxiom_Pastebutton_token:
184
free_pastebutton(node, des);
185
free_node(node->next, des);
186
break;
187
case openaxiom_Ifcond_token:
188
free_node(node->data.ifnode->cond, des);
189
free_node(node->data.ifnode->thennode, des);
190
free_node(node->data.ifnode->elsenode, des);
191
break;
192
case openaxiom_Dash_token:
193
case openaxiom_Lsquarebrace_token:
194
case openaxiom_Word_token:
195
case openaxiom_WindowId_token:
196
case openaxiom_Punctuation_token:
197
case openaxiom_Lbrace_token:
198
case openaxiom_Rbrace_token:
199
case openaxiom_SimpleBox_token:
200
case openaxiom_Verbatim_token:
201
case openaxiom_Math_token:
202
case openaxiom_Spadsrctxt_token:
203
case openaxiom_Spadsrc_token:
204
free_if_non_NULL(node->data.text);
205
free_node(node->next, des);
206
break;
207
case openaxiom_Inputstring_token:
208
if (des)
209
delete_item(node->data.text);
210
free_if_non_NULL(node->data.text);
211
free_node(node->next, des);
212
break;
213
case openaxiom_It_token:
214
case openaxiom_Sl_token:
215
case openaxiom_Tt_token:
216
case openaxiom_Rm_token:
217
case openaxiom_Emphasize_token:
218
case openaxiom_Beep_token:
219
case openaxiom_BoldFace_token:
220
case openaxiom_Par_token:
221
case openaxiom_Newline_token:
222
case openaxiom_Horizontalline_token:
223
case openaxiom_Item_token:
224
case openaxiom_Beginscroll_token:
225
case openaxiom_Endscroll_token:
226
case openaxiom_Group_token:
227
case openaxiom_Table_token:
228
case openaxiom_Macro_token:
229
case openaxiom_Pound_token:
230
case openaxiom_Center_token:
231
case openaxiom_Box_token:
232
case openaxiom_Mbox_token:
233
case openaxiom_Tableitem_token:
234
case openaxiom_Scrollingnode_token:
235
case openaxiom_Headernode_token:
236
case openaxiom_Titlenode_token:
237
case openaxiom_Footernode_token:
238
case openaxiom_Controlbitmap_token:
239
case openaxiom_Fi_token:
240
case openaxiom_Description_token:
241
case openaxiom_Rsquarebrace_token:
242
case openaxiom_Endpaste_token:
243
case openaxiom_Endpastebutton_token:
244
free_node(node->next, des);
245
break;
246
case openaxiom_Inputbitmap_token:
247
case openaxiom_Inputpixmap_token:
248
free_if_non_NULL(node->data.text);
249
free_node(node->next, des);
250
break;
251
case openaxiom_Quitbutton_token:
252
case openaxiom_Helpbutton_token:
253
case openaxiom_Upbutton_token:
254
case openaxiom_Returnbutton_token:
255
if (des && node->link->win) {
256
hash_delete(gWindow->page->fLinkHashTable,(char *) &node->link->win);
257
XDestroyWindow(gXDisplay, node->link->win);
258
}
259
free_if_non_NULL(node->link);
260
free_node(node->next, des);
261
break;
262
case openaxiom_Memolink_token:
263
case openaxiom_Downlink_token:
264
case openaxiom_Windowlink_token:
265
case openaxiom_Link_token:
266
case openaxiom_Lisplink_token:
267
case openaxiom_Lispwindowlink_token:
268
case openaxiom_Spadcall_token:
269
case openaxiom_Spadcallquit_token:
270
case openaxiom_LispMemoLink_token:
271
case openaxiom_Lispcommand_token:
272
case openaxiom_Lispcommandquit_token:
273
case openaxiom_LispDownLink_token:
274
case openaxiom_Unixlink_token:
275
case openaxiom_Spadlink_token:
276
case openaxiom_Spadmemolink_token:
277
case openaxiom_Spaddownlink_token:
278
case openaxiom_Unixcommand_token:
279
case openaxiom_Spadcommand_token:
280
case openaxiom_Spadgraph_token:
281
if (des && node->link->win) {
282
hash_delete(gWindow->page->fLinkHashTable,(char *) &node->link->win);
283
XDestroyWindow(gXDisplay, node->link->win);
284
}
285
/* TTT don't free the link before freeing nodes off it */
286
/* free_node(node->link->reference.node);*/
287
free_if_non_NULL(node->link);
288
free_node(node->next, des);
289
break;
290
case openaxiom_Free_token:
291
case openaxiom_Indent_token:
292
case openaxiom_Indentrel_token:
293
case openaxiom_HSpace_token:
294
case openaxiom_Space_token:
295
case openaxiom_VSpace_token:
296
case openaxiom_Button_token:
297
case openaxiom_Bound_token:
298
case openaxiom_Tab_token:
299
free_node(node->next, des);
300
free_node(node->data.node, des);
301
break;
302
case openaxiom_End_token:
303
case openaxiom_Endcenter_token:
304
case openaxiom_Endlink_token:
305
case openaxiom_Endgroup_token:
306
case openaxiom_Endbox_token:
307
case openaxiom_Endmbox_token:
308
case openaxiom_Endspadcommand_token:
309
case openaxiom_Endpix_token:
310
case openaxiom_Endmacro_token:
311
case openaxiom_Endparameter_token:
312
case openaxiom_Endtable_token:
313
case openaxiom_Endtableitem_token:
314
case openaxiom_Noop_token:
315
case openaxiom_Endinputbox_token:
316
case openaxiom_Enddescription_token:
317
case openaxiom_Endif_token:
318
case openaxiom_Endtitems_token:
319
case openaxiom_Enditems_token:
320
case openaxiom_Endverbatim_token:
321
case openaxiom_Endmath_token:
322
case openaxiom_Endspadsrc_token:
323
free_node(node->next, des);
324
break;
325
case openaxiom_Endheader_token:
326
case openaxiom_Endtitle_token:
327
case openaxiom_Endfooter_token:
328
case openaxiom_Endscrolling_token:
329
case openaxiom_Endarg_token:
330
break;
331
case openaxiom_Endbutton_token:
332
case openaxiom_Beginitems_token:
333
free_if_non_NULL(node->data.text);
334
free_node(node->next, des);
335
break;
336
337
default:
338
339
/* printf("don't know how to free type %d\n", node->type); */
340
return;
341
}
342
free(node);
343
}
344
345
IfNode *
346
alloc_ifnode()
347
{
348
IfNode *tempif;
349
350
tempif = (IfNode *) halloc(sizeof(IfNode), "IfNode");
351
tempif->thennode = tempif->elsenode = tempif->cond = NULL;
352
return tempif;
353
}
354
355
CondNode *
356
alloc_condnode()
357
{
358
CondNode *temp;
359
360
temp = (CondNode *) halloc(sizeof(CondNode), "Cond Node");
361
temp->cond = temp->label = NULL;
362
return temp;
363
}
364
365
static void
366
free_cond(CondNode *cond)
367
{
368
if (cond) {
369
free(cond->label);
370
if (cond->cond)
371
free(cond->cond);
372
free(cond);
373
}
374
}
375
376
/* Allocate a new HyperDoc page */
377
378
HyperDocPage *
379
alloc_page(const char *name)
380
{
381
HyperDocPage *page;
382
383
page = (HyperDocPage *) halloc(sizeof(HyperDocPage), "HyperDocPage");
384
page->name = name;
385
page->header = page->scrolling = page->footer = page->title = NULL;
386
page->scroll_off = 0;
387
page->sock = NULL;
388
page->box_hash = page->depend_hash = NULL;
389
page->fLinkHashTable = (HashTable *) halloc(sizeof(HashTable), "Page->fLinkHashTable");
390
page->input_list = page->current_item = NULL;
391
page->page_flags = 0000000;
392
page->filename = NULL;
393
page->helppage = alloc_string(TopLevelHelpPage);
394
page->radio_boxes = NULL;
395
page->button_list = NULL;
396
page->s_button_list = NULL;
397
return page;
398
}
399
400
void
401
free_page(HyperDocPage *page)
402
{
403
/*
404
* This routine now checks for an environment variable NOFREE. If found
405
* it returns.
406
*/
407
408
if (page == NULL)
409
return;
410
411
switch (page->type) {
412
case UlUnknownPage:
413
case UnknownPage:
414
case ErrorPage:
415
case Unixfd:
416
case SpadGen:
417
case Normal:
418
419
/*
420
* if(page->name) free(page->name); if(page->filename)
421
* free(page->filename);
422
*/
423
free_node(page->scrolling, 0);
424
free_node(page->header, 0);
425
free_node(page->footer, 0);
426
free_node(page->title, 0);
427
free_button_list(page->s_button_list);
428
free_button_list(page->button_list);
429
/*
430
if (page->sock != NULL)
431
free(page->sock);
432
*/
433
free_hash(page->depend_hash, (FreeFunction)free_depend);
434
/* TTT line below causes freeing of freed memory and freed memory reads
435
links should have been freed by the recursive free_node's above (cf.free_node)
436
this is apparently because we are called from free_hd_window
437
and we had made a call to free w->fWindowHashTable which is made
438
to point to the same thing
439
so we do it HERE not THERE
440
*/
441
free_hash(page->fLinkHashTable, (FreeFunction)dont_free);
442
free_hash(page->box_hash, (FreeFunction)free_input_box);
443
free_input_list(page->input_list);
444
free_radio_boxes(page->radio_boxes);
445
free(page->helppage);
446
free(page);
447
break;
448
case UnloadedPageType:
449
break;
450
default:
451
/* fprintf(stderr, "Unknown Page type: %d\n", page->type); */
452
break;
453
}
454
}
455
456
static void
457
free_paste(PasteNode *paste, short int des)
458
{
459
if (paste) {
460
free_group_stack(paste->group);
461
free_item_stack(paste->item_stack);
462
free_node(paste->arg_node, des);
463
free(paste);
464
}
465
}
466
467
static void
468
free_pastebutton(TextNode *node, short int des)
469
{
470
/*
471
* if I am freeing from within parse patch, then I have to do some
472
* special things first
473
*/
474
475
476
/* the following seems to be unused */
477
if (gActiveWindow == node->link->win)
478
gActiveWindow = -1;
479
480
481
482
if (des) {
483
PasteNode *paste;
484
paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, node->data.text);
485
486
if (!paste->haspaste) {
487
/* squash this thing */
488
489
hash_delete(gWindow->fPasteHashTable, (char *)node->data.text);
490
free_paste(paste, des);
491
hash_delete(gWindow->page->fLinkHashTable,(char *) &node->link->win);
492
493
XDestroyWindow(gXDisplay, node->link->win);
494
}
495
else
496
paste->hasbutton = 0;
497
}
498
499
free_if_non_NULL(node->data.text);
500
501
}
502
503
static void
504
free_pastearea(TextNode *node, short int des)
505
{
506
if (des) {
507
PasteNode *paste;
508
paste = (PasteNode *) hash_find(gWindow->fPasteHashTable, node->data.text);
509
if (paste) {
510
if (!paste->hasbutton) {
511
/* squash this thing */
512
hash_delete(gWindow->fPasteHashTable, node->data.text);
513
free_paste(paste, des);
514
}
515
else
516
paste->haspaste = 0;
517
}
518
}
519
520
free_if_non_NULL(node->data.text);
521
}
522
523
524
void
525
free_string(char *str)
526
{
527
free_if_non_NULL(str);
528
}
529
530
static void
531
free_depend(SpadcomDepend *sd)
532
{
533
free_if_non_NULL((char *) sd);
534
}
535
536
static void
537
dont_free(void *link)
538
{
539
return;
540
}
541
542
#if 0
543
----------- NOT USED
544
static void
545
free_link(HyperLink *link)
546
{
547
printf("Link type %d\n",link->type);
548
free_if_non_NULL((char *) link);
549
}
550
----------- NOT USED
551
#endif
552
553
static void
554
free_lines(LineStruct *lines)
555
{
556
if (lines->prev != NULL)
557
lines->prev->next = NULL;
558
while (lines != NULL) {
559
LineStruct *del;
560
del = lines;
561
lines = lines->next;
562
free(del->buffer);
563
free(del);
564
}
565
}
566
567
void
568
free_input_item(InputItem *sym, short int des)
569
{
570
free_if_non_NULL(sym->name);
571
free_lines(sym->lines);
572
if (des)
573
XDestroyWindow(gXDisplay, sym->win);
574
}
575
576
void
577
free_input_list(InputItem *il)
578
{
579
while (il) {
580
InputItem *trash = il;
581
il = il->next;
582
free_input_item(trash, 0);
583
free(trash);
584
}
585
}
586
587
static void
588
free_input_box(InputBox *box)
589
{
590
if (box) {
591
free_if_non_NULL(box->name);
592
free(box);
593
}
594
}
595
596
static void
597
free_radio_boxes(RadioBoxes *radio)
598
{
599
if (radio) {
600
free_radio_boxes(radio->next);
601
free_if_non_NULL(radio->name);
602
free(radio);
603
}
604
}
605
606
#if 0
607
--------------- NOT USED
608
static void
609
free_image(ImageStruct *image)
610
{
611
free(image->image.xi->data);
612
free(image->image.xi);
613
free(image);
614
}
615
--------------- NOT USED
616
#endif
617
618
#if 0
619
--------------- NOT USED
620
static void
621
free_macro(MacroStore *macro)
622
{
623
if (macro) {
624
free(macro->name);
625
if (macro->macro_string)
626
free(macro->macro_string);
627
free(macro);
628
}
629
}
630
--------------- NOT USED
631
#endif
632
633
634
635
LineStruct *
636
alloc_inputline(int size)
637
{
638
int i;
639
LineStruct *line =
640
(LineStruct *) halloc(sizeof(LineStruct), "Line Structure");
641
642
line->prev = line->next = NULL;
643
line->buffer = (char *) halloc(sizeof(char) * size + 2, "symbol buffer");
644
for (i = 0; i < size + 2; i++)
645
line->buffer[i] = 0;
646
line->buff_pntr = line->len = 0;
647
return line;
648
}
649
650
PasteNode *
651
alloc_paste_node(char *name)
652
{
653
PasteNode *pastenode =
654
(PasteNode *) halloc(sizeof(PasteNode), "PasteNode");
655
656
pastenode->group = NULL;
657
pastenode->item_stack = NULL;
658
pastenode->arg_node = NULL;
659
pastenode->end_node = NULL;
660
pastenode->name = alloc_string(name);
661
pastenode->haspaste = pastenode->hasbutton = 0;
662
return pastenode;
663
}
664
665
PatchStore *
666
alloc_patchstore()
667
{
668
PatchStore *p = (PatchStore *) halloc(sizeof(PatchStore), "PatchStore");
669
670
p->loaded = 0;
671
p->string = NULL;
672
return p;
673
}
674
675
void
676
free_patch(PatchStore *p)
677
{
678
if (p) {
679
if (p->name)
680
free(p->name);
681
if (p->fpos.name)
682
free(p->fpos.name);
683
if (p->string)
684
free(p->string);
685
free(p);
686
}
687
}
688
689
InputBox *
690
alloc_inputbox()
691
{
692
InputBox *box = (InputBox *) halloc(sizeof(InputBox), "InputBox");
693
694
box->picked = 0;
695
box->next = NULL;
696
box->rbs = NULL;
697
return box;
698
}
699
700
RadioBoxes *
701
alloc_rbs()
702
{
703
RadioBoxes *newrb = (RadioBoxes *) halloc(sizeof(RadioBoxes), "Radio Boxes");
704
705
newrb->next = NULL;
706
newrb->boxes = NULL;
707
return newrb;
708
}
709
710
ButtonList *
711
alloc_button_list()
712
{
713
ButtonList *newbl = (ButtonList *) halloc(sizeof(ButtonList), "Button List");
714
715
newbl->link = NULL;
716
newbl->x0 = newbl->y0 = newbl->x1 = newbl->y1 = 0;
717
newbl->next = NULL;
718
return newbl;
719
}
720
721
void
722
free_button_list(ButtonList *bl)
723
{
724
while (bl) {
725
ButtonList *nbl = bl->next;
726
free(bl);
727
bl = nbl;
728
}
729
}
730
731
732
/* resizable static buffers */
733
734
#define BufferSlop 0
735
736
char *
737
resizeBuffer(int size, char *oldBuf, int *oldSize)
738
{
739
char *newBuf;
740
int newSize;
741
742
if (size <= *oldSize)
743
return oldBuf;
744
745
newSize = size + BufferSlop;
746
newBuf = (char *) halloc(newSize,"Buffer");
747
memset(newBuf,'\0',newSize);
748
if (oldBuf) {
749
memcpy(newBuf, oldBuf, *oldSize);
750
free(oldBuf);
751
}
752
*oldSize = newSize;
753
754
return newBuf;
755
}
756
757