dbcaa265e90a287f268c502fbbbf37bf7ec01832
[idzebra-moved-to-github.git] / data1 / d1_sutrs.c
1 /* This file is part of the Zebra server.
2    Copyright (C) 1994-2010 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 */
19
20 /* converts data1 tree to SUTRS record */
21
22 #include <idzebra/data1.h>
23
24 #define NTOBUF_INDENT   2
25 #define NTOBUF_MARGIN 75
26
27 static int wordlen(char *b, int i)
28 {
29     int l = 0;
30
31     while (i && !d1_isspace(*b))
32         l++, b++, i--;
33     return l;
34 }
35
36 static int nodetobuf(data1_node *n, int select, WRBUF b, int indent, int col)
37 {
38     data1_node *c;
39     char line[1024];
40
41     for (c = n->child; c; c = c->next)
42     {
43         char *tag;
44
45         if (c->which == DATA1N_tag)
46         {
47             if (select && !c->u.tag.node_selected)
48                 continue;
49             if (c->u.tag.element && c->u.tag.element->tag)
50                 tag = c->u.tag.element->tag->names->name; /* first name */
51             else
52                 tag = c->u.tag.tag; /* local string tag */
53             if (data1_matchstr(tag, "wellknown")) /* skip wellknown */
54             {
55                 if (col)
56                     wrbuf_putc(b, '\n');
57                 sprintf(line, "%*s%s:", indent * NTOBUF_INDENT, "", tag);
58                 wrbuf_write(b, line, strlen(line));
59                 col = strlen(line);
60             }
61             if (nodetobuf(c, select, b, indent+1, col) < 0)
62                 return 0;
63         }
64         else if (c->which == DATA1N_data)
65         {
66             char *p = c->u.data.data;
67             int l = c->u.data.len;
68             int first = 0;
69
70             if ((c->u.data.what == DATA1I_text ||
71                 c->u.data.what == DATA1I_xmltext) && c->u.data.formatted_text)
72             {
73                 wrbuf_putc(b, '\n');
74                 wrbuf_write(b, c->u.data.data, c->u.data.len);
75                 sprintf(line, "%*s", indent * NTOBUF_INDENT, "");
76                 wrbuf_write(b, line, strlen(line));
77                 col = indent * NTOBUF_INDENT;
78             }
79             else if (c->u.data.what == DATA1I_text ||
80                      c->u.data.what == DATA1I_xmltext)
81             {
82                 while (l)
83                 {
84                     int wlen;
85
86                     while (l && d1_isspace(*p))
87                         p++, l--;
88                     if (!l)
89                         break;
90                     /* break if we'll cross margin and word is not too long */
91                     if (col + (wlen = wordlen(p, l)) > NTOBUF_MARGIN && wlen <
92                         NTOBUF_MARGIN - indent * NTOBUF_INDENT)
93                     {
94                         sprintf(line, "\n%*s", indent * NTOBUF_INDENT, "");
95                         wrbuf_write(b, line, strlen(line));
96                         col = indent * NTOBUF_INDENT;
97                         first = 1;
98                     }
99                     if (!first)
100                     {
101                         wrbuf_putc(b, ' ');
102                         col++;
103                     }
104                     while (l && !d1_isspace(*p))
105                     {
106                         if (col > NTOBUF_MARGIN)
107                         {
108                             wrbuf_putc(b, '=');
109                             wrbuf_putc(b, '\n');
110                             sprintf(line, "%*s", indent * NTOBUF_INDENT, "");
111                             wrbuf_write(b, line, strlen(line));
112                             col = indent * NTOBUF_INDENT;
113                         }
114                         wrbuf_putc(b, *p);
115                         p++;
116                         l--;
117                         col++;
118                     }
119                     first = 0;
120                 }
121             }
122             else if (c->u.data.what == DATA1I_num)
123             {
124                 wrbuf_putc(b, ' ');
125                 wrbuf_write(b, c->u.data.data, c->u.data.len);
126             }
127         }
128     }
129     return 0;
130 }
131
132 /*
133  * Return area containing SUTRS-formatted data. Ownership of this data
134  * remains in this module, and the buffer is reused on next call. This may
135  * need changing.
136  */
137
138 char *data1_nodetobuf (data1_handle dh, data1_node *n, int select, int *len)
139 {
140     WRBUF b = data1_get_wrbuf (dh);
141
142     wrbuf_rewind(b);
143     if (nodetobuf(n, select, b, 0, 0))
144         return 0;
145     wrbuf_putc(b, '\n');
146     *len = wrbuf_len(b);
147     return wrbuf_buf(b);
148 }
149 /*
150  * Local variables:
151  * c-basic-offset: 4
152  * c-file-style: "Stroustrup"
153  * indent-tabs-mode: nil
154  * End:
155  * vim: shiftwidth=4 tabstop=8 expandtab
156  */
157