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