Finally working version.
[erwise] / erwise / Misc.c
1 static char *rcsid = "$Id: Misc.c,v 1.1 1992/05/18 21:43:03 tvr Exp $";
2
3 #include "Includes.h"
4
5
6 void displaypage(char *topaddress, HText_t * parenthtext, HText_t * htext,
7                   char *address);
8 int addresscmp(char *addr1, char *addr2);
9
10
11 Connection_t *Connections = (Connection_t *) NULL;
12 Page_t *Pages = (Page_t *) NULL;
13
14
15 Page_t *FindPage(hierarchy, address)
16 Page_t *hierarchy;
17 char *address;
18 {
19     while (address && hierarchy)
20         if (!addresscmp(hierarchy->Address, address))
21             return hierarchy;
22         else
23             hierarchy = hierarchy->Next;
24
25     return (Page_t *) NULL;
26 }
27
28
29 Page_t *
30  GlobalFindPage(address)
31 char *address;
32 {
33     Page_t *hierarchy = Pages, *tmppage;
34
35     while (address && hierarchy)
36         if (tmppage = FindPage(hierarchy->Children, address))
37             return tmppage;
38         else
39             hierarchy = hierarchy->Next;
40
41     return (Page_t *) NULL;
42 }
43
44
45 Page_t *
46  AddPage(page, address, htext, toppage)
47 Page_t **page;
48 char *address;
49 HText_t *htext;
50 Page_t *toppage;
51 {
52     if (*page) {
53         while ((*page)->Next)
54             page = &(*page)->Next;
55         (*page)->Next = (Page_t *) Malloc(sizeof(**page));
56         page = &(*page)->Next;
57     } else
58         *page = (Page_t *) Malloc(sizeof(**page));
59
60     (*page)->Address = strdup(address);
61     (*page)->HText = htext;
62     (*page)->ParentPage = toppage;
63     (*page)->Parents = (Page_t *) NULL;
64     (*page)->Children = (Page_t *) NULL;
65     (*page)->Next = (Page_t *) NULL;
66
67     return *page;
68 }
69
70
71 void DeletePage(page, address)
72 Page_t **page;
73 char *address;
74 {
75     Page_t *oldpage = *page;
76
77     if (!strcmp((*page)->Address, address)) {
78         *page = (*page)->Next;
79         Free(oldpage);
80     } else
81         while (*page)
82             if (!strcmp((*page)->Address, address)) {
83                 *page = (*page)->Next;
84                 Free(oldpage);
85             } else {
86                 page = &(*page)->Next;
87                 oldpage = *page;
88             }
89 }
90
91
92 void DisplayWarning(text)
93 char *text;
94 {
95     fprintf(stderr, "Warning: %s\n", text);
96 }
97
98
99 void DisplayFatal(text)
100 char *text;
101 {
102     fprintf(stderr, "Fatal: %s\n", text);
103
104     abort();
105 }
106
107
108 int CanBeCursor(htextobject)
109 HTextObject_t *htextobject;
110 {
111     int i;
112
113     if (htextobject->paragraph)
114         return FALSE;
115
116     for (i = 0; i < htextobject->length; i++)
117         if (htextobject->data[i] != ' ')
118             return TRUE;
119
120     return FALSE;
121 }
122
123
124 void *
125  Malloc(size)
126 int size;
127 {
128     void *tmpptr;
129
130     if (!(tmpptr = (void *) malloc(size))) {
131         DisplayFatal("No swap, buy a computer");
132         exit(1);
133     }                           /* Not reached */
134     return tmpptr;
135 }
136
137
138 void *
139  ReAlloc(ptr, size)
140 void *ptr;
141 int size;
142 {
143     void *tmpptr;
144
145     if (!ptr)
146         return Malloc(size);
147     else if (!(tmpptr = (void *) realloc((char *) ptr, size))) {
148         DisplayFatal("No swap, buy a computer");
149         exit(1);
150     }                           /* Not reached */
151     return tmpptr;
152 }
153
154
155 void Free(ptr)
156 void *ptr;
157 {
158     if (ptr)
159         free(ptr);
160 }
161
162
163 void StartLoading(address, topaddress, parentaddress)
164 char *address;
165 char *topaddress;
166 char *parentaddress;
167 {
168     Page_t *oldpage, *tmppage, *toppage, *parentpage;
169     HText_t *newhtext;
170     ClConnection_t *clconnection;
171     Connection_t *connection;
172
173     toppage = FindPage(Pages, topaddress);
174     parentpage = (toppage && parentaddress) ?
175         FindPage(toppage->Children, parentaddress) : (Page_t *) NULL;
176
177     if (toppage && (oldpage = GlobalFindPage(address))) {
178         if (tmppage = FindPage(toppage->Children, address)) {
179             if (tmppage->HText) {
180                 /* add the parent */
181                 if (parentaddress && strcmp(parentaddress, address) &&
182                     !FindPage(tmppage->Parents, parentaddress))
183                     AddPage(&tmppage->Parents, parentaddress, tmppage->HText,
184                             parentpage);
185                 /* display the page */
186                 displaypage(toppage ? toppage->Address : (char *) NULL,
187                        parentpage ? parentpage->HText : (HText_t *) NULL,
188                             tmppage->HText, address);
189
190                 return;
191             }
192         } else {
193             if (oldpage->HText) {
194 #if 0
195                 /* copy the htext */
196                 newhtext = HtDuplicate(oldpage->HText);
197                 /* add the page */
198                 tmppage = AddPage(&toppage->Children, address, newhtext,
199                                   toppage);
200                 /* add the parent */
201                 if (parentaddress && strcmp(parentaddress, address) &&
202                     !FindPage(tmppage->Parents, parentaddress))
203                     AddPage(&tmppage->Parents, parentaddress, tmppage->HText,
204                             parentpage);
205                 /* display the page */
206                 displaypage(toppage ? toppage->Address : (char *) NULL,
207                        parentpage ? parentpage->HText : (HText_t *) NULL,
208                             newhtext, address);
209
210                 return;
211 #endif
212                 HTAnchor_setDocument((void *) oldpage->HText->node_anchor,
213                                      (void *) NULL);
214
215             }
216         }
217     }
218     if (FindConnection(address))
219         return;
220
221     if (!(clconnection = ClOpenConnection(address))) {
222         DisplayWarning("Error in ClOpenConnection");
223         return;
224     }
225     connection = AddConnection(address, toppage, parentpage, clconnection);
226
227     PollConnection(connection);
228 }
229
230
231 void PollConnection(connection)
232 Connection_t *connection;
233 {
234     HText_t *htext;
235     int status;
236     int oldfd = connection->FD;
237     char *topaddress, *parentaddress;
238     Page_t *tmppage, *toppage, *parentpage;
239
240     htext = ClReadData(connection->ClConnection, &status, &connection->FD);
241
242     switch (status) {
243     case CL_CONTINUES:
244         if (connection->FD && connection->Status == POLLING) {
245             connection->InputId =
246                 UiAddInputFD(connection->FD,
247                              (void (*) (void *)) &PollConnection,
248                              (void *) connection);
249             connection->Status = SELECTING;
250         } else if (!connection->FD) {
251             if (oldfd)
252                 UiDeleteInputFD(connection->InputId);
253             connection->TimeOutId =
254                 UiAddTimeOut(200, (void (*) (void *)) &PollConnection,
255                              (void *) connection);
256             connection->Status = POLLING;
257         }
258         break;
259     case CL_COMPLETED:
260         if (connection->Status == SELECTING)
261             UiDeleteInputFD(connection->InputId);
262         if (htext && !connection->TopPage->HText)
263             connection->TopPage->HText = htext;
264
265         if (htext) {
266             parentaddress = connection->ParentPage ?
267                 connection->ParentPage->Address : (char *) NULL;
268             toppage = connection->TopPage;
269
270             parentpage = connection->ParentPage;
271             if (!(tmppage = FindPage(toppage->Children, connection->Address))) {
272                 tmppage = AddPage(&toppage->Children, connection->Address,
273                                   htext, toppage);
274                 /* add the parent (what the fuck have I been thinkin' here?) */
275                 if (connection->ParentPage && parentaddress &&
276                     !FindPage(tmppage->Parents, parentaddress))
277                     AddPage(&tmppage->Parents, parentaddress,
278                             tmppage->HText, parentpage);
279             } else
280                 tmppage->HText = htext;
281
282             displaypage(connection->TopPage ?
283                         connection->TopPage->Address : (char *) NULL,
284                         connection->ParentPage ?
285                         connection->ParentPage->HText : (HText_t *) NULL,
286                         htext, connection->Address);
287         }
288         DeleteConnection(connection->Address);
289         break;
290     case CL_FAILED:
291         if (connection->Status == SELECTING)
292             UiDeleteInputFD(connection->InputId);
293         DeleteConnection(connection->Address);
294         break;
295     default:
296         DisplayWarning("Uh? :O");
297     }
298 }
299
300
301 void displaypage(topaddress, parenthtext, htext, address)
302 char *topaddress;
303 HText_t *parenthtext;
304 HText_t *htext;
305 char *address;
306 {
307     HTextAnchor_t *htanchor = (HTextAnchor_t *) NULL;
308     HTextObject_t *htextobject;
309     char *tag = HTParse(address, "", PARSE_ANCHOR);
310
311     if (tag && tag[0]) {
312         htanchor = htext->anchorlist;
313         while (htanchor)
314             if (htanchor->anchor && htanchor->anchor->tag &&
315                 !strcmp(htanchor->anchor->tag, tag))
316                 break;
317             else
318                 htanchor = htanchor->next;
319         Free(tag);
320     }
321     htextobject = htanchor ? htanchor->object : htext->first;
322
323     while (htextobject && !CanBeCursor(htextobject))
324         htextobject = htextobject->next;
325
326     UiDisplayPage(topaddress, parenthtext, htext, htextobject,
327                   (char *) HTAnchor_title(htext->node_anchor));
328 }
329
330
331 Connection_t *
332  AddConnection(address, toppage, parentpage, clconnection)
333 char *address;
334 Page_t *toppage;
335 Page_t *parentpage;
336 ClConnection_t *clconnection;
337 {
338     Connection_t *tmpconnection = Connections;
339
340     if (tmpconnection) {
341         while (tmpconnection->Next)
342             tmpconnection = tmpconnection->Next;
343         tmpconnection = tmpconnection->Next = Malloc(sizeof(*tmpconnection));
344     } else
345         tmpconnection = Connections = Malloc(sizeof(*tmpconnection));
346
347     tmpconnection->Address = strdup(address);
348     tmpconnection->TopPage = toppage;
349     tmpconnection->ParentPage = parentpage;
350     tmpconnection->ClConnection = clconnection;
351     tmpconnection->FD = 0;
352     tmpconnection->Status = POLLING;
353     tmpconnection->Next = (Connection_t *) NULL;
354
355     if (UiConnectionsDialogDisplayed())
356         ConnectionsCB((char *) NULL, (HText_t *) NULL,
357                       (HTextObject_t *) NULL, (void *) NULL);
358
359     return tmpconnection;
360 }
361
362
363 Connection_t *
364  FindConnection(address)
365 char *address;
366 {
367     Connection_t *tmpconnection = Connections;
368
369     while (tmpconnection)
370         if (!addresscmp(tmpconnection->Address, address))
371             return tmpconnection;
372         else
373             tmpconnection = tmpconnection->Next;
374
375     return (Connection_t *) NULL;
376 }
377
378
379 void DeleteConnection(address)
380 char *address;
381 {
382     Connection_t *tmpconnection = Connections;
383
384     if (tmpconnection)
385         if (!strcmp(tmpconnection->Address, address))
386             Connections = Connections->Next;
387         else {
388             while (tmpconnection->Next &&
389                    strcmp(tmpconnection->Next->Address, address))
390                 tmpconnection = tmpconnection->Next;
391             if (tmpconnection->Next) {
392                 Connection_t *tmptmpconnection;
393
394                 tmptmpconnection = tmpconnection->Next;
395                 tmpconnection->Next = tmpconnection->Next->Next;
396                 tmpconnection = tmptmpconnection;
397             } else
398                 tmpconnection = (Connection_t *) NULL;
399         }
400     if (tmpconnection) {
401         if (UiConnectionsDialogDisplayed())
402             ConnectionsCB((char *) NULL, (HText_t *) NULL,
403                           (HTextObject_t *) NULL, (void *) NULL);
404         Free(tmpconnection->Address);
405         Free(tmpconnection);
406     } else
407         DisplayWarning("DeleteConnection failed");
408 }
409
410
411 int addresscmp(addr1, addr2)
412 char *addr1, *addr2;
413 {
414     int i = 0;
415
416     while (addr1[i] && addr2[i] && addr1[i] != '#' && addr2[i] != '#')
417         if (addr1[i] != addr2[i])
418             return 1;
419         else
420             i++;
421
422     if ((addr1[i] && addr1[i] != '#') || (addr2[i] && addr2[i] != '#'))
423         return 1;
424
425     return 0;
426 }