1 #line 1 "steel.cpp"
2 /**************************************************************************\
3 * Copyright (c) Kongsberg Oil & Gas Technologies AS
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from
19 * this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 \**************************************************************************/
33
34 /* ********************************************************************** *
35 * TODO:
36 * - API to get file position data when encountering errors
37 * - implement writing
38 * - read/write the two color extensions (binary only)
39 * - be robust for corrupt files
40 * - wtf does "A facet normal coordinate may have a leading minus sign;
41 * a vertex coordinate may not." for stl ascii files mean? do I need to
42 * take special care because of this? why are there no proper formal
43 * specs for the stl file formats?
44 * UPDATE: it probably means that all vertices must lie in the positive
45 * octant in the worldspace - negative coordinates in any dimension is
46 * not allowed. might be sensible, given that STL files are generally
47 * created for use by 3D rinters.
48 * - figure out how to support gzipped files (in combination with flex,
49 * memory buffer techniques will probably have to be used)
50 * - cr+lf on DOS/unix for ascii files - is this a problem?
51 * - remove any error-handling asserts
52 * ********************************************************************** */
53
54 #include <cassert>
55 #include <cstdlib>
56 #include <cstring>
57
58 #include <Inventor/system/inttypes.h>
59
60 #include "steel.h"
61
62 #line 62 "steel.cpp"
63
64 #define YY_INT_ALIGNED short int
65
66 /* A lexical scanner generated by flex */
67
68 #define yy_create_buffer stl_yy_create_buffer
69 #define yy_delete_buffer stl_yy_delete_buffer
70 #define yy_flex_debug stl_yy_flex_debug
71 #define yy_init_buffer stl_yy_init_buffer
72 #define yy_flush_buffer stl_yy_flush_buffer
73 #define yy_load_buffer_state stl_yy_load_buffer_state
74 #define yy_switch_to_buffer stl_yy_switch_to_buffer
75 #define yyin stl_yyin
76 #define yyleng stl_yyleng
77 #define yylex stl_yylex
78 #define yylineno stl_yylineno
79 #define yyout stl_yyout
80 #define yyrestart stl_yyrestart
81 #define yytext stl_yytext
82 #define yywrap stl_yywrap
83 #define yyalloc stl_yyalloc
84 #define yyrealloc stl_yyrealloc
85 #define yyfree stl_yyfree
86
87 #define FLEX_SCANNER
88 #define YY_FLEX_MAJOR_VERSION 2
89 #define YY_FLEX_MINOR_VERSION 6
90 #define YY_FLEX_SUBMINOR_VERSION 3
91 #if YY_FLEX_SUBMINOR_VERSION > 0
92 #define FLEX_BETA
93 #endif
94
95 #define yy_create_buffer stl_yy_create_buffer
96
97 #define yy_delete_buffer stl_yy_delete_buffer
98
99 #define yy_scan_buffer stl_yy_scan_buffer
100
101 #define yy_scan_string stl_yy_scan_string
102
103 #define yy_scan_bytes stl_yy_scan_bytes
104
105 #define yy_init_buffer stl_yy_init_buffer
106
107 #define yy_flush_buffer stl_yy_flush_buffer
108
109 #define yy_load_buffer_state stl_yy_load_buffer_state
110
111 #define yy_switch_to_buffer stl_yy_switch_to_buffer
112
113 #define yypush_buffer_state stl_yypush_buffer_state
114
115 #define yypop_buffer_state stl_yypop_buffer_state
116
117 #define yyensure_buffer_stack stl_yyensure_buffer_stack
118
119 #define yylex stl_yylex
120
121 #define yyrestart stl_yyrestart
122
123 #define yylex_init stl_yylex_init
124
125 #define yylex_init_extra stl_yylex_init_extra
126
127 #define yylex_destroy stl_yylex_destroy
128
129 #define yyget_debug stl_yyget_debug
130
131 #define yyset_debug stl_yyset_debug
132
133 #define yyget_extra stl_yyget_extra
134
135 #define yyset_extra stl_yyset_extra
136
137 #define yyget_in stl_yyget_in
138
139 #define yyset_in stl_yyset_in
140
141 #define yyget_out stl_yyget_out
142
143 #define yyset_out stl_yyset_out
144
145 #define yyget_leng stl_yyget_leng
146
147 #define yyget_text stl_yyget_text
148
149 #define yyget_lineno stl_yyget_lineno
150
151 #define yyset_lineno stl_yyset_lineno
152
153 #define yywrap stl_yywrap
154
155 #define yyalloc stl_yyalloc
156
157 #define yyrealloc stl_yyrealloc
158
159 #define yyfree stl_yyfree
160
161 #define yytext stl_yytext
162
163 #define yyleng stl_yyleng
164
165 #define yyin stl_yyin
166
167 #define yyout stl_yyout
168
169 #define yy_flex_debug stl_yy_flex_debug
170
171 #define yylineno stl_yylineno
172
173 /* First, we deal with platform-specific or compiler-specific issues. */
174
175 /* begin standard C headers. */
176 #include <cstdio>
177 #include <cstring>
178 #include <cerrno>
179 #include <cstdlib>
180
181 /* end standard C headers. */
182
183 /* flex integer type definitions */
184
185 #ifndef FLEXINT_H
186 #define FLEXINT_H
187
188 /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
189
190 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
191
192 /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
193 * if you want the limit (max/min) macros for int types.
194 */
195 #ifndef __STDC_LIMIT_MACROS
196 #define __STDC_LIMIT_MACROS 1
197 #endif
198
199 #include <inttypes.h>
200 typedef int8_t flex_int8_t;
201 typedef uint8_t flex_uint8_t;
202 typedef int16_t flex_int16_t;
203 typedef uint16_t flex_uint16_t;
204 typedef int32_t flex_int32_t;
205 typedef uint32_t flex_uint32_t;
206 #else
207 typedef signed char flex_int8_t;
208 typedef short int flex_int16_t;
209 typedef int flex_int32_t;
210 typedef unsigned char flex_uint8_t;
211 typedef unsigned short int flex_uint16_t;
212 typedef unsigned int flex_uint32_t;
213
214 /* Limits of integral types. */
215 #ifndef INT8_MIN
216 #define INT8_MIN (-128)
217 #endif
218 #ifndef INT16_MIN
219 #define INT16_MIN (-32767-1)
220 #endif
221 #ifndef INT32_MIN
222 #define INT32_MIN (-2147483647-1)
223 #endif
224 #ifndef INT8_MAX
225 #define INT8_MAX (127)
226 #endif
227 #ifndef INT16_MAX
228 #define INT16_MAX (32767)
229 #endif
230 #ifndef INT32_MAX
231 #define INT32_MAX (2147483647)
232 #endif
233 #ifndef UINT8_MAX
234 #define UINT8_MAX (255U)
235 #endif
236 #ifndef UINT16_MAX
237 #define UINT16_MAX (65535U)
238 #endif
239 #ifndef UINT32_MAX
240 #define UINT32_MAX (4294967295U)
241 #endif
242
243 #endif /* ! C99 */
244
245 #endif /* ! FLEXINT_H */
246
247 /* TODO: this is always defined, so inline it */
248 #define yyconst const
249
250 #if defined(__GNUC__) && __GNUC__ >= 3
251 #define yynoreturn __attribute__((__noreturn__))
252 #else
253 #define yynoreturn
254 #endif
255
256 /* Returned upon end-of-file. */
257 #define YY_NULL 0
258
259 /* Promotes a possibly negative, possibly signed char to an
260 * integer in range [0..255] for use as an array index.
261 */
262 #define YY_SC_TO_UI(c) ((YY_CHAR) (c))
263
264 /* Enter a start condition. This macro really ought to take a parameter,
265 * but we do it the disgusting crufty way forced on us by the ()-less
266 * definition of BEGIN.
267 */
268 #define BEGIN (yy_start) = 1 + 2 *
269 /* Translate the current start state into a value that can be later handed
270 * to BEGIN to return to the state. The YYSTATE alias is for lex
271 * compatibility.
272 */
273 #define YY_START (((yy_start) - 1) / 2)
274 #define YYSTATE YY_START
275 /* Action number for EOF rule of a given start state. */
276 #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
277 /* Special action meaning "start processing a new file". */
278 #define YY_NEW_FILE stl_yyrestart(stl_yyin )
279 #define YY_END_OF_BUFFER_CHAR 0
280
281 /* Size of default input buffer. */
282 #ifndef YY_BUF_SIZE
283 #ifdef __ia64__
284 /* On IA-64, the buffer size is 16k, not 8k.
285 * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
286 * Ditto for the __ia64__ case accordingly.
287 */
288 #define YY_BUF_SIZE 32768
289 #else
290 #define YY_BUF_SIZE 16384
291 #endif /* __ia64__ */
292 #endif
293
294 /* The state buf must be large enough to hold one state per character in the main buffer.
295 */
296 #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
297
298 #ifndef YY_TYPEDEF_YY_BUFFER_STATE
299 #define YY_TYPEDEF_YY_BUFFER_STATE
300 typedef struct yy_buffer_state *YY_BUFFER_STATE;
301 #endif
302
303 #ifndef YY_TYPEDEF_YY_SIZE_T
304 #define YY_TYPEDEF_YY_SIZE_T
305 typedef size_t yy_size_t;
306 #endif
307
308 extern int stl_yyleng;
309
310 extern FILE *stl_yyin, *stl_yyout;
311
312 #define EOB_ACT_CONTINUE_SCAN 0
313 #define EOB_ACT_END_OF_FILE 1
314 #define EOB_ACT_LAST_MATCH 2
315
316 #define YY_LESS_LINENO(n)
317 #define YY_LINENO_REWIND_TO(ptr)
318
319 /* Return all but the first "n" matched characters back to the input stream. */
320 #define yyless(n) \
321 do \
322 { \
323 /* Undo effects of setting up stl_yytext. */ \
324 int yyless_macro_arg = (n); \
325 YY_LESS_LINENO(yyless_macro_arg);\
326 *yy_cp = (yy_hold_char); \
327 YY_RESTORE_YY_MORE_OFFSET \
328 (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
329 YY_DO_BEFORE_ACTION; /* set up stl_yytext again */ \
330 } \
331 while ( 0 )
332 #define unput(c) yyunput( c, (yytext_ptr) )
333
334 #ifndef YY_STRUCT_YY_BUFFER_STATE
335 #define YY_STRUCT_YY_BUFFER_STATE
336 struct yy_buffer_state
337 {
338 FILE *yy_input_file;
339
340 char *yy_ch_buf; /* input buffer */
341 char *yy_buf_pos; /* current position in input buffer */
342
343 /* Size of input buffer in bytes, not including room for EOB
344 * characters.
345 */
346 int yy_buf_size;
347
348 /* Number of characters read into yy_ch_buf, not including EOB
349 * characters.
350 */
351 int yy_n_chars;
352
353 /* Whether we "own" the buffer - i.e., we know we created it,
354 * and can realloc() it to grow it, and should free() it to
355 * delete it.
356 */
357 int yy_is_our_buffer;
358
359 /* Whether this is an "interactive" input source; if so, and
360 * if we're using stdio for input, then we want to use getc()
361 * instead of fread(), to make sure we stop fetching input after
362 * each newline.
363 */
364 int yy_is_interactive;
365
366 /* Whether we're considered to be at the beginning of a line.
367 * If so, '^' rules will be active on the next match, otherwise
368 * not.
369 */
370 int yy_at_bol;
371
372 int yy_bs_lineno; /**< The line count. */
373 int yy_bs_column; /**< The column count. */
374
375 /* Whether to try to fill the input buffer when we reach the
376 * end of it.
377 */
378 int yy_fill_buffer;
379
380 int yy_buffer_status;
381
382 #define YY_BUFFER_NEW 0
383 #define YY_BUFFER_NORMAL 1
384 /* When an EOF's been seen but there's still some text to process
385 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
386 * shouldn't try reading from the input source any more. We might
387 * still have a bunch of tokens to match, though, because of
388 * possible backing-up.
389 *
390 * When we actually see the EOF, we change the status to "new"
391 * (via stl_yyrestart()), so that the user can continue scanning by
392 * just pointing stl_yyin at a new input file.
393 */
394 #define YY_BUFFER_EOF_PENDING 2
395
396 };
397 #endif /* !YY_STRUCT_YY_BUFFER_STATE */
398
399 /* Stack of input buffers. */
400 static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
401 static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
402 static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */
403
404 /* We provide macros for accessing buffer states in case in the
405 * future we want to put the buffer states in a more general
406 * "scanner state".
407 *
408 * Returns the top of the stack, or NULL.
409 */
410 #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
411 ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
412 : NULL)
413 /* Same as previous macro, but useful when we know that the buffer stack is not
414 * NULL or when we need an lvalue. For internal use only.
415 */
416 #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
417
418 /* yy_hold_char holds the character lost when stl_yytext is formed. */
419 static char yy_hold_char;
420 static int yy_n_chars; /* number of characters read into yy_ch_buf */
421 int stl_yyleng;
422
423 /* Points to current character in buffer. */
424 static char *yy_c_buf_p = NULL;
425 static int yy_init = 0; /* whether we need to initialize */
426 static int yy_start = 0; /* start state number */
427
428 /* Flag which is used to allow stl_yywrap()'s to do buffer switches
429 * instead of setting up a fresh stl_yyin. A bit of a hack ...
430 */
431 static int yy_did_buffer_switch_on_eof;
432
433 void stl_yyrestart ( FILE *input_file );
434 void stl_yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer );
435 YY_BUFFER_STATE stl_yy_create_buffer ( FILE *file, int size );
436 void stl_yy_delete_buffer ( YY_BUFFER_STATE b );
437 void stl_yy_flush_buffer ( YY_BUFFER_STATE b );
438 void stl_yypush_buffer_state ( YY_BUFFER_STATE new_buffer );
439 void stl_yypop_buffer_state ( void );
440
441 static void stl_yyensure_buffer_stack ( void );
442 static void stl_yy_load_buffer_state ( void );
443 static void stl_yy_init_buffer ( YY_BUFFER_STATE b, FILE *file );
444 #define YY_FLUSH_BUFFER stl_yy_flush_buffer(YY_CURRENT_BUFFER )
445
446 YY_BUFFER_STATE stl_yy_scan_buffer ( char *base, yy_size_t size );
447 YY_BUFFER_STATE stl_yy_scan_string ( const char *yy_str );
448 YY_BUFFER_STATE stl_yy_scan_bytes ( const char *bytes, int len );
449
450 void *stl_yyalloc ( yy_size_t );
451 void *stl_yyrealloc ( void *, yy_size_t );
452 void stl_yyfree ( void * );
453
454 #define yy_new_buffer stl_yy_create_buffer
455 #define yy_set_interactive(is_interactive) \
456 { \
457 if ( ! YY_CURRENT_BUFFER ){ \
458 stl_yyensure_buffer_stack (); \
459 YY_CURRENT_BUFFER_LVALUE = \
460 stl_yy_create_buffer(stl_yyin,YY_BUF_SIZE ); \
461 } \
462 YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
463 }
464 #define yy_set_bol(at_bol) \
465 { \
466 if ( ! YY_CURRENT_BUFFER ){\
467 stl_yyensure_buffer_stack (); \
468 YY_CURRENT_BUFFER_LVALUE = \
469 stl_yy_create_buffer(stl_yyin,YY_BUF_SIZE ); \
470 } \
471 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
472 }
473 #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
474
475 /* Begin user sect3 */
476
477 #define stl_yywrap() (/*CONSTCOND*/1)
478 #define YY_SKIP_YYWRAP
479 typedef flex_uint8_t YY_CHAR;
480
481 FILE *stl_yyin = NULL, *stl_yyout = NULL;
482
483 typedef int yy_state_type;
484
485 extern int stl_yylineno;
486 int stl_yylineno = 1;
487
488 extern char *stl_yytext;
489 #ifdef yytext_ptr
490 #undef yytext_ptr
491 #endif
492 #define yytext_ptr stl_yytext
493
494 static yy_state_type yy_get_previous_state ( void );
495 static yy_state_type yy_try_NUL_trans ( yy_state_type current_state );
496 static int yy_get_next_buffer ( void );
497 static void yynoreturn yy_fatal_error ( const char* msg );
498
499 /* Done after the current pattern has been matched and before the
500 * corresponding action - sets up stl_yytext.
501 */
502 #define YY_DO_BEFORE_ACTION \
503 (yytext_ptr) = yy_bp; \
504 (yytext_ptr) -= (yy_more_len); \
505 stl_yyleng = (int) (yy_cp - (yytext_ptr)); \
506 (yy_hold_char) = *yy_cp; \
507 *yy_cp = '\0'; \
508 (yy_c_buf_p) = yy_cp;
509 #define YY_NUM_RULES 13
510 #define YY_END_OF_BUFFER 14
511 /* This struct is not used in this scanner,
512 but its presence is necessary. */
513 struct yy_trans_info
514 {
515 flex_int32_t yy_verify;
516 flex_int32_t yy_nxt;
517 };
518 static const flex_int16_t yy_accept[142] =
519 { 0,
520 0, 0, 14, 12, 8, 10, 9, 12, 12, 12,
521 12, 12, 12, 12, 8, 0, 0, 0, 0, 0,
522 0, 0, 0, 0, 0, 0, 0, 0, 11, 0,
523 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
524 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
525 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
526 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
527 0, 5, 0, 0, 0, 0, 0, 0, 6, 0,
528 0, 7, 0, 0, 0, 0, 0, 0, 0, 0,
529 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
530
531 0, 0, 0, 0, 0, 0, 4, 0, 0, 0,
532 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
533 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
534 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
535 0
536 } ;
537
538 static const YY_CHAR yy_ec[256] =
539 { 0,
540 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
541 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
542 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
543 1, 2, 1, 1, 5, 1, 1, 1, 1, 1,
544 1, 1, 6, 1, 6, 7, 1, 8, 8, 8,
545 8, 8, 8, 8, 8, 8, 8, 1, 1, 1,
546 1, 1, 1, 1, 9, 1, 10, 11, 12, 13,
547 1, 1, 14, 1, 1, 15, 16, 17, 18, 19,
548 1, 20, 21, 22, 23, 24, 1, 25, 1, 1,
549 1, 1, 1, 1, 1, 1, 26, 1, 27, 28,
550
551 29, 30, 1, 1, 31, 1, 1, 32, 33, 34,
552 35, 36, 1, 37, 38, 39, 40, 41, 1, 42,
553 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
554 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
555 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
556 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
557 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
558 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
559 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
560 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
561
562 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
563 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
564 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
565 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
566 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
567 1, 1, 1, 1, 1
568 } ;
569
570 static const YY_CHAR yy_meta[43] =
571 { 0,
572 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
573 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
574 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
575 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
576 1, 1
577 } ;
578
579 static const flex_int16_t yy_base[146] =
580 { 0,
581 0, 40, 328, 331, 80, 331, 331, 0, 0, 1,
582 0, 2, 2, 324, 0, 5, 1, 15, 23, 30,
583 37, 0, 41, 36, 34, 42, 39, 323, 331, 120,
584 48, 43, 55, 66, 61, 85, 76, 68, 70, 68,
585 3, 71, 83, 84, 89, 96, 102, 323, 5, 331,
586 322, 117, 100, 114, 108, 114, 122, 134, 320, 127,
587 331, 320, 115, 144, 127, 146, 122, 149, 159, 157,
588 166, 331, 168, 142, 170, 313, 175, 171, 331, 317,
589 182, 331, 159, 187, 311, 180, 181, 192, 309, 189,
590 197, 308, 200, 188, 204, 307, 205, 312, 213, 302,
591
592 220, 222, 300, 223, 227, 214, 331, 297, 230, 235,
593 287, 238, 245, 284, 252, 250, 279, 236, 257, 265,
594 264, 267, 253, 260, 275, 231, 272, 280, 206, 282,
595 289, 145, 262, 296, 331, 124, 294, 301, 81, 304,
596 331, 46, 24, 15, 0
597 } ;
598
599 static const flex_int16_t yy_def[146] =
600 { 0,
601 142, 142, 141, 141, 141, 141, 141, 141, 141, 141,
602 141, 141, 141, 143, 5, 141, 141, 141, 141, 141,
603 141, 141, 141, 141, 141, 141, 141, 143, 141, 141,
604 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
605 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
606 141, 144, 141, 141, 141, 141, 141, 141, 144, 144,
607 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
608 141, 141, 145, 141, 141, 141, 141, 141, 141, 145,
609 145, 141, 141, 141, 141, 141, 141, 141, 141, 141,
610 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
611
612 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
613 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
614 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
615 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
616 0, 141, 141, 141, 141
617 } ;
618
619 static const flex_int16_t yy_nxt[374] =
620 { 0,
621 80, 5, 6, 7, 49, 50, 49, 50, 23, 23,
622 30, 8, 9, 27, 10, 59, 22, 11, 24, 26,
623 12, 22, 25, 13, 28, 23, 23, 30, 8, 9,
624 27, 10, 24, 22, 11, 24, 26, 12, 22, 25,
625 13, 5, 6, 7, 14, 25, 4, 26, 27, 24,
626 31, 8, 9, 32, 10, 33, 34, 11, 35, 40,
627 12, 41, 25, 13, 26, 27, 42, 31, 8, 9,
628 32, 10, 33, 34, 11, 35, 40, 12, 41, 43,
629 13, 15, 44, 42, 45, 46, 36, 47, 140, 48,
630 51, 16, 17, 52, 18, 53, 43, 19, 54, 44,
631
632 20, 45, 46, 21, 47, 39, 48, 51, 16, 17,
633 52, 18, 53, 55, 19, 54, 56, 20, 60, 61,
634 21, 36, 39, 66, 62, 63, 64, 65, 60, 61,
635 55, 138, 37, 56, 38, 68, 70, 73, 67, 74,
636 39, 62, 63, 64, 65, 71, 72, 66, 18, 37,
637 68, 38, 133, 70, 73, 67, 74, 39, 78, 79,
638 75, 83, 67, 18, 76, 18, 77, 71, 72, 81,
639 82, 75, 78, 79, 87, 76, 84, 77, 83, 67,
640 18, 85, 77, 81, 82, 92, 86, 93, 88, 94,
641 95, 87, 89, 88, 90, 96, 90, 89, 84, 90,
642
643 97, 84, 98, 86, 91, 99, 94, 93, 86, 100,
644 103, 101, 104, 130, 99, 106, 107, 97, 100, 98,
645 101, 106, 107, 95, 95, 86, 108, 101, 110, 102,
646 104, 109, 111, 97, 112, 114, 110, 115, 131, 116,
647 111, 123, 112, 124, 117, 112, 106, 107, 109, 118,
648 97, 119, 113, 106, 107, 120, 109, 121, 119, 115,
649 124, 116, 120, 125, 121, 125, 118, 124, 116, 133,
650 126, 121, 121, 109, 122, 127, 128, 132, 118, 133,
651 129, 128, 130, 134, 135, 129, 122, 130, 136, 130,
652 125, 115, 127, 137, 112, 118, 131, 134, 135, 139,
653
654 127, 140, 134, 135, 113, 134, 135, 104, 138, 101,
655 137, 140, 137, 105, 102, 93, 90, 127, 91, 82,
656 77, 69, 61, 58, 57, 29, 29, 141, 141, 137,
657 3, 141, 141, 141, 141, 141, 141, 141, 141, 141,
658 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
659 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
660 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
661 141, 141, 141
662 } ;
663
664 static const flex_int16_t yy_chk[374] =
665 { 0,
666 145, 1, 1, 1, 41, 41, 49, 49, 9, 17,
667 22, 1, 1, 13, 1, 144, 8, 1, 10, 12,
668 1, 16, 11, 1, 143, 9, 17, 22, 1, 1,
669 13, 1, 18, 8, 1, 10, 12, 1, 16, 11,
670 1, 2, 2, 2, 2, 19, 142, 20, 21, 18,
671 23, 2, 2, 24, 2, 25, 26, 2, 27, 31,
672 2, 32, 19, 2, 20, 21, 33, 23, 2, 2,
673 24, 2, 25, 26, 2, 27, 31, 2, 32, 34,
674 2, 5, 35, 33, 37, 38, 36, 39, 139, 40,
675 42, 5, 5, 43, 5, 44, 34, 5, 45, 35,
676
677 5, 37, 38, 5, 39, 36, 40, 42, 5, 5,
678 43, 5, 44, 46, 5, 45, 47, 5, 52, 52,
679 5, 30, 36, 57, 53, 54, 55, 56, 60, 60,
680 46, 136, 30, 47, 30, 58, 63, 65, 57, 67,
681 30, 53, 54, 55, 56, 64, 64, 66, 58, 30,
682 68, 30, 132, 63, 65, 57, 67, 30, 70, 70,
683 69, 74, 66, 68, 69, 58, 69, 71, 71, 73,
684 73, 75, 78, 78, 83, 75, 77, 75, 74, 66,
685 68, 77, 77, 81, 81, 86, 77, 86, 84, 87,
686 90, 83, 84, 88, 84, 90, 90, 88, 91, 88,
687
688 90, 93, 94, 77, 91, 95, 87, 93, 91, 95,
689 97, 95, 97, 129, 99, 106, 106, 90, 99, 94,
690 99, 101, 101, 102, 104, 91, 101, 101, 105, 102,
691 104, 101, 105, 102, 105, 109, 110, 109, 126, 112,
692 110, 118, 110, 118, 112, 112, 113, 113, 101, 112,
693 102, 116, 113, 115, 115, 116, 113, 116, 119, 115,
694 123, 124, 119, 133, 119, 121, 112, 124, 122, 133,
695 121, 121, 120, 113, 122, 121, 125, 127, 122, 127,
696 125, 128, 125, 130, 130, 128, 117, 128, 130, 130,
697 131, 114, 121, 130, 111, 122, 131, 134, 134, 137,
698
699 131, 137, 138, 138, 108, 140, 140, 103, 138, 100,
700 130, 140, 138, 98, 96, 92, 89, 131, 85, 80,
701 76, 62, 59, 51, 48, 28, 14, 3, 0, 138,
702 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
703 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
704 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
705 141, 141, 141, 141, 141, 141, 141, 141, 141, 141,
706 141, 141, 141
707 } ;
708
709 static yy_state_type yy_last_accepting_state;
710 static char *yy_last_accepting_cpos;
711
712 extern int stl_yy_flex_debug;
713 int stl_yy_flex_debug = 0;
714
715 /* The intent behind this definition is that it'll catch
716 * any uses of REJECT which flex missed.
717 */
718 #define REJECT reject_used_but_not_detected
719 static int yy_more_flag = 0;
720 static int yy_more_len = 0;
721 #define yymore() ((yy_more_flag) = 1)
722 #define YY_MORE_ADJ (yy_more_len)
723 #define YY_RESTORE_YY_MORE_OFFSET
724 char *stl_yytext;
725 #line 1 "steel.l"
726
727 #line 64 "steel.l"
728 /* @stl_real@
729 This is a typedef for the C type float. It is used so the floating point type
730 can be changed at a later date. It is not likely to happen though, as the
731 STL file format specifies that the floats should be IEEE 32-bit floats.
732 */
733
734 /* @stl_facet_s@
735 This is an opaque handle for one facet record in an STL file. It contains
736 the position of the three vertices in the triangle face, and the normal
737 vector. For binary STL files, there is also two bytes of padding data
738 that is used for color information in a couple of STL format extensions,
739 which is also accessible with this data type.
740 */
741
742 struct stl_facet_s {
743 stl_real nx, ny, nz;
744 stl_real v1x, v1y, v1z;
745 stl_real v2x, v2y, v2z;
746 stl_real v3x, v3y, v3z;
747 unsigned int color;
748 };
749
750 /* @stl_reader_s@
751 This is an opaque handle for an STL file that is opened for reading.
752 Both ascii and binary file access is handled with this type.
753 */
754
755 struct stl_reader_s {
756 char * filename;
757 FILE * file;
758 char * info;
759 stl_facet * facet;
760 const char * error;
761 unsigned int flags;
762 unsigned int linenum;
763 int pending;
764 int vertex;
765 int facets;
766 int facets_total;
767 int hickups;
768 };
769
770 /* @stl_writer_s@
771 This is an opaque handle for an STL file that is opened for writing.
772 */
773
774 struct stl_writer_s {
775 char * filename;
776 FILE * file;
777 char * info;
778 const char * error;
779 int facets;
780 unsigned int flags;
781 stl_facet * facet;
782 int linenum;
783 };
784
785 /* prototypes for internal functions used in lex part */
786 static int stl_parse_real_triple(char * text, stl_real * a, stl_real * b, stl_real * c);
787
788 #define STL_PUBLIC_FLAGS 0x000000ff
789 #define STL_NO_PENDING ((STL_ERROR) - 1)
790 #define YY_DECL int stl_scan(stl_reader * reader)
791 #line 791 "steel.cpp"
792 #define YY_NO_INPUT 1
793 #line 793 "steel.cpp"
794
795 #define INITIAL 0
796
797 #ifndef YY_NO_UNISTD_H
798 /* Special case for "unistd.h", since it is non-ANSI. We include it way
799 * down here because we want the user's section 1 to have been scanned first.
800 * The user has a chance to override it with an option.
801 */
802 #include <unistd.h>
803 #endif
804
805 #ifndef YY_EXTRA_TYPE
806 #define YY_EXTRA_TYPE void *
807 #endif
808
809 static int yy_init_globals ( void );
810
811 /* Accessor methods to globals.
812 These are made visible to non-reentrant scanners for convenience. */
813
814 int stl_yylex_destroy ( void );
815
816 int stl_yyget_debug ( void );
817
818 void stl_yyset_debug ( int debug_flag );
819
820 YY_EXTRA_TYPE stl_yyget_extra ( void );
821
822 void stl_yyset_extra ( YY_EXTRA_TYPE user_defined );
823
824 FILE *stl_yyget_in ( void );
825
826 void stl_yyset_in ( FILE * _in_str );
827
828 FILE *stl_yyget_out ( void );
829
830 void stl_yyset_out ( FILE * _out_str );
831
832 int stl_yyget_leng ( void );
833
834 char *stl_yyget_text ( void );
835
836 int stl_yyget_lineno ( void );
837
838 void stl_yyset_lineno ( int _line_number );
839
840 /* Macros after this point can all be overridden by user definitions in
841 * section 1.
842 */
843
844 #ifndef YY_SKIP_YYWRAP
845 #ifdef __cplusplus
846 extern "C" int stl_yywrap ( void );
847 #else
848 extern int stl_yywrap ( void );
849 #endif
850 #endif
851
852 #ifndef YY_NO_UNPUT
853
854 #endif
855
856 #ifndef yytext_ptr
857 static void yy_flex_strncpy ( char *, const char *, int );
858 #endif
859
860 #ifdef YY_NEED_STRLEN
861 static int yy_flex_strlen ( const char * );
862 #endif
863
864 #ifndef YY_NO_INPUT
865 #ifdef __cplusplus
866 static int yyinput ( void );
867 #else
868 static int input ( void );
869 #endif
870
871 #endif
872
873 /* Amount of stuff to slurp up with each read. */
874 #ifndef YY_READ_BUF_SIZE
875 #ifdef __ia64__
876 /* On IA-64, the buffer size is 16k, not 8k */
877 #define YY_READ_BUF_SIZE 16384
878 #else
879 #define YY_READ_BUF_SIZE 8192
880 #endif /* __ia64__ */
881 #endif
882
883 /* Copy whatever the last rule matched to the standard output. */
884 #ifndef ECHO
885 /* This used to be an fputs(), but since the string might contain NUL's,
886 * we now use fwrite().
887 */
888 #define ECHO do { if (fwrite( stl_yytext, (size_t) stl_yyleng, 1, stl_yyout )) {} } while (0)
889 #endif
890
891 /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
892 * is returned in "result".
893 */
894 #ifndef YY_INPUT
895 #define YY_INPUT(buf,result,max_size) \
896 if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
897 { \
898 int c = '*'; \
899 int n; \
900 for ( n = 0; n < max_size && \
901 (c = getc( stl_yyin )) != EOF && c != '\n'; ++n ) \
902 buf[n] = (char) c; \
903 if ( c == '\n' ) \
904 buf[n++] = (char) c; \
905 if ( c == EOF && ferror( stl_yyin ) ) \
906 YY_FATAL_ERROR( "input in flex scanner failed" ); \
907 result = n; \
908 } \
909 else \
910 { \
911 errno=0; \
912 while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, stl_yyin)) == 0 && ferror(stl_yyin)) \
913 { \
914 if( errno != EINTR) \
915 { \
916 YY_FATAL_ERROR( "input in flex scanner failed" ); \
917 break; \
918 } \
919 errno=0; \
920 clearerr(stl_yyin); \
921 } \
922 }\
923 \
924
925 #endif
926
927 /* No semi-colon after return; correct usage is to write "yyterminate();" -
928 * we don't want an extra ';' after the "return" because that will cause
929 * some compilers to complain about unreachable statements.
930 */
931 #ifndef yyterminate
932 #define yyterminate() return YY_NULL
933 #endif
934
935 /* Number of entries by which start-condition stack grows. */
936 #ifndef YY_START_STACK_INCR
937 #define YY_START_STACK_INCR 25
938 #endif
939
940 /* Report a fatal error. */
941 #ifndef YY_FATAL_ERROR
942 #define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
943 #endif
944
945 /* end tables serialization structures and prototypes */
946
947 /* Default declaration of generated scanner - a define so the user can
948 * easily add parameters.
949 */
950 #ifndef YY_DECL
951 #define YY_DECL_IS_OURS 1
952
953 extern int stl_yylex (void);
954
955 #define YY_DECL int stl_yylex (void)
956 #endif /* !YY_DECL */
957
958 /* Code executed at the beginning of each rule, after stl_yytext and stl_yyleng
959 * have been set up.
960 */
961 #ifndef YY_USER_ACTION
962 #define YY_USER_ACTION
963 #endif
964
965 /* Code executed at the end of each rule. */
966 #ifndef YY_BREAK
967 #define YY_BREAK /*LINTED*/break;
968 #endif
969
970 #define YY_RULE_SETUP \
971 if ( stl_yyleng > 0 ) \
972 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
973 (stl_yytext[stl_yyleng - 1] == '\n'); \
974 YY_USER_ACTION
975
976 /** The main scanner function which does all the work.
977 */
978 YY_DECL
979 {
980 yy_state_type yy_current_state;
981 char *yy_cp, *yy_bp;
982 int yy_act;
983
984 if ( !(yy_init) )
985 {
986 (yy_init) = 1;
987
988 #ifdef YY_USER_INIT
989 YY_USER_INIT;
990 #endif
991
992 if ( ! (yy_start) )
993 (yy_start) = 1; /* first start state */
994
995 if ( ! stl_yyin )
996 stl_yyin = stdin;
997
998 if ( ! stl_yyout )
999 stl_yyout = stdout;
1000
1001 if ( ! YY_CURRENT_BUFFER ) {
1002 stl_yyensure_buffer_stack ();
1003 YY_CURRENT_BUFFER_LVALUE =
1004 stl_yy_create_buffer(stl_yyin,YY_BUF_SIZE );
1005 }
1006
1007 stl_yy_load_buffer_state( );
1008 }
1009
1010 {
1011 #line 148 "steel.l"
1012
1013
1014 #line 1014 "steel.cpp"
1015
1016 while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */
1017 {
1018 (yy_more_len) = 0;
1019 if ( (yy_more_flag) )
1020 {
1021 (yy_more_len) = (int) ((yy_c_buf_p) - (yytext_ptr));
1022 (yy_more_flag) = 0;
1023 }
1024 yy_cp = (yy_c_buf_p);
1025
1026 /* Support of stl_yytext. */
1027 *yy_cp = (yy_hold_char);
1028
1029 /* yy_bp points to the position in yy_ch_buf of the start of
1030 * the current run.
1031 */
1032 yy_bp = yy_cp;
1033
1034 yy_current_state = (yy_start);
1035 yy_current_state += YY_AT_BOL();
1036 yy_match:
1037 do
1038 {
1039 YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
1040 if ( yy_accept[yy_current_state] )
1041 {
1042 (yy_last_accepting_state) = yy_current_state;
1043 (yy_last_accepting_cpos) = yy_cp;
1044 }
1045 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1046 {
1047 yy_current_state = (int) yy_def[yy_current_state];
1048 if ( yy_current_state >= 142 )
1049 yy_c = yy_meta[yy_c];
1050 }
1051 yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
1052 ++yy_cp;
1053 }
1054 while ( yy_current_state != 141 );
1055 yy_cp = (yy_last_accepting_cpos);
1056 yy_current_state = (yy_last_accepting_state);
1057
1058 yy_find_action:
1059 yy_act = yy_accept[yy_current_state];
1060
1061 YY_DO_BEFORE_ACTION;
1062
1063 do_action: /* This label is used only to access EOF actions. */
1064
1065 switch ( yy_act )
1066 { /* beginning of action switch */
1067 case 0: /* must back up */
1068 /* undo the effects of YY_DO_BEFORE_ACTION */
1069 *yy_cp = (yy_hold_char);
1070 yy_cp = (yy_last_accepting_cpos);
1071 yy_current_state = (yy_last_accepting_state);
1072 goto yy_find_action;
1073
1074 case 1:
1075 *yy_cp = (yy_hold_char); /* undo effects of setting up stl_yytext */
1076 (yy_c_buf_p) = yy_cp -= 1;
1077 YY_DO_BEFORE_ACTION; /* set up stl_yytext again */
1078 YY_RULE_SETUP
1079 #line 150 "steel.l"
1080 {
1081 char * ptr = stl_yytext;
1082 while ( *ptr == ' ' || *ptr == '\t' ) ptr++;
1083 while ( *ptr != ' ' && *ptr != '\t' ) ptr++;
1084 while ( *ptr && (*ptr == ' ' || *ptr == '\t') ) ptr++;
1085 if ( strlen(ptr) > 0 ) {
1086 reader->info = (char *) malloc(strlen(ptr)+1);
1087 assert(reader->info);
1088 strcpy(reader->info, ptr);
1089 reader->pending = STL_INIT_INFO;
1090 } else {
1091 reader->pending = STL_NO_PENDING;
1092 }
1093 return STL_BEGIN;
1094 }
1095 YY_BREAK
1096 case 2:
1097 *yy_cp = (yy_hold_char); /* undo effects of setting up stl_yytext */
1098 (yy_c_buf_p) = yy_cp -= 1;
1099 YY_DO_BEFORE_ACTION; /* set up stl_yytext again */
1100 YY_RULE_SETUP
1101 #line 166 "steel.l"
1102 {
1103 reader->hickups = 0; /* reset flex hickup counter */
1104 assert(reader->facet != NULL);
1105 if ( reader->info != NULL ) {
1106 free(reader->info);
1107 reader->info = NULL;
1108 }
1109 stl_parse_real_triple(stl_yytext, &(reader->facet->nx), &(reader->facet->ny), &(reader->facet->nz));
1110 }
1111 YY_BREAK
1112 case 3:
1113 *yy_cp = (yy_hold_char); /* undo effects of setting up stl_yytext */
1114 (yy_c_buf_p) = yy_cp -= 1;
1115 YY_DO_BEFORE_ACTION; /* set up stl_yytext again */
1116 YY_RULE_SETUP
1117 #line 176 "steel.l"
1118 {
1119 reader->vertex = 0;
1120 }
1121 YY_BREAK
1122 case 4:
1123 *yy_cp = (yy_hold_char); /* undo effects of setting up stl_yytext */
1124 (yy_c_buf_p) = yy_cp -= 1;
1125 YY_DO_BEFORE_ACTION; /* set up stl_yytext again */
1126 YY_RULE_SETUP
1127 #line 180 "steel.l"
1128 {
1129 stl_real x = 0.0f, y = 0.0f, z = 0.0f;
1130 assert(reader->facet != NULL);
1131 stl_parse_real_triple(stl_yytext, &x, &y, &z);
1132 switch ( reader->vertex ) {
1133 case 0:
1134 reader->facet->v1x = x;
1135 reader->facet->v1y = y;
1136 reader->facet->v1z = z;
1137 break;
1138 case 1:
1139 reader->facet->v2x = x;
1140 reader->facet->v2y = y;
1141 reader->facet->v2z = z;
1142 break;
1143 case 2:
1144 reader->facet->v3x = x;
1145 reader->facet->v3y = y;
1146 reader->facet->v3z = z;
1147 break;
1148 default:
1149 reader->error = "vertex data error";
1150 return STL_ERROR;
1151 }
1152 reader->vertex++;
1153 }
1154 YY_BREAK
1155 case 5:
1156 *yy_cp = (yy_hold_char); /* undo effects of setting up stl_yytext */
1157 (yy_c_buf_p) = yy_cp -= 1;
1158 YY_DO_BEFORE_ACTION; /* set up stl_yytext again */
1159 YY_RULE_SETUP
1160 #line 207 "steel.l"
1161 {
1162 }
1163 YY_BREAK
1164 case 6:
1165 *yy_cp = (yy_hold_char); /* undo effects of setting up stl_yytext */
1166 (yy_c_buf_p) = yy_cp -= 1;
1167 YY_DO_BEFORE_ACTION; /* set up stl_yytext again */
1168 YY_RULE_SETUP
1169 #line 210 "steel.l"
1170 {
1171 reader->pending = STL_NO_PENDING;
1172 return STL_FACET;
1173 }
1174 YY_BREAK
1175 case 7:
1176 *yy_cp = (yy_hold_char); /* undo effects of setting up stl_yytext */
1177 (yy_c_buf_p) = yy_cp -= 1;
1178 YY_DO_BEFORE_ACTION; /* set up stl_yytext again */
1179 YY_RULE_SETUP
1180 #line 215 "steel.l"
1181 {
1182 char * ptr = stl_yytext;
1183 if ( reader->info != NULL ) {
1184 free(reader->info);
1185 reader->info = NULL;
1186 }
1187 /* FIXME: this scanning is now incorrect if not "endsolid" */
1188 while ( *ptr && (*ptr == ' ' || *ptr == '\t') ) ptr++;
1189 while ( *ptr && (*ptr != ' ' && *ptr != '\t') ) ptr++;
1190 while ( *ptr && (*ptr == ' ' || *ptr == '\t') ) ptr++;
1191 if ( strlen(ptr) > 0 ) {
1192 reader->info = (char *) malloc(strlen(ptr)+1);
1193 assert(reader->info);
1194 strcpy(reader->info, ptr);
1195 reader->pending = STL_END;
1196 return STL_EXIT_INFO;
1197 }
1198 reader->pending = STL_NO_PENDING;
1199 return STL_END;
1200 }
1201 YY_BREAK
1202 case 8:
1203 YY_RULE_SETUP
1204 #line 236 "steel.l"
1205 {
1206 }
1207 YY_BREAK
1208 case 9:
1209 YY_RULE_SETUP
1210 #line 239 "steel.l"
1211 {
1212 }
1213 YY_BREAK
1214 case 10:
1215 /* rule 10 can match eol */
1216 YY_RULE_SETUP
1217 #line 242 "steel.l"
1218 {
1219 reader->linenum++;
1220 }
1221 YY_BREAK
1222 case 11:
1223 *yy_cp = (yy_hold_char); /* undo effects of setting up stl_yytext */
1224 (yy_c_buf_p) = yy_cp -= 1;
1225 YY_DO_BEFORE_ACTION; /* set up stl_yytext again */
1226 YY_RULE_SETUP
1227 #line 246 "steel.l"
1228 {
1229 /* SIM extension - enable commenting out lines with # */
1230 }
1231 YY_BREAK
1232 case 12:
1233 YY_RULE_SETUP
1234 #line 250 "steel.l"
1235 {
1236 /* 8k into sphere.stl, flex needs some help to get going again... */
1237 if ( reader->hickups < 32 ) {
1238 reader->hickups += 1;
1239 yymore(); /* where is stl_yymore()? */
1240 } else {
1241 reader->error = "unknown problem - too many flex hickups";
1242 reader->pending = STL_ERROR;
1243 return STL_ERROR;
1244 }
1245 }
1246 YY_BREAK
1247 case YY_STATE_EOF(INITIAL):
1248 #line 262 "steel.l"
1249 {
1250 reader->error = "premature end of file";
1251 reader->pending = STL_ERROR;
1252 return STL_ERROR;
1253 }
1254 YY_BREAK
1255 case 13:
1256 YY_RULE_SETUP
1257 #line 268 "steel.l"
1258 ECHO;
1259 YY_BREAK
1260 #line 1260 "steel.cpp"
1261
1262 case YY_END_OF_BUFFER:
1263 {
1264 /* Amount of text matched not including the EOB char. */
1265 int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
1266
1267 /* Undo the effects of YY_DO_BEFORE_ACTION. */
1268 *yy_cp = (yy_hold_char);
1269 YY_RESTORE_YY_MORE_OFFSET
1270
1271 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
1272 {
1273 /* We're scanning a new file or input source. It's
1274 * possible that this happened because the user
1275 * just pointed stl_yyin at a new source and called
1276 * stl_yylex(). If so, then we have to assure
1277 * consistency between YY_CURRENT_BUFFER and our
1278 * globals. Here is the right place to do so, because
1279 * this is the first action (other than possibly a
1280 * back-up) that will match for the new input source.
1281 */
1282 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1283 YY_CURRENT_BUFFER_LVALUE->yy_input_file = stl_yyin;
1284 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
1285 }
1286
1287 /* Note that here we test for yy_c_buf_p "<=" to the position
1288 * of the first EOB in the buffer, since yy_c_buf_p will
1289 * already have been incremented past the NUL character
1290 * (since all states make transitions on EOB to the
1291 * end-of-buffer state). Contrast this with the test
1292 * in input().
1293 */
1294 if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1295 { /* This was really a NUL. */
1296 yy_state_type yy_next_state;
1297
1298 (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
1299
1300 yy_current_state = yy_get_previous_state( );
1301
1302 /* Okay, we're now positioned to make the NUL
1303 * transition. We couldn't have
1304 * yy_get_previous_state() go ahead and do it
1305 * for us because it doesn't know how to deal
1306 * with the possibility of jamming (and we don't
1307 * want to build jamming into it because then it
1308 * will run more slowly).
1309 */
1310
1311 yy_next_state = yy_try_NUL_trans( yy_current_state );
1312
1313 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1314
1315 if ( yy_next_state )
1316 {
1317 /* Consume the NUL. */
1318 yy_cp = ++(yy_c_buf_p);
1319 yy_current_state = yy_next_state;
1320 goto yy_match;
1321 }
1322
1323 else
1324 {
1325 yy_cp = (yy_last_accepting_cpos);
1326 yy_current_state = (yy_last_accepting_state);
1327 goto yy_find_action;
1328 }
1329 }
1330
1331 else switch ( yy_get_next_buffer( ) )
1332 {
1333 case EOB_ACT_END_OF_FILE:
1334 {
1335 (yy_did_buffer_switch_on_eof) = 0;
1336
1337 if ( stl_yywrap( ) )
1338 {
1339 /* Note: because we've taken care in
1340 * yy_get_next_buffer() to have set up
1341 * stl_yytext, we can now set up
1342 * yy_c_buf_p so that if some total
1343 * hoser (like flex itself) wants to
1344 * call the scanner after we return the
1345 * YY_NULL, it'll still work - another
1346 * YY_NULL will get returned.
1347 */
1348 (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
1349
1350 yy_act = YY_STATE_EOF(YY_START);
1351 goto do_action;
1352 }
1353
1354 else
1355 {
1356 if ( ! (yy_did_buffer_switch_on_eof) )
1357 YY_NEW_FILE;
1358 }
1359 break;
1360 }
1361
1362 case EOB_ACT_CONTINUE_SCAN:
1363 (yy_c_buf_p) =
1364 (yytext_ptr) + yy_amount_of_matched_text;
1365
1366 yy_current_state = yy_get_previous_state( );
1367
1368 yy_cp = (yy_c_buf_p);
1369 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1370 goto yy_match;
1371
1372 case EOB_ACT_LAST_MATCH:
1373 (yy_c_buf_p) =
1374 &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
1375
1376 yy_current_state = yy_get_previous_state( );
1377
1378 yy_cp = (yy_c_buf_p);
1379 yy_bp = (yytext_ptr) + YY_MORE_ADJ;
1380 goto yy_find_action;
1381 }
1382 break;
1383 }
1384
1385 default:
1386 YY_FATAL_ERROR(
1387 "fatal flex scanner internal error--no action found" );
1388 } /* end of action switch */
1389 } /* end of scanning one token */
1390 } /* end of user's declarations */
1391 } /* end of stl_yylex */
1392
1393 /* yy_get_next_buffer - try to read in a new buffer
1394 *
1395 * Returns a code representing an action:
1396 * EOB_ACT_LAST_MATCH -
1397 * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
1398 * EOB_ACT_END_OF_FILE - end of file
1399 */
1400 static int yy_get_next_buffer (void)
1401 {
1402 char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
1403 char *source = (yytext_ptr);
1404 int number_to_move, i;
1405 int ret_val;
1406
1407 if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
1408 YY_FATAL_ERROR(
1409 "fatal flex scanner internal error--end of buffer missed" );
1410
1411 if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
1412 { /* Don't try to fill the buffer, so this is an EOF. */
1413 if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
1414 {
1415 /* We matched a single character, the EOB, so
1416 * treat this as a final EOF.
1417 */
1418 return EOB_ACT_END_OF_FILE;
1419 }
1420
1421 else
1422 {
1423 /* We matched some text prior to the EOB, first
1424 * process it.
1425 */
1426 return EOB_ACT_LAST_MATCH;
1427 }
1428 }
1429
1430 /* Try to read more data. */
1431
1432 /* First move last chars to start of buffer. */
1433 number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);
1434
1435 for ( i = 0; i < number_to_move; ++i )
1436 *(dest++) = *(source++);
1437
1438 if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
1439 /* don't do the read, it's not guaranteed to return an EOF,
1440 * just force an EOF
1441 */
1442 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
1443
1444 else
1445 {
1446 int num_to_read =
1447 YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
1448
1449 while ( num_to_read <= 0 )
1450 { /* Not enough room in the buffer - grow it. */
1451
1452 /* just a shorter name for the current buffer */
1453 YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
1454
1455 int yy_c_buf_p_offset =
1456 (int) ((yy_c_buf_p) - b->yy_ch_buf);
1457
1458 if ( b->yy_is_our_buffer )
1459 {
1460 int new_size = b->yy_buf_size * 2;
1461
1462 if ( new_size <= 0 )
1463 b->yy_buf_size += b->yy_buf_size / 8;
1464 else
1465 b->yy_buf_size *= 2;
1466
1467 b->yy_ch_buf = (char *)
1468 /* Include room in for 2 EOB chars. */
1469 stl_yyrealloc((void *) b->yy_ch_buf,(yy_size_t) (b->yy_buf_size + 2) );
1470 }
1471 else
1472 /* Can't grow it, we don't own it. */
1473 b->yy_ch_buf = NULL;
1474
1475 if ( ! b->yy_ch_buf )
1476 YY_FATAL_ERROR(
1477 "fatal error - scanner input buffer overflow" );
1478
1479 (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
1480
1481 num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
1482 number_to_move - 1;
1483
1484 }
1485
1486 if ( num_to_read > YY_READ_BUF_SIZE )
1487 num_to_read = YY_READ_BUF_SIZE;
1488
1489 /* Read in more data. */
1490 YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
1491 (yy_n_chars), num_to_read );
1492
1493 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1494 }
1495
1496 if ( (yy_n_chars) == 0 )
1497 {
1498 if ( number_to_move == YY_MORE_ADJ )
1499 {
1500 ret_val = EOB_ACT_END_OF_FILE;
1501 stl_yyrestart(stl_yyin );
1502 }
1503
1504 else
1505 {
1506 ret_val = EOB_ACT_LAST_MATCH;
1507 YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
1508 YY_BUFFER_EOF_PENDING;
1509 }
1510 }
1511
1512 else
1513 ret_val = EOB_ACT_CONTINUE_SCAN;
1514
1515 if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
1516 /* Extend the array by 50%, plus the number we really need. */
1517 int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
1518 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) stl_yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,(yy_size_t) new_size );
1519 if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
1520 YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
1521 }
1522
1523 (yy_n_chars) += number_to_move;
1524 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
1525 YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
1526
1527 (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
1528
1529 return ret_val;
1530 }
1531
1532 /* yy_get_previous_state - get the state just before the EOB char was reached */
1533
yy_get_previous_state(void)1534 static yy_state_type yy_get_previous_state (void)
1535 {
1536 yy_state_type yy_current_state;
1537 char *yy_cp;
1538
1539 yy_current_state = (yy_start);
1540 yy_current_state += YY_AT_BOL();
1541
1542 for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
1543 {
1544 YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
1545 if ( yy_accept[yy_current_state] )
1546 {
1547 (yy_last_accepting_state) = yy_current_state;
1548 (yy_last_accepting_cpos) = yy_cp;
1549 }
1550 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1551 {
1552 yy_current_state = (int) yy_def[yy_current_state];
1553 if ( yy_current_state >= 142 )
1554 yy_c = yy_meta[yy_c];
1555 }
1556 yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
1557 }
1558
1559 return yy_current_state;
1560 }
1561
1562 /* yy_try_NUL_trans - try to make a transition on the NUL character
1563 *
1564 * synopsis
1565 * next_state = yy_try_NUL_trans( current_state );
1566 */
yy_try_NUL_trans(yy_state_type yy_current_state)1567 static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
1568 {
1569 int yy_is_jam;
1570 char *yy_cp = (yy_c_buf_p);
1571
1572 YY_CHAR yy_c = 1;
1573 if ( yy_accept[yy_current_state] )
1574 {
1575 (yy_last_accepting_state) = yy_current_state;
1576 (yy_last_accepting_cpos) = yy_cp;
1577 }
1578 while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
1579 {
1580 yy_current_state = (int) yy_def[yy_current_state];
1581 if ( yy_current_state >= 142 )
1582 yy_c = yy_meta[yy_c];
1583 }
1584 yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
1585 yy_is_jam = (yy_current_state == 141);
1586
1587 return yy_is_jam ? 0 : yy_current_state;
1588 }
1589
1590 #ifndef YY_NO_UNPUT
1591
1592 #endif
1593
1594 #ifndef YY_NO_INPUT
1595 #ifdef __cplusplus
yyinput(void)1596 static int yyinput (void)
1597 #else
1598 static int input (void)
1599 #endif
1600
1601 {
1602 int c;
1603
1604 *(yy_c_buf_p) = (yy_hold_char);
1605
1606 if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
1607 {
1608 /* yy_c_buf_p now points to the character we want to return.
1609 * If this occurs *before* the EOB characters, then it's a
1610 * valid NUL; if not, then we've hit the end of the buffer.
1611 */
1612 if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
1613 /* This was really a NUL. */
1614 *(yy_c_buf_p) = '\0';
1615
1616 else
1617 { /* need more input */
1618 int offset = (int) ((yy_c_buf_p) - (yytext_ptr));
1619 ++(yy_c_buf_p);
1620
1621 switch ( yy_get_next_buffer( ) )
1622 {
1623 case EOB_ACT_LAST_MATCH:
1624 /* This happens because yy_g_n_b()
1625 * sees that we've accumulated a
1626 * token and flags that we need to
1627 * try matching the token before
1628 * proceeding. But for input(),
1629 * there's no matching to consider.
1630 * So convert the EOB_ACT_LAST_MATCH
1631 * to EOB_ACT_END_OF_FILE.
1632 */
1633
1634 /* Reset buffer status. */
1635 stl_yyrestart(stl_yyin );
1636
1637 /*FALLTHROUGH*/
1638
1639 case EOB_ACT_END_OF_FILE:
1640 {
1641 if ( stl_yywrap( ) )
1642 return 0;
1643
1644 if ( ! (yy_did_buffer_switch_on_eof) )
1645 YY_NEW_FILE;
1646 #ifdef __cplusplus
1647 return yyinput();
1648 #else
1649 return input();
1650 #endif
1651 }
1652
1653 case EOB_ACT_CONTINUE_SCAN:
1654 (yy_c_buf_p) = (yytext_ptr) + offset;
1655 break;
1656 }
1657 }
1658 }
1659
1660 c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
1661 *(yy_c_buf_p) = '\0'; /* preserve stl_yytext */
1662 (yy_hold_char) = *++(yy_c_buf_p);
1663
1664 YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
1665
1666 return c;
1667 }
1668 #endif /* ifndef YY_NO_INPUT */
1669
1670 /** Immediately switch to a different input stream.
1671 * @param input_file A readable stream.
1672 *
1673 * @note This function does not reset the start condition to @c INITIAL .
1674 */
stl_yyrestart(FILE * input_file)1675 void stl_yyrestart (FILE * input_file )
1676 {
1677
1678 if ( ! YY_CURRENT_BUFFER ){
1679 stl_yyensure_buffer_stack ();
1680 YY_CURRENT_BUFFER_LVALUE =
1681 stl_yy_create_buffer(stl_yyin,YY_BUF_SIZE );
1682 }
1683
1684 stl_yy_init_buffer(YY_CURRENT_BUFFER,input_file );
1685 stl_yy_load_buffer_state( );
1686 }
1687
1688 /** Switch to a different input buffer.
1689 * @param new_buffer The new input buffer.
1690 *
1691 */
stl_yy_switch_to_buffer(YY_BUFFER_STATE new_buffer)1692 void stl_yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
1693 {
1694
1695 /* TODO. We should be able to replace this entire function body
1696 * with
1697 * stl_yypop_buffer_state();
1698 * stl_yypush_buffer_state(new_buffer);
1699 */
1700 stl_yyensure_buffer_stack ();
1701 if ( YY_CURRENT_BUFFER == new_buffer )
1702 return;
1703
1704 if ( YY_CURRENT_BUFFER )
1705 {
1706 /* Flush out information for old buffer. */
1707 *(yy_c_buf_p) = (yy_hold_char);
1708 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1709 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1710 }
1711
1712 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1713 stl_yy_load_buffer_state( );
1714
1715 /* We don't actually know whether we did this switch during
1716 * EOF (stl_yywrap()) processing, but the only time this flag
1717 * is looked at is after stl_yywrap() is called, so it's safe
1718 * to go ahead and always set it.
1719 */
1720 (yy_did_buffer_switch_on_eof) = 1;
1721 }
1722
stl_yy_load_buffer_state(void)1723 static void stl_yy_load_buffer_state (void)
1724 {
1725 (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
1726 (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
1727 stl_yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
1728 (yy_hold_char) = *(yy_c_buf_p);
1729 }
1730
1731 /** Allocate and initialize an input buffer state.
1732 * @param file A readable stream.
1733 * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
1734 *
1735 * @return the allocated buffer state.
1736 */
stl_yy_create_buffer(FILE * file,int size)1737 YY_BUFFER_STATE stl_yy_create_buffer (FILE * file, int size )
1738 {
1739 YY_BUFFER_STATE b;
1740
1741 b = (YY_BUFFER_STATE) stl_yyalloc(sizeof( struct yy_buffer_state ) );
1742 if ( ! b )
1743 YY_FATAL_ERROR( "out of dynamic memory in stl_yy_create_buffer()" );
1744
1745 b->yy_buf_size = size;
1746
1747 /* yy_ch_buf has to be 2 characters longer than the size given because
1748 * we need to put in 2 end-of-buffer characters.
1749 */
1750 b->yy_ch_buf = (char *) stl_yyalloc((yy_size_t) (b->yy_buf_size + 2) );
1751 if ( ! b->yy_ch_buf )
1752 YY_FATAL_ERROR( "out of dynamic memory in stl_yy_create_buffer()" );
1753
1754 b->yy_is_our_buffer = 1;
1755
1756 stl_yy_init_buffer(b,file );
1757
1758 return b;
1759 }
1760
1761 /** Destroy the buffer.
1762 * @param b a buffer created with stl_yy_create_buffer()
1763 *
1764 */
stl_yy_delete_buffer(YY_BUFFER_STATE b)1765 void stl_yy_delete_buffer (YY_BUFFER_STATE b )
1766 {
1767
1768 if ( ! b )
1769 return;
1770
1771 if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
1772 YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
1773
1774 if ( b->yy_is_our_buffer )
1775 stl_yyfree((void *) b->yy_ch_buf );
1776
1777 stl_yyfree((void *) b );
1778 }
1779
1780 /* Initializes or reinitializes a buffer.
1781 * This function is sometimes called more than once on the same buffer,
1782 * such as during a stl_yyrestart() or at EOF.
1783 */
stl_yy_init_buffer(YY_BUFFER_STATE b,FILE * file)1784 static void stl_yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
1785
1786 {
1787 int oerrno = errno;
1788
1789 stl_yy_flush_buffer(b );
1790
1791 b->yy_input_file = file;
1792 b->yy_fill_buffer = 1;
1793
1794 /* If b is the current buffer, then stl_yy_init_buffer was _probably_
1795 * called from stl_yyrestart() or through yy_get_next_buffer.
1796 * In that case, we don't want to reset the lineno or column.
1797 */
1798 if (b != YY_CURRENT_BUFFER){
1799 b->yy_bs_lineno = 1;
1800 b->yy_bs_column = 0;
1801 }
1802
1803 b->yy_is_interactive = 0;
1804
1805 errno = oerrno;
1806 }
1807
1808 /** Discard all buffered characters. On the next scan, YY_INPUT will be called.
1809 * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
1810 *
1811 */
stl_yy_flush_buffer(YY_BUFFER_STATE b)1812 void stl_yy_flush_buffer (YY_BUFFER_STATE b )
1813 {
1814 if ( ! b )
1815 return;
1816
1817 b->yy_n_chars = 0;
1818
1819 /* We always need two end-of-buffer characters. The first causes
1820 * a transition to the end-of-buffer state. The second causes
1821 * a jam in that state.
1822 */
1823 b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
1824 b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
1825
1826 b->yy_buf_pos = &b->yy_ch_buf[0];
1827
1828 b->yy_at_bol = 1;
1829 b->yy_buffer_status = YY_BUFFER_NEW;
1830
1831 if ( b == YY_CURRENT_BUFFER )
1832 stl_yy_load_buffer_state( );
1833 }
1834
1835 /** Pushes the new state onto the stack. The new state becomes
1836 * the current state. This function will allocate the stack
1837 * if necessary.
1838 * @param new_buffer The new state.
1839 *
1840 */
stl_yypush_buffer_state(YY_BUFFER_STATE new_buffer)1841 void stl_yypush_buffer_state (YY_BUFFER_STATE new_buffer )
1842 {
1843 if (new_buffer == NULL)
1844 return;
1845
1846 stl_yyensure_buffer_stack();
1847
1848 /* This block is copied from stl_yy_switch_to_buffer. */
1849 if ( YY_CURRENT_BUFFER )
1850 {
1851 /* Flush out information for old buffer. */
1852 *(yy_c_buf_p) = (yy_hold_char);
1853 YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
1854 YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
1855 }
1856
1857 /* Only push if top exists. Otherwise, replace top. */
1858 if (YY_CURRENT_BUFFER)
1859 (yy_buffer_stack_top)++;
1860 YY_CURRENT_BUFFER_LVALUE = new_buffer;
1861
1862 /* copied from stl_yy_switch_to_buffer. */
1863 stl_yy_load_buffer_state( );
1864 (yy_did_buffer_switch_on_eof) = 1;
1865 }
1866
1867 /** Removes and deletes the top of the stack, if present.
1868 * The next element becomes the new top.
1869 *
1870 */
stl_yypop_buffer_state(void)1871 void stl_yypop_buffer_state (void)
1872 {
1873 if (!YY_CURRENT_BUFFER)
1874 return;
1875
1876 stl_yy_delete_buffer(YY_CURRENT_BUFFER );
1877 YY_CURRENT_BUFFER_LVALUE = NULL;
1878 if ((yy_buffer_stack_top) > 0)
1879 --(yy_buffer_stack_top);
1880
1881 if (YY_CURRENT_BUFFER) {
1882 stl_yy_load_buffer_state( );
1883 (yy_did_buffer_switch_on_eof) = 1;
1884 }
1885 }
1886
1887 /* Allocates the stack if it does not exist.
1888 * Guarantees space for at least one push.
1889 */
stl_yyensure_buffer_stack(void)1890 static void stl_yyensure_buffer_stack (void)
1891 {
1892 yy_size_t num_to_alloc;
1893
1894 if (!(yy_buffer_stack)) {
1895
1896 /* First allocation is just for 2 elements, since we don't know if this
1897 * scanner will even need a stack. We use 2 instead of 1 to avoid an
1898 * immediate realloc on the next call.
1899 */
1900 num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */
1901 (yy_buffer_stack) = (struct yy_buffer_state**)stl_yyalloc
1902 (num_to_alloc * sizeof(struct yy_buffer_state*)
1903 );
1904 if ( ! (yy_buffer_stack) )
1905 YY_FATAL_ERROR( "out of dynamic memory in stl_yyensure_buffer_stack()" );
1906
1907 memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
1908
1909 (yy_buffer_stack_max) = num_to_alloc;
1910 (yy_buffer_stack_top) = 0;
1911 return;
1912 }
1913
1914 if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
1915
1916 /* Increase the buffer to prepare for a possible push. */
1917 yy_size_t grow_size = 8 /* arbitrary grow size */;
1918
1919 num_to_alloc = (yy_buffer_stack_max) + grow_size;
1920 (yy_buffer_stack) = (struct yy_buffer_state**)stl_yyrealloc
1921 ((yy_buffer_stack),
1922 num_to_alloc * sizeof(struct yy_buffer_state*)
1923 );
1924 if ( ! (yy_buffer_stack) )
1925 YY_FATAL_ERROR( "out of dynamic memory in stl_yyensure_buffer_stack()" );
1926
1927 /* zero only the new slots.*/
1928 memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
1929 (yy_buffer_stack_max) = num_to_alloc;
1930 }
1931 }
1932
1933 #ifndef YY_EXIT_FAILURE
1934 #define YY_EXIT_FAILURE 2
1935 #endif
1936
yy_fatal_error(const char * msg)1937 static void yynoreturn yy_fatal_error (const char* msg )
1938 {
1939 (void) fprintf( stderr, "%s\n", msg );
1940 exit( YY_EXIT_FAILURE );
1941 }
1942
1943 /* Redefine yyless() so it works in section 3 code. */
1944
1945 #undef yyless
1946 #define yyless(n) \
1947 do \
1948 { \
1949 /* Undo effects of setting up stl_yytext. */ \
1950 int yyless_macro_arg = (n); \
1951 YY_LESS_LINENO(yyless_macro_arg);\
1952 stl_yytext[stl_yyleng] = (yy_hold_char); \
1953 (yy_c_buf_p) = stl_yytext + yyless_macro_arg; \
1954 (yy_hold_char) = *(yy_c_buf_p); \
1955 *(yy_c_buf_p) = '\0'; \
1956 stl_yyleng = yyless_macro_arg; \
1957 } \
1958 while ( 0 )
1959
1960 /* Accessor methods (get/set functions) to struct members. */
1961
1962 /** Get the current line number.
1963 *
1964 */
stl_yyget_lineno(void)1965 int stl_yyget_lineno (void)
1966 {
1967
1968 return stl_yylineno;
1969 }
1970
1971 /** Get the input stream.
1972 *
1973 */
stl_yyget_in(void)1974 FILE *stl_yyget_in (void)
1975 {
1976 return stl_yyin;
1977 }
1978
1979 /** Get the output stream.
1980 *
1981 */
stl_yyget_out(void)1982 FILE *stl_yyget_out (void)
1983 {
1984 return stl_yyout;
1985 }
1986
1987 /** Get the length of the current token.
1988 *
1989 */
stl_yyget_leng(void)1990 int stl_yyget_leng (void)
1991 {
1992 return stl_yyleng;
1993 }
1994
1995 /** Get the current token.
1996 *
1997 */
1998
stl_yyget_text(void)1999 char *stl_yyget_text (void)
2000 {
2001 return stl_yytext;
2002 }
2003
2004 /** Set the current line number.
2005 * @param _line_number line number
2006 *
2007 */
stl_yyset_lineno(int _line_number)2008 void stl_yyset_lineno (int _line_number )
2009 {
2010
2011 stl_yylineno = _line_number;
2012 }
2013
2014 /** Set the input stream. This does not discard the current
2015 * input buffer.
2016 * @param _in_str A readable stream.
2017 *
2018 * @see stl_yy_switch_to_buffer
2019 */
stl_yyset_in(FILE * _in_str)2020 void stl_yyset_in (FILE * _in_str )
2021 {
2022 stl_yyin = _in_str ;
2023 }
2024
stl_yyset_out(FILE * _out_str)2025 void stl_yyset_out (FILE * _out_str )
2026 {
2027 stl_yyout = _out_str ;
2028 }
2029
stl_yyget_debug(void)2030 int stl_yyget_debug (void)
2031 {
2032 return stl_yy_flex_debug;
2033 }
2034
stl_yyset_debug(int _bdebug)2035 void stl_yyset_debug (int _bdebug )
2036 {
2037 stl_yy_flex_debug = _bdebug ;
2038 }
2039
yy_init_globals(void)2040 static int yy_init_globals (void)
2041 {
2042 /* Initialization is the same as for the non-reentrant scanner.
2043 * This function is called from stl_yylex_destroy(), so don't allocate here.
2044 */
2045
2046 (yy_buffer_stack) = NULL;
2047 (yy_buffer_stack_top) = 0;
2048 (yy_buffer_stack_max) = 0;
2049 (yy_c_buf_p) = NULL;
2050 (yy_init) = 0;
2051 (yy_start) = 0;
2052
2053 /* Defined in main.c */
2054 #ifdef YY_STDINIT
2055 stl_yyin = stdin;
2056 stl_yyout = stdout;
2057 #else
2058 stl_yyin = NULL;
2059 stl_yyout = NULL;
2060 #endif
2061
2062 /* For future reference: Set errno on error, since we are called by
2063 * stl_yylex_init()
2064 */
2065 return 0;
2066 }
2067
2068 /* stl_yylex_destroy is for both reentrant and non-reentrant scanners. */
stl_yylex_destroy(void)2069 int stl_yylex_destroy (void)
2070 {
2071
2072 /* Pop the buffer stack, destroying each element. */
2073 while(YY_CURRENT_BUFFER){
2074 stl_yy_delete_buffer(YY_CURRENT_BUFFER );
2075 YY_CURRENT_BUFFER_LVALUE = NULL;
2076 stl_yypop_buffer_state();
2077 }
2078
2079 /* Destroy the stack itself. */
2080 stl_yyfree((yy_buffer_stack) );
2081 (yy_buffer_stack) = NULL;
2082
2083 /* Reset the globals. This is important in a non-reentrant scanner so the next time
2084 * stl_yylex() is called, initialization will occur. */
2085 yy_init_globals( );
2086
2087 return 0;
2088 }
2089
2090 /*
2091 * Internal utility routines.
2092 */
2093
2094 #ifndef yytext_ptr
yy_flex_strncpy(char * s1,const char * s2,int n)2095 static void yy_flex_strncpy (char* s1, const char * s2, int n )
2096 {
2097
2098 int i;
2099 for ( i = 0; i < n; ++i )
2100 s1[i] = s2[i];
2101 }
2102 #endif
2103
2104 #ifdef YY_NEED_STRLEN
yy_flex_strlen(const char * s)2105 static int yy_flex_strlen (const char * s )
2106 {
2107 int n;
2108 for ( n = 0; s[n]; ++n )
2109 ;
2110
2111 return n;
2112 }
2113 #endif
2114
stl_yyalloc(yy_size_t size)2115 void *stl_yyalloc (yy_size_t size )
2116 {
2117 return malloc(size);
2118 }
2119
stl_yyrealloc(void * ptr,yy_size_t size)2120 void *stl_yyrealloc (void * ptr, yy_size_t size )
2121 {
2122
2123 /* The cast to (char *) in the following accommodates both
2124 * implementations that use char* generic pointers, and those
2125 * that use void* generic pointers. It works with the latter
2126 * because both ANSI C and C++ allow castless assignment from
2127 * any pointer type to void*, and deal with argument conversions
2128 * as though doing an assignment.
2129 */
2130 return realloc(ptr, size);
2131 }
2132
stl_yyfree(void * ptr)2133 void stl_yyfree (void * ptr )
2134 {
2135 free( (char *) ptr ); /* see stl_yyrealloc() for (char *) cast */
2136 }
2137
2138 #define YYTABLES_NAME "yytables"
2139
2140 #line 268 "steel.l"
2141
2142
2143 #ifndef FALSE
2144 #define FALSE 0
2145 #define TRUE (!FALSE)
2146 #endif
2147
2148 /* ********************************************************************** */
2149 /* internal functions */
2150
2151 #define STL_SCAN_TO_REAL(strptr) \
2152 do { \
2153 int roll = TRUE; \
2154 while ( roll ) { \
2155 switch ( *strptr ) { \
2156 case '\0': \
2157 return FALSE; \
2158 case '0': case '1': case '2': case '3': case '4': \
2159 case '5': case '6': case '7': case '8': case '9': \
2160 case '-': case '+': case '.': \
2161 roll = FALSE; \
2162 break; \
2163 default: \
2164 strptr++; \
2165 break; \
2166 } \
2167 } \
2168 } while ( FALSE )
2169
2170 #define STL_SCAN_TO_WHITESPACE(strptr) \
2171 do { \
2172 int roll = TRUE; \
2173 while ( roll ) { \
2174 switch ( *strptr ) { \
2175 case '\0': \
2176 return FALSE; \
2177 case ' ': case '\t': \
2178 roll = FALSE; \
2179 break; \
2180 default: \
2181 strptr++; \
2182 break; \
2183 } \
2184 } \
2185 } while ( FALSE )
2186
2187 int
stl_parse_real_triple(char * text,stl_real * a,stl_real * b,stl_real * c)2188 stl_parse_real_triple(char * text, stl_real * a, stl_real * b, stl_real * c)
2189 {
2190 char * real1, * real2, * real3;
2191 STL_SCAN_TO_REAL(text);
2192 real1 = text;
2193 STL_SCAN_TO_WHITESPACE(text);
2194 STL_SCAN_TO_REAL(text);
2195 real2 = text;
2196 STL_SCAN_TO_WHITESPACE(text);
2197 STL_SCAN_TO_REAL(text);
2198 real3 = text;
2199 if ( a ) *a = (stl_real) strtod(real1, NULL);
2200 if ( b ) *b = (stl_real) strtod(real2, NULL);
2201 if ( c ) *c = (stl_real) strtod(real3, NULL);
2202 return TRUE;
2203 }
2204
2205 static
2206 int
stl_host_is_bigendian(void)2207 stl_host_is_bigendian(void)
2208 {
2209 static int retval = -1;
2210 if ( retval == -1 ) {
2211 union {
2212 unsigned char bytes[4];
2213 uint32_t word;
2214 } data;
2215 data.word = 0x01;
2216 if ( data.bytes[3] == 0x01 )
2217 retval = TRUE;
2218 else
2219 retval = FALSE;
2220 }
2221 return retval;
2222 }
2223
2224 static
2225 uint32_t
stl_ntohl(uint32_t word)2226 stl_ntohl(uint32_t word)
2227 {
2228 if ( stl_host_is_bigendian() ) {
2229 uint32_t swapped =
2230 ((word & 0x000000ff) << 24) | ((word & 0x0000ff00) << 8) |
2231 ((word & 0x00ff0000) >> 8) | ((word & 0xff000000) >> 24);
2232 return swapped;
2233 }
2234 return word;
2235 }
2236
2237 static
2238 void
stl_reader_binary_facet(stl_reader * reader)2239 stl_reader_binary_facet(stl_reader * reader)
2240 {
2241 int readok = 1;
2242 // FIXME: use one 50-byte read operation instead
2243 union {
2244 unsigned char bytes[4];
2245 uint32_t data;
2246 float real;
2247 } data;
2248
2249
2250 assert(reader != NULL);
2251 assert(reader->file != NULL);
2252 assert(reader->facet != NULL);
2253 readok &= fread(&data.bytes, 4, 1, reader->file);
2254 data.data = stl_ntohl(data.data);
2255 reader->facet->nx = data.real;
2256 readok &= fread(&data.bytes, 4, 1, reader->file);
2257 data.data = stl_ntohl(data.data);
2258 reader->facet->ny = data.real;
2259 readok &= fread(&data.bytes, 4, 1, reader->file);
2260 data.data = stl_ntohl(data.data);
2261 reader->facet->nz = data.real;
2262 readok &= fread(&data.bytes, 4, 1, reader->file);
2263 data.data = stl_ntohl(data.data);
2264 reader->facet->v1x = data.real;
2265 readok &= fread(&data.bytes, 4, 1, reader->file);
2266 data.data = stl_ntohl(data.data);
2267 reader->facet->v1y = data.real;
2268 readok &= fread(&data.bytes, 4, 1, reader->file);
2269 data.data = stl_ntohl(data.data);
2270 reader->facet->v1z = data.real;
2271 readok &= fread(&data.bytes, 4, 1, reader->file);
2272 data.data = stl_ntohl(data.data);
2273 reader->facet->v2x = data.real;
2274 readok &= fread(&data.bytes, 4, 1, reader->file);
2275 data.data = stl_ntohl(data.data);
2276 reader->facet->v2y = data.real;
2277 readok &= fread(&data.bytes, 4, 1, reader->file);
2278 data.data = stl_ntohl(data.data);
2279 reader->facet->v2z = data.real;
2280 readok &= fread(&data.bytes, 4, 1, reader->file);
2281 data.data = stl_ntohl(data.data);
2282 reader->facet->v3x = data.real;
2283 readok &= fread(&data.bytes, 4, 1, reader->file);
2284 data.data = stl_ntohl(data.data);
2285 reader->facet->v3y = data.real;
2286 readok &= fread(&data.bytes, 4, 1, reader->file);
2287 data.data = stl_ntohl(data.data);
2288 reader->facet->v3z = data.real;
2289 readok &= fread(&data.bytes, 2, 1, reader->file);
2290 /* byteswap? */
2291 reader->facet->color = data.bytes[0] | (data.bytes[1] << 8);
2292 /* fprintf(stderr, " color : 0x%04x\n", reader->facet->color); */
2293 reader->facets++;
2294 }
2295
2296 static
2297 int
stl_writer_put_binary_facet(stl_writer * writer,stl_facet * facet)2298 stl_writer_put_binary_facet(stl_writer * writer, stl_facet * facet)
2299 {
2300 int writeok = 1;
2301 union {
2302 unsigned char bytes[4];
2303 uint32_t data;
2304 float real;
2305 } data;
2306 assert(writer != NULL);
2307 assert(writer->file != NULL);
2308 assert(writer->facet != NULL);
2309 data.real = writer->facet->nx;
2310 data.data = stl_ntohl(data.data);
2311 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2312 data.real = writer->facet->ny;
2313 data.data = stl_ntohl(data.data);
2314 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2315 data.real = writer->facet->nz;
2316 data.data = stl_ntohl(data.data);
2317 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2318 data.real = writer->facet->v1x;
2319 data.data = stl_ntohl(data.data);
2320 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2321 data.real = writer->facet->v1y;
2322 data.data = stl_ntohl(data.data);
2323 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2324 data.real = writer->facet->v1z;
2325 data.data = stl_ntohl(data.data);
2326 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2327 data.real = writer->facet->v2x;
2328 data.data = stl_ntohl(data.data);
2329 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2330 data.real = writer->facet->v2y;
2331 data.data = stl_ntohl(data.data);
2332 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2333 data.real = writer->facet->v2z;
2334 data.data = stl_ntohl(data.data);
2335 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2336 data.real = writer->facet->v3x;
2337 data.data = stl_ntohl(data.data);
2338 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2339 data.real = writer->facet->v3y;
2340 data.data = stl_ntohl(data.data);
2341 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2342 data.real = writer->facet->v3z;
2343 data.data = stl_ntohl(data.data);
2344 writeok &= fwrite(&data.bytes, 4, 1, writer->file);
2345
2346 data.bytes[0] = writer->facet->color & 0xff;
2347 data.bytes[1] = (writer->facet->color >> 8) & 0xff;
2348 /* byteswap? */
2349 writeok &= fwrite(&data.bytes, 2, 1, writer->file);
2350 /* fprintf(stderr, " color : 0x%04x\n", reader->facet->color); */
2351
2352 return TRUE;
2353 }
2354
2355 /* ********************************************************************** */
2356
2357 /* @STL_STEEL_MAJOR_VERSION@
2358 This define is the major part (#.-.-) of the steel release version number.
2359 It is provided for knowing which version number you link with so it can
2360 be compared to the steel version loaded at runtime.
2361 */
2362
2363 /* @STL_STEEL_MINOR_VERSION@
2364 This define is the minor part (-.#.-) of the steel release version number.
2365 It is provided for knowing which version number you link with so it can
2366 be compared to the steel version loaded at runtime.
2367 */
2368
2369 /* @STL_STEEL_MICRO_VERSION@
2370 This define is the micro part (-.-.#) of the steel release version number.
2371 It is provided for knowing which version number you link with so it can
2372 be compared to the steel version loaded at runtime.
2373 */
2374
2375 /* @STL_STEEL_ABI_VERSION@
2376 This define is the ABI version of the steel library you link with.
2377 It is provided for knowing which steel ABI you link with so it can be
2378 compared to the ABI of the steel library loaded at runtime.
2379 */
2380
2381 /* @STL_STEEL_ABI_REVISION@
2382 This define is the revision of the steel ABI version you link with.
2383 It is provided for knowing which steel ABI you link with so it can be
2384 compared to the ABI of the steel library loaded at runtime.
2385 */
2386
2387 /* @STL_STEEL_ABI_AGE@
2388 This define is the age of the steel ABI you link with.
2389 It is provided for knowing which steel ABI you link with so it can be
2390 compared to the ABI of the steel library loaded at runtime.
2391 */
2392
2393 /* ********************************************************************** */
2394
2395 /* @stl_steel_major@
2396 This function returns the major part (#.-.-) of the steel release version
2397 number.
2398 */
2399
2400 int
stl_steel_major(void)2401 stl_steel_major(void)
2402 {
2403 return STL_STEEL_MAJOR;
2404 }
2405
2406 /* @stl_steel_minor@
2407 This function returns the minor part (-.#.-) of the steel release version
2408 number.
2409 */
2410
2411 int
stl_steel_minor(void)2412 stl_steel_minor(void)
2413 {
2414 return STL_STEEL_MINOR;
2415 }
2416
2417 /* @stl_steel_micro@
2418 This function returns the micro part (-.-.#) of the steel release version
2419 number.
2420 */
2421
2422 int
stl_steel_micro(void)2423 stl_steel_micro(void)
2424 {
2425 return STL_STEEL_MICRO;
2426 }
2427
2428 /* @stl_steel_abi_version@
2429 This function returns the version of the steel library ABI. It is the same
2430 as the libtool "current" number.
2431 */
2432
2433 int
stl_steel_abi_version(void)2434 stl_steel_abi_version(void)
2435 {
2436 return STL_STEEL_ABI_VERSION;
2437 }
2438
2439 /* @stl_steel_abi_revision@
2440 This function returns the revision of the current steel library ABI version.
2441 It is the same as the libtool "revision" number.
2442 */
2443
2444 int
stl_steel_abi_revision(void)2445 stl_steel_abi_revision(void)
2446 {
2447 return STL_STEEL_ABI_REVISION;
2448 }
2449
2450 /* @stl_steel_abi_age@
2451 This function returns the age of the current steel library ABI.
2452 It is essentially the same as the libtool "age" number.
2453 */
2454
2455 int
stl_steel_abi_age(void)2456 stl_steel_abi_age(void)
2457 {
2458 return STL_STEEL_ABI_AGE;
2459 }
2460
2461 /* @stl_steel_abi_supported@
2462 This function returns TRUE if the requested ABI version is supported and
2463 FALSE otherwise.
2464 */
2465
2466 int
stl_steel_abi_supported(int version,int revision)2467 stl_steel_abi_supported(int version, int revision)
2468 {
2469 if ( (version < STL_STEEL_ABI_VERSION) &&
2470 (version >= (STL_STEEL_ABI_VERSION - STL_STEEL_ABI_AGE)) )
2471 return TRUE;
2472 if ( (version == STL_STEEL_ABI_VERSION) &&
2473 (revision <= STL_STEEL_ABI_REVISION) )
2474 return TRUE;
2475 return FALSE;
2476 }
2477
2478 /* ********************************************************************** */
2479
2480 /* @stl_facet_create_uninitialized@
2481 */
2482
2483 stl_facet *
stl_facet_create_uninitialized(void)2484 stl_facet_create_uninitialized(void)
2485 {
2486 stl_facet * facet;
2487 facet = (stl_facet *) malloc(sizeof(stl_facet));
2488 assert(facet);
2489 return facet;
2490 }
2491
2492 /* @stl_facet_create@
2493 */
2494
2495 stl_facet *
stl_facet_create(void)2496 stl_facet_create(void)
2497 {
2498 stl_facet * facet;
2499 facet = stl_facet_create_uninitialized();
2500 facet->nx = facet->ny = facet->nz = 0.0f;
2501 facet->v1x = facet->v1y = facet->v1z = 0.0f;
2502 facet->v2x = facet->v2y = facet->v2z = 0.0f;
2503 facet->v3x = facet->v3y = facet->v3z = 0.0f;
2504 facet->color = STL_NO_COLOR;
2505 return facet;
2506 } /* stl_facet_create() */
2507
2508 /* @stl_facet_clone@
2509 */
2510
2511 stl_facet *
stl_facet_clone(stl_facet * facet)2512 stl_facet_clone(stl_facet * facet)
2513 {
2514 stl_facet * clone;
2515 assert(facet != NULL);
2516 clone = stl_facet_create_uninitialized();
2517 stl_facet_copy(facet, clone);
2518 return clone;
2519 } /* stl_facet_clone() */
2520
2521 /* @stl_facet_destroy@
2522 */
2523
2524 void
stl_facet_destroy(stl_facet * facet)2525 stl_facet_destroy(stl_facet * facet)
2526 {
2527 assert(facet != NULL);
2528 free(facet);
2529 } /* stl_facet_destroy() */
2530
2531 /* @stl_facet_copy@
2532 */
2533
2534 void
stl_facet_copy(stl_facet * source,stl_facet * target)2535 stl_facet_copy(stl_facet * source, stl_facet * target)
2536 {
2537 assert(source != NULL && target != NULL);
2538 target->nx = source->nx;
2539 target->ny = source->ny;
2540 target->nz = source->nz;
2541 target->v1x = source->v1x;
2542 target->v1y = source->v1y;
2543 target->v1z = source->v1z;
2544 target->v2x = source->v2x;
2545 target->v2y = source->v2y;
2546 target->v2z = source->v2z;
2547 target->v3x = source->v3x;
2548 target->v3y = source->v3y;
2549 target->v3z = source->v3z;
2550 target->color = source->color;
2551 } /* stl_facet_copy() */
2552
2553 /* @stl_facet_set_normal@
2554 */
2555
2556 void
stl_facet_set_normal(stl_facet * facet,stl_real x,stl_real y,stl_real z)2557 stl_facet_set_normal(stl_facet * facet, stl_real x, stl_real y, stl_real z)
2558 {
2559 assert(facet != NULL);
2560 facet->nx = x;
2561 facet->ny = y;
2562 facet->nz = z;
2563 } /* stl_facet_set_normal() */
2564
2565 /* @stl_facet_get_normal@
2566 */
2567
2568 void
stl_facet_get_normal(stl_facet * facet,stl_real * x,stl_real * y,stl_real * z)2569 stl_facet_get_normal(stl_facet * facet, stl_real * x, stl_real * y, stl_real * z)
2570 {
2571 assert(facet != NULL);
2572 if ( x ) *x = facet->nx;
2573 if ( y ) *y = facet->ny;
2574 if ( z ) *z = facet->nz;
2575 } /* stl_facet_get_normal() */
2576
2577 /* @stl_facet_set_vertex1@
2578 */
2579
2580 void
stl_facet_set_vertex1(stl_facet * facet,stl_real x,stl_real y,stl_real z)2581 stl_facet_set_vertex1(stl_facet * facet, stl_real x, stl_real y, stl_real z)
2582 {
2583 assert(facet != NULL);
2584 facet->v1x = x;
2585 facet->v1y = y;
2586 facet->v1z = z;
2587 } /* stl_facet_set_vertex1() */
2588
2589 /* @stl_facet_get_vertex1@
2590 */
2591
2592 void
stl_facet_get_vertex1(stl_facet * facet,stl_real * x,stl_real * y,stl_real * z)2593 stl_facet_get_vertex1(stl_facet * facet, stl_real * x, stl_real * y, stl_real * z)
2594 {
2595 assert(facet != NULL);
2596 if ( x ) *x = facet->v1x;
2597 if ( y ) *y = facet->v1y;
2598 if ( z ) *z = facet->v1z;
2599 } /* stl_facet_get_vertex1() */
2600
2601 /* @stl_facet_set_vertex2@
2602 */
2603
2604 void
stl_facet_set_vertex2(stl_facet * facet,stl_real x,stl_real y,stl_real z)2605 stl_facet_set_vertex2(stl_facet * facet, stl_real x, stl_real y, stl_real z)
2606 {
2607 assert(facet != NULL);
2608 facet->v2x = x;
2609 facet->v2y = y;
2610 facet->v2z = z;
2611 } /* stl_facet_set_vertex2() */
2612
2613 /* @stl_facet_get_vertex2@
2614 */
2615
2616 void
stl_facet_get_vertex2(stl_facet * facet,stl_real * x,stl_real * y,stl_real * z)2617 stl_facet_get_vertex2(stl_facet * facet, stl_real * x, stl_real * y, stl_real * z)
2618 {
2619 assert(facet != NULL);
2620 if ( x ) *x = facet->v2x;
2621 if ( y ) *y = facet->v2y;
2622 if ( z ) *z = facet->v2z;
2623 } /* stl_facet_get_vertex2() */
2624
2625 /* @stl_facet_set_vertex3@
2626 */
2627
2628 void
stl_facet_set_vertex3(stl_facet * facet,stl_real x,stl_real y,stl_real z)2629 stl_facet_set_vertex3(stl_facet * facet, stl_real x, stl_real y, stl_real z)
2630 {
2631 assert(facet != NULL);
2632 facet->v3x = x;
2633 facet->v3y = y;
2634 facet->v3z = z;
2635 } /* stl_facet_set_vertex3() */
2636
2637 /* @stl_facet_get_vertex3@
2638 */
2639
2640 void
stl_facet_get_vertex3(stl_facet * facet,stl_real * x,stl_real * y,stl_real * z)2641 stl_facet_get_vertex3(stl_facet * facet, stl_real * x, stl_real * y, stl_real * z)
2642 {
2643 assert(facet != NULL);
2644 if ( x ) *x = facet->v3x;
2645 if ( y ) *y = facet->v3y;
2646 if ( z ) *z = facet->v3z;
2647 } /* stl_facet_get_vertex3() */
2648
2649 /* @stl_facet_get_padding@
2650 */
2651
2652 void
stl_facet_set_padding(stl_facet * facet,unsigned int padding)2653 stl_facet_set_padding(stl_facet * facet, unsigned int padding)
2654 {
2655 assert(facet != NULL);
2656 } /* stl_facet_set_padding() */
2657
2658 /* @stl_facet_get_padding@
2659 */
2660
2661 unsigned int
stl_facet_get_padding(stl_facet * facet)2662 stl_facet_get_padding(stl_facet * facet)
2663 {
2664 assert(facet != NULL);
2665 return 0;
2666 } /* stl_facet_get_padding() */
2667
2668 /* @stl_facet_set_color@
2669 */
2670
2671 void
stl_facet_set_color(stl_facet * facet,unsigned int rgb)2672 stl_facet_set_color(stl_facet * facet, unsigned int rgb)
2673 {
2674 assert(facet != NULL);
2675 facet->color = rgb;
2676 } /* stl_facet_set_color() */
2677
2678 /* @stl_facet_get_color@
2679 This function returns the color of the facet, if one has been set.
2680 */
2681
2682 unsigned int
stl_facet_get_color(stl_facet * facet)2683 stl_facet_get_color(stl_facet * facet)
2684 {
2685 assert(facet != NULL);
2686 return facet->color;
2687 } /* stl_facet_get_color() */
2688
2689 /* ********************************************************************** */
2690
2691 /* @stl_reader_create@
2692 */
2693
2694 stl_reader *
stl_reader_create(const char * filename)2695 stl_reader_create(const char * filename)
2696 {
2697 stl_reader * reader;
2698 int id;
2699 long length;
2700 unsigned char bytes[4];
2701 assert(filename != NULL);
2702 reader = (stl_reader *) malloc(sizeof(stl_reader));
2703 assert(reader);
2704 reader->filename = NULL;
2705 reader->file = NULL;
2706 reader->info = NULL;
2707 reader->facet = NULL;
2708 reader->error = NULL;
2709 reader->flags = 0;
2710 reader->linenum = 0;
2711 reader->pending = STL_NO_PENDING;
2712 reader->vertex = 0;
2713 reader->facets = 0;
2714 reader->facets_total = 0;
2715 reader->hickups = 0;
2716 reader->file = fopen(filename, "rb");
2717 if ( reader->file == NULL ) {
2718 free(reader);
2719 return NULL;
2720 }
2721 reader->filename = (char *) malloc(strlen(filename)+1);
2722 assert(reader->filename);
2723 strcpy(reader->filename, filename);
2724 reader->facet = stl_facet_create();
2725
2726 /* check if file is binary stl file first */
2727 do {
2728 int readok = 1;
2729 /* FIXME: scan header for "COLOR=" for the "Materialise" color extension */
2730 reader->linenum = 0;
2731 readok &= !fseek(reader->file, 0, SEEK_END);
2732 length = ftell(reader->file);
2733 readok &= !fseek(reader->file, 80, SEEK_SET);
2734 readok &= fread(bytes, 4, 1, reader->file);
2735 reader->facets_total =
2736 (bytes[3] << 24) | (bytes[2] << 16) | (bytes[1] << 8) | bytes[0];
2737 if ( (84 + (reader->facets_total * 50)) != length ) {
2738 break; /* not a binary stl file */
2739 }
2740 reader->flags |= STL_BINARY;
2741 readok &= !fseek(reader->file, 0, SEEK_SET);
2742 reader->info = static_cast<char *>(malloc(81));
2743 assert(reader->info);
2744 readok &= fread(reader->info, 80, 1, reader->file);
2745 reader->info[80] = '\0';
2746 readok &= !fseek(reader->file, 84, SEEK_SET); /* position of first facet */
2747 reader->pending = STL_INIT_INFO;
2748 return reader;
2749 } while ( FALSE );
2750
2751 /* now try ascii stl */
2752 do {
2753 int readok = 1;
2754 reader->linenum = 1;
2755 reader->file = freopen(reader->filename, "r", reader->file);
2756 assert(reader->file);
2757 id = stl_reader_peek(reader);
2758 if ( id == STL_ERROR ) {
2759 break; /* not an ascii stl file */
2760 }
2761 readok &= !fseek(reader->file, 0, SEEK_SET);
2762 stl_yyrestart(reader->file);
2763 reader->pending = STL_NO_PENDING;
2764 return reader;
2765 } while ( FALSE );
2766
2767 /* the file is not an stl file */
2768 (void)fclose(reader->file);
2769 free(reader->filename);
2770 reader->filename = NULL;
2771 stl_facet_destroy(reader->facet);
2772 reader->facet = NULL;
2773 free(reader);
2774 /* could return a reader with pending STL_ERROR and error message instead? */
2775 return NULL;
2776 } /* stl_reader_create() */
2777
2778 /* @stl_reader_destroy@
2779 */
2780
2781 void
stl_reader_destroy(stl_reader * reader)2782 stl_reader_destroy(stl_reader * reader)
2783 {
2784 assert(reader != NULL);
2785 if ( reader->filename ) {
2786 free(reader->filename);
2787 reader->filename = NULL;
2788 }
2789 if ( reader->info ) {
2790 free(reader->info);
2791 reader->info = NULL;
2792 }
2793 if ( reader->file ) {
2794 fclose(reader->file);
2795 reader->file = NULL;
2796 }
2797 if ( reader->facet ) {
2798 stl_facet_destroy(reader->facet);
2799 reader->facet = NULL;
2800 }
2801 free(reader);
2802 } /* stl_reader_destroy() */
2803
2804 /* @stl_reader_flags@
2805 */
2806
2807 unsigned int
stl_reader_flags(stl_reader * reader)2808 stl_reader_flags(stl_reader * reader)
2809 {
2810 assert(reader != NULL);
2811 return reader->flags;
2812 } /* stl_reader_flags() */
2813
2814 /* @stl_reader_peek@
2815 */
2816
2817 int
stl_reader_peek(stl_reader * reader)2818 stl_reader_peek(stl_reader * reader)
2819 {
2820 int peekval;
2821 assert(reader != NULL);
2822 if ( reader->pending != STL_NO_PENDING ) {
2823 peekval = reader->pending;
2824 if ( reader->pending == STL_END ) {
2825 reader->pending = STL_ERROR;
2826 }
2827 if ( reader->pending == STL_BEGIN ) {
2828 if ( reader->info != NULL ) {
2829 reader->pending = STL_INIT_INFO;
2830 } else {
2831 reader->pending = STL_NO_PENDING;
2832 }
2833 } else if ( reader->pending != STL_ERROR ) {
2834 reader->pending = STL_NO_PENDING;
2835 }
2836 return peekval;
2837 }
2838 if ( !(reader->flags & STL_BINARY) ) {
2839 stl_yyin = reader->file;
2840 peekval = stl_scan(reader);
2841 } else {
2842 if ( reader->facets == reader->facets_total ) {
2843 return STL_END;
2844 }
2845 stl_reader_binary_facet(reader);
2846 return STL_FACET;
2847 }
2848 if ( reader->error ) {
2849 return STL_ERROR;
2850 }
2851 return peekval;
2852 } /* stl_reader_peek() */
2853
2854 /* @stl_reader_get_info@
2855 */
2856
2857 const char *
stl_reader_get_info(stl_reader * reader)2858 stl_reader_get_info(stl_reader * reader)
2859 {
2860 assert(reader != NULL);
2861 return reader->info;
2862 } /* stl_reader_get_info() */
2863
2864 /* @stl_reader_get_facet@
2865 */
2866
2867 stl_facet *
stl_reader_get_facet(stl_reader * reader)2868 stl_reader_get_facet(stl_reader * reader)
2869 {
2870 assert(reader != NULL);
2871 assert(reader->facet != NULL);
2872 return stl_facet_clone(reader->facet);
2873 } /* stl_reader_get_facet() */
2874
2875 /* @stl_reader_fill_facet@
2876 */
2877
2878 void
stl_reader_fill_facet(stl_reader * reader,stl_facet * facet)2879 stl_reader_fill_facet(stl_reader * reader, stl_facet * facet)
2880 {
2881 assert(reader != NULL);
2882 assert(reader->facet != NULL);
2883 facet->nx = reader->facet->nx;
2884 facet->ny = reader->facet->ny;
2885 facet->nz = reader->facet->nz;
2886 facet->v1x = reader->facet->v1x;
2887 facet->v1y = reader->facet->v1y;
2888 facet->v1z = reader->facet->v1z;
2889 facet->v2x = reader->facet->v2x;
2890 facet->v2y = reader->facet->v2y;
2891 facet->v2z = reader->facet->v2z;
2892 facet->v3x = reader->facet->v3x;
2893 facet->v3y = reader->facet->v3y;
2894 facet->v3z = reader->facet->v3z;
2895 facet->color = reader->facet->color;
2896 } /* stl_reader_fill_facet() */
2897
2898 /* @stl_reader_get_error@
2899 */
2900
2901 const char *
stl_reader_get_error(stl_reader * reader)2902 stl_reader_get_error(stl_reader * reader)
2903 {
2904 assert(reader != NULL);
2905 return reader->error;
2906 } /* stl_reader_get_error() */
2907
2908 /* @stl_reader_get_line_number@
2909 */
2910
2911 int
stl_reader_get_line_number(stl_reader * reader)2912 stl_reader_get_line_number(stl_reader * reader)
2913 {
2914 assert(reader != NULL);
2915 return reader->linenum;
2916 }
2917
2918 /* ********************************************************************** */
2919
2920 /* @stl_writer_create@
2921 */
2922
2923 stl_writer *
stl_writer_create(const char * filename,unsigned int flags)2924 stl_writer_create(const char * filename, unsigned int flags)
2925 {
2926 stl_writer * writer;
2927 assert(filename != NULL);
2928 writer = (stl_writer *) malloc(sizeof(stl_writer));
2929 assert(writer);
2930 writer->filename = (char *) malloc(strlen(filename)+1);
2931 assert(writer->filename);
2932 strcpy(writer->filename, filename);
2933 writer->flags = (flags & STL_PUBLIC_FLAGS);
2934 if ( writer->flags & STL_BINARY ) {
2935 writer->file = fopen(writer->filename, "wb");
2936 assert(writer->file);
2937 writer->linenum = 0;
2938 } else {
2939 writer->file = fopen(writer->filename, "w");
2940 assert(writer->file);
2941 writer->linenum = 1;
2942 }
2943 assert(writer->file);
2944 writer->facets = 0;
2945 writer->error = NULL;
2946 writer->facet = NULL;
2947 writer->info = NULL;
2948 return writer;
2949 } /* stl_writer_create() */
2950
2951 /* @stl_writer_destroy@
2952 */
2953
2954 int
stl_writer_destroy(stl_writer * writer)2955 stl_writer_destroy(stl_writer * writer)
2956 {
2957 assert(writer != NULL);
2958 assert(writer->file != NULL);
2959 if ( writer->flags & STL_BINARY ) {
2960 int writeok = 1;
2961 unsigned char bytes[4];
2962 bytes[3] = (writer->facets >> 24) & 0xff;
2963 bytes[2] = (writer->facets >> 16) & 0xff;
2964 bytes[1] = (writer->facets >> 8) & 0xff;
2965 bytes[0] = writer->facets & 0xff;
2966 writeok &= !fflush(writer->file);
2967 writeok &= !fseek(writer->file, 80, SEEK_SET);
2968 writeok &= fwrite(bytes, 4, 1, writer->file);
2969 } else {
2970 fprintf(writer->file, "endsolid\n");
2971 writer->linenum++;
2972 }
2973 fclose(writer->file);
2974 writer->file = NULL;
2975 if ( writer->info != NULL ) {
2976 free(writer->info);
2977 writer->info = NULL;
2978 }
2979 if ( writer->facet != NULL ) {
2980 stl_facet_destroy(writer->facet);
2981 writer->facet = NULL;
2982 }
2983 free(writer);
2984 return STL_OK;
2985 } /* stl_writer_destroy() */
2986
2987 /* @stl_writer_flags@
2988 */
2989
2990 unsigned int
stl_writer_get_flags(stl_writer * writer)2991 stl_writer_get_flags(stl_writer * writer)
2992 {
2993 assert(writer != NULL);
2994 return writer->flags & STL_PUBLIC_FLAGS;
2995 } /* stl_writer_flags() */
2996
2997 /* @stl_writer_put_info@
2998 */
2999
3000 int
stl_writer_set_info(stl_writer * writer,const char * info)3001 stl_writer_set_info(stl_writer * writer, const char * info)
3002 {
3003 assert(writer != NULL);
3004 assert(writer->file != NULL);
3005 if ( writer->info != NULL ) {
3006 free(writer->info);
3007 writer->info = NULL;
3008 }
3009 if ( info == NULL ) {
3010 return STL_OK;
3011 }
3012 if ( writer->facets != 0 ) {
3013 writer->error =
3014 "programming error - info must be set before writing facets";
3015 return STL_ERROR;
3016 }
3017 if ( strlen(info) > 80 ) {
3018 writer->error = "too long info string";
3019 return STL_ERROR;
3020 }
3021 writer->info = (char *) malloc(strlen(info)+1);
3022 assert(writer->info);
3023 strcpy(writer->info, info);
3024 return STL_OK;
3025 } /* stl_writer_put_info() */
3026
3027 /* @stl_writer_set_facet@
3028 */
3029
3030 void
stl_writer_set_facet(stl_writer * writer,stl_facet * facet)3031 stl_writer_set_facet(stl_writer * writer, stl_facet * facet)
3032 {
3033 assert(writer);
3034 writer->facet = facet;
3035 }
3036
3037 /* @stl_writer_get_facet@
3038 */
3039
3040 stl_facet *
stl_writer_get_facet(stl_writer * writer)3041 stl_writer_get_facet(stl_writer * writer)
3042 {
3043 assert(writer);
3044 return writer->facet;
3045 }
3046
3047 /* @stl_writer_put_facet@
3048 */
3049
3050 int
stl_writer_put_facet(stl_writer * writer,stl_facet * facet)3051 stl_writer_put_facet(stl_writer * writer, stl_facet * facet)
3052 {
3053 assert(writer != NULL);
3054 assert(writer->file != NULL);
3055 assert(facet);
3056
3057 if ( writer->facets == 0 ) {
3058 /* write info */
3059 if ( writer->flags & STL_BINARY ) {
3060 /* FIXME: take color extension into account when constructing header */
3061 char header[84];
3062 memset(header, 0, 84);
3063 if ( writer->info ) {
3064 if ( strlen(writer->info) < 80 ) {
3065 strcpy(header, writer->info);
3066 }
3067 }
3068 if ( fwrite(header, 84, 1, writer->file) != 1 ) {
3069 writer->error = "writing header failed";
3070 return STL_ERROR;
3071 }
3072 } else {
3073 if ( writer->info ) {
3074 fprintf(writer->file, "solid %s\n", writer->info);
3075 free(writer->info);
3076 writer->info = NULL;
3077 } else {
3078 fprintf(writer->file, "solid\n");
3079 }
3080 }
3081 }
3082
3083 if ( writer->flags & STL_BINARY ) {
3084 stl_writer_put_binary_facet(writer, facet);
3085 } else {
3086 float x, y, z;
3087 stl_facet_get_normal(facet, &x, &y, &z);
3088 fprintf(writer->file, " facet normal %g %g %g\n", x, y, z);
3089 writer->linenum++;
3090 fprintf(writer->file, " outer loop\n");
3091 writer->linenum++;
3092 stl_facet_get_vertex1(facet, &x, &y, &z);
3093 fprintf(writer->file, " vertex %g %g %g\n", x, y, z);
3094 writer->linenum++;
3095 stl_facet_get_vertex2(facet, &x, &y, &z);
3096 fprintf(writer->file, " vertex %g %g %g\n", x, y, z);
3097 writer->linenum++;
3098 stl_facet_get_vertex3(facet, &x, &y, &z);
3099 fprintf(writer->file, " vertex %g %g %g\n", x, y, z);
3100 writer->linenum++;
3101 fprintf(writer->file, " endloop\n");
3102 writer->linenum++;
3103 fprintf(writer->file, " endfacet\n");
3104 writer->linenum++;
3105 }
3106 // fflush(writer->file);
3107 writer->facets++;
3108 return STL_OK;
3109 } /* stl_writer_put_facet() */
3110
3111 /* @stl_writer_get_error@
3112 This function returns the last error message for the writer object.
3113 */
3114
3115 const char *
stl_writer_get_error(stl_writer * writer)3116 stl_writer_get_error(stl_writer * writer)
3117 {
3118 assert(writer != NULL);
3119 return writer->error;
3120 } /* stl_writer_get_error() */
3121
3122 /* ********************************************************************** */
3123
3124