home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / POLYEDIT.LZH / ML / STR.C < prev    next >
C/C++ Source or Header  |  1996-06-21  |  11KB  |  495 lines

  1. /*
  2.  *        文字列制御
  3.  *
  4.  *        T.Kobayashi        1993.8.21
  5.  */
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <stdlib.h>
  9. #include <io.h>
  10. #include <assert.h>
  11. #include <ctype.h>
  12.  
  13. #ifdef X68K
  14. #include <doslib.h>
  15. #include <direct.h>
  16. #else
  17. #include <dir.h>
  18. #endif
  19.  
  20. #include "parse.h"
  21. #include "exec.h"
  22. #include "strclass.h"
  23.  
  24. #include "inlib.h"
  25. #include "err.h"
  26.  
  27. int        StringClassID ;
  28.  
  29. static    int        StringToString( int, int, DataStruct* );
  30. static    int        StringCat( int, int, DataStruct* );
  31. static    int        ToAscii( int, int, DataStruct* );
  32. static    int        AsciiTo( int, int, DataStruct* );
  33. static    int        StringComp( int, int, DataStruct* );
  34. static    int        StringLen( int, int, DataStruct* );
  35. static    int        SubString( int, int, DataStruct* );
  36. static    int        StringSearch( int, int, DataStruct* );
  37. static    int        StringToInt( int, int, DataStruct* );
  38. static    int        StringToReal( int, int, DataStruct* );
  39. static    int        GetEnv( int, int, DataStruct* );
  40. static    int        StdAccess( int, int, DataStruct* );
  41. static    int        StringToLower( int, int, DataStruct* );
  42. static    int        StringToUpper( int, int, DataStruct* );
  43. static    int        StringSprintf( int, int, DataStruct* );
  44.  
  45. /*    初期化    */
  46. void    StringInit()
  47. {
  48.     StringClassID = ObjectSetClass( "String", MaxFunctions, 0 );
  49.     FunctionSet( StringClassID, "tostring", StringToString );
  50.     OperatorSet( StringClassID, OPE_PLUS, StringCat );
  51.     OperatorSet( StringClassID, OPE_LSS, StringComp );
  52.     OperatorSet( StringClassID, OPE_GTR, StringComp );
  53.     OperatorSet( StringClassID, OPE_LSSEQ, StringComp );
  54.     OperatorSet( StringClassID, OPE_GTREQ, StringComp );
  55.     OperatorSet( StringClassID, OPE_EQ, StringComp );
  56.     OperatorSet( StringClassID, OPE_NOTEQ, StringComp );
  57.     OperatorSet( StringClassID, OPE_NOT, StringLen );
  58.  
  59.     FunctionSet( StringClassID, "strtoasc", ToAscii );
  60.     FunctionSet( 0,                "asctostr", AsciiTo );
  61.     FunctionSet( StringClassID, "substr", SubString );
  62.     FunctionSet( StringClassID, "search", StringSearch );
  63.     FunctionSet( StringClassID, "atoi", StringToInt );
  64.     FunctionSet( StringClassID, "atof", StringToReal );
  65.     FunctionSet( StringClassID, "getenv", GetEnv );
  66.     FunctionSet( StringClassID, "access", StdAccess );
  67.     FunctionSet( StringClassID, "tolower", StringToLower );
  68.     FunctionSet( StringClassID, "toupper", StringToUpper );
  69.     FunctionSet( StringClassID, "sprintf", StringSprintf);
  70. }
  71.  
  72. /*    文字列の確保    */
  73. StringClass    *StringAlloc( size )
  74. int        size ;
  75. {
  76.     StringClass    *p ;
  77.  
  78.     p = (StringClass*)ObjectAlloc( size+1, StringClassID );
  79.  
  80.     p->str[0] = '\0' ;
  81.     return p ;
  82. }
  83.  
  84. StringClass    *StringSet( str )
  85. char    *str ;
  86. {
  87.     StringClass    *ret ;
  88.  
  89.     ret = StringAlloc( strlen( str ) );
  90.     strcpy( ret->str, str );
  91.     return ret ;
  92. }
  93.  
  94. static    int        StringToString( ident, args, buf )
  95. int        ident ;
  96. int        args ;
  97. DataStruct    *buf ;
  98. {
  99.     assert( buf[0].type == TYPE_OBJECT );
  100.     if ( args >= 2 )
  101.         CallFunctionLocalParent( StringClassID, ident, args, buf );
  102.     else
  103.     {
  104.         DataStruct    *top ;
  105.         top = StackAlloc( 1 );
  106.         top->type = TYPE_OBJECT ;
  107.         top->od.ptr = ObjectCopy( buf->od.ptr );
  108.     }
  109.     return RETURN_RETURN ;
  110. }
  111.  
  112. /*    連結    */
  113. static    int        StringCat( ident, args, buf )
  114. int        ident ;
  115. int        args ;
  116. DataStruct    *buf ;
  117. {
  118.     StringClass    *str1, *str2, *ret ;
  119.  
  120.     assert( buf[0].type == TYPE_OBJECT );
  121.     str1 = (StringClass*)buf[0].od.ptr ;
  122.  
  123.     ident = IdentSearch( IdentFunction, "tostring" );
  124.     CallFunctionLocal( ident, 1, buf+1 );
  125.     assert( buf[1].type == TYPE_OBJECT );
  126.     str2 = (StringClass*)buf[1].od.ptr ;
  127.  
  128.     ret = StringAlloc( strlen( str1->str ) + strlen( str2->str ) );
  129.     strcpy( ret->str, str1->str );
  130.     strcat( ret->str, str2->str );
  131.  
  132.     buf = StackAlloc( 1 );
  133.     buf->type = TYPE_OBJECT ;
  134.     buf->od.ptr = (Object*)ret ;
  135.  
  136.     return RETURN_RETURN ;
  137. }
  138.  
  139. /*    アスキーコードを得る    */
  140. static    int        ToAscii( ident, args, buf )
  141. int        ident ;
  142. int        args ;
  143. DataStruct    *buf ;
  144. {
  145.     assert( buf[0].type == TYPE_OBJECT );
  146.     StackPushInt( ((StringClass*)buf[0].od.ptr)->str[0] );
  147.     return RETURN_RETURN ;
  148. }
  149.  
  150. /*    アスキーコードから文字列を得る    */
  151. static    int        AsciiTo( ident, args, buf )
  152. int        ident ;
  153. int        args ;
  154. DataStruct    *buf ;
  155. {
  156.     StringClass    *ret ;
  157.  
  158.     ArgCheck( "asctostr", args, buf, TYPE_INT, TYPE_NOASN );
  159.  
  160.     ret = StringAlloc( 2 );
  161.     ret->str[0] = buf[0].id.i ;
  162.     ret->str[1] = '\0' ;
  163.  
  164.     buf = StackAlloc( 1 );
  165.     buf->type = TYPE_OBJECT ;
  166.     buf->od.ptr = (Object*)ret ;
  167.  
  168.     return RETURN_RETURN ;
  169. }
  170.  
  171.  
  172. /*    比較    */
  173. static    int        StringComp( ident, args, buf )
  174. int        ident ;
  175. int        args ;
  176. DataStruct    *buf ;
  177. {
  178.     StringClass    *str1, *str2 ;
  179.     int        ret ;
  180.  
  181.     assert( buf[0].type == TYPE_OBJECT );
  182.     if ( ObjectCheck( &buf[1], StringClassID ) == FALSE )
  183.     {
  184.         ExecError( "比較演算の型が違います。(String)" );
  185.         return RETURN_VOID ;
  186.     }
  187.     str1 = (StringClass*)buf[0].od.ptr ;
  188.     str2 = (StringClass*)buf[1].od.ptr ;
  189.  
  190.     switch( ident )
  191.     {
  192.         case OPE_LSS:
  193.             ret = ( strcmp( str1->str, str2->str ) < 0 );
  194.             break ;
  195.         case OPE_GTR:
  196.             ret = ( strcmp( str1->str, str2->str ) > 0 );
  197.             break ;
  198.         case OPE_LSSEQ:
  199.             ret = ( strcmp( str1->str, str2->str ) <= 0 );
  200.             break ;
  201.         case OPE_GTREQ:
  202.             ret = ( strcmp( str1->str, str2->str ) >= 0 );
  203.             break ;
  204.         case OPE_EQ:
  205.             ret = ( strcmp( str1->str, str2->str ) == 0 );
  206.             break ;
  207.         case OPE_NOTEQ:
  208.             ret = ( strcmp( str1->str, str2->str ) != 0 );
  209.             break ;
  210.         default:
  211.             assert( FALSE );
  212.             return RETURN_VOID ;
  213.     }
  214.     StackPushInt( ret );
  215.     return RETURN_RETURN ;
  216. }
  217.  
  218. /*    長さを得る    */
  219. static    int        StringLen( ident, args, buf )
  220. int        ident ;
  221. int        args ;
  222. DataStruct    *buf ;
  223. {
  224.     StringClass    *str ;
  225.  
  226.     assert( buf[0].type == TYPE_OBJECT );
  227.     str = (StringClass*)buf[0].od.ptr ;
  228.  
  229.     StackPushInt( strlen( str->str ) );
  230.     return RETURN_RETURN ;
  231. }
  232.  
  233. /*    部分文字列を得る    */
  234. static    int        SubString( ident, args, buf )
  235. int        ident ;
  236. int        args ;
  237. DataStruct    *buf ;
  238. {
  239.     int        n, len ;
  240.     StringClass    *str, *ret ;
  241.  
  242.     ArgCheck( "String:substr", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
  243.  
  244.     str = (StringClass*)buf[0].od.ptr ;
  245.     n = buf[1].id.i ;
  246.     len = strlen( str->str );
  247.     if ( n >= 0 )
  248.     {
  249.         ret = StringAlloc( n + 1 );
  250.         strncpy( ret->str, str->str, n );
  251.         ret->str[n] = '\0' ;
  252.     }
  253.     else
  254.     {
  255.         n = - n ;
  256.         ret = StringAlloc( n + 1 );
  257.         strncpy( ret->str, str->str + len - n, n );
  258.         ret->str[n] = '\0' ;
  259.     }
  260.     buf = StackAlloc( 1 );
  261.     buf->type = TYPE_OBJECT ;
  262.     buf->od.ptr = (Object*)ret ;
  263.  
  264.     return RETURN_RETURN ;
  265. }
  266.  
  267. /*    文字列中の部分文字列を検索    */
  268. static    int        StringSearch( ident, args, buf )
  269. int        ident ;
  270. int        args ;
  271. DataStruct    *buf ;
  272. {
  273.     int        i, j ;
  274.     char    *str1, *str2 ;
  275.  
  276.     ArgCheck( "String:search", args, buf, TYPE_OBJECT, TYPE_OBJECT, TYPE_NOASN );
  277.  
  278.     if ( ObjectCheck( &buf[1], StringClassID ) == FALSE )
  279.     {
  280.         ExecError( "2番目の引数の型が不正です(String:search)" );
  281.         return RETURN_VOID ;
  282.     }
  283.  
  284.     str1 = ((StringClass*)buf[0].od.ptr)->str ;
  285.     str2 = ((StringClass*)buf[1].od.ptr)->str ;
  286.  
  287.     for( i = 0 ; str1[i] != '\0' ; i++ )
  288.     {
  289.         if ( str1[i] == str2[0] )
  290.         {
  291.             for( j = 0 ; str1[i+j] == str2[j] && str2[j] != '\0' ; j++ );
  292.             if ( str2[j] == '\0' )
  293.                 break ;
  294.         }
  295.     }
  296.     if ( str1[i] == '\0' )
  297.         i = -1 ;
  298.  
  299.     StackPushInt( i );
  300.     return RETURN_RETURN ;
  301. }
  302.  
  303. /*    整数に変換    */
  304. static    int        StringToInt( ident, args, buf )
  305. int        ident ;
  306. int        args ;
  307. DataStruct    *buf ;
  308. {
  309.     StackPushInt( atoi( ((StringClass*)buf[0].od.ptr)->str ) );
  310.     return RETURN_RETURN ;
  311. }
  312.  
  313. /*    実数に変換    */
  314. static    int        StringToReal( ident, args, buf )
  315. int        ident ;
  316. int        args ;
  317. DataStruct    *buf ;
  318. {
  319.     StackPushReal( atof( ((StringClass*)buf[0].od.ptr)->str ) );
  320.     return RETURN_RETURN ;
  321. }
  322.  
  323. /*    環境変数を得る    */
  324. static    int        GetEnv( ident, args, buf )
  325. int        ident ;
  326. int        args ;
  327. DataStruct    *buf ;
  328. {
  329.     char    *env ;
  330.     StringClass    *str, *ret ;
  331.  
  332.     ArgCheck( "getenv", args, buf, TYPE_OBJECT, TYPE_NOASN );
  333.  
  334.     str = (StringClass*)buf[0].od.ptr ;
  335.     env = getenv( str->str );
  336.     if ( env == NULL )
  337.         ret = StringSet( "" );
  338.     else
  339.         ret = StringSet( env );
  340.  
  341.     buf = StackAlloc( 1 );
  342.     buf->type = TYPE_OBJECT ;
  343.     buf->od.ptr = (Object*)ret ;
  344.  
  345.     return RETURN_RETURN ;
  346. }
  347.  
  348. static    int        StdAccess( ident, args, buf )
  349. int        ident ;
  350. int        args ;
  351. DataStruct    *buf ;
  352. {
  353.     int        ret, mode = 0 ;
  354.  
  355.     if ( args >= 2 )
  356.     {
  357.         ArgCheck( "access", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
  358.         mode = buf[1].id.i ;
  359.     }
  360.  
  361.     if ( access( ((StringClass*)buf[0].od.ptr)->str, mode ) == 0 )
  362.         ret = TRUE ;
  363.     else
  364.         ret = FALSE ;
  365.  
  366.     StackPushBoolean( ret );
  367.     return RETURN_RETURN ;
  368. }
  369.  
  370. /*    文字列を小文字に    */
  371. static    int        StringToLower( ident, args, buf )
  372. int        ident ;
  373. int        args ;
  374. DataStruct    *buf ;
  375. {
  376.     StringClass    *str, *ret ;
  377.     char *p, *q;
  378.  
  379.     ArgCheck( "tolower", args, buf, TYPE_OBJECT, TYPE_NOASN );
  380.  
  381.     str = (StringClass*)buf[0].od.ptr ;
  382.     ret = StringAlloc( strlen( str->str ) );
  383.  
  384.     for (p = str->str, q = ret->str; *p; ++p, ++q) {
  385.         *q = tolower(*p);
  386.     }
  387.     *q = '\0';
  388.  
  389.     buf = StackAlloc( 1 );
  390.     buf->type = TYPE_OBJECT ;
  391.     buf->od.ptr = (Object*)ret ;
  392.  
  393.     return RETURN_RETURN ;
  394. }
  395.  
  396. /*    文字列を大文字に    */
  397. static    int        StringToUpper( ident, args, buf )
  398. int        ident ;
  399. int        args ;
  400. DataStruct    *buf ;
  401. {
  402.     StringClass    *str, *ret ;
  403.     char *p, *q;
  404.  
  405.     ArgCheck( "toupper", args, buf, TYPE_OBJECT, TYPE_NOASN );
  406.  
  407.     str = (StringClass*)buf[0].od.ptr ;
  408.     ret = StringAlloc( strlen( str->str ) );
  409.  
  410.     for (p = str->str, q = ret->str; *p; ++p, ++q) {
  411.         *q = toupper(*p);
  412.     }
  413.     *q = '\0';
  414.  
  415.     buf = StackAlloc( 1 );
  416.     buf->type = TYPE_OBJECT ;
  417.     buf->od.ptr = (Object*)ret ;
  418.  
  419.     return RETURN_RETURN ;
  420. }
  421.  
  422. static    int        StringSprintf( ident, args, buf )
  423. int        ident ;
  424. int        args ;
  425. DataStruct    *buf ;
  426. {
  427.     char tmpbuf[1024];
  428.     char fmtbuf[32];
  429.  
  430.     int i, j, flag;
  431.     StringClass    *ret ;
  432.     char *fmt, *p, *q;
  433.     fmt = ((StringClass*)buf[0].od.ptr)->str;
  434.     i = 1;
  435.     flag = FALSE;
  436.     q = tmpbuf;
  437.     for (p = fmt; *p; p++) {
  438.         if (flag == FALSE) {
  439.             if (*p == '%') {
  440.                 j = 0;
  441.                 fmtbuf[j++] = '%';
  442.                 flag = TRUE;
  443.             } else {
  444.                 *q++ = *p;
  445.             }
  446.         } else {
  447.             if (*p == '%') {
  448.                 *q++ = '%';
  449.                 flag = FALSE;
  450.             } else if (!isalpha(*p)) {
  451.                 fmtbuf[j++] = *p;
  452.             } else {
  453.                 flag = FALSE;
  454.                 fmtbuf[j++] = *p;
  455.                 fmtbuf[j] = '\0';
  456.                 switch (*p) {
  457.                 case 'S': case 's':
  458.                     if (!ObjectCheck(&buf[i], StringClassID)) {
  459.                         ExecError( "%d番目の引数の型が不正です(String:sprintf)", i+1 );
  460.                     }
  461.                     sprintf(q, fmtbuf, ((StringClass*)(buf[i].od.ptr))->str);
  462.                     break;
  463.                 case 'C': case 'c':
  464.                 case 'D': case 'd':
  465.                 case 'X': case 'x':
  466.                     if (buf[i].type != TYPE_INT && buf[i].type != TYPE_BOOLEAN) {
  467.                         ExecError( "%d番目の引数の型が不正です(String:sprintf)", i+1 );
  468.                     }
  469.                     sprintf(q, fmtbuf, buf[i].id.i);
  470.                     break;
  471.                 case 'F': case 'f': case 'E': case 'e':
  472.                     if (buf[i].type != TYPE_REAL) {
  473.                         ExecError( "%d番目の引数の型が不正です(String:sprintf)", i+1 );
  474.                     }
  475.                     sprintf(q, fmtbuf, buf[i].rd.r);
  476.                     break;
  477.                 deafult:
  478.                     strcpy(q, fmtbuf);
  479.                 }
  480.                 i++;
  481.                 q += strlen(q);
  482.             }
  483.         }
  484.     }
  485.     *q = '\0';
  486.     ret = StringSet(tmpbuf);
  487.  
  488.     buf = StackAlloc( 1 );
  489.     buf->type = TYPE_OBJECT ;
  490.     buf->od.ptr = (Object*)ret ;
  491.  
  492.     return RETURN_RETURN ;
  493. }
  494.  
  495.