home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume18 / scene / part01 / scene.c < prev    next >
C/C++ Source or Header  |  1991-04-26  |  30KB  |  1,251 lines

  1. /* A lexical scanner generated by flex */
  2.  
  3. /* scanner skeleton version:
  4.  * $Header: /usr/fsys/odin/a/vern/flex/RCS/flex.skel,v 2.16 90/08/03 14:09:36 vern Exp $
  5.  */
  6.  
  7. #define FLEX_SCANNER
  8.  
  9. #include <stdio.h>
  10.  
  11.  
  12. /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
  13. #ifdef c_plusplus
  14. #ifndef __cplusplus
  15. #define __cplusplus
  16. #endif
  17. #endif
  18.  
  19.  
  20. #ifdef __cplusplus
  21.  
  22. #include <stdlib.h>
  23. #include <osfcn.h>
  24.  
  25. /* use prototypes in function declarations */
  26. #define YY_USE_PROTOS
  27.  
  28. /* the "const" storage-class-modifier is valid */
  29. #define YY_USE_CONST
  30.  
  31. #else    /* ! __cplusplus */
  32.  
  33. #ifdef __STDC__
  34.  
  35. #ifdef __GNUC__
  36. #include <stddef.h>
  37. void *malloc( size_t );
  38. void free( void* );
  39. #else
  40. #include <stdlib.h>
  41. #endif    /* __GNUC__ */
  42.  
  43. #define YY_USE_PROTOS
  44. #define YY_USE_CONST
  45.  
  46. #endif    /* __STDC__ */
  47. #endif    /* ! __cplusplus */
  48.  
  49.  
  50. #ifdef __TURBOC__
  51. #define YY_USE_CONST
  52. #endif
  53.  
  54.  
  55. #ifndef YY_USE_CONST
  56. #define const
  57. #endif
  58.  
  59.  
  60. #ifdef YY_USE_PROTOS
  61. #define YY_PROTO(proto) proto
  62. #else
  63. #define YY_PROTO(proto) ()
  64. /* we can't get here if it's an ANSI C compiler, or a C++ compiler,
  65.  * so it's got to be a K&R compiler, and therefore there's no standard
  66.  * place from which to include these definitions
  67.  */
  68. char *malloc();
  69. int free();
  70. int read();
  71. #endif
  72.  
  73.  
  74. /* amount of stuff to slurp up with each read */
  75. #ifndef YY_READ_BUF_SIZE
  76. #define YY_READ_BUF_SIZE 8192
  77. #endif
  78.  
  79. /* returned upon end-of-file */
  80. #define YY_END_TOK 0
  81.  
  82. /* copy whatever the last rule matched to the standard output */
  83.  
  84. /* cast to (char *) is because for 8-bit chars, yytext is (unsigned char *) */
  85. /* this used to be an fputs(), but since the string might contain NUL's,
  86.  * we now use fwrite()
  87.  */
  88. #define ECHO (void) fwrite( (char *) yytext, yyleng, 1, yyout )
  89.  
  90. /* gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
  91.  * is returned in "result".
  92.  */
  93. #define YY_INPUT(buf,result,max_size) \
  94.     if ( (result = read( fileno(yyin), (char *) buf, max_size )) < 0 ) \
  95.         YY_FATAL_ERROR( "read() in flex scanner failed" );
  96. #define YY_NULL 0
  97.  
  98. /* no semi-colon after return; correct usage is to write "yyterminate();" -
  99.  * we don't want an extra ';' after the "return" because that will cause
  100.  * some compilers to complain about unreachable statements.
  101.  */
  102. #define yyterminate() return ( YY_NULL )
  103.  
  104. /* report a fatal error */
  105.  
  106. /* The funky do-while is used to turn this macro definition into
  107.  * a single C statement (which needs a semi-colon terminator).
  108.  * This avoids problems with code like:
  109.  *
  110.  *     if ( something_happens )
  111.  *        YY_FATAL_ERROR( "oops, the something happened" );
  112.  *    else
  113.  *        everything_okay();
  114.  *
  115.  * Prior to using the do-while the compiler would get upset at the
  116.  * "else" because it interpreted the "if" statement as being all
  117.  * done when it reached the ';' after the YY_FATAL_ERROR() call.
  118.  */
  119.  
  120. #define YY_FATAL_ERROR(msg) \
  121.     do \
  122.         { \
  123.         (void) fputs( msg, stderr ); \
  124.         (void) putc( '\n', stderr ); \
  125.         exit( 1 ); \
  126.         } \
  127.     while ( 0 )
  128.  
  129. /* default yywrap function - always treat EOF as an EOF */
  130. #define yywrap() 1
  131.  
  132. /* enter a start condition.  This macro really ought to take a parameter,
  133.  * but we do it the disgusting crufty way forced on us by the ()-less
  134.  * definition of BEGIN
  135.  */
  136. #define BEGIN yy_start = 1 + 2 *
  137.  
  138. /* action number for EOF rule of a given start state */
  139. #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
  140.  
  141. /* special action meaning "start processing a new file" */
  142. #define YY_NEW_FILE \
  143.     do \
  144.         { \
  145.         yy_init_buffer( yy_current_buffer, yyin ); \
  146.         yy_load_buffer_state(); \
  147.         } \
  148.     while ( 0 )
  149.  
  150. /* default declaration of generated scanner - a define so the user can
  151.  * easily add parameters
  152.  */
  153. #define YY_DECL int yylex YY_PROTO(( void )) 
  154.  
  155. /* code executed at the end of each rule */
  156. #define YY_BREAK break;
  157.  
  158. #define YY_END_OF_BUFFER_CHAR 0
  159.  
  160. #ifndef YY_BUF_SIZE
  161. #define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of default input buffer */
  162. #endif
  163.  
  164. typedef struct yy_buffer_state *YY_BUFFER_STATE;
  165.  
  166. #define YY_CHAR char
  167. # line 1 "scene.l"
  168. #define INITIAL 0
  169. # line 2 "scene.l"
  170.  
  171. /*
  172.  * scene - a scene-file processor for TeX
  173.  */
  174.  
  175. /*
  176.  * Copyright 1991, Garrett A. Wollman
  177.  *
  178.  * The recipient is licensed to compile, modify, and distribute this work
  179.  * provided that this comment remains intact and unmodified in any such
  180.  * versions, and the documentation (such as it is) is included.
  181.  * Modified version must clearly be marked as such.
  182.  *
  183.  * If this program is of any use to anybody, I would appreciate hearing
  184.  * about it.  Please send E-mail to wollman@sadye.uvm.edu (in bangland,
  185.  * ...uunet!uvm-gen!griffin!wollman).
  186.  */
  187.  
  188. /* These prototypes are fairly standard... although it should
  189.  * probably be "void *" as the first parm to qsort()
  190.  */
  191. extern void volatile exit(int);
  192. extern void qsort(char *,int,int,int (*)(const void *,const void *));
  193.  
  194. int scene_no;
  195.  
  196. /*
  197.  * Look, I told you this was a quick hack, didn't I?
  198.  * The program doesn't even check if you overrun any
  199.  * of these fixed limits.  Boo! Hiss!  But I can't be
  200.  * bothered to do it right so long as it still works
  201.  * for me.
  202.  */
  203.  
  204. struct character {
  205.     char name[255];
  206.     short scenes[512];
  207.     int num_scenes;
  208. } chars[256];
  209.  
  210. struct scene {
  211.     char book[32];
  212.     int chars[64];
  213.     int num_chars;
  214.     int page;
  215.     char music[64];
  216.     char musicby[64];
  217. } scenes[640];
  218.  
  219. /* some more prototypes */
  220. static void add_char_to_scene(char *);
  221. static void write_scene(void);
  222. static void sort_scene_chars(void);
  223. static int sort_int_by_char(const void *,const void *);
  224. static int sort_char_by_name(const void *,const void *);
  225.  
  226. extern int strcmp(const char *,const char *);
  227. extern char *strcpy(char *,const char *);
  228. extern char *strcat(char *,const char *);
  229.  
  230. /* some more local data */
  231. char curr_book[256];
  232. int curr_page;
  233.  
  234. # line 68 "scene.l"
  235. static short int yy_nxt[][16] =
  236.     {
  237.         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  238.         0,    0,    0,    0,    0,    0,
  239.  
  240.         3,    4,    5,    6,    4,    7,    8,    9,   10,   11,
  241.        12,    7,    8,    9,   11,   12,
  242.  
  243.         3,    4,    5,    6,    4,    7,    8,    9,   10,   11,
  244.        12,    7,    8,    9,   11,   12,
  245.  
  246.        -3,   -3,   -3,   -3,   -3,   -3,   -3,   -3,   -3,   -3,
  247.        -3,   -3,   -3,   -3,   -3,   -3,
  248.  
  249.         3,   -4,   -4,   -4,   -4,   -4,   -4,   -4,   -4,   -4,
  250.        -4,   -4,   -4,   -4,   -4,   -4,
  251.  
  252.         3,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,   -5,
  253.        -5,   -5,   -5,   -5,   -5,   -5,
  254.  
  255.         3,   13,   14,   13,   15,   13,   13,   13,   13,   13,
  256.        13,   13,   13,   13,   13,   13,
  257.  
  258.         3,   16,   17,   16,   16,   16,   16,   16,   16,   16,
  259.        16,   16,   16,   16,   16,   16,
  260.  
  261.         3,   18,   17,   18,   18,   18,   18,   18,   18,   18,
  262.        18,   18,   18,   18,   18,   18,
  263.  
  264.         3,   19,   17,   19,   19,   19,   19,   19,   19,   19,
  265.        19,   19,   19,   19,   19,   19,
  266.  
  267.         3,  -10,   20,  -10,  -10,  -10,  -10,  -10,  -10,  -10,
  268.       -10,  -10,  -10,  -10,  -10,  -10,
  269.  
  270.         3,   21,   17,   21,   21,   21,   21,   21,   21,   21,
  271.        21,   21,   21,   21,   21,   21,
  272.  
  273.         3,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,  -12,
  274.       -12,  -12,  -12,  -12,  -12,  -12,
  275.  
  276.         3,   13,   13,   13,  -13,   13,   13,   13,   13,   13,
  277.        13,   13,   13,   13,   13,   13,
  278.  
  279.         3,   13,   13,   13,  -14,   13,   13,   13,   13,   13,
  280.        13,   13,   13,   13,   13,   13,
  281.  
  282.         3,  -15,  -15,  -15,   15,  -15,  -15,  -15,  -15,  -15,
  283.       -15,  -15,  -15,  -15,  -15,  -15,
  284.  
  285.         3,   16,  -16,   16,   16,   16,   16,   16,   16,   16,
  286.        16,   16,   16,   16,   16,   16,
  287.  
  288.         3,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,  -17,
  289.       -17,  -17,  -17,  -17,  -17,  -17,
  290.  
  291.         3,   18,  -18,   18,   18,   18,   18,   18,   18,   18,
  292.        18,   18,   18,   18,   18,   18,
  293.  
  294.         3,   19,  -19,   19,   19,   19,   19,   19,   19,   19,
  295.        19,   19,   19,   19,   19,   19,
  296.  
  297.         3,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,  -20,
  298.       -20,  -20,  -20,  -20,  -20,  -20,
  299.  
  300.         3,   21,  -21,   21,   21,   21,   21,   21,   21,   21,
  301.        21,   21,   21,   21,   21,   21
  302.  
  303.     } ;
  304.  
  305.  
  306. /* done after the current pattern has been matched and before the
  307.  * corresponding action - sets up yytext
  308.  */
  309. #define YY_DO_BEFORE_ACTION \
  310.     yytext = yy_bp; \
  311.     yyleng = yy_cp - yy_bp; \
  312.     yy_hold_char = *yy_cp; \
  313.     *yy_cp = '\0'; \
  314.     yy_c_buf_p = yy_cp;
  315.  
  316. #define EOB_ACT_CONTINUE_SCAN 0
  317. #define EOB_ACT_END_OF_FILE 1
  318. #define EOB_ACT_LAST_MATCH 2
  319.  
  320. /* return all but the first 'n' matched characters back to the input stream */
  321. #define yyless(n) \
  322.     do \
  323.         { \
  324.         /* undo effects of setting up yytext */ \
  325.         *yy_cp = yy_hold_char; \
  326.         yy_c_buf_p = yy_cp = yy_bp + n; \
  327.         YY_DO_BEFORE_ACTION; /* set up yytext again */ \
  328.         } \
  329.     while ( 0 )
  330.  
  331. #define unput(c) yyunput( c, yytext )
  332.  
  333.  
  334. struct yy_buffer_state
  335.     {
  336.     FILE *yy_input_file;
  337.  
  338.     YY_CHAR *yy_ch_buf;        /* input buffer */
  339.     YY_CHAR *yy_buf_pos;    /* current position in input buffer */
  340.  
  341.     /* size of input buffer in bytes, not including room for EOB characters*/
  342.     int yy_buf_size;    
  343.  
  344.     /* number of characters read into yy_ch_buf, not including EOB characters */
  345.     int yy_n_chars;
  346.  
  347.     int yy_eof_status;        /* whether we've seen an EOF on this buffer */
  348. #define EOF_NOT_SEEN 0
  349.     /* "pending" happens when the EOF has been seen but there's still
  350.      * some text process
  351.      */
  352. #define EOF_PENDING 1
  353. #define EOF_DONE 2
  354.     };
  355.  
  356. static YY_BUFFER_STATE yy_current_buffer;
  357.  
  358. /* we provide macros for accessing buffer states in case in the
  359.  * future we want to put the buffer states in a more general
  360.  * "scanner state"
  361.  */
  362. #define YY_CURRENT_BUFFER yy_current_buffer
  363.  
  364.  
  365. /* yy_hold_char holds the character lost when yytext is formed */
  366. static YY_CHAR yy_hold_char;
  367.  
  368. static int yy_n_chars;        /* number of characters read into yy_ch_buf */
  369.  
  370.  
  371.  
  372. #ifndef YY_USER_ACTION
  373. #define YY_USER_ACTION
  374. #endif
  375.  
  376. #ifndef YY_USER_INIT
  377. #define YY_USER_INIT
  378. #endif
  379.  
  380. extern YY_CHAR *yytext;
  381. extern int yyleng;
  382. extern FILE *yyin, *yyout;
  383.  
  384. YY_CHAR *yytext;
  385. int yyleng;
  386.  
  387. FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
  388.  
  389. #define YY_END_OF_BUFFER 13
  390. typedef int yy_state_type;
  391. static const short int yy_accept[22] =
  392.     {   0,
  393.         0,    0,   13,   11,    1,   11,   11,   11,   11,   11,
  394.        11,    2,    6,    6,    5,    8,    9,    4,    3,   10,
  395.         7
  396.     } ;
  397.  
  398. static const YY_CHAR yy_ec[128] =
  399.     {   0,
  400.         1,    1,    1,    1,    1,    1,    1,    1,    1,    2,
  401.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  402.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  403.         1,    1,    1,    1,    3,    1,    1,    1,    1,    1,
  404.         1,    1,    1,    1,    1,    1,    1,    4,    4,    4,
  405.         4,    4,    4,    4,    4,    4,    4,    1,    1,    1,
  406.         1,    1,    1,    1,    5,    6,    7,    1,    8,    1,
  407.         1,    1,    1,    1,    1,    1,    9,    1,    1,    1,
  408.         1,    1,   10,    1,    1,    1,    1,    1,    1,    1,
  409.         1,    1,    1,    1,    1,    1,   11,   12,   13,    1,
  410.  
  411.         8,    1,    1,    1,    1,    1,    1,    1,   14,    1,
  412.         1,    1,    1,    1,   15,    1,    1,    1,    1,    1,
  413.         1,    1,    1,    1,    1,    1,    1
  414.     } ;
  415.  
  416. /* the intent behind this definition is that it'll catch
  417.  * any uses of REJECT which flex missed
  418.  */
  419. #define REJECT reject_used_but_not_detected
  420. #define yymore() yymore_used_but_not_detected
  421. #define YY_MORE_ADJ 0
  422.  
  423. /* these variables are all declared out here so that section 3 code can
  424.  * manipulate them
  425.  */
  426. /* points to current character in buffer */
  427. static YY_CHAR *yy_c_buf_p = (YY_CHAR *) 0;
  428. static int yy_init = 1;        /* whether we need to initialize */
  429. static int yy_start = 0;    /* start state number */
  430.  
  431. /* flag which is used to allow yywrap()'s to do buffer switches
  432.  * instead of setting up a fresh yyin.  A bit of a hack ...
  433.  */
  434. static int yy_did_buffer_switch_on_eof;
  435.  
  436. static yy_state_type yy_get_previous_state YY_PROTO(( void ));
  437. static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
  438. static int yy_get_next_buffer YY_PROTO(( void ));
  439. static void yyunput YY_PROTO(( YY_CHAR c, YY_CHAR *buf_ptr ));
  440. void yyrestart YY_PROTO(( FILE *input_file ));
  441. void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
  442. void yy_load_buffer_state YY_PROTO(( void ));
  443. YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
  444. void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
  445. void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
  446.  
  447. #define yy_new_buffer yy_create_buffer
  448.  
  449. #ifdef __cplusplus
  450. static int yyinput YY_PROTO(( void ));
  451. #else
  452. static int input YY_PROTO(( void ));
  453. #endif
  454.  
  455. YY_DECL
  456.     {
  457.     register yy_state_type yy_current_state;
  458.     register YY_CHAR *yy_cp, *yy_bp;
  459.     register int yy_act;
  460.  
  461.  
  462.  
  463.  
  464.     if ( yy_init )
  465.     {
  466.     YY_USER_INIT;
  467.  
  468.     if ( ! yy_start )
  469.         yy_start = 1;    /* first start state */
  470.  
  471.     if ( ! yyin )
  472.         yyin = stdin;
  473.  
  474.     if ( ! yyout )
  475.         yyout = stdout;
  476.  
  477.     if ( yy_current_buffer )
  478.         yy_init_buffer( yy_current_buffer, yyin );
  479.     else
  480.         yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
  481.  
  482.     yy_load_buffer_state();
  483.  
  484.     yy_init = 0;
  485.     }
  486.  
  487.     while ( 1 )        /* loops until end-of-file is reached */
  488.     {
  489.     yy_cp = yy_c_buf_p;
  490.  
  491.     /* support of yytext */
  492.     *yy_cp = yy_hold_char;
  493.  
  494.     /* yy_bp points to the position in yy_ch_buf of the start of the
  495.      * current run.
  496.      */
  497.     yy_bp = yy_cp;
  498.  
  499.     yy_current_state = yy_start;
  500. yy_match:
  501.     while ( (yy_current_state = yy_nxt[yy_current_state][yy_ec[*yy_cp]]) > 0 )
  502.         ++yy_cp;
  503.  
  504.     yy_current_state = -yy_current_state;
  505.  
  506. yy_find_action:
  507.     yy_act = yy_accept[yy_current_state];
  508.  
  509.     YY_DO_BEFORE_ACTION;
  510.     YY_USER_ACTION;
  511.  
  512. do_action:    /* this label is used only to access EOF actions */
  513.  
  514.  
  515.     switch ( yy_act )
  516.         {
  517. case 1:
  518. # line 70 "scene.l"
  519. ;
  520.     YY_BREAK
  521. case 2:
  522. # line 72 "scene.l"
  523. {
  524.             write_scene();
  525.             scene_no++;
  526.         }
  527.     YY_BREAK
  528. case 3:
  529. # line 77 "scene.l"
  530. {
  531.             add_char_to_scene(yytext + 1);
  532.         }
  533.     YY_BREAK
  534. case 4:
  535. # line 81 "scene.l"
  536. {
  537.             strcpy(curr_book,yytext + 1);
  538.             strcpy(scenes[scene_no - 1].book,yytext + 1);
  539.         }
  540.     YY_BREAK
  541. case 5:
  542. # line 86 "scene.l"
  543. {
  544.             sscanf(yytext,"#%d",&(scenes[scene_no - 1].page));
  545.         }
  546.     YY_BREAK
  547. case 6:
  548. # line 90 "scene.l"
  549. {
  550.             fprintf(stderr,"Invalid page number, ignoring\n");
  551.         }
  552.     YY_BREAK
  553. case 7:
  554. # line 94 "scene.l"
  555. {
  556.             strcpy(scenes[scene_no - 1].music,yytext + 1);
  557.         }
  558.     YY_BREAK
  559. case 8:
  560. # line 98 "scene.l"
  561. {
  562.             strcpy(scenes[scene_no - 1].musicby,yytext + 1);
  563.         }
  564.     YY_BREAK
  565. case 9:
  566. # line 102 "scene.l"
  567. {
  568.             fprintf(stderr,"Invalid null %c, ignoring\n",yytext[0]);
  569.         }
  570.     YY_BREAK
  571. case 10:
  572. # line 106 "scene.l"
  573. {
  574.             write_scene();
  575.             return(0);
  576.         }
  577.     YY_BREAK
  578. case 11:
  579. # line 111 "scene.l"
  580. {
  581.             fprintf(stderr,"What does %c mean?\n",yytext[0]);
  582.         }
  583.     YY_BREAK
  584. case 12:
  585. # line 115 "scene.l"
  586. ECHO;
  587.     YY_BREAK
  588.         case YY_STATE_EOF(INITIAL):
  589.         yyterminate();
  590.  
  591.         case YY_END_OF_BUFFER:
  592.         {
  593.         /* amount of text matched not including the EOB char */
  594.         int yy_amount_of_matched_text = yy_cp - yytext - 1;
  595.  
  596.         /* undo the effects of YY_DO_BEFORE_ACTION */
  597.         *yy_cp = yy_hold_char;
  598.  
  599.         /* note that here we test for yy_c_buf_p "<=" to the position
  600.          * of the first EOB in the buffer, since yy_c_buf_p will
  601.          * already have been incremented past the NUL character
  602.          * (since all states make transitions on EOB to the end-
  603.          * of-buffer state).  Contrast this with the test in yyinput().
  604.          */
  605.         if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
  606.             /* this was really a NUL */
  607.             {
  608.             yy_state_type yy_next_state;
  609.  
  610.             yy_c_buf_p = yytext + yy_amount_of_matched_text;
  611.  
  612.             yy_current_state = yy_get_previous_state();
  613.  
  614.             /* okay, we're now positioned to make the
  615.              * NUL transition.  We couldn't have
  616.              * yy_get_previous_state() go ahead and do it
  617.              * for us because it doesn't know how to deal
  618.              * with the possibility of jamming (and we
  619.              * don't want to build jamming into it because
  620.              * then it will run more slowly)
  621.              */
  622.  
  623.             yy_next_state = yy_try_NUL_trans( yy_current_state );
  624.  
  625.             yy_bp = yytext + YY_MORE_ADJ;
  626.  
  627.             if ( yy_next_state )
  628.             {
  629.             /* consume the NUL */
  630.             yy_cp = ++yy_c_buf_p;
  631.             yy_current_state = yy_next_state;
  632.             goto yy_match;
  633.             }
  634.  
  635.             else
  636.             {
  637.                 yy_cp = yy_c_buf_p;
  638.             goto yy_find_action;
  639.             }
  640.             }
  641.  
  642.         else switch ( yy_get_next_buffer() )
  643.             {
  644.             case EOB_ACT_END_OF_FILE:
  645.             {
  646.             yy_did_buffer_switch_on_eof = 0;
  647.  
  648.             if ( yywrap() )
  649.                 {
  650.                 /* note: because we've taken care in
  651.                  * yy_get_next_buffer() to have set up yytext,
  652.                  * we can now set up yy_c_buf_p so that if some
  653.                  * total hoser (like flex itself) wants
  654.                  * to call the scanner after we return the
  655.                  * YY_NULL, it'll still work - another YY_NULL
  656.                  * will get returned.
  657.                  */
  658.                 yy_c_buf_p = yytext + YY_MORE_ADJ;
  659.  
  660.                 yy_act = YY_STATE_EOF((yy_start - 1) / 2);
  661.                 goto do_action;
  662.                 }
  663.  
  664.             else
  665.                 {
  666.                 if ( ! yy_did_buffer_switch_on_eof )
  667.                 YY_NEW_FILE;
  668.                 }
  669.             }
  670.             break;
  671.  
  672.             case EOB_ACT_CONTINUE_SCAN:
  673.             yy_c_buf_p = yytext + yy_amount_of_matched_text;
  674.  
  675.             yy_current_state = yy_get_previous_state();
  676.  
  677.             yy_cp = yy_c_buf_p;
  678.             yy_bp = yytext + YY_MORE_ADJ;
  679.             goto yy_match;
  680.  
  681.             case EOB_ACT_LAST_MATCH:
  682.             yy_c_buf_p =
  683.                 &yy_current_buffer->yy_ch_buf[yy_n_chars];
  684.  
  685.             yy_current_state = yy_get_previous_state();
  686.  
  687.             yy_cp = yy_c_buf_p;
  688.             yy_bp = yytext + YY_MORE_ADJ;
  689.             goto yy_find_action;
  690.             }
  691.         break;
  692.         }
  693.  
  694.         default:
  695. #ifdef FLEX_DEBUG
  696.         printf( "action # %d\n", yy_act );
  697. #endif
  698.         YY_FATAL_ERROR(
  699.             "fatal flex scanner internal error--no action found" );
  700.         }
  701.     }
  702.     }
  703.  
  704.  
  705. /* yy_get_next_buffer - try to read in a new buffer
  706.  *
  707.  * synopsis
  708.  *     int yy_get_next_buffer();
  709.  *     
  710.  * returns a code representing an action
  711.  *     EOB_ACT_LAST_MATCH - 
  712.  *     EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  713.  *     EOB_ACT_END_OF_FILE - end of file
  714.  */
  715.  
  716. static int yy_get_next_buffer()
  717.  
  718.     {
  719.     register YY_CHAR *dest = yy_current_buffer->yy_ch_buf;
  720.     register YY_CHAR *source = yytext - 1; /* copy prev. char, too */
  721.     register int number_to_move, i;
  722.     int ret_val;
  723.  
  724.     if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
  725.     YY_FATAL_ERROR(
  726.         "fatal flex scanner internal error--end of buffer missed" );
  727.  
  728.     /* try to read more data */
  729.  
  730.     /* first move last chars to start of buffer */
  731.     number_to_move = yy_c_buf_p - yytext;
  732.  
  733.     for ( i = 0; i < number_to_move; ++i )
  734.     *(dest++) = *(source++);
  735.  
  736.     if ( yy_current_buffer->yy_eof_status != EOF_NOT_SEEN )
  737.     /* don't do the read, it's not guaranteed to return an EOF,
  738.      * just force an EOF
  739.      */
  740.     yy_n_chars = 0;
  741.  
  742.     else
  743.     {
  744.     int num_to_read = yy_current_buffer->yy_buf_size - number_to_move - 1;
  745.  
  746.     if ( num_to_read > YY_READ_BUF_SIZE )
  747.         num_to_read = YY_READ_BUF_SIZE;
  748.  
  749.     else if ( num_to_read <= 0 )
  750.         YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" );
  751.  
  752.     /* read in more data */
  753.     YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
  754.           yy_n_chars, num_to_read );
  755.     }
  756.  
  757.     if ( yy_n_chars == 0 )
  758.     {
  759.     if ( number_to_move == 1 )
  760.         {
  761.         ret_val = EOB_ACT_END_OF_FILE;
  762.         yy_current_buffer->yy_eof_status = EOF_DONE;
  763.         }
  764.  
  765.     else
  766.         {
  767.         ret_val = EOB_ACT_LAST_MATCH;
  768.         yy_current_buffer->yy_eof_status = EOF_PENDING;
  769.         }
  770.     }
  771.  
  772.     else
  773.     ret_val = EOB_ACT_CONTINUE_SCAN;
  774.  
  775.     yy_n_chars += number_to_move;
  776.     yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
  777.     yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
  778.  
  779.     /* yytext begins at the second character in yy_ch_buf; the first
  780.      * character is the one which preceded it before reading in the latest
  781.      * buffer; it needs to be kept around in case it's a newline, so
  782.      * yy_get_previous_state() will have with '^' rules active
  783.      */
  784.  
  785.     yytext = &yy_current_buffer->yy_ch_buf[1];
  786.  
  787.     return ( ret_val );
  788.     }
  789.  
  790.  
  791. /* yy_get_previous_state - get the state just before the EOB char was reached
  792.  *
  793.  * synopsis
  794.  *     yy_state_type yy_get_previous_state();
  795.  */
  796.  
  797. static yy_state_type yy_get_previous_state()
  798.  
  799.     {
  800.     register yy_state_type yy_current_state;
  801.     register YY_CHAR *yy_cp;
  802.  
  803.     yy_current_state = yy_start;
  804.  
  805.     for ( yy_cp = yytext + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
  806.     {
  807.     yy_current_state = yy_nxt[yy_current_state][(*yy_cp ? yy_ec[*yy_cp] : 1)];
  808.     }
  809.  
  810.     return ( yy_current_state );
  811.     }
  812.  
  813.  
  814. /* yy_try_NUL_trans - try to make a transition on the NUL character
  815.  *
  816.  * synopsis
  817.  *     next_state = yy_try_NUL_trans( current_state );
  818.  */
  819.  
  820. #ifdef YY_USE_PROTOS
  821. static yy_state_type yy_try_NUL_trans( register yy_state_type yy_current_state )
  822. #else
  823. static yy_state_type yy_try_NUL_trans( yy_current_state )
  824. register yy_state_type yy_current_state;
  825. #endif
  826.  
  827.     {
  828.     register int yy_is_jam;
  829.  
  830.     yy_current_state = yy_nxt[yy_current_state][1];
  831.     yy_is_jam = (yy_current_state <= 0);
  832.  
  833.     return ( yy_is_jam ? 0 : yy_current_state );
  834.     }
  835.  
  836.  
  837. #ifdef YY_USE_PROTOS
  838. static void yyunput( YY_CHAR c, register YY_CHAR *yy_bp )
  839. #else
  840. static void yyunput( c, yy_bp )
  841. YY_CHAR c;
  842. register YY_CHAR *yy_bp;
  843. #endif
  844.  
  845.     {
  846.     register YY_CHAR *yy_cp = yy_c_buf_p;
  847.  
  848.     /* undo effects of setting up yytext */
  849.     *yy_cp = yy_hold_char;
  850.  
  851.     if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
  852.     { /* need to shift things up to make room */
  853.     register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */
  854.     register YY_CHAR *dest =
  855.         &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size + 2];
  856.     register YY_CHAR *source =
  857.         &yy_current_buffer->yy_ch_buf[number_to_move];
  858.  
  859.     while ( source > yy_current_buffer->yy_ch_buf )
  860.         *--dest = *--source;
  861.  
  862.     yy_cp += dest - source;
  863.     yy_bp += dest - source;
  864.     yy_n_chars = yy_current_buffer->yy_buf_size;
  865.  
  866.     if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
  867.         YY_FATAL_ERROR( "flex scanner push-back overflow" );
  868.     }
  869.  
  870.     if ( yy_cp > yy_bp && yy_cp[-1] == '\n' )
  871.     yy_cp[-2] = '\n';
  872.  
  873.     *--yy_cp = c;
  874.  
  875.     /* note: the formal parameter *must* be called "yy_bp" for this
  876.      *       macro to now work correctly
  877.      */
  878.     YY_DO_BEFORE_ACTION; /* set up yytext again */
  879.     }
  880.  
  881.  
  882. #ifdef __cplusplus
  883. static int yyinput()
  884. #else
  885. static int input()
  886. #endif
  887.  
  888.     {
  889.     int c;
  890.     YY_CHAR *yy_cp = yy_c_buf_p;
  891.  
  892.     *yy_cp = yy_hold_char;
  893.  
  894.     if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
  895.     {
  896.     /* yy_c_buf_p now points to the character we want to return.
  897.      * If this occurs *before* the EOB characters, then it's a
  898.      * valid NUL; if not, then we've hit the end of the buffer.
  899.      */
  900.     if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
  901.         /* this was really a NUL */
  902.         *yy_c_buf_p = '\0';
  903.  
  904.     else
  905.         { /* need more input */
  906.         yytext = yy_c_buf_p;
  907.         ++yy_c_buf_p;
  908.  
  909.         switch ( yy_get_next_buffer() )
  910.         {
  911.         case EOB_ACT_END_OF_FILE:
  912.             {
  913.             if ( yywrap() )
  914.             {
  915.             yy_c_buf_p = yytext + YY_MORE_ADJ;
  916.             return ( EOF );
  917.             }
  918.  
  919.             YY_NEW_FILE;
  920.  
  921. #ifdef __cplusplus
  922.             return ( yyinput() );
  923. #else
  924.             return ( input() );
  925. #endif
  926.             }
  927.             break;
  928.  
  929.         case EOB_ACT_CONTINUE_SCAN:
  930.             yy_c_buf_p = yytext + YY_MORE_ADJ;
  931.             break;
  932.  
  933.         case EOB_ACT_LAST_MATCH:
  934. #ifdef __cplusplus
  935.             YY_FATAL_ERROR( "unexpected last match in yyinput()" );
  936. #else
  937.             YY_FATAL_ERROR( "unexpected last match in input()" );
  938. #endif
  939.         }
  940.         }
  941.     }
  942.  
  943.     c = *yy_c_buf_p;
  944.     yy_hold_char = *++yy_c_buf_p;
  945.  
  946.     return ( c );
  947.     }
  948.  
  949.  
  950. #ifdef YY_USE_PROTOS
  951. void yyrestart( FILE *input_file )
  952. #else
  953. void yyrestart( input_file )
  954. FILE *input_file;
  955. #endif
  956.  
  957.     {
  958.     yy_init_buffer( yy_current_buffer, input_file );
  959.     yy_load_buffer_state();
  960.     }
  961.  
  962.  
  963. #ifdef YY_USE_PROTOS
  964. void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
  965. #else
  966. void yy_switch_to_buffer( new_buffer )
  967. YY_BUFFER_STATE new_buffer;
  968. #endif
  969.  
  970.     {
  971.     if ( yy_current_buffer == new_buffer )
  972.     return;
  973.  
  974.     if ( yy_current_buffer )
  975.     {
  976.     /* flush out information for old buffer */
  977.     *yy_c_buf_p = yy_hold_char;
  978.     yy_current_buffer->yy_buf_pos = yy_c_buf_p;
  979.     yy_current_buffer->yy_n_chars = yy_n_chars;
  980.     }
  981.  
  982.     yy_current_buffer = new_buffer;
  983.     yy_load_buffer_state();
  984.  
  985.     /* we don't actually know whether we did this switch during
  986.      * EOF (yywrap()) processing, but the only time this flag
  987.      * is looked at is after yywrap() is called, so it's safe
  988.      * to go ahead and always set it.
  989.      */
  990.     yy_did_buffer_switch_on_eof = 1;
  991.     }
  992.  
  993.  
  994. #ifdef YY_USE_PROTOS
  995. void yy_load_buffer_state( void )
  996. #else
  997. void yy_load_buffer_state()
  998. #endif
  999.  
  1000.     {
  1001.     yy_n_chars = yy_current_buffer->yy_n_chars;
  1002.     yytext = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
  1003.     yyin = yy_current_buffer->yy_input_file;
  1004.     yy_hold_char = *yy_c_buf_p;
  1005.     }
  1006.  
  1007.  
  1008. #ifdef YY_USE_PROTOS
  1009. YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
  1010. #else
  1011. YY_BUFFER_STATE yy_create_buffer( file, size )
  1012. FILE *file;
  1013. int size;
  1014. #endif
  1015.  
  1016.     {
  1017.     YY_BUFFER_STATE b;
  1018.  
  1019.     b = (YY_BUFFER_STATE) malloc( sizeof( struct yy_buffer_state ) );
  1020.  
  1021.     if ( ! b )
  1022.     YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
  1023.  
  1024.     b->yy_buf_size = size;
  1025.  
  1026.     /* yy_ch_buf has to be 2 characters longer than the size given because
  1027.      * we need to put in 2 end-of-buffer characters.
  1028.      */
  1029.     b->yy_ch_buf = (YY_CHAR *) malloc( (unsigned) (b->yy_buf_size + 2) );
  1030.  
  1031.     if ( ! b->yy_ch_buf )
  1032.     YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
  1033.  
  1034.     yy_init_buffer( b, file );
  1035.  
  1036.     return ( b );
  1037.     }
  1038.  
  1039.  
  1040. #ifdef YY_USE_PROTOS
  1041. void yy_delete_buffer( YY_BUFFER_STATE b )
  1042. #else
  1043. void yy_delete_buffer( b )
  1044. YY_BUFFER_STATE b;
  1045. #endif
  1046.  
  1047.     {
  1048.     if ( b == yy_current_buffer )
  1049.     yy_current_buffer = (YY_BUFFER_STATE) 0;
  1050.  
  1051.     free( (char *) b->yy_ch_buf );
  1052.     free( (char *) b );
  1053.     }
  1054.  
  1055.  
  1056. #ifdef YY_USE_PROTOS
  1057. void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
  1058. #else
  1059. void yy_init_buffer( b, file )
  1060. YY_BUFFER_STATE b;
  1061. FILE *file;
  1062. #endif
  1063.  
  1064.     {
  1065.     b->yy_input_file = file;
  1066.  
  1067.     /* we put in the '\n' and start reading from [1] so that an
  1068.      * initial match-at-newline will be true.
  1069.      */
  1070.  
  1071.     b->yy_ch_buf[0] = '\n';
  1072.     b->yy_n_chars = 1;
  1073.  
  1074.     /* we always need two end-of-buffer characters.  The first causes
  1075.      * a transition to the end-of-buffer state.  The second causes
  1076.      * a jam in that state.
  1077.      */
  1078.     b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
  1079.     b->yy_ch_buf[2] = YY_END_OF_BUFFER_CHAR;
  1080.  
  1081.     b->yy_buf_pos = &b->yy_ch_buf[1];
  1082.  
  1083.     b->yy_eof_status = EOF_NOT_SEEN;
  1084.     }
  1085. # line 115 "scene.l"
  1086.  
  1087.  
  1088. void add_char_to_scene(char *thechar) {
  1089.     int i;
  1090.  
  1091.     i = 0;
  1092.     while(chars[i].num_scenes) {
  1093.         if(!strcmp(chars[i].name,thechar))
  1094.             break;
  1095.         i++;
  1096.     }
  1097.  
  1098.     if(chars[i].num_scenes) {
  1099.         chars[i].num_scenes++;
  1100.         chars[i].scenes[chars[i].num_scenes-1] = scene_no;
  1101.     } else {
  1102.         strcpy(chars[i].name,thechar);
  1103.         chars[i].scenes[0] = scene_no;
  1104.         chars[i].num_scenes = 1;
  1105.     }
  1106.  
  1107.     scenes[scene_no-1].chars[scenes[scene_no-1].num_chars] = i;
  1108.     scenes[scene_no-1].num_chars++;
  1109. }
  1110.  
  1111. void write_scene(void) {
  1112.     static int first = 1;
  1113.     int i;
  1114.  
  1115.     if(first) {
  1116.         first = 0;
  1117.         return;
  1118.     }
  1119.  
  1120.     if(!scenes[scene_no-1].book[0]) {
  1121.       strcpy(scenes[scene_no-1].book,curr_book);
  1122.     }
  1123.  
  1124.     printf("\\vskip 12pt\nScene {\\scenef %d}\n\n",scene_no);
  1125.     printf("from {\\bookf %s}, p. %d\n\n",scenes[scene_no-1].book,
  1126.                         scenes[scene_no-1].page);
  1127.     printf("Characters: ");
  1128.     
  1129.     sort_scene_chars();
  1130.  
  1131.     for(i=0; i<scenes[scene_no-1].num_chars; i++) {
  1132.         printf("%s{\\charf %s}",
  1133.                i?",\n":"",
  1134.                chars[scenes[scene_no-1].chars[i]].name);
  1135.     }
  1136.     printf("%s.\n\n",i?"":"Narrator");
  1137.  
  1138.     if(scenes[scene_no-1].music[0]) {
  1139.       printf("Music: {\\musicf ``%s''}, %s",
  1140.          scenes[scene_no-1].music,
  1141.          scenes[scene_no-1].musicby);
  1142.     }
  1143.  
  1144.     printf("\n\n");
  1145. }
  1146.  
  1147. static void sort_scene_chars(void) {
  1148.   int i;
  1149.  
  1150.   qsort((char *)scenes[scene_no-1].chars,scenes[scene_no-1].num_chars,
  1151.     sizeof scenes[scene_no-1].chars[0],
  1152.     sort_int_by_char);
  1153. }
  1154.  
  1155. static int sort_int_by_char(const void *a,const void *b) {
  1156.   int i = *(const int *)a,j = *(const int *)b;
  1157.  
  1158.   return(strcmp(chars[i].name,chars[j].name));
  1159. }
  1160.  
  1161. static int sort_char_by_name(const void *a,const void *b) {
  1162.   const char *n = ((const struct character *)a)->name;
  1163.   const char *o = ((const struct character *)b)->name;
  1164.  
  1165.   return(strcmp(n,o));
  1166. }
  1167.  
  1168. /*
  1169.  * WARNING
  1170.  * This function destroys the mapping from scens[i].chars[i] to
  1171.  * an actual character.  It MUST BE CALLED LAST (or at least after
  1172.  * this mapping is no longer needed.
  1173.  */
  1174. static void anal_chars(void) {
  1175.   int i,j,last,olast;
  1176.  
  1177.   for(i=0; chars[i].num_scenes; i++); /* i is now number of characters */
  1178.  
  1179.   qsort((char *)chars,i,sizeof chars[0],sort_char_by_name);
  1180.  
  1181.   printf("\\vskip 0pt plus 1filll\n{\\bigfont Character Windows}\n\n");
  1182.  
  1183.   for(i=0; chars[i].num_scenes; i++) {
  1184.     printf("\\vskip 12pt\nCharacter %s appears in scenes: \n",chars[i].name);
  1185.  
  1186.     last = 0; olast = 0;
  1187.  
  1188.     /* look, this could be a lot smarter if I felt like working on it more.
  1189.        If I ever get around to it, maybe.  Maybe. */
  1190.  
  1191.     for(j=0; j < chars[i].num_scenes; j++) {
  1192.       if(last && (chars[i].scenes[j] == last + 1)) {
  1193.     /*
  1194.      * The last one we got was one less than this one, so keep on
  1195.      * going.
  1196.      */
  1197.     olast = last++;
  1198.       } else if(last) {
  1199.     /*
  1200.      * The last one we got was something else, so output the
  1201.      * last one, a comma, and then this one.
  1202.      */
  1203.     if(olast) {
  1204.       printf("--%d",last);
  1205.       olast = 0;
  1206.     }
  1207.  
  1208.     printf(", %d",last=chars[i].scenes[j]);
  1209.       } else {
  1210.     /*
  1211.      * The first scene: just print it.
  1212.      */
  1213.     printf("%d",last=chars[i].scenes[j]); /* side effect */
  1214.       }
  1215.     }
  1216.     if(last && olast) {
  1217.       printf("--%d",last);
  1218.     }
  1219.     printf(".\n\n");
  1220.   }
  1221. }
  1222.  
  1223.  
  1224. void main(int argc,char **argv) {
  1225.   argc--; argv++;
  1226.   if(argc) {
  1227.     if(!freopen(*argv,"r",stdin)) {
  1228.       fprintf(stderr,"scene: cannot open input file %s\n",*argv);
  1229.       exit(1);
  1230.     }
  1231.   }
  1232.  
  1233.   /* USER CUSTOMIZATION
  1234.    * You may want to change some of these definitions, especially
  1235.    * if your printer has good fonts of its own.
  1236.    */
  1237.   printf("\\font\\scenef=cmbx10 scaled \\magstep2\n"
  1238.      "\\font\\bookf=cmti10 scaled \\magstephalf\n"
  1239.      "\\font\\charf=cmbx10 scaled \\magstep1\n"
  1240.      "\\font\\musicf=cmsl10 scaled \\magstephalf\n"
  1241.      "\\font\\bodyfont=cmr10 scaled \\magstephalf\n"
  1242.      "\\font\\bigfont=cmr10 scaled \\magstep2\n"
  1243.      "{\\bodyfont\n");
  1244.  
  1245.   yylex();
  1246.   anal_chars();
  1247.   printf("}\\end\n");
  1248.   exit(0);
  1249. }
  1250.  
  1251.