08d5ee652901e1014022a67953fa7a5e16db1f75
[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 static void inline_destroy_subfield(inline_subfield *p)
51 {
52     if (p)
53     {
54         if (p->name) xfree(p->name);
55         if (p->data) xfree(p->data);
56         if (p->parent) p->parent->next = p->next;
57         xfree(p);
58     }
59 }
60 static void inline_destroy_subfield_recursive(inline_subfield *p)
61 {
62     if (p)
63     {
64         inline_destroy_subfield_recursive(p->next);
65         if (p->name) xfree(p->name);
66         if (p->data) xfree(p->data);
67         if (p->parent)
68             p->parent->next = 0;
69         xfree(p);
70     }
71 }
72 inline_field *inline_parse(const char *s)
73 {
74     inline_field *pf = inline_mk_field();
75     char *p = (char *)s;
76     
77     if (!pf)
78         return 0;
79
80     if ((sscanf(p, "%3s", pf->name)) != 1)
81         return 0;
82
83     p += SZ_FNAME;
84
85     if (!memcmp(pf->name, "00", 2))
86     {
87         pf->list = inline_mk_subfield(0);
88         pf->list->data = xstrdup(p);
89     }
90     else
91     {
92         if ((sscanf(p, "%c%c", pf->ind1, pf->ind2)) == 2)
93         {
94             char *pdup;
95             inline_subfield *parent = 0;
96             
97             p += 2*SZ_IND;
98     
99             if (!strlen(p) || *p != '$')
100             {
101                 return pf;
102             }
103             
104             pdup = p = xstrdup(p);
105             
106             for (p=strtok(p, "$"); p; p = strtok(NULL, "$"))
107             {
108                 inline_subfield *psf = inline_mk_subfield(parent);
109                 
110                 if (!psf)
111                     break;
112                     
113                 if (!parent)
114                     pf->list = psf;
115                 else
116                     parent->next = psf;
117                 parent = psf;   
118                 sscanf(p, "%1s", psf->name);
119                 p += SZ_SFNAME;
120                 psf->data = (char *) xstrdup(p);
121             }
122             
123             xfree(pdup);
124         }
125     }
126     return pf;
127 }