1 /*
2 Copyright (C) 2013-2021, Dirk Krause
3 SPDX-License-Identifier: BSD-3-Clause
4 */
5 
6 /*
7 	WARNING: This file was generated by the dkct program (see
8 	http://dktools.sourceforge.net/ for details).
9 	Changes you make here will be lost if dkct is run again!
10 	You should modify the original source and run dkct on it.
11 	Original source: hbnode.ctr
12 */
13 
14 /**	@file hbnode.c The hbnode module.
15 */
16 
17 
18 #include <htmlbook/htmlbook.h>
19 #include <libdk3c/dk3all.h>
20 #include <libdk3c/dk3unused.h>
21 
22 
23 
24 
25 
26 
27 
28 void
hbnode_link_delete(hb_link_t * ptr)29 hbnode_link_delete(hb_link_t *ptr)
30 {
31 
32   if(ptr) {
33     ptr->lno = 0UL;
34     dk3_release(ptr->url);
35     dk3_delete(ptr);
36   }
37 }
38 
39 
40 
41 hb_link_t *
hbnode_link_new(dkChar const * url,unsigned long lno,dk3_app_t * app)42 hbnode_link_new(dkChar const *url, unsigned long lno, dk3_app_t *app)
43 {
44   hb_link_t	*back	= NULL;
45 
46   if(url) {
47     back = dk3_new_app(hb_link_t,1,app);
48     if(back) {
49       back->lno		= lno;
50       back->url		= dk3str_dup_app(url,app);
51       back->flags	= 0;
52       if(!(back->url)) {
53         hbnode_link_delete(back);
54 	back = NULL;
55       }
56     }
57   }
58   return back;
59 }
60 
61 
62 
63 int
hbnode_link_compare(const void * l,const void * r,int cr)64 hbnode_link_compare(const void *l, const void *r, int cr)
65 {
66   hb_link_t	*pl;
67   hb_link_t	*pr;
68   int		 back	= 0;
69 
70   if(l) {
71     if(r) {
72       pl = (hb_link_t *)l;
73       switch(cr) {
74         case 0: {
75 	  pr = (hb_link_t *)r;
76 	  back = dk3str_cmp(pl->url, pr->url);
77 	} break;
78 	case 1: {
79 	  back = dk3str_cmp(pl->url, (dkChar const *)r);
80 	} break;
81 	default: {
82 	  pr = (hb_link_t *)r;
83 	  if(pl->lno > pr->lno) {
84 	    back = 1;
85 	  } else {
86 	    if(pl->lno < pr->lno) {
87 	      back = -1;
88 	    }
89 	  }
90 	} break;
91       }
92       if(-1 > back) { back = -1; }
93       if( 1 < back) { back =  1; }
94     } else back = 1;
95   } else {
96     if(r) back = -1;
97   }
98   return back;
99 }
100 
101 
102 
103 int
hb_node_compare(void const * l,void const * r,int DK3_ARG_UNUSED (cr))104 hb_node_compare(void const *l, void const *r, int DK3_ARG_UNUSED(cr) )
105 {
106   hb_node_t const	*pl;
107   hb_node_t const	*pr;
108   int			 back = 0;
109 
110   DK3_UNUSED_ARG(cr)
111   if(l) {
112     if(r) {
113       pl = (hb_node_t const *)l;
114       pr = (hb_node_t const *)r;
115       if(pl->objno > pr->objno) {
116         back = 1;
117       } else {
118         if(pr->objno > pl->objno) {
119 	  back = -1;
120 	}
121       }
122     } else {
123       back = 1;
124     }
125   } else {
126     if(r) {
127       back = -1;
128     }
129   }
130   return back;
131 }
132 
133 
134 
135 void
hb_node_delete(hb_node_t * ptr)136 hb_node_delete(hb_node_t *ptr)
137 {
138   hb_link_t		*linkptr;
139   hb_line_t		*hp;
140   dk3_key_value_t	*kp;
141   if(ptr) {
142 
143     if(ptr->s_lbylno) {
144       if(ptr->i_lbylno) {
145         dk3sto_it_close(ptr->i_lbylno);
146       }
147       dk3sto_close(ptr->s_lbylno);
148     }
149     ptr->s_lbylno = NULL; ptr->i_lbylno = NULL;
150     if(ptr->s_lbyurl) {
151       if(ptr->i_lbyurl) {
152         dk3sto_it_reset(ptr->i_lbyurl);
153 	while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(ptr->i_lbyurl))) {
154 	  hbnode_link_delete(linkptr);
155 	}
156         dk3sto_it_close(ptr->i_lbyurl);
157       }
158       dk3sto_close(ptr->s_lbyurl);
159     }
160     ptr->s_lbyurl = NULL; ptr->i_lbyurl = NULL;
161     if(ptr->s_lines) {
162       if(ptr->i_lines) {
163         dk3sto_it_reset(ptr->i_lines);
164 	while(NULL != (hp = (hb_line_t *)dk3sto_it_next(ptr->i_lines))) {
165 	  hbcont_line_delete(hp);
166 	}
167         dk3sto_it_close(ptr->i_lines);
168       }
169       dk3sto_close(ptr->s_lines);
170     } ptr->s_lines = NULL; ptr->i_lines = NULL;
171     if(ptr->s_variables) {
172       if(ptr->i_variables) {
173         dk3sto_it_reset(ptr->i_variables);
174 	do {
175 	  kp = (dk3_key_value_t *)dk3sto_it_next(ptr->i_variables);
176 	  if(kp) { dk3kv_delete(kp); }
177 	} while(kp);
178         dk3sto_it_close(ptr->i_variables);
179       }
180       dk3sto_close(ptr->s_variables);
181     }
182     ptr->s_variables = NULL; ptr->i_variables = NULL;
183     if(ptr->s_jsfiles) {
184       if(ptr->i_jsfiles) {
185         dk3sto_it_reset(ptr->i_jsfiles);
186 	while(NULL != (linkptr = (hb_link_t *)dk3sto_it_next(ptr->i_jsfiles))) {
187 
188 	  hbnode_link_delete(linkptr);
189 	}
190         dk3sto_it_close(ptr->i_jsfiles);
191       }
192       dk3sto_close(ptr->s_jsfiles);
193     } ptr->s_jsfiles = NULL; ptr->i_jsfiles = NULL;
194     /*	We can simply close the storage here, all nodes are listed
195     	in the s_nodes storage of the job structure.
196     */
197     if(ptr->s_subnodes) {
198       if(ptr->i_subnodes) {
199         dk3sto_it_close(ptr->i_subnodes);
200       }
201       dk3sto_close(ptr->s_subnodes);
202     }
203     ptr->s_subnodes = NULL;
204     ptr->i_subnodes = NULL;
205     ptr->parent = NULL;
206     ptr->curchild = NULL;
207     ptr->jumpnode = NULL;
208 #if TRACE_DEBUG
209 
210 
211 
212 
213     if(ptr->parent) {
214     }
215     if(ptr->title) {
216     }
217     if(ptr->shorttitle) {
218     }
219     if(ptr->fulltitle) {
220     }
221     if(ptr->filename) {
222     }
223     if(ptr->suffix) {
224     }
225     if(ptr->templatefi) {
226     }
227     if(ptr->stylefile) {
228     }
229     if(ptr->author) {
230     }
231     if(ptr->location) {
232     }
233     if(ptr->icontoc) {
234     }
235     if(ptr->iconprev) {
236     }
237     if(ptr->iconnext) {
238     }
239     if(ptr->iconhome) {
240     }
241     if(ptr->iconindex) {
242     }
243     if(ptr->favicon) {
244     }
245     if(ptr->metadesc) {
246     }
247     if(ptr->metakeyw) {
248     }
249 #endif
250     dk3_release(ptr->title);
251     dk3_release(ptr->shorttitle);
252     dk3_release(ptr->fulltitle);
253     dk3_release(ptr->filename);
254     dk3_release(ptr->suffix);
255     dk3_release(ptr->templatefi);
256     dk3_release(ptr->stylefile);
257     dk3_release(ptr->author);
258     dk3_release(ptr->location);
259     dk3_release(ptr->icontoc);
260     dk3_release(ptr->iconprev);
261     dk3_release(ptr->iconnext);
262     dk3_release(ptr->iconindex);
263     dk3_release(ptr->iconhome);
264     dk3_release(ptr->favicon);
265     dk3_release(ptr->metadesc);
266     dk3_release(ptr->metakeyw);
267     ptr->lineno = 0UL;
268     ptr->objno = 0UL;
269     ptr->indent = 0;
270     ptr->inenc = 0;
271     ptr->options = 0U;
272     ptr->havenavimenu = 0;
273     dk3_delete(ptr);
274 
275   }
276 }
277 
278 
279 
280 /**	Find depth of a node.
281 	@param	ptr	Node to inspect.
282 	@return	Node depth.
283 */
284 static
285 int
hbnode_find_depth(hb_node_t * ptr)286 hbnode_find_depth(hb_node_t *ptr)
287 {
288   int		 back = 0;
289 
290   ptr = ptr->parent;
291   while(ptr) {
292     back++;
293     ptr = ptr->parent;
294   }
295   return back;
296 }
297 
298 
299 
300 hb_node_t *
hb_node_new(hb_job_t * job,hb_node_t * parent,unsigned long lineno,unsigned long objno,int indent)301 hb_node_new(
302   hb_job_t		*job,
303   hb_node_t		*parent,
304   unsigned long		 lineno,
305   unsigned long		 objno,
306   int			 indent
307 )
308 {
309   hb_node_t		*back	= NULL;
310   int			 ok	= 0;
311 
312   back = dk3_new_app(hb_node_t,1,job->app);
313   if(back) {
314     back->parent = parent;
315     back->curchild = NULL;
316     back->jumpnode = NULL;
317     back->s_subnodes = NULL;
318     back->i_subnodes = NULL;
319     back->s_variables = NULL;
320     back->i_variables = NULL;
321     back->s_lines = NULL;
322     back->i_lines = NULL;
323     back->s_lbyurl = NULL;
324     back->i_lbyurl = NULL;
325     back->s_lbylno = NULL;
326     back->i_lbylno = NULL;
327     back->s_jsfiles = NULL;
328     back->i_jsfiles = NULL;
329     back->title = NULL;
330     back->shorttitle = NULL;
331     back->fulltitle = NULL;
332     back->filename = NULL;
333     back->suffix = NULL;
334     back->templatefi = NULL;
335     back->stylefile = NULL;
336     back->author = NULL;
337     back->location = NULL;
338     back->icontoc = NULL;
339     back->iconprev = NULL;
340     back->iconnext = NULL;
341     back->iconindex = NULL;
342     back->iconhome = NULL;
343     back->favicon = NULL;
344     back->metadesc = NULL;
345     back->metakeyw = NULL;
346     back->lineno = lineno;
347     back->objno = objno;
348     back->pobjno = 0UL;
349     back->nextlink = 0UL;
350     back->nextindex = 0UL;
351     back->outFileName = NULL;
352     back->headno = 0UL;
353     back->nextsubheadno = 0UL;
354     back->nextjs = 0UL;
355     back->contnum = 0L;
356     back->havenavimenu = 0;
357     back->htdt = HTML_DOCTYPE_UNSPECIFIED;
358     /* back->inenc = -1; */
359     if(parent) {
360       back->inenc = parent->inenc;
361     } else {
362       back->inenc = job->iecmd;
363     }
364     /*	As each node is configured after the parent is finished we can
365     	implement option inheritance by simply copying the parents options.
366     */
367     back->options = 0U; if(parent) { back->options = parent->options; }
368     back->indent = indent;
369     back->depth = 0;
370     back->tocstate = HB_TOC_STATE_INIT;
371     back->s_subnodes = dk3sto_open_app(job->app);
372     if(back->s_subnodes) {
373       dk3sto_set_comp(back->s_subnodes, hb_node_compare, 0);
374       back->i_subnodes = dk3sto_it_open(back->s_subnodes);
375       if(back->i_subnodes) {
376         back->s_variables = dk3sto_open_app(job->app);
377 	if(back->s_variables) {
378 	  dk3sto_set_comp(back->s_variables, dk3kv_compare, 0);
379 	  back->i_variables = dk3sto_it_open(back->s_variables);
380 	  if(back->i_variables) {
381 	    back->s_lbyurl = dk3sto_open_app(job->app);
382 	    if(back->s_lbyurl) {
383 	      dk3sto_set_comp(back->s_lbyurl, hbnode_link_compare, 0);
384 	      back->i_lbyurl = dk3sto_it_open(back->s_lbyurl);
385 	      if(back->i_lbyurl) {
386 	        back->s_lbylno = dk3sto_open_app(job->app);
387 		if(back->s_lbylno) {
388 		  dk3sto_set_comp(back->s_lbylno, hbnode_link_compare, 2);
389 		  back->i_lbylno = dk3sto_it_open(back->s_lbylno);
390 		  if(back->i_lbylno) {
391 		    ok = 1;
392 		  }
393 		}
394 	      }
395 	    }
396 	  }
397 	}
398       }
399     }
400     if(!(ok)) {
401       hb_node_delete(back);
402       back = NULL;
403     }
404     if(back) {
405       back->depth = hbnode_find_depth(back);
406     }
407   }
408   return back;
409 }
410 
411 
412 
413 dkChar const *
hbnode_variable(hb_node_t * node,dkChar const * name)414 hbnode_variable(hb_node_t *node, dkChar const *name)
415 {
416   dk3_key_value_t	*kvp;
417   dkChar const		*back	= NULL;
418   int			 cc	= 1;
419 
420   if((node) && (name)) {
421     while(cc) {
422       if(node) {
423         kvp = (dk3_key_value_t *)dk3sto_it_find_like(node->i_variables,name,1);
424 	if(kvp) {
425 	  cc = 0;
426 	  back = kvp->val;
427 	} else {
428 	  node = node->parent;
429 	}
430       } else {
431         cc = 0;
432       }
433     }
434   }
435   return back;
436 }
437 
438 
439 
440