Renamed logf function to yaz_log. Removed VC++ project files.
[yaz-moved-to-github.git] / retrieval / d1_absyn.c
1 /*
2  * Copyright (c) 1995-1999, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: d1_absyn.c,v $
7  * Revision 1.24  1999-08-27 09:40:32  adam
8  * Renamed logf function to yaz_log. Removed VC++ project files.
9  *
10  * Revision 1.23  1998/10/15 08:29:16  adam
11  * Tag set type may be specified in reference to it using "tagset"
12  * directive in .abs-files and "include" directive in .tag-files.
13  *
14  * Revision 1.22  1998/10/13 16:09:47  adam
15  * Added support for arbitrary OID's for tagsets, schemas and attribute sets.
16  * Added support for multiple attribute set references and tagset references
17  * from an abstract syntax file.
18  * Fixed many bad logs-calls in routines that read the various
19  * specifications regarding data1 (*.abs,*.att,...) and made the messages
20  * consistent whenever possible.
21  * Added extra 'lineno' argument to function readconf_line.
22  *
23  * Revision 1.21  1998/06/09 13:55:07  adam
24  * Minor changes.
25  *
26  * Revision 1.20  1998/05/18 13:07:02  adam
27  * Changed the way attribute sets are handled by the retriaval module.
28  * Extended Explain conversion / schema.
29  * Modified server and client to work with ASN.1 compiled protocol handlers.
30  *
31  * Revision 1.19  1998/03/05 08:15:32  adam
32  * Implemented data1_add_insert_taggeddata utility which is more flexible
33  * than data1_insert_taggeddata.
34  *
35  * Revision 1.18  1998/02/27 14:08:04  adam
36  * Added const to some char pointer arguments.
37  * Reworked data1_read_node so that it doesn't create a tree with
38  * pointers to original "SGML"-buffer.
39  *
40  * Revision 1.17  1998/02/11 11:53:34  adam
41  * Changed code so that it compiles as C++.
42  *
43  * Revision 1.16  1997/12/18 10:51:30  adam
44  * Implemented sub-trees feature for schemas - including forward
45  * references.
46  *
47  * Revision 1.15  1997/12/09 16:18:16  adam
48  * Work on EXPLAIN schema. First implementation of sub-schema facility
49  * in the *.abs files.
50  *
51  * Revision 1.14  1997/10/31 12:20:09  adam
52  * Improved memory debugging for xmalloc/nmem.c. References to NMEM
53  * instead of ODR in n ESPEC-1 handling in source d1_espec.c.
54  * Bug fix: missing fclose in data1_read_espec1.
55  *
56  * Revision 1.13  1997/10/27 13:54:18  adam
57  * Changed structure field in data1 node to be simple string which
58  * is "unknown" to the retrieval system itself.
59  *
60  * Revision 1.12  1997/09/17 12:10:34  adam
61  * YAZ version 1.4.
62  *
63  * Revision 1.11  1997/09/05 09:50:55  adam
64  * Removed global data1_tabpath - uses data1_get_tabpath() instead.
65  *
66  * Revision 1.10  1997/05/14 06:54:01  adam
67  * C++ support.
68  *
69  * Revision 1.9  1997/02/19 14:46:15  adam
70  * The "all" specifier only affects elements that are indexed (and not
71  * all elements).
72  *
73  * Revision 1.8  1997/01/02 10:47:59  quinn
74  * Added optional, physical ANY
75  *
76  * Revision 1.7  1996/06/10 08:56:01  quinn
77  * Work on Summary.
78  *
79  * Revision 1.6  1996/05/31  13:52:21  quinn
80  * Fixed uninitialized variable for local tags in abstract syntax.
81  *
82  * Revision 1.5  1996/05/09  07:27:43  quinn
83  * Multiple local attributes values supported.
84  *
85  * Revision 1.4  1996/05/01  12:45:28  quinn
86  * Support use of local tag names in abs file.
87  *
88  * Revision 1.3  1995/11/01  16:34:55  quinn
89  * Making data1 look for tables in data1_tabpath
90  *
91  * Revision 1.2  1995/11/01  13:54:44  quinn
92  * Minor adjustments
93  *
94  * Revision 1.1  1995/11/01  11:56:06  quinn
95  * Added Retrieval (data management) functions en masse.
96  *
97  */
98
99 #include <ctype.h>
100 #include <stdio.h>
101 #include <assert.h>
102 #include <stdlib.h>
103 #include <string.h>
104
105 #include <oid.h>
106 #include <log.h>
107 #include <data1.h>
108
109 #define D1_MAX_NESTING  128
110
111 struct data1_absyn_cache_info 
112 {
113     char *name;
114     data1_absyn *absyn;
115     data1_absyn_cache next;
116 };
117
118 struct data1_attset_cache_info 
119 {
120     char *name;
121     data1_attset *attset;
122     data1_attset_cache next;
123 };
124
125 data1_absyn *data1_absyn_search (data1_handle dh, const char *name)
126 {
127     data1_absyn_cache p = *data1_absyn_cache_get (dh);
128
129     while (p)
130     {
131         if (!strcmp (name, p->name))
132             return p->absyn;
133         p = p->next;
134     }
135     return NULL;
136 }
137
138 void data1_absyn_trav (data1_handle dh, void *handle,
139                        void (*fh)(data1_handle dh, void *h, data1_absyn *a))
140 {
141     data1_absyn_cache p = *data1_absyn_cache_get (dh);
142
143     while (p)
144     {
145         (*fh)(dh, handle, p->absyn);
146         p = p->next;
147     }
148 }
149
150 data1_absyn *data1_absyn_add (data1_handle dh, const char *name)
151 {
152     char fname[512];
153     NMEM mem = data1_nmem_get (dh);
154
155     data1_absyn_cache p = (data1_absyn_cache)nmem_malloc (mem, sizeof(*p));
156     data1_absyn_cache *pp = data1_absyn_cache_get (dh);
157
158     sprintf(fname, "%s.abs", name);
159     p->absyn = data1_read_absyn (dh, fname);
160     p->name = nmem_strdup (mem, name);
161     p->next = *pp;
162     *pp = p;
163     return p->absyn;
164 }
165
166 data1_absyn *data1_get_absyn (data1_handle dh, const char *name)
167 {
168     data1_absyn *absyn;
169
170     if (!(absyn = data1_absyn_search (dh, name)))
171         absyn = data1_absyn_add (dh, name);
172     return absyn;
173 }
174
175 data1_attset *data1_attset_search_name (data1_handle dh, const char *name)
176 {
177     data1_attset_cache p = *data1_attset_cache_get (dh);
178
179     while (p)
180     {
181         if (!strcmp (name, p->name))
182             return p->attset;
183         p = p->next;
184     }
185     return NULL;
186 }
187
188 data1_attset *data1_attset_search_id (data1_handle dh, int id)
189 {
190     data1_attset_cache p = *data1_attset_cache_get (dh);
191
192     while (p)
193     {
194         if (id == p->attset->reference)
195             return p->attset;
196         p = p->next;
197     }
198     return NULL;
199 }
200
201 data1_attset *data1_attset_add (data1_handle dh, const char *name)
202 {
203     char fname[512], aname[512];
204     NMEM mem = data1_nmem_get (dh);
205     data1_attset *attset;
206
207     strcpy (aname, name);
208     sprintf(fname, "%s.att", name);
209     attset = data1_read_attset (dh, fname);
210     if (!attset)
211     {
212         char *cp;
213         attset = data1_read_attset (dh, name);
214         if (attset && (cp = strrchr (aname, '.')))
215             *cp = '\0';
216     }
217     if (!attset)
218         yaz_log (LOG_WARN|LOG_ERRNO, "Couldn't load attribute set %s", name);
219     else
220     {
221         data1_attset_cache p = (data1_attset_cache)
222             nmem_malloc (mem, sizeof(*p));
223         data1_attset_cache *pp = data1_attset_cache_get (dh);
224         
225         attset->name = p->name = nmem_strdup (mem, aname);
226         p->attset = attset;
227         p->next = *pp;
228         *pp = p;
229     }
230     return attset;
231 }
232
233 data1_attset *data1_get_attset (data1_handle dh, const char *name)
234 {
235     data1_attset *attset;
236
237     if (!(attset = data1_attset_search_name (dh, name)))
238         attset = data1_attset_add (dh, name);
239     return attset;
240 }
241
242 data1_esetname *data1_getesetbyname(data1_handle dh, data1_absyn *a,
243                                     const char *name)
244 {
245     data1_esetname *r;
246
247     for (r = a->esetnames; r; r = r->next)
248         if (!data1_matchstr(r->name, name))
249             return r;
250     return 0;
251 }
252
253 data1_element *data1_getelementbytagname (data1_handle dh, data1_absyn *abs,
254                                           data1_element *parent,
255                                           const char *tagname)
256 {
257     data1_element *r;
258
259     if (!parent)
260         r = abs->main_elements;
261     else
262         r = parent->children;
263     assert (abs->main_elements);
264     for (; r; r = r->next)
265     {
266         data1_name *n;
267
268         for (n = r->tag->names; n; n = n->next)
269             if (!data1_matchstr(tagname, n->name))
270                 return r;
271     }
272     return 0;
273 }
274
275 data1_element *data1_getelementbyname (data1_handle dh, data1_absyn *absyn,
276                                        const char *name)
277 {
278     data1_element *r;
279     assert (absyn->main_elements);
280     for (r = absyn->main_elements; r; r = r->next)
281         if (!data1_matchstr(r->name, name))
282             return r;
283     return 0;
284 }
285
286
287 void fix_element_ref (data1_handle dh, data1_absyn *absyn, data1_element *e)
288 {
289     for (; e; e = e->next)
290     {
291         if (!e->sub_name)
292         {
293             if (e->children)
294                 fix_element_ref (dh, absyn, e->children);
295         }
296         else
297         {
298             data1_sub_elements *sub_e = absyn->sub_elements;
299             while (sub_e && strcmp (e->sub_name, sub_e->name))
300                 sub_e = sub_e->next;
301             if (sub_e)
302                 e->children = sub_e->elements;
303             else
304                 yaz_log (LOG_WARN, "Unresolved reference to sub-elements %s",
305                       e->sub_name);
306         }
307     }
308 }
309
310 data1_absyn *data1_read_absyn (data1_handle dh, const char *file)
311 {
312     data1_sub_elements *cur_elements = NULL;
313     data1_absyn *res = 0;
314     FILE *f;
315     data1_element **ppl[D1_MAX_NESTING];
316     data1_esetname **esetpp;
317     data1_maptab **maptabp;
318     data1_marctab **marcp;
319     data1_termlist *all = 0;
320     data1_attset_child **attset_childp;
321     data1_tagset **tagset_childp;
322     int level = 0;
323     int lineno = 0;
324     int argc;
325     char *argv[50], line[512];
326
327     if (!(f = yaz_path_fopen(data1_get_tabpath (dh), file, "r")))
328     {
329         yaz_log(LOG_WARN|LOG_ERRNO, "Couldn't open %s", file);
330         return 0;
331     }
332     
333     res = (data1_absyn *) nmem_malloc(data1_nmem_get(dh), sizeof(*res));
334     res->name = 0;
335     res->reference = VAL_NONE;
336     res->tagset = 0;
337     tagset_childp = &res->tagset;
338
339     res->attset = data1_empty_attset (dh);
340     attset_childp =  &res->attset->children;
341
342     res->varset = 0;
343     res->esetnames = 0;
344     esetpp = &res->esetnames;
345     res->maptabs = 0;
346     maptabp = &res->maptabs;
347     res->marc = 0;
348     marcp = &res->marc;
349
350     res->sub_elements = NULL;
351     res->main_elements = NULL;
352
353     while ((argc = readconf_line(f, &lineno, line, 512, argv, 50)))
354     {
355         char *cmd = *argv;
356         if (!strcmp(cmd, "elm"))
357         {
358             data1_element *new_element;
359             int i;
360             char *p, *sub_p, *path, *name, *termlists;
361             int type, value;
362             data1_termlist **tp;
363
364             if (argc < 4)
365             {
366                 yaz_log(LOG_WARN, "%s:%d: Bad # of args to elm", file, lineno);
367                 continue;
368             }
369             path = argv[1];
370             name = argv[2];
371             termlists = argv[3];
372
373             if (!cur_elements)
374             {
375                 cur_elements = (data1_sub_elements *)
376                     nmem_malloc(data1_nmem_get(dh), sizeof(*cur_elements));
377                 cur_elements->next = res->sub_elements;
378                 cur_elements->elements = NULL;
379                 cur_elements->name = "main";
380                 res->sub_elements = cur_elements;
381                 
382                 level = 0;
383                 ppl[level] = &cur_elements->elements;
384             }
385             p = path;
386             for (i = 0;; i++)
387             {
388                 char *e;
389
390                 if ((e = strchr(p, '/')))
391                     p = e+1;
392                 else
393                     break;
394             }
395             if (i > level + 1)
396             {
397                 yaz_log(LOG_WARN, "%s:%d: Bad level increase", file, lineno);
398                 fclose(f);
399                 return 0;
400             }
401             level = i;
402             new_element = *ppl[level] = (data1_element *)
403                 nmem_malloc(data1_nmem_get(dh), sizeof(*new_element));
404             new_element->next = new_element->children = 0;
405             new_element->tag = 0;
406             new_element->termlists = 0;
407             new_element->sub_name = 0;
408             
409             tp = &new_element->termlists;
410             ppl[level] = &new_element->next;
411             ppl[level+1] = &new_element->children;
412             
413             /* consider subtree (if any) ... */
414             if ((sub_p = strchr (p, ':')) && sub_p[1])
415             {
416                 *sub_p++ = '\0';
417                 new_element->sub_name =
418                     nmem_strdup (data1_nmem_get(dh), sub_p);            
419             }
420             /* well-defined tag */
421             if (sscanf(p, "(%d,%d)", &type, &value) == 2)
422             {
423                 if (!res->tagset)
424                 {
425                     yaz_log(LOG_WARN, "%s:%d: No tagset loaded", file, lineno);
426                     fclose(f);
427                     return 0;
428                 }
429                 if (!(new_element->tag = data1_gettagbynum (dh, res->tagset,
430                                                             type, value)))
431                 {
432                     yaz_log(LOG_WARN, "%s:%d: Couldn't find tag %s in tagset",
433                          file, lineno, p);
434                     fclose(f);
435                     return 0;
436                 }
437             }
438             /* private tag */
439             else if (*p)
440             {
441                 data1_tag *nt =
442                     new_element->tag = (data1_tag *)
443                     nmem_malloc(data1_nmem_get (dh),
444                                 sizeof(*new_element->tag));
445                 nt->which = DATA1T_string;
446                 nt->value.string = nmem_strdup(data1_nmem_get (dh), p);
447                 nt->names = (data1_name *)
448                     nmem_malloc(data1_nmem_get(dh), 
449                                 sizeof(*new_element->tag->names));
450                 nt->names->name = nt->value.string;
451                 nt->names->next = 0;
452                 nt->kind = DATA1K_string;
453                 nt->next = 0;
454                 nt->tagset = 0;
455             }
456             else
457             {
458                 yaz_log(LOG_WARN, "%s:%d: Bad element", file, lineno);
459                 fclose(f);
460                 return 0;
461             }
462             /* parse termList definitions */
463             p = termlists;
464             if (*p == '-')
465                 new_element->termlists = 0;
466             else
467             {
468                 assert (res->attset);
469                 do
470                 {
471                     char attname[512], structure[512];
472                     int r;
473                     
474                     if (!(r = sscanf(p, "%511[^:,]:%511[^,]", attname,
475                                      structure)))
476                     {
477                         yaz_log(LOG_WARN,
478                              "%s:%d: Syntax error in termlistspec '%s'",
479                              file, lineno, p);
480                         fclose(f);
481                         return 0;
482                     }
483                     if (*attname == '!')
484                         strcpy(attname, name);
485                     *tp = (data1_termlist *)
486                         nmem_malloc(data1_nmem_get(dh), sizeof(**tp));
487                     (*tp)->next = 0;
488                     if (!((*tp)->att = data1_getattbyname(dh, res->attset,
489                                                           attname)))
490                     {
491                         yaz_log(LOG_WARN,
492                              "%s:%d: Couldn't find att '%s' in attset",
493                              file, lineno, attname);
494                         fclose(f);
495                         return 0;
496                     }
497                     if (r < 2) /* is the structure qualified? */
498                         (*tp)->structure = "w";
499                     else 
500                     {
501                         (*tp)->structure = (char *)
502                             nmem_malloc (data1_nmem_get (dh),
503                                          strlen(structure)+1);
504                         strcpy ((*tp)->structure, structure);
505                     }
506                     tp = &(*tp)->next;
507                 }
508                 while ((p = strchr(p, ',')) && *(++p));
509                 *tp = all; /* append any ALL entries to the list */
510             }
511             new_element->name = nmem_strdup(data1_nmem_get (dh), name);
512         }
513         else if (!strcmp(cmd, "section"))
514         {
515             char *name;
516             
517             if (argc < 2)
518             {
519                 yaz_log(LOG_WARN, "%s:%d: Bad # of args to section",
520                      file, lineno);
521                 continue;
522             }
523             name = argv[1];
524             
525             cur_elements = (data1_sub_elements *)
526                 nmem_malloc(data1_nmem_get(dh), sizeof(*cur_elements));
527             cur_elements->next = res->sub_elements;
528             cur_elements->elements = NULL;
529             cur_elements->name = nmem_strdup (data1_nmem_get(dh), name);
530             res->sub_elements = cur_elements;
531             
532             level = 0;
533             ppl[level] = &cur_elements->elements;
534         }
535         else if (!strcmp(cmd, "all"))
536         {
537             char *p;
538             data1_termlist **tp = &all;
539             
540             if (all)
541             {
542                 yaz_log(LOG_WARN, "%s:%d: Too many 'all' directives - ignored",
543                      file, lineno);
544                 continue;
545             }
546
547             if (argc != 2)
548             {
549                 yaz_log(LOG_WARN, "%s:%d: Bad # of args to 'all' directive",
550                      file, lineno);
551                 continue;
552             }
553             p = argv[1];
554             assert (res->attset);
555             do
556             {
557                 char attname[512], structure[512];
558                 int r;
559                 
560                 if (!(r = sscanf(p, "%511[^:,]:%511[^,]", attname,
561                                  structure)))
562                 {
563                     yaz_log(LOG_WARN, "%s:%d: Syntax error in termlistspec",
564                          file, lineno);
565                     fclose(f);
566                     return 0;
567                 }
568                 *tp = (data1_termlist *)
569                     nmem_malloc(data1_nmem_get(dh), sizeof(**tp));
570                 if (!((*tp)->att =
571                       data1_getattbyname (dh, res->attset, attname)))
572                 {
573                     yaz_log(LOG_WARN, "%s:%d: Couldn't find att '%s' in attset",
574                          file, lineno, attname);
575                     fclose(f);
576                     return 0;
577                 }
578                 if (r < 2) /* is the structure qualified? */
579                     (*tp)->structure = "w";
580                 else 
581                 {
582                     (*tp)->structure =
583                         (char *)nmem_malloc (data1_nmem_get (dh),
584                                              strlen(structure)+1);
585                     strcpy ((*tp)->structure, structure);
586                 }
587                 (*tp)->next = 0;
588                 tp = &(*tp)->next;
589             }
590             while ((p = strchr(p, ',')) && *(++p));
591         }
592         else if (!strcmp(cmd, "name"))
593         {
594             if (argc != 2)
595             {
596                 yaz_log(LOG_WARN, "%s:%d: Bad # of args to name directive",
597                      file, lineno);
598                 continue;
599             }
600             res->name = nmem_strdup(data1_nmem_get(dh), argv[1]);
601         }
602         else if (!strcmp(cmd, "reference"))
603         {
604             char *name;
605             
606             if (argc != 2)
607             {
608                 yaz_log(LOG_WARN, "%s:%d: Bad # of args to reference",
609                      file, lineno);
610                 continue;
611             }
612             name = argv[1];
613             if ((res->reference = oid_getvalbyname(name)) == VAL_NONE)
614             {
615                 yaz_log(LOG_WARN, "%s:%d: Unknown tagset ref '%s'", 
616                      file, lineno, name);
617                 continue;
618             }
619         }
620         else if (!strcmp(cmd, "attset"))
621         {
622             char *name;
623             data1_attset *attset;
624             
625             if (argc != 2)
626             {
627                 yaz_log(LOG_WARN, "%s:%d: Bad # of args to attset",
628                      file, lineno);
629                 continue;
630             }
631             name = argv[1];
632             if (!(attset = data1_get_attset (dh, name)))
633             {
634                 yaz_log(LOG_WARN, "%s:%d: Couldn't find attset  %s",
635                      file, lineno, name);
636                 continue;
637             }
638             *attset_childp = (data1_attset_child *)
639                 nmem_malloc (data1_nmem_get(dh), sizeof(**attset_childp));
640             (*attset_childp)->child = attset;
641             (*attset_childp)->next = 0;
642             attset_childp = &(*attset_childp)->next;
643         }
644         else if (!strcmp(cmd, "tagset"))
645         {
646             char *name;
647             int type = 0;
648             if (argc < 2)
649             {
650                 yaz_log(LOG_WARN, "%s:%d: Bad # of args to tagset",
651                      file, lineno);
652                 continue;
653             }
654             name = argv[1];
655             if (argc == 3)
656                 type = atoi(argv[2]);
657             *tagset_childp = data1_read_tagset (dh, name, type);
658             if (!(*tagset_childp))
659             {
660                 yaz_log(LOG_WARN, "%s:%d: Couldn't load tagset %s",
661                      file, lineno, name);
662                 continue;
663             }
664             tagset_childp = &(*tagset_childp)->next;
665         }
666         else if (!strcmp(cmd, "varset"))
667         {
668             char *name;
669
670             if (argc != 2)
671             {
672                 yaz_log(LOG_WARN, "%s:%d: Bad # of args in varset",
673                      file, lineno);
674                 continue;
675             }
676             name = argv[1];
677             if (!(res->varset = data1_read_varset (dh, name)))
678             {
679                 yaz_log(LOG_WARN, "%s:%d: Couldn't load Varset %s",
680                      file, lineno, name);
681                 continue;
682             }
683         }
684         else if (!strcmp(cmd, "esetname"))
685         {
686             char *name, *fname;
687
688             if (argc != 3)
689             {
690                 yaz_log(LOG_WARN, "%s:%d: Bad # of args in esetname",
691                      file, lineno);
692                 continue;
693             }
694             name = argv[1];
695             fname = argv[2];
696             
697             *esetpp = (data1_esetname *)
698                 nmem_malloc(data1_nmem_get(dh), sizeof(**esetpp));
699             (*esetpp)->name = nmem_strdup(data1_nmem_get(dh), name);
700             (*esetpp)->next = 0;
701             if (*fname == '@')
702                 (*esetpp)->spec = 0;
703             else if (!((*esetpp)->spec = data1_read_espec1 (dh, fname)))
704             {
705                 yaz_log(LOG_WARN, "%s:%d: Espec-1 read failed for %s",
706                      file, lineno, fname);
707                 continue;
708             }
709             esetpp = &(*esetpp)->next;
710         }
711         else if (!strcmp(cmd, "maptab"))
712         {
713             char *name;
714             
715             if (argc != 2)
716             {
717                 yaz_log(LOG_WARN, "%s:%d: Bad # of args for maptab",
718                      file, lineno);
719                 continue;
720             }
721             name = argv[1];
722             if (!(*maptabp = data1_read_maptab (dh, name)))
723             {
724                 yaz_log(LOG_WARN, "%s:%d: Couldn't load maptab %s",
725                      file, lineno, name);
726                 continue;
727             }
728             maptabp = &(*maptabp)->next;
729         }
730         else if (!strcmp(cmd, "marc"))
731         {
732             char *name;
733             
734             if (argc != 2)
735             {
736                 yaz_log(LOG_WARN, "%s:%d: Bad # or args for marc",
737                      file, lineno);
738                 continue;
739             }
740             name = argv[1];
741             if (!(*marcp = data1_read_marctab (dh, name)))
742             {
743                 yaz_log(LOG_WARN, "%s:%d: Couldn't read marctab %s",
744                      file, lineno, name);
745                 continue;
746             }
747             marcp = &(*marcp)->next;
748         }
749         else
750         {
751             yaz_log(LOG_WARN, "%s:%d: Unknown directive '%s'", file, lineno, cmd);
752             continue;
753         }
754     }
755     fclose(f);
756     
757     for (cur_elements = res->sub_elements; cur_elements;
758          cur_elements = cur_elements->next)
759     {
760         if (!strcmp (cur_elements->name, "main"))
761             res->main_elements = cur_elements->elements;
762         fix_element_ref (dh, res, cur_elements->elements);
763     }
764     yaz_log (LOG_DEBUG, "%s: data1_read_absyn end", file);
765     return res;
766 }