~ubuntu-branches/ubuntu/utopic/gettext/utopic

« back to all changes in this revision

Viewing changes to gettext-tools/gnulib-lib/html-ostream.c

  • Committer: Colin Watson
  • Date: 2010-08-01 21:36:08 UTC
  • mfrom: (2.1.10 sid)
  • Revision ID: cjwatson@canonical.com-20100801213608-yy7vkm8lpatep3ci
merge from Debian 0.18.1.1-1

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
#line 1 "html-ostream.oo.c"
4
4
/* Output stream that produces HTML output.
5
 
   Copyright (C) 2006-2007 Free Software Foundation, Inc.
 
5
   Copyright (C) 2006-2009 Free Software Foundation, Inc.
6
6
   Written by Bruno Haible <bruno@clisp.org>, 2006.
7
7
 
8
8
   This program is free software: you can redistribute it and/or modify
27
27
#include <stdlib.h>
28
28
#include <string.h>
29
29
 
30
 
#include "gl_list.h"
 
30
#include "gl_xlist.h"
31
31
#include "gl_array_list.h"
32
32
#include "unistr.h"
33
33
#include "xalloc.h"
57
57
      size_t i;
58
58
 
59
59
      for (i = stream->last_class_stack_size; i < stream->curr_class_stack_size; i++)
60
 
        {
61
 
          char *classname = (char *) gl_list_get_at (stream->class_stack, i);
 
60
        {
 
61
          char *classname = (char *) gl_list_get_at (stream->class_stack, i);
62
62
 
63
 
          ostream_write_str (stream->destination, "<span class=\"");
64
 
          ostream_write_str (stream->destination, classname);
65
 
          ostream_write_str (stream->destination, "\">");
66
 
        }
 
63
          ostream_write_str (stream->destination, "<span class=\"");
 
64
          ostream_write_str (stream->destination, classname);
 
65
          ostream_write_str (stream->destination, "\">");
 
66
        }
67
67
      stream->last_class_stack_size = stream->curr_class_stack_size;
68
68
    }
69
69
  else if (stream->curr_class_stack_size < stream->last_class_stack_size)
71
71
      size_t i = stream->last_class_stack_size;
72
72
 
73
73
      while (i > stream->curr_class_stack_size)
74
 
        {
75
 
          char *classname;
 
74
        {
 
75
          char *classname;
76
76
 
77
 
          --i;
78
 
          classname = (char *) gl_list_get_at (stream->class_stack, i);
79
 
          ostream_write_str (stream->destination, "</span>");
80
 
          if (shrink_stack)
81
 
            {
82
 
              gl_list_remove_at (stream->class_stack, i);
83
 
              free (classname);
84
 
            }
85
 
        }
 
77
          --i;
 
78
          classname = (char *) gl_list_get_at (stream->class_stack, i);
 
79
          ostream_write_str (stream->destination, "</span>");
 
80
          if (shrink_stack)
 
81
            {
 
82
              gl_list_remove_at (stream->class_stack, i);
 
83
              free (classname);
 
84
            }
 
85
        }
86
86
      stream->last_class_stack_size = stream->curr_class_stack_size;
87
87
    }
88
88
}
98
98
 
99
99
      inbufcount = stream->buflen;
100
100
      if (inbufcount > 0)
101
 
        memcpy (inbuffer, stream->buf, inbufcount);
 
101
        memcpy (inbuffer, stream->buf, inbufcount);
102
102
      for (;;)
103
 
        {
104
 
          /* At this point, inbuffer[0..inbufcount-1] is filled.  */
105
 
          {
106
 
            /* Combine the previous rest with a chunk of new input.  */
107
 
            size_t n =
108
 
              (len <= BUFFERSIZE - inbufcount ? len : BUFFERSIZE - inbufcount);
109
 
 
110
 
            if (n > 0)
111
 
              {
112
 
                memcpy (inbuffer + inbufcount, data, n);
113
 
                data = (char *) data + n;
114
 
                inbufcount += n;
115
 
                len -= n;
116
 
              }
117
 
          }
118
 
          {
119
 
            /* Handle complete UTF-8 characters.  */
120
 
            const char *inptr = inbuffer;
121
 
            size_t insize = inbufcount;
122
 
 
123
 
            while (insize > 0)
124
 
              {
125
 
                unsigned char c0;
126
 
                unsigned int uc;
127
 
                int nbytes;
128
 
 
129
 
                c0 = ((const unsigned char *) inptr)[0];
130
 
                if (insize < (c0 < 0xc0 ? 1 : c0 < 0xe0 ? 2 : c0 < 0xf0 ? 3 :
131
 
                              c0 < 0xf8 ? 4 : c0 < 0xfc ? 5 : 6))
132
 
                  break;
133
 
 
134
 
                nbytes = u8_mbtouc (&uc, (const unsigned char *) inptr, insize);
135
 
 
136
 
                if (uc == '\n')
137
 
                  {
138
 
                    size_t prev_class_stack_size = stream->curr_class_stack_size;
139
 
                    stream->curr_class_stack_size = 0;
140
 
                    emit_pending_spans (stream, false);
141
 
                    ostream_write_str (stream->destination, "<br/>");
142
 
                    stream->curr_class_stack_size = prev_class_stack_size;
143
 
                  }
144
 
                else
145
 
                  {
146
 
                    emit_pending_spans (stream, true);
147
 
 
148
 
                    switch (uc)
149
 
                      {
150
 
                      case '"':
151
 
                        ostream_write_str (stream->destination, "&quot;");
152
 
                        break;
153
 
                      case '&':
154
 
                        ostream_write_str (stream->destination, "&amp;");
155
 
                        break;
156
 
                      case '<':
157
 
                        ostream_write_str (stream->destination, "&lt;");
158
 
                        break;
159
 
                      case '>':
160
 
                        /* Needed to avoid "]]>" in the output.  */
161
 
                        ostream_write_str (stream->destination, "&gt;");
162
 
                        break;
163
 
                      case ' ':
164
 
                        /* Needed because HTML viewers merge adjacent spaces
165
 
                           and drop spaces adjacent to <br> and similar.  */
166
 
                        ostream_write_str (stream->destination, "&nbsp;");
167
 
                        break;
168
 
                      default:
169
 
                        if (uc >= 0x20 && uc < 0x7F)
170
 
                          {
171
 
                            /* Output ASCII characters as such.  */
172
 
                            char bytes[1];
173
 
                            bytes[0] = uc;
174
 
                            ostream_write_mem (stream->destination, bytes, 1);
175
 
                          }
176
 
                        else
177
 
                          {
178
 
                            /* Output non-ASCII characters in #&nnn;
179
 
                               notation.  */
180
 
                            char bytes[32];
181
 
                            sprintf (bytes, "&#%d;", uc);
182
 
                            ostream_write_str (stream->destination, bytes);
183
 
                          }
184
 
                        break;
185
 
                      }
186
 
                  }
187
 
 
188
 
                inptr += nbytes;
189
 
                insize -= nbytes;
190
 
              }
191
 
            /* Put back the unconverted part.  */
192
 
            if (insize > BUFSIZE)
193
 
              abort ();
194
 
            if (len == 0)
195
 
              {
196
 
                if (insize > 0)
197
 
                  memcpy (stream->buf, inptr, insize);
198
 
                stream->buflen = insize;
199
 
                break;
200
 
              }
201
 
            if (insize > 0)
202
 
              memmove (inbuffer, inptr, insize);
203
 
            inbufcount = insize;
204
 
          }
205
 
        }
 
103
        {
 
104
          /* At this point, inbuffer[0..inbufcount-1] is filled.  */
 
105
          {
 
106
            /* Combine the previous rest with a chunk of new input.  */
 
107
            size_t n =
 
108
              (len <= BUFFERSIZE - inbufcount ? len : BUFFERSIZE - inbufcount);
 
109
 
 
110
            if (n > 0)
 
111
              {
 
112
                memcpy (inbuffer + inbufcount, data, n);
 
113
                data = (char *) data + n;
 
114
                inbufcount += n;
 
115
                len -= n;
 
116
              }
 
117
          }
 
118
          {
 
119
            /* Handle complete UTF-8 characters.  */
 
120
            const char *inptr = inbuffer;
 
121
            size_t insize = inbufcount;
 
122
 
 
123
            while (insize > 0)
 
124
              {
 
125
                unsigned char c0;
 
126
                ucs4_t uc;
 
127
                int nbytes;
 
128
 
 
129
                c0 = ((const unsigned char *) inptr)[0];
 
130
                if (insize < (c0 < 0xc0 ? 1 : c0 < 0xe0 ? 2 : c0 < 0xf0 ? 3 :
 
131
                              c0 < 0xf8 ? 4 : c0 < 0xfc ? 5 : 6))
 
132
                  break;
 
133
 
 
134
                nbytes = u8_mbtouc (&uc, (const unsigned char *) inptr, insize);
 
135
 
 
136
                if (uc == '\n')
 
137
                  {
 
138
                    size_t prev_class_stack_size = stream->curr_class_stack_size;
 
139
                    stream->curr_class_stack_size = 0;
 
140
                    emit_pending_spans (stream, false);
 
141
                    ostream_write_str (stream->destination, "<br/>");
 
142
                    stream->curr_class_stack_size = prev_class_stack_size;
 
143
                  }
 
144
                else
 
145
                  {
 
146
                    emit_pending_spans (stream, true);
 
147
 
 
148
                    switch (uc)
 
149
                      {
 
150
                      case '"':
 
151
                        ostream_write_str (stream->destination, "&quot;");
 
152
                        break;
 
153
                      case '&':
 
154
                        ostream_write_str (stream->destination, "&amp;");
 
155
                        break;
 
156
                      case '<':
 
157
                        ostream_write_str (stream->destination, "&lt;");
 
158
                        break;
 
159
                      case '>':
 
160
                        /* Needed to avoid "]]>" in the output.  */
 
161
                        ostream_write_str (stream->destination, "&gt;");
 
162
                        break;
 
163
                      case ' ':
 
164
                        /* Needed because HTML viewers merge adjacent spaces
 
165
                           and drop spaces adjacent to <br> and similar.  */
 
166
                        ostream_write_str (stream->destination, "&nbsp;");
 
167
                        break;
 
168
                      default:
 
169
                        if (uc >= 0x20 && uc < 0x7F)
 
170
                          {
 
171
                            /* Output ASCII characters as such.  */
 
172
                            char bytes[1];
 
173
                            bytes[0] = uc;
 
174
                            ostream_write_mem (stream->destination, bytes, 1);
 
175
                          }
 
176
                        else
 
177
                          {
 
178
                            /* Output non-ASCII characters in #&nnn;
 
179
                               notation.  */
 
180
                            char bytes[32];
 
181
                            sprintf (bytes, "&#%d;", (int) uc);
 
182
                            ostream_write_str (stream->destination, bytes);
 
183
                          }
 
184
                        break;
 
185
                      }
 
186
                  }
 
187
 
 
188
                inptr += nbytes;
 
189
                insize -= nbytes;
 
190
              }
 
191
            /* Put back the unconverted part.  */
 
192
            if (insize > BUFSIZE)
 
193
              abort ();
 
194
            if (len == 0)
 
195
              {
 
196
                if (insize > 0)
 
197
                  memcpy (stream->buf, inptr, insize);
 
198
                stream->buflen = insize;
 
199
                break;
 
200
              }
 
201
            if (insize > 0)
 
202
              memmove (inbuffer, inptr, insize);
 
203
            inbufcount = insize;
 
204
          }
 
205
        }
206
206
      #undef BUFFERSIZE
207
207
    }
208
208
}
226
226
 
227
227
/* Implementation of html_ostream_t methods.  */
228
228
 
229
 
void
 
229
static void
230
230
html_ostream__begin_span (html_ostream_t stream, const char *classname)
231
231
{
232
232
  if (stream->last_class_stack_size > stream->curr_class_stack_size
233
233
      && strcmp ((char *) gl_list_get_at (stream->class_stack,
234
 
                                          stream->curr_class_stack_size),
235
 
                 classname) != 0)
 
234
                                          stream->curr_class_stack_size),
 
235
                 classname) != 0)
236
236
    emit_pending_spans (stream, true);
237
237
  /* Now either
238
238
       last_class_stack_size <= curr_class_stack_size
243
243
       - in this case we only need to increment curr_class_stack_size.  */
244
244
  if (stream->last_class_stack_size <= stream->curr_class_stack_size)
245
245
    gl_list_add_at (stream->class_stack, stream->curr_class_stack_size,
246
 
                    xstrdup (classname));
 
246
                    xstrdup (classname));
247
247
  stream->curr_class_stack_size++;
248
248
}
249
249
 
250
 
void
 
250
static void
251
251
html_ostream__end_span (html_ostream_t stream, const char *classname)
252
252
{
253
253
  if (!(stream->curr_class_stack_size > 0
254
 
        && strcmp ((char *) gl_list_get_at (stream->class_stack,
255
 
                                            stream->curr_class_stack_size - 1),
256
 
                   classname) == 0))
 
254
        && strcmp ((char *) gl_list_get_at (stream->class_stack,
 
255
                                            stream->curr_class_stack_size - 1),
 
256
                   classname) == 0))
257
257
    /* Improperly nested begin_span/end_span calls.  */
258
258
    abort ();
259
259
  stream->curr_class_stack_size--;