be255a2bfc1b145819dc433f68341d98b30d8058
[yaz-moved-to-github.git] / retrieval / d1_sutrs.c
1 /*
2  * Copyright (c) 1995, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: d1_sutrs.c,v $
7  * Revision 1.2  1995-11-01 13:54:49  quinn
8  * Minor adjustments
9  *
10  * Revision 1.1  1995/11/01  11:56:09  quinn
11  * Added Retrieval (data management) functions en masse.
12  *
13  *
14  */
15
16 #include <ctype.h>
17
18 #include <wrbuf.h>
19
20 #include <data1.h>
21
22 #define NTOBUF_INDENT   2
23 #define NTOBUF_MARGIN 75
24
25 static int wordlen(char *b)
26 {
27     int l = 0;
28
29     while (*b && !isspace(*b))
30         l++, b++;
31     return l;
32 }
33
34 static int nodetobuf(data1_node *n, int select, WRBUF b, int indent, int col)
35 {
36     data1_node *c;
37     char line[1024];
38
39     for (c = n->child; c; c = c->next)
40     {
41         char *tag;
42
43         if (c->which == DATA1N_tag)
44         {
45             if (select && !c->u.tag.node_selected)
46                 continue;
47             if (c->u.tag.element && c->u.tag.element->tag)
48                 tag = c->u.tag.element->tag->names->name; /* first name */
49             else
50                 tag = c->u.tag.tag; /* local string tag */
51             if (data1_matchstr(tag, "wellknown")) /* skip wellknown */
52             {
53                 if (col)
54                     wrbuf_putc(b, '\n');
55                 sprintf(line, "%*s%s:", indent * NTOBUF_INDENT, "", tag);
56                 wrbuf_write(b, line, strlen(line));
57                 col = strlen(line);
58             }
59             if (nodetobuf(c, select, b, indent+1, col) < 0)
60                 return 0;
61         }
62         else if (c->which == DATA1N_data)
63         {
64             char *p = c->u.data.data;
65             int l = c->u.data.len;
66             int first = 0;
67
68             if (c->u.data.what == DATA1I_text)
69             {
70                 while (l)
71                 {
72                     int wlen;
73
74                     while (l && isspace(*p))
75                         p++, l--;
76                     if (!l)
77                         break;
78                     /* break if we'll cross margin and word is not too long */
79                     if (col + (wlen = wordlen(p)) > NTOBUF_MARGIN && wlen <
80                         NTOBUF_MARGIN - indent * NTOBUF_INDENT)
81                     {
82                         sprintf(line, "\n%*s", indent * NTOBUF_INDENT, "");
83                         wrbuf_write(b, line, strlen(line));
84                         col = indent * NTOBUF_INDENT;
85                         first = 1;
86                     }
87                     if (!first)
88                     {
89                         wrbuf_putc(b, ' ');
90                         col++;
91                     }
92                     while (l && !isspace(*p))
93                     {
94                         if (col > NTOBUF_MARGIN)
95                         {
96                             wrbuf_putc(b, '=');
97                             wrbuf_putc(b, '\n');
98                             sprintf(line, "%*s", indent * NTOBUF_INDENT, "");
99                             wrbuf_write(b, line, strlen(line));
100                             col = indent * NTOBUF_INDENT;
101                         }
102                         wrbuf_putc(b, *p);
103                         p++;
104                         l--;
105                         col++;
106                     }
107                     first = 0;
108                 }
109             }
110             else if (c->u.data.what == DATA1I_num)
111             {
112                 wrbuf_putc(b, ' ');
113                 wrbuf_write(b, c->u.data.data, c->u.data.len);
114             }
115         }
116     }
117     return 0;
118 }
119
120 /*
121  * Return area containing SUTRS-formatted data. Ownership of this data
122  * remains in this module, and the buffer is reused on next call. This may
123  * need changing.
124  */
125
126 char *data1_nodetobuf(data1_node *n, int select, int *len)
127 {
128     static WRBUF b = 0;
129
130     if (!b)
131         b = wrbuf_alloc();
132     else
133         wrbuf_rewind(b);
134     if (nodetobuf(n, select, b, 0, 0))
135         return 0;
136     wrbuf_putc(b, '\n');
137     *len = wrbuf_len(b);
138     return wrbuf_buf(b);
139 }