4b09b69b35b4869cd66ba77f6ad9fe6aaaac682e
[idzebra-moved-to-github.git] / recctrl / inline.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <ctype.h>
4 #include <yaz/yaz-util.h>
5 #include "inline.h"
6
7 static void inline_destroy_subfield_recursive(inline_subfield *p);
8
9 static inline_field *inline_mk_field(void)
10 {
11     inline_field *p = (inline_field *) xmalloc(sizeof(*p));
12
13     if (p)
14     {
15         memset(p, 0, sizeof(*p));
16         p->name = (char *) xmalloc(SZ_FNAME+1);
17         *(p->name) = '\0';
18         p->ind1 = (char *) xmalloc(SZ_IND+1);
19         *(p->ind1) = '\0';
20         p->ind2 = (char *) xmalloc(SZ_IND+1);
21         *(p->ind2) = '\0';
22     }
23     return p;
24 }
25 void inline_destroy_field(inline_field *p)
26 {
27     if (p)
28     {
29         if (p->name) xfree(p->name);
30         if (p->ind1) xfree(p->ind1);
31         if (p->ind2) xfree(p->ind2);
32         if (p->list)
33             inline_destroy_subfield_recursive(p->list);
34         xfree(p);
35     }
36 }
37 static inline_subfield *inline_mk_subfield(inline_subfield *parent)
38 {
39     inline_subfield *p = (inline_subfield *)xmalloc(sizeof(*p));
40     
41     if (p)
42     {
43         memset(p, 0, sizeof(*p));
44         p->name = (char *) xmalloc(SZ_SFNAME+1);
45         *(p->name) = '\0';
46         p->parent = parent;
47     }
48     return p;
49 }
50
51 #if 0
52 static void inline_destroy_subfield(inline_subfield *p)
53 {
54     if (p)
55     {
56         if (p->name) xfree(p->name);
57         if (p->data) xfree(p->data);
58         if (p->parent) p->parent->next = p->next;
59         xfree(p);
60     }
61 }
62 #endif
63
64 static void inline_destroy_subfield_recursive(inline_subfield *p)
65 {
66     if (p)
67     {
68         inline_destroy_subfield_recursive(p->next);
69         if (p->name) xfree(p->name);
70         if (p->data) xfree(p->data);
71         if (p->parent)
72             p->parent->next = 0;
73         xfree(p);
74     }
75 }
76 inline_field *inline_parse(const char *s)
77 {
78     inline_field *pf = inline_mk_field();
79     char *p = (char *)s;
80     
81     if (!pf)
82         return 0;
83
84     if ((sscanf(p, "%3s", pf->name)) != 1)
85         return 0;
86
87     p += SZ_FNAME;
88
89     if (!memcmp(pf->name, "00", 2))
90     {
91         pf->list = inline_mk_subfield(0);
92         pf->list->data = xstrdup(p);
93     }
94     else
95     {
96         if ((sscanf(p, "%c%c", pf->ind1, pf->ind2)) == 2)
97         {
98             char *pdup;
99             inline_subfield *parent = 0;
100             
101             p += 2*SZ_IND;
102     
103             if (!strlen(p) || *p != '$')
104             {
105                 return pf;
106             }
107             
108             pdup = p = xstrdup(p);
109             
110             for (p=strtok(p, "$"); p; p = strtok(NULL, "$"))
111             {
112                 inline_subfield *psf = inline_mk_subfield(parent);
113                 
114                 if (!psf)
115                     break;
116                     
117                 if (!parent)
118                     pf->list = psf;
119                 else
120                     parent->next = psf;
121                 parent = psf;   
122                 sscanf(p, "%1s", psf->name);
123                 p += SZ_SFNAME;
124                 psf->data = (char *) xstrdup(p);
125             }
126             
127             xfree(pdup);
128         }
129     }
130     return pf;
131 }