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