~ubuntu-branches/ubuntu/maverick/newsbeuter/maverick

« back to all changes in this revision

Viewing changes to xmlrss/nxml_write.c

  • Committer: Bazaar Package Importer
  • Author(s): Nico Golde
  • Date: 2009-04-21 14:06:18 UTC
  • mfrom: (4.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20090421140618-osnjk19bgkebyg9h
Tags: 2.0-1
* New upstream release.
  - Remove dependeny on mrss and nxml and add libxml2, newsbeuter
    now comes with its own parser.
  - Remove debian/patches and quilt dependency.
* Bump to policy 3.8.1, no changes needed.
* debian/copyright: adjust years.
* Remove dh_clean -k call as it is deprecated -> dh_prep.
* Change newsbeuter homepage, it now has an official one.
* Fix watch file url, new upstream code location.
* Add bookmark-scuttle.sh to installed contrib files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* nXml - Copyright (C) 2005-2007 bakunin - Andrea Marchesini 
2
 
 *                                    <bakunin@autistici.org>
3
 
 *
4
 
 * This library is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU Lesser General Public
6
 
 * License as published by the Free Software Foundation; either
7
 
 * version 2.1 of the License, or (at your option) any later version.
8
 
 * 
9
 
 * This library is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 * Lesser General Public License for more details.
13
 
 * 
14
 
 * You should have received a copy of the GNU Lesser General Public
15
 
 * License along with this library; if not, write to the Free Software
16
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
 
 */
18
 
 
19
 
#include "_nxml.h"
20
 
 
21
 
static void
22
 
__nxml_write_escape_string (void (*func) (void *, char *, ...), void *obj,
23
 
                            char *str)
24
 
{
25
 
  int i;
26
 
  int len;
27
 
  char buf[1024];
28
 
  int j;
29
 
 
30
 
#define __NXML_CHECK_BUF \
31
 
           if(j==sizeof(buf)-1) { buf[j]=0; func(obj, "%s",buf); j=0; }
32
 
 
33
 
  if (!str)
34
 
    return;
35
 
 
36
 
  len = strlen (str);
37
 
 
38
 
  for (j = i = 0; i < len; i++)
39
 
    {
40
 
      if (str[i] == '\r')
41
 
        continue;
42
 
 
43
 
      else if (str[i] == '<')
44
 
        {
45
 
          buf[j++] = '&';
46
 
          __NXML_CHECK_BUF;
47
 
          buf[j++] = 'l';
48
 
          __NXML_CHECK_BUF;
49
 
          buf[j++] = 't';
50
 
          __NXML_CHECK_BUF;
51
 
          buf[j++] = ';';
52
 
          __NXML_CHECK_BUF;
53
 
        }
54
 
 
55
 
      else if (str[i] == '>')
56
 
        {
57
 
          buf[j++] = '&';
58
 
          __NXML_CHECK_BUF;
59
 
          buf[j++] = 'g';
60
 
          __NXML_CHECK_BUF;
61
 
          buf[j++] = 't';
62
 
          __NXML_CHECK_BUF;
63
 
          buf[j++] = ';';
64
 
          __NXML_CHECK_BUF;
65
 
        }
66
 
 
67
 
      else if (str[i] == '&')
68
 
        {
69
 
          buf[j++] = '&';
70
 
          __NXML_CHECK_BUF;
71
 
          buf[j++] = 'a';
72
 
          __NXML_CHECK_BUF;
73
 
          buf[j++] = 'm';
74
 
          __NXML_CHECK_BUF;
75
 
          buf[j++] = 'p';
76
 
          __NXML_CHECK_BUF;
77
 
          buf[j++] = ';';
78
 
          __NXML_CHECK_BUF;
79
 
        }
80
 
 
81
 
      else if (str[i] == '\'')
82
 
        {
83
 
          buf[j++] = '&';
84
 
          __NXML_CHECK_BUF;
85
 
          buf[j++] = 'a';
86
 
          __NXML_CHECK_BUF;
87
 
          buf[j++] = 'p';
88
 
          __NXML_CHECK_BUF;
89
 
          buf[j++] = 'o';
90
 
          __NXML_CHECK_BUF;
91
 
          buf[j++] = 's';
92
 
          __NXML_CHECK_BUF;
93
 
          buf[j++] = ';';
94
 
          __NXML_CHECK_BUF;
95
 
        }
96
 
 
97
 
      else if (str[i] == '\"')
98
 
        {
99
 
          buf[j++] = '&';
100
 
          __NXML_CHECK_BUF;
101
 
          buf[j++] = 'q';
102
 
          __NXML_CHECK_BUF;
103
 
          buf[j++] = 'u';
104
 
          __NXML_CHECK_BUF;
105
 
          buf[j++] = 'o';
106
 
          __NXML_CHECK_BUF;
107
 
          buf[j++] = 't';
108
 
          __NXML_CHECK_BUF;
109
 
          buf[j++] = ';';
110
 
          __NXML_CHECK_BUF;
111
 
        }
112
 
 
113
 
      else
114
 
        {
115
 
          buf[j++] = str[i];
116
 
          __NXML_CHECK_BUF;
117
 
        }
118
 
    }
119
 
 
120
 
  if (j)
121
 
    {
122
 
      buf[j] = 0;
123
 
      func (obj, "%s", buf);
124
 
      j = 0;
125
 
    }
126
 
}
127
 
 
128
 
static int
129
 
__nxml_write_haslines (char *what)
130
 
{
131
 
  while (what && *what)
132
 
    {
133
 
      if (*what == '\n')
134
 
        return 1;
135
 
      what++;
136
 
    }
137
 
 
138
 
  return 0;
139
 
}
140
 
 
141
 
static void
142
 
__nxml_write_indent (void (*func) (void *, char *, ...), void *obj,
143
 
                     int indent)
144
 
{
145
 
  int i;
146
 
  for (i = 0; i < indent; i++)
147
 
    func (obj, "  ");
148
 
}
149
 
 
150
 
static void
151
 
__nxml_write_newline (void (*func) (void *, char *, ...), void *obj)
152
 
{
153
 
  func (obj, "\n");
154
 
}
155
 
 
156
 
static void
157
 
__nxml_write_data_text (nxml_data_t * data,
158
 
                        void (*func) (void *, char *, ...), void *obj)
159
 
{
160
 
  __nxml_write_escape_string (func, obj, data->value);
161
 
}
162
 
 
163
 
static void
164
 
__nxml_write_data_comment (nxml_data_t * data,
165
 
                           void (*func) (void *, char *, ...), void *obj)
166
 
{
167
 
  func (obj, "<!--%s-->", data->value);
168
 
}
169
 
 
170
 
static void
171
 
__nxml_write_data_pi (nxml_data_t * data, void (*func) (void *, char *, ...),
172
 
                      void *obj)
173
 
{
174
 
  func (obj, "<?%s?>", data->value);
175
 
}
176
 
 
177
 
static void
178
 
__nxml_write_data_doctype (nxml_doctype_t * data,
179
 
                           void (*func) (void *, char *, ...), void *obj)
180
 
{
181
 
  func (obj, "<!DOCTYPE %s %s>", data->name, data->value);
182
 
}
183
 
 
184
 
static void
185
 
__nxml_write_data_element (nxml_data_t * data,
186
 
                           void (*func) (void *, char *, ...), void *obj)
187
 
{
188
 
  nxml_attr_t *attr;
189
 
 
190
 
  func (obj, "<");
191
 
  if (data->ns && data->ns->prefix)
192
 
    func (obj, "%s:", data->ns->prefix);
193
 
  func (obj, "%s", data->value);
194
 
 
195
 
  attr = data->attributes;
196
 
  while (attr)
197
 
    {
198
 
      func (obj, " ");
199
 
 
200
 
      if (attr->ns && attr->ns->prefix)
201
 
        func (obj, "%s:", attr->ns->prefix);
202
 
      func (obj, "%s=\"", attr->name);
203
 
 
204
 
      __nxml_write_escape_string (func, obj, attr->value);
205
 
      func (obj, "\"");
206
 
      attr = attr->next;
207
 
    }
208
 
 
209
 
  if (!data->children)
210
 
    func (obj, " /");
211
 
 
212
 
  func (obj, ">");
213
 
}
214
 
 
215
 
static void
216
 
__nxml_write_data (nxml_t * nxml, nxml_data_t * data,
217
 
                   void (*func) (void *, char *, ...), void *obj, int indent)
218
 
{
219
 
  nxml_data_t *tmp;
220
 
  int i;
221
 
 
222
 
  switch (data->type)
223
 
    {
224
 
    case NXML_TYPE_TEXT:
225
 
      if (data->children || data->next || __nxml_write_haslines (data->value)
226
 
          || (data->parent && data->parent->children != data))
227
 
        {
228
 
          i = 1;
229
 
          __nxml_write_indent (func, obj, indent);
230
 
        }
231
 
      else
232
 
        i = 0;
233
 
 
234
 
      __nxml_write_data_text (data, func, obj);
235
 
 
236
 
      if (i)
237
 
        __nxml_write_newline (func, obj);
238
 
      break;
239
 
 
240
 
    case NXML_TYPE_COMMENT:
241
 
      __nxml_write_indent (func, obj, indent);
242
 
      __nxml_write_data_comment (data, func, obj);
243
 
      __nxml_write_newline (func, obj);
244
 
      break;
245
 
 
246
 
    case NXML_TYPE_PI:
247
 
      __nxml_write_indent (func, obj, indent);
248
 
      __nxml_write_data_pi (data, func, obj);
249
 
      __nxml_write_newline (func, obj);
250
 
      break;
251
 
 
252
 
    default:
253
 
      __nxml_write_indent (func, obj, indent);
254
 
      __nxml_write_data_element (data, func, obj);
255
 
 
256
 
      if (!data->children || data->children->type != NXML_TYPE_TEXT
257
 
          || data->children->next
258
 
          || __nxml_write_haslines (data->children->value))
259
 
        __nxml_write_newline (func, obj);
260
 
 
261
 
      break;
262
 
    }
263
 
 
264
 
  if (data->children)
265
 
    {
266
 
      tmp = data->children;
267
 
 
268
 
      while (tmp)
269
 
        {
270
 
          __nxml_write_data (nxml, tmp, func, obj, indent + 1);
271
 
          tmp = tmp->next;
272
 
        }
273
 
 
274
 
      if (data->type == NXML_TYPE_ELEMENT)
275
 
        {
276
 
          if (!data->children || data->children->type != NXML_TYPE_TEXT
277
 
              || data->children->next || data->children->children
278
 
              || __nxml_write_haslines (data->children->value))
279
 
            __nxml_write_indent (func, obj, indent);
280
 
 
281
 
          func (obj, "</");
282
 
          if (data->ns && data->ns->prefix)
283
 
            func (obj, "%s:", data->ns->prefix);
284
 
          func (obj, "%s>", data->value);
285
 
 
286
 
          __nxml_write_newline (func, obj);
287
 
        }
288
 
    }
289
 
}
290
 
 
291
 
static nxml_error_t
292
 
__nxml_write_real (nxml_t * nxml, void (*func) (void *, char *, ...),
293
 
                   void *obj)
294
 
{
295
 
  nxml_data_t *data;
296
 
  nxml_doctype_t *doctype;
297
 
 
298
 
  func (obj, "<?xml");
299
 
 
300
 
  func (obj, " version=\"");
301
 
 
302
 
  switch (nxml->version)
303
 
    {
304
 
    case NXML_VERSION_1_0:
305
 
      func (obj, "1.0");
306
 
      break;
307
 
    default:
308
 
      func (obj, "1.1");
309
 
    }
310
 
 
311
 
  func (obj, "\"");
312
 
 
313
 
  if (nxml->encoding)
314
 
    func (obj, " encoding=\"%s\"", nxml->encoding);
315
 
 
316
 
  func (obj, " standalone=\"%s\"?>\n\n", nxml->standalone ? "yes" : "no");
317
 
 
318
 
  doctype = nxml->doctype;
319
 
 
320
 
  while (doctype)
321
 
    {
322
 
      __nxml_write_indent (func, obj, 0);
323
 
      __nxml_write_data_doctype (doctype, func, obj);
324
 
      __nxml_write_newline (func, obj);
325
 
 
326
 
      doctype = doctype->next;
327
 
    }
328
 
 
329
 
  data = nxml->data;
330
 
 
331
 
  while (data)
332
 
    {
333
 
      __nxml_write_data (nxml, data, func, obj, 0);
334
 
 
335
 
      data = data->next;
336
 
    }
337
 
 
338
 
  return NXML_OK;
339
 
}
340
 
 
341
 
static void
342
 
__nxml_file_write (void *obj, char *str, ...)
343
 
{
344
 
  va_list va;
345
 
 
346
 
  va_start (va, str);
347
 
  vfprintf ((FILE *) obj, str, va);
348
 
  va_end (va);
349
 
}
350
 
 
351
 
static void
352
 
__nxml_buffer_write (void *obj, char *str, ...)
353
 
{
354
 
  va_list va;
355
 
  char s[4096];
356
 
  int len;
357
 
  char **buffer = (char **) obj;
358
 
 
359
 
  va_start (va, str);
360
 
  len = vsnprintf (s, sizeof (s), str, va);
361
 
  va_end (va);
362
 
 
363
 
  if (!*buffer)
364
 
    {
365
 
      if (!(*buffer = (char *) malloc (sizeof (char) * (len + 1))))
366
 
        return;
367
 
 
368
 
      strcpy (*buffer, s);
369
 
    }
370
 
  else
371
 
    {
372
 
      if (!(*buffer = (char *) realloc (*buffer,
373
 
                                        sizeof (char) * (strlen (*buffer) +
374
 
                                                         len + 1))))
375
 
        return;
376
 
 
377
 
      strcat (*buffer, s);
378
 
    }
379
 
}
380
 
 
381
 
/*************************** EXTERNAL FUNCTION ******************************/
382
 
 
383
 
nxml_error_t
384
 
nxml_write_file (nxml_t * nxml, const char *file)
385
 
{
386
 
  FILE *fl;
387
 
  nxml_error_t ret;
388
 
 
389
 
  if (!nxml || !file)
390
 
    return NXML_ERR_DATA;
391
 
 
392
 
  if (!(fl = fopen (file, "wb")))
393
 
    return NXML_ERR_POSIX;
394
 
 
395
 
  ret = __nxml_write_real (nxml, __nxml_file_write, fl);
396
 
  fclose (fl);
397
 
 
398
 
  return ret;
399
 
}
400
 
 
401
 
nxml_error_t
402
 
nxml_write_buffer (nxml_t * nxml, char **buffer)
403
 
{
404
 
  if (!nxml || !buffer)
405
 
    return NXML_ERR_DATA;
406
 
 
407
 
  return __nxml_write_real (nxml, __nxml_buffer_write, buffer);
408
 
}
409
 
 
410
 
/* EOF */