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