~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to src/glsl/pp/sl_pp_purify.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**************************************************************************
2
 
 * 
3
 
 * Copyright 2009 VMware, Inc.
4
 
 * All Rights Reserved.
5
 
 * 
6
 
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 
 * copy of this software and associated documentation files (the
8
 
 * "Software"), to deal in the Software without restriction, including
9
 
 * without limitation the rights to use, copy, modify, merge, publish,
10
 
 * distribute, sub license, and/or sell copies of the Software, and to
11
 
 * permit persons to whom the Software is furnished to do so, subject to
12
 
 * the following conditions:
13
 
 * 
14
 
 * The above copyright notice and this permission notice (including the
15
 
 * next paragraph) shall be included in all copies or substantial portions
16
 
 * of the Software.
17
 
 * 
18
 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
 
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
 
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22
 
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
 
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
 
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 
 * 
26
 
 **************************************************************************/
27
 
 
28
 
#include <stdlib.h>
29
 
#include <stdarg.h>
30
 
#include <stdio.h>
31
 
#include "sl_pp_purify.h"
32
 
 
33
 
 
34
 
/*
35
 
 * Preprocessor purifier performs the following tasks.
36
 
 * - Convert all variants of newlines into a Unix newline.
37
 
 * - Merge continued lines into a single long line.
38
 
 * - Remove line comments and replace block comments with whitespace.
39
 
 */
40
 
 
41
 
 
42
 
static unsigned int
43
 
_purify_newline(const char *input,
44
 
                char *out,
45
 
                unsigned int *current_line)
46
 
{
47
 
   if (input[0] == '\n') {
48
 
      *out = '\n';
49
 
      (*current_line)++;
50
 
      if (input[1] == '\r') {
51
 
         /*
52
 
          * The GLSL spec is not explicit about whether this
53
 
          * combination is a valid newline or not.
54
 
          * Let's assume it is acceptable.
55
 
          */
56
 
         return 2;
57
 
      }
58
 
      return 1;
59
 
   }
60
 
   if (input[0] == '\r') {
61
 
      *out = '\n';
62
 
      (*current_line)++;
63
 
      if (input[1] == '\n') {
64
 
         return 2;
65
 
      }
66
 
      return 1;
67
 
   }
68
 
   *out = input[0];
69
 
   return 1;
70
 
}
71
 
 
72
 
 
73
 
static unsigned int
74
 
_purify_backslash(const char *input,
75
 
                  char *out,
76
 
                  unsigned int *current_line)
77
 
{
78
 
   unsigned int eaten = 0;
79
 
 
80
 
   for (;;) {
81
 
      if (input[0] == '\\') {
82
 
         char next;
83
 
         unsigned int next_eaten;
84
 
         unsigned int next_line = *current_line;
85
 
 
86
 
         eaten++;
87
 
         input++;
88
 
 
89
 
         next_eaten = _purify_newline(input, &next, &next_line);
90
 
         if (next == '\n') {
91
 
            /*
92
 
             * If this is really a line continuation sequence, eat
93
 
             * it and do not exit the loop.
94
 
             */
95
 
            eaten += next_eaten;
96
 
            input += next_eaten;
97
 
            *current_line = next_line;
98
 
         } else {
99
 
            /*
100
 
             * It is an error to put anything between a backslash
101
 
             * and a newline and still expect it to behave like a line
102
 
             * continuation sequence.
103
 
             * Even if it is an innocent whitespace.
104
 
             */
105
 
            *out = '\\';
106
 
            break;
107
 
         }
108
 
      } else {
109
 
         eaten += _purify_newline(input, out, current_line);
110
 
         break;
111
 
      }
112
 
   }
113
 
   return eaten;
114
 
}
115
 
 
116
 
 
117
 
static void
118
 
_report_error(char *buf,
119
 
              unsigned int cbbuf,
120
 
              const char *msg,
121
 
              ...)
122
 
{
123
 
   va_list args;
124
 
 
125
 
   va_start(args, msg);
126
 
   vsnprintf(buf, cbbuf, msg, args);
127
 
   va_end(args);
128
 
}
129
 
 
130
 
 
131
 
void
132
 
sl_pp_purify_state_init(struct sl_pp_purify_state *state,
133
 
                        const char *input,
134
 
                        const struct sl_pp_purify_options *options)
135
 
{
136
 
   state->options = *options;
137
 
   state->input = input;
138
 
   state->current_line = 1;
139
 
   state->inside_c_comment = 0;
140
 
}
141
 
 
142
 
 
143
 
static unsigned int
144
 
_purify_comment(struct sl_pp_purify_state *state,
145
 
                char *output,
146
 
                unsigned int *current_line,
147
 
                char *errormsg,
148
 
                unsigned int cberrormsg)
149
 
{
150
 
   for (;;) {
151
 
      unsigned int eaten;
152
 
      char next;
153
 
 
154
 
      eaten = _purify_backslash(state->input, &next, current_line);
155
 
      state->input += eaten;
156
 
      while (next == '*') {
157
 
         eaten = _purify_backslash(state->input, &next, current_line);
158
 
         state->input += eaten;
159
 
         if (next == '/') {
160
 
            *output = ' ';
161
 
            state->inside_c_comment = 0;
162
 
            return 1;
163
 
         }
164
 
      }
165
 
      if (next == '\n') {
166
 
         *output = '\n';
167
 
         state->inside_c_comment = 1;
168
 
         return 1;
169
 
      }
170
 
      if (next == '\0') {
171
 
         _report_error(errormsg, cberrormsg, "expected `*/' but end of translation unit found");
172
 
         return 0;
173
 
      }
174
 
   }
175
 
}
176
 
 
177
 
 
178
 
unsigned int
179
 
sl_pp_purify_getc(struct sl_pp_purify_state *state,
180
 
                  char *output,
181
 
                  unsigned int *current_line,
182
 
                  char *errormsg,
183
 
                  unsigned int cberrormsg)
184
 
{
185
 
   unsigned int eaten;
186
 
 
187
 
   if (state->inside_c_comment) {
188
 
      return _purify_comment(state, output, current_line, errormsg, cberrormsg);
189
 
   }
190
 
 
191
 
   eaten = _purify_backslash(state->input, output, current_line);
192
 
   state->input += eaten;
193
 
   if (*output == '/') {
194
 
      char next;
195
 
      unsigned int next_line = *current_line;
196
 
 
197
 
      eaten = _purify_backslash(state->input, &next, &next_line);
198
 
      if (next == '/') {
199
 
         state->input += eaten;
200
 
         *current_line = next_line;
201
 
 
202
 
         /* Replace a line comment with either a newline or nil. */
203
 
         for (;;) {
204
 
            eaten = _purify_backslash(state->input, &next, current_line);
205
 
            state->input += eaten;
206
 
            if (next == '\n' || next == '\0') {
207
 
               *output = next;
208
 
               return eaten;
209
 
            }
210
 
         }
211
 
      } else if (next == '*') {
212
 
         state->input += eaten;
213
 
         *current_line = next_line;
214
 
 
215
 
         return _purify_comment(state, output, current_line, errormsg, cberrormsg);
216
 
      }
217
 
   }
218
 
   return eaten;
219
 
}
220
 
 
221
 
 
222
 
struct out_buf {
223
 
   char *out;
224
 
   unsigned int len;
225
 
   unsigned int capacity;
226
 
   unsigned int current_line;
227
 
   char *errormsg;
228
 
   unsigned int cberrormsg;
229
 
};
230
 
 
231
 
 
232
 
static int
233
 
_out_buf_putc(struct out_buf *obuf,
234
 
              char c)
235
 
{
236
 
   if (obuf->len >= obuf->capacity) {
237
 
      unsigned int new_max = obuf->capacity;
238
 
 
239
 
      if (new_max < 0x100) {
240
 
         new_max = 0x100;
241
 
      } else if (new_max < 0x10000) {
242
 
         new_max *= 2;
243
 
      } else {
244
 
         new_max += 0x10000;
245
 
      }
246
 
 
247
 
      obuf->out = realloc(obuf->out, new_max);
248
 
      if (!obuf->out) {
249
 
         _report_error(obuf->errormsg, obuf->cberrormsg, "out of memory");
250
 
         return -1;
251
 
      }
252
 
      obuf->capacity = new_max;
253
 
   }
254
 
 
255
 
   obuf->out[obuf->len++] = c;
256
 
 
257
 
   return 0;
258
 
}
259
 
 
260
 
 
261
 
int
262
 
sl_pp_purify(const char *input,
263
 
             const struct sl_pp_purify_options *options,
264
 
             char **output,
265
 
             char *errormsg,
266
 
             unsigned int cberrormsg,
267
 
             unsigned int *errorline)
268
 
{
269
 
   struct out_buf obuf;
270
 
   struct sl_pp_purify_state state;
271
 
 
272
 
   obuf.out = NULL;
273
 
   obuf.len = 0;
274
 
   obuf.capacity = 0;
275
 
   obuf.current_line = 1;
276
 
   obuf.errormsg = errormsg;
277
 
   obuf.cberrormsg = cberrormsg;
278
 
 
279
 
   sl_pp_purify_state_init(&state, input, options);
280
 
 
281
 
   for (;;) {
282
 
      unsigned int eaten;
283
 
      char c;
284
 
 
285
 
      eaten = sl_pp_purify_getc(&state, &c, &obuf.current_line, errormsg, cberrormsg);
286
 
      if (!eaten) {
287
 
         *errorline = obuf.current_line;
288
 
         return -1;
289
 
      }
290
 
      if (_out_buf_putc(&obuf, c)) {
291
 
         *errorline = obuf.current_line;
292
 
         return -1;
293
 
      }
294
 
 
295
 
      if (c == '\0') {
296
 
         break;
297
 
      }
298
 
   }
299
 
 
300
 
   *output = obuf.out;
301
 
   return 0;
302
 
}