home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / REND.LZH / READER / SCANNER.C < prev    next >
C/C++ Source or Header  |  1996-07-23  |  13KB  |  770 lines

  1. /*
  2.         トークンの切り出し関数
  3.  
  4.         Copyright T.Kobayashi
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <math.h>
  11. #if defined(X68000) || defined(MSC) || defined(__BORLANDC__)
  12.     #include <conio.h>
  13. #endif
  14. #ifdef MSC
  15.     #include <search.h>
  16. #endif
  17.  
  18. #define SCANNER
  19. #include "reader.h"
  20. #include "word.h"
  21.  
  22. #if defined(DJ) || defined(MSC) || defined(__BORLANDC__)
  23.     #define LINEARSEARCH
  24. #endif
  25.  
  26. #define OLD_FASION        1
  27.  
  28. #define NOT_NUMBER        11
  29. #define NOT_COLOR        12
  30. #define BAD_MATRIX        13
  31. #define BAD_ARGS        14
  32. #define NAME_TOO_LONG    15
  33. #define NAME_WRONG        16
  34. #define BAD_EXIST        17
  35. #define NOT_FOUND        18
  36.  
  37. #define UNEXPECTED_EOF    21
  38. #define FILE_NOT_OPEN    22
  39. #define GET_ESC            23
  40.  
  41. #define ESC                0x1B
  42.  
  43. static char *words[] = {
  44.             "amb",
  45.             "atr",
  46.             "att",
  47.             "back",
  48.             "blu",
  49.             "bumpmap",
  50.             "cmp",
  51.             "col",
  52.             "colormap",
  53.             "cst",
  54.             "deg",
  55.             "depth",
  56.             "dif",
  57.             "dst",
  58.             "env",
  59.             "eye",
  60.             "fram",
  61.             "frm",
  62.             "glad",
  63.             "hsv",
  64.             "image",
  65.             "len",
  66.             "light",
  67.             "map",
  68.             "mapsize",
  69.             "mapview",
  70.             "mapwind",
  71.             "mat",
  72.             "mod",
  73.             "mov",
  74.             "msk",
  75.             "non",
  76.             "obj",
  77.             "opt",
  78.             "pal",
  79.             "parts",
  80.             "plt",
  81.             "pnt",
  82.             "point",
  83.             "poly",
  84.             "prim",
  85.             "private",
  86.             "pxn",
  87.             "pxs",
  88.             "red",
  89.             "ref",
  90.             "rfr",
  91.             "rgb",
  92.             "rln",
  93.             "rotx",
  94.             "roty",
  95.             "rotz",
  96.             "scal",
  97.             "scr",
  98.             "shade",
  99.             "spc",
  100.             "spot",
  101.             "star",
  102.             "stop",
  103.             "suf",
  104.             "target",
  105.             "tra",
  106.             "trp",
  107.             "uvpoly",
  108.             "uvshade",
  109.             "vec"
  110.         };
  111.  
  112. int        FileLine ;                    /*    行番号                */
  113. /*char    FileName[MAXWORD] ;*/
  114. char    FileName[F_NAME_LEN] ;         /*    ファイルネーム        */
  115. char    nextword[F_NAME_LEN] ;         /*    次のワード            */
  116. int        wordid ;                    /*    予約語のid        */
  117. int        errcount ;                    /*    エラーの数            */
  118. int        errlevel ;                    /*    エラーレベル
  119.                                         0        : Nomal
  120.                                         1 - 9    : Warning
  121.                                         10 - 19    : Error
  122.                                         20 - 29    : Fatal
  123.                                     */
  124.  
  125. int        warninglevel = 1 ;            /*    警告レベル            */
  126. int        end_of_file ;                /*    エンドオブファイル    */
  127. #ifdef WINDOWS
  128. FILE    *errfp = NULL;            /*    エラー出力ファイル    */
  129. #else
  130. FILE    *errfp = stdout ;            /*    エラー出力ファイル    */
  131. #endif
  132. Float    minscale = 1e-10 ;            /*    最小の正数            */
  133. /*    By Taka2    */
  134. void    (*interrupt)(void);                /*  割り込みルーチン    */
  135. /*    By Taka2    */
  136. void    (*errorexec)(int) = exit ;        /*  エラー処理ルーチン    */
  137.  
  138.     int        virtualmode ;                            /*  仮想記憶モード        */
  139. #if 0
  140. #ifndef DJ
  141.     #ifdef    GCC
  142.         register    int        virtualmode asm( "d7" );    /*  仮想記憶モード        */
  143.     #else
  144.         int        virtualmode ;                            /*  仮想記憶モード        */
  145.     #endif
  146. #else
  147.         int        virtualmode ;                            /*  仮想記憶モード        */
  148. #endif
  149. #endif
  150.  
  151. static    FILE    *fp ;
  152. static    int        open1 ;        /*    (  ) の検出 */
  153.  
  154. static    int        comment( void );
  155. static    int        isword( int );
  156. #ifndef LINEARSEARCH
  157. static    int        comp( char**, char** );
  158. #endif
  159. static    Float    frgb( Float , Float , Float );
  160. static    void    hsvtorgb( Float[ 3 ] , Float[ 3 ] );
  161. static    int        isname( char* );
  162. static    void    error( int, char* );
  163.  
  164. #ifndef BUFFERING
  165. #define scangetc(fp)        getc(fp)
  166. #define scanungetc(c,fp)    ungetc(c,fp)
  167. #else
  168. #define SCANBUFFERSIZE    16384
  169. static    char    scanbuffer[SCANBUFFERSIZE+1], *scanpointer;
  170. static    int        scancounter, scanendflag;
  171.  
  172. static inline int    scangetc(fp)
  173. FILE *fp;
  174. {
  175.     if (scancounter == 0) {
  176.         if (scanendflag) {
  177.             return EOF;
  178.         }
  179.         scanpointer = scanbuffer+1;
  180.         scancounter = fread(scanpointer, 1, SCANBUFFERSIZE, fp);
  181.         if (scancounter != SCANBUFFERSIZE) {
  182.             scanendflag = TRUE;
  183.         }
  184.     }
  185.     if (*scanpointer == 0x1a) {
  186.         return EOF;
  187.     }
  188.     scancounter--;
  189.     return *scanpointer++;
  190. }
  191.  
  192. static inline void    scanungetc(ch, fp)
  193. int ch;
  194. FILE *fp;
  195. {
  196.     scancounter++;
  197.     *--scanpointer = ch;
  198. }
  199.  
  200. #endif
  201. #undef isspace
  202.  
  203. static inline int isspace(int c)
  204. {
  205.     return 0 <= c && c <= 32;
  206. }
  207.  
  208.  
  209. /*
  210.     ファイルのオープン
  211.         戻り値    1:正常
  212.             0:エラー
  213. */
  214. int        fileopen( name )
  215. char    *name ;
  216. {
  217.     fp = fopen( name, "rb" );
  218.     FileLine = 1 ;
  219.     strcpy( FileName, name );
  220.     if ( fp == NULL )
  221.     {
  222.         error( FILE_NOT_OPEN, name );
  223.         strcpy( FileName, "" );
  224.         return( 0 ) ;
  225.     }
  226.     end_of_file = 0 ;
  227.     errlevel = 0 ;
  228.     errcount = 0 ;
  229. #ifdef BUFFERING
  230.     scancounter = 0;
  231.     scanendflag = FALSE;
  232. #endif
  233.     get() ;
  234.     return( 1 );
  235. }
  236.  
  237. void    fileclose()
  238. {
  239.     fclose( fp );
  240.     strcpy( FileName, "" );
  241. }
  242.  
  243. /*    コメントの削除    */
  244. static    int        comment()
  245. {
  246.     int        ch ;
  247.  
  248.     ch = scangetc( fp );
  249.     do {
  250.         while ( isspace( ch ) )
  251.         {
  252.             if ( ch == '\n' )
  253.                 FileLine++;
  254.             ch = scangetc( fp );
  255.         }
  256.  
  257.         if ( ch == '/' ) {
  258.             ch = scangetc( fp );
  259.             if ( ch != '*' )
  260.             {
  261.                 scanungetc( ch, fp );
  262.                 return( '/' );
  263.             }
  264.             for(;;)
  265.             {
  266.                 do {
  267.                     ch = scangetc( fp );
  268.                     if ( ch == '\n' )
  269.                         FileLine++;
  270.                     if ( ch == EOF )
  271.                         error( UNEXPECTED_EOF, "" );
  272.                 } while ( ch != '*' );
  273.                 if ( (ch = scangetc( fp )) == '/' )
  274.                 {
  275.                     ch = scangetc( fp );
  276.                     break;
  277.                 }
  278.                 else
  279.                     scanungetc( ch, fp );
  280.             }
  281.         }
  282.     } while ( isspace( ch ) );
  283.  
  284.     return( ch );
  285. }
  286.  
  287. static    int        isword( c )
  288. int        c ;
  289. {
  290.     return( isalnum( c ) || c == '_' || c == '.' || c == '+' || c == '-' || c == '\\' || c == ':');
  291. }
  292.  
  293. #ifdef LINEARSEARCH
  294. char **linearsearch(char *key, char **words, int count)
  295. {
  296.     for (;count > 0;--count, words++) {
  297.         if (*key == **words) {
  298.             if (strcmp(key, *words) == 0) {
  299.                 return words;
  300.             }
  301.         }
  302.     }
  303.     return NULL;
  304. }
  305. #endif
  306.  
  307. /*    トークンの切り出し    */
  308. void    get()
  309. {
  310.     int        ch, count, i, n ;
  311.     char    *p, *str, **wp ;
  312.  
  313. #ifndef WINDOWS
  314.     if ( interrupt != NULL )
  315.         (*interrupt)();
  316. #endif
  317.  
  318.     if ( end_of_file )
  319.     {
  320.         error( UNEXPECTED_EOF, "" );
  321.         return ;
  322.     }
  323.  
  324.     ch = comment();
  325.  
  326.     if ( ch == EOF )
  327.     {
  328.         end_of_file = 1 ;
  329.         return ;
  330.     }
  331.  
  332.     count = 0 ;
  333.     if ( isword( ch ) )
  334.     {
  335.         while ( ch != EOF && isword( ch ) && count < MAXWORD-1 )
  336.         {
  337.             nextword[count] = (char)ch;
  338.             count ++;
  339.             ch = scangetc( fp );
  340.         }
  341.     }
  342.     nextword[count] = '\0';
  343.  
  344.     if ( strcmp( nextword, "" ) == 0 )
  345.     {
  346.         nextword[0] = (char )ch ;
  347.         nextword[1] = '\0' ;
  348.     }
  349.     else
  350.         scanungetc( ch, fp );
  351.  
  352.  
  353.     /*    かっこのチェック    */
  354.     str = "(){}" ;
  355.     p = strchr( str, nextword[0] ) ;
  356.     if ( p != NULL )
  357.     {
  358.         wordid = 200 + (int)(p - str) ;
  359.         return ;
  360.     }
  361.  
  362.     /*    数字のチェック    */
  363.     n = strlen( nextword );
  364.     for( i = 0 ; i < n ; ++i )
  365.     {
  366.         p = strchr( "0123456789.-+Ee", nextword[i] );
  367.         if ( p == NULL )
  368.             break ;
  369.     }
  370.     if ( i == n )
  371.     {
  372.         wordid = WORD_NUM ;
  373.         return ;
  374.     }
  375.  
  376.     /*    予約語のチェック    */
  377.     p = nextword ;
  378. #ifdef LINEARSEARCH
  379.     wp = linearsearch(p, words, WORDS);
  380. #else
  381.     wp = (char**)bsearch( (char*)&p, (char*)words, WORDS, sizeof(char*), (int (*)(void*,void*))comp);
  382. #endif
  383.     if ( wp == NULL )
  384.         wordid = WORD_NAME ;
  385.     else
  386.         wordid = (int)(wp - words) ;
  387.     return ;
  388. }
  389.  
  390. #ifndef LINEARSEARCH
  391. /*    比較関数    */
  392. static    int        comp( a1, a2 )
  393. char    **a1, **a2 ;
  394. {
  395.     return( strcmp( *a1, *a2 ) );
  396. }
  397. #endif
  398.  
  399. /*    数字の読み込み    */
  400. int        getint()
  401. {
  402.     int        n ;
  403.  
  404.     if ( wordid != WORD_NUM )
  405.     {
  406.         error( NOT_NUMBER, "" );
  407.         get() ;
  408.         return( 0 );
  409.     }
  410.     n = atoi( nextword );
  411.     get() ;
  412.     return( n );
  413. }
  414.  
  415. /*    数字の読み込み    */
  416. Float    getFloat()
  417. {
  418.     Float    w ;
  419.  
  420.     if ( wordid != WORD_NUM )
  421.     {
  422.         error( NOT_NUMBER, "" );
  423.         get() ;
  424.         return( 0.0 );
  425.     }
  426.     w = atof( nextword );
  427.     get() ;
  428.     return( w );
  429. }
  430.  
  431. /*    カラーの読み込み    */
  432. int        getcolor( col )
  433. Color    col ;
  434. {
  435.     Vector    v, v2 ;
  436.  
  437.     switch( wordid )
  438.     {
  439.         case WORD_RGB :
  440.             isopen1() ;
  441.             getvector( v );
  442.             vtoc( col, v );
  443.             isclose1() ;
  444.             return( TRUE );
  445.         case WORD_HSV :
  446.             isopen1() ;
  447.             getvector( v );
  448.             hsvtorgb( v2, v );
  449.             vtoc( col, v2 );
  450.             isclose1() ;
  451.             return( TRUE );
  452.         case WORD_NUM :
  453.             v[0] = v[1] = v[2] = atof( nextword );
  454.             vtoc( col, v );
  455.             get() ;
  456.             return( FALSE );
  457.         default :
  458.             error( NOT_COLOR, "" );
  459.     }
  460.     return FALSE;
  461. }
  462.  
  463. static    Float    frgb( Float h , Float m1 , Float m2 )
  464. {
  465.     if( h < 0.0 )
  466.         h = h + 1.0 ;
  467.     if( h > 1.0 )
  468.         h = h - 1.0 ;
  469.     if( h < 1.0 / 6.0 )
  470.         return m1 + ( m2 - m1 ) * h * 6.0 ;
  471.     if( ( h >= 1.0 / 6.0 ) && ( h < 1.0 / 2.0 ) )
  472.         return m2 ;
  473.     if( ( h >= 1.0 / 2.0 ) && ( h < 2.0 / 3.0 ) )
  474.         return m1 + ( m2 - m1 ) * ( 2.0 / 3.0 - h ) * 6.0 ;
  475.     if( ( h >= 2.0 / 3.0 ) && ( h <= 1.0 ) )
  476.         return m1 ;
  477.  
  478.     return 0.0;
  479. }
  480.  
  481. static    void    hsvtorgb( rgb, hsv )
  482. Float    hsv[ 3 ] , rgb[ 3 ] ;
  483. {
  484.     Float    m1 , m2 ;
  485.  
  486.     if( hsv[ 2 ] <= 0.5 )
  487.         m2 = hsv[ 2 ] * ( 1 + hsv[ 1 ] ) ;
  488.     else
  489.         m2 = hsv[ 2 ] + hsv[ 1 ] - hsv[ 2 ] * hsv[ 1 ] ;
  490.  
  491.     m1 = 2 * hsv[ 2 ] - m2 ;
  492.     if( hsv[ 1 ] == 0.0 )
  493.     {
  494.         rgb[ 0 ] = hsv[ 2 ] ;
  495.         rgb[ 1 ] = hsv[ 2 ] ;
  496.         rgb[ 2 ] = hsv[ 2 ] ;
  497.     }
  498.     else
  499.     {
  500.         rgb[ 0 ] = frgb( hsv[ 0 ] + 1.0 / 3.0 , m1 , m2 ) ;
  501.         rgb[ 1 ] = frgb( hsv[ 0 ] , m1 , m2 ) ;
  502.         rgb[ 2 ] = frgb( hsv[ 0 ] - 1.0 / 3.0 , m1 , m2 ) ;
  503.     }
  504. }
  505.  
  506.  
  507.  
  508. /*    ベクトルの読み込み    */
  509. void    getvector( v )
  510. Vector    v ;
  511. {
  512.     v[0] = getFloat() ;
  513.     v[1] = getFloat() ;
  514.     v[2] = getFloat() ;
  515. }
  516.  
  517. /*    名前の読み込み    */
  518. void    getname( name )
  519. char    *name ;
  520. {
  521.     if ( strlen( nextword ) > MAXWORD - 1 )
  522.         error( NAME_TOO_LONG, nextword );
  523.     else if ( ! isname( nextword ) )
  524.         error( NAME_WRONG, nextword );
  525.     else
  526.         strcpy( name, nextword );
  527.     get() ;
  528.     if ( wordid == WORD_OPEN1 )
  529.     {
  530.         error( BAD_ARGS, "" );
  531.         skip( ")" );
  532.     }
  533. }
  534.  
  535. /*     ファイル名の読み込み    */
  536. void    getfilename( name )
  537. char    *name ;
  538. {
  539.     if ( strlen( nextword ) > F_NAME_LEN - 1 )
  540.         error( NAME_TOO_LONG, nextword );
  541.     else
  542.         strcpy( name, nextword );
  543.     get() ;
  544.     if ( wordid == WORD_OPEN1 )
  545.     {
  546.         error( BAD_ARGS, "" );
  547.         skip( ")" );
  548.     }
  549. }
  550.  
  551. void    skip( name )
  552. char    *name ;
  553. {
  554.     do
  555.     {
  556.         get() ;
  557.     }
  558.     while( strcmp( nextword, name ) != 0 ) ;
  559.     get() ;
  560. }
  561.  
  562. /*    移動指定の読み込み    */
  563. void    getmat( m )
  564. Matrix    m ;
  565. {
  566.     int        i, j ;
  567.     Vector    xv, zv, v ;
  568.     Matrix    mm ;
  569.  
  570.     m_unit( m );
  571.     switch( wordid )
  572.     {
  573.         case WORD_MOV :
  574.             isopen1() ;
  575.             getvector( v );
  576.             m_mov( m, v );
  577.             break ;
  578.         case WORD_ROTX :
  579.             isopen1() ;
  580.             m_rot( m, 0, getFloat() );
  581.             break ;
  582.         case WORD_ROTY :
  583.             isopen1() ;
  584.             m_rot( m, 1, getFloat() );
  585.             break ;
  586.         case WORD_ROTZ :
  587.             isopen1() ;
  588.             m_rot( m, 2, getFloat() );
  589.             break ;
  590.         case WORD_SCAL :
  591.             isopen1() ;
  592.             getvector( v );
  593.             m_scal( m, v );
  594.             break ;
  595.         case WORD_VEC :
  596.             isopen1() ;
  597.             getvector( xv ) ;
  598.             getvector( zv ) ;
  599.             m_vec( m, xv, zv );
  600.             break ;
  601.         case WORD_MAT :
  602.             isopen1() ;
  603.             for( i = 0 ; i < 4 ; ++i )
  604.                 for( j = 0 ; j < 4 ; ++j )
  605.                     m[i][j] = getFloat() ;
  606.             break ;
  607.         default :
  608.             error( BAD_EXIST, nextword );
  609.             get() ;
  610.             return ;
  611.     }
  612.     if ( m_inv( mm, m ) == 0 )    /*    逆行列ができない。    */
  613.         error( BAD_MATRIX, "" );
  614.  
  615.     isclose1() ;
  616. }
  617.  
  618. /*    "(" の検出    */
  619. void    isopen1()
  620. {
  621.     get() ;
  622.     if ( wordid == WORD_OPEN1 )
  623.     {
  624.         get() ;
  625.         open1 = 1 ;
  626.     }
  627.     else
  628.     {
  629.         error( OLD_FASION, "( がない。" );
  630.         open1 = 0 ;
  631.     }
  632. }
  633.  
  634. /*    ")"の検出    */
  635. void    isclose1()
  636. {
  637.     if ( open1 )
  638.     {
  639.         if ( wordid != WORD_CLOSE1 )
  640.             error( NOT_FOUND, ")" );
  641.         else
  642.             get() ;
  643.     }
  644. }
  645.  
  646.  
  647. static    int        isname( name )
  648. char    *name ;
  649. {
  650.     if ( ! ( isalpha( *name ) || *name == '_' ) )
  651.         return( 0 ) ;
  652.  
  653.     while( *(++name) != '\0' )
  654.         if ( ! ( isalnum( *name ) || *name == '_' || *name == '.' ) )
  655.             return( 0 );
  656.  
  657.     return( 1 );
  658. }
  659.  
  660. static    void    error( n, str )
  661. int        n ;
  662. char    *str ;
  663. {
  664.     char    *msg ;
  665.     int        level ;
  666.  
  667.     switch( n )
  668.     {
  669.         case OLD_FASION :
  670.             msg = "警告:古い規格の書式です。:%s" ;
  671.             level = 1 ;
  672.             break ;
  673.         case NOT_NUMBER :
  674.             msg = "数字が必要です。" ;
  675.             level = 10 ;
  676.             break ;
  677.         case NOT_COLOR :
  678.             msg = "色情報がおかしい。" ;
  679.             level = 10 ;
  680.             break ;
  681.         case BAD_MATRIX :
  682.             msg = "座標変換指定がおかしい。" ;
  683.             level = 10 ;
  684.             break ;
  685.         case BAD_ARGS :
  686.             msg = "引数の処理はできません。" ;
  687.             level = 10 ;
  688.             break ;
  689.         case NAME_TOO_LONG :
  690.             msg = "名前(%s)が長すぎます。(31文字まで)" ;
  691.             level = 10 ;
  692.             break ;
  693.         case NAME_WRONG :
  694.             msg = "名前(%s)がおかしい" ;
  695.             level = 10 ;
  696.             break ;
  697.         case BAD_EXIST :
  698.             msg = " %s が存在します。" ;
  699.             level = 10 ;
  700.             break ;
  701.         case NOT_FOUND :
  702.             msg = " %s がありません。" ;
  703.             level = 10 ;
  704.             break ;
  705.         case UNEXPECTED_EOF :
  706.             msg = "エンドオブファイルになりました。" ;
  707.             level = 20 ;
  708.             break ;
  709.         case FILE_NOT_OPEN :
  710.             msg = "ファイル %s がオープンできません。" ;
  711.             level = 20 ;
  712.             break ;
  713.         case GET_ESC :
  714.             msg = " ESC キーが押されました。" ;
  715.             level = 20 ;
  716.             break ;
  717.         default :
  718.             msg = "エラーコードの誤り。( scanner.c )" ;
  719.             level = 20 ;
  720.             break ;
  721.     } ;
  722.  
  723.     errormessage( level, msg, str );
  724. }
  725.  
  726. void    errormessage( level, msg, str )
  727. int        level ;
  728. char    *msg, *str ;
  729. {
  730.     if (errfp == NULL) errfp = stdout;
  731.  
  732.     if ( errlevel < level )
  733.         errlevel = level ;
  734.  
  735.     if ( level >= warninglevel )
  736.     {
  737.         fprintf( errfp, "%-15s%3d : ", FileName, FileLine );
  738.         fprintf( errfp, msg, str );
  739.         fprintf( errfp, "\n" );
  740.     }
  741.  
  742.     if ( level >= 10 )
  743.         ++ errcount ;
  744. #ifdef MESSAGE
  745.     if (level >= 20) {
  746.         extern int printwarning(const char *format, ...);
  747.         char fmt[256];
  748.         strcpy(fmt, "%-15s%3d : ");
  749.         strcat(fmt, msg);
  750.         printwarning( fmt, FileName, FileLine, str);
  751.     }
  752. #endif
  753.  
  754.     if ( errcount >= 100 )
  755.     {
  756. #ifdef MESSAGE
  757.         extern int printwarning(const char *format, ...);
  758.         printwarning( "エラーの数が100を越えました。中止します。");
  759. #endif
  760.         fprintf( errfp,
  761.             "エラーの数が100を越えました。中止します。\n" );
  762.         level = 20 ;
  763.     }
  764.  
  765.     if ( level >= 20 ) {
  766.  
  767.         (*errorexec)( level );
  768.     }
  769. }
  770.