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 >
Wrap
C/C++ Source or Header
|
1996-06-21
|
11KB
|
495 lines
/*
* 文字列制御
*
* T.Kobayashi 1993.8.21
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <io.h>
#include <assert.h>
#include <ctype.h>
#ifdef X68K
#include <doslib.h>
#include <direct.h>
#else
#include <dir.h>
#endif
#include "parse.h"
#include "exec.h"
#include "strclass.h"
#include "inlib.h"
#include "err.h"
int StringClassID ;
static int StringToString( int, int, DataStruct* );
static int StringCat( int, int, DataStruct* );
static int ToAscii( int, int, DataStruct* );
static int AsciiTo( int, int, DataStruct* );
static int StringComp( int, int, DataStruct* );
static int StringLen( int, int, DataStruct* );
static int SubString( int, int, DataStruct* );
static int StringSearch( int, int, DataStruct* );
static int StringToInt( int, int, DataStruct* );
static int StringToReal( int, int, DataStruct* );
static int GetEnv( int, int, DataStruct* );
static int StdAccess( int, int, DataStruct* );
static int StringToLower( int, int, DataStruct* );
static int StringToUpper( int, int, DataStruct* );
static int StringSprintf( int, int, DataStruct* );
/* 初期化 */
void StringInit()
{
StringClassID = ObjectSetClass( "String", MaxFunctions, 0 );
FunctionSet( StringClassID, "tostring", StringToString );
OperatorSet( StringClassID, OPE_PLUS, StringCat );
OperatorSet( StringClassID, OPE_LSS, StringComp );
OperatorSet( StringClassID, OPE_GTR, StringComp );
OperatorSet( StringClassID, OPE_LSSEQ, StringComp );
OperatorSet( StringClassID, OPE_GTREQ, StringComp );
OperatorSet( StringClassID, OPE_EQ, StringComp );
OperatorSet( StringClassID, OPE_NOTEQ, StringComp );
OperatorSet( StringClassID, OPE_NOT, StringLen );
FunctionSet( StringClassID, "strtoasc", ToAscii );
FunctionSet( 0, "asctostr", AsciiTo );
FunctionSet( StringClassID, "substr", SubString );
FunctionSet( StringClassID, "search", StringSearch );
FunctionSet( StringClassID, "atoi", StringToInt );
FunctionSet( StringClassID, "atof", StringToReal );
FunctionSet( StringClassID, "getenv", GetEnv );
FunctionSet( StringClassID, "access", StdAccess );
FunctionSet( StringClassID, "tolower", StringToLower );
FunctionSet( StringClassID, "toupper", StringToUpper );
FunctionSet( StringClassID, "sprintf", StringSprintf);
}
/* 文字列の確保 */
StringClass *StringAlloc( size )
int size ;
{
StringClass *p ;
p = (StringClass*)ObjectAlloc( size+1, StringClassID );
p->str[0] = '\0' ;
return p ;
}
StringClass *StringSet( str )
char *str ;
{
StringClass *ret ;
ret = StringAlloc( strlen( str ) );
strcpy( ret->str, str );
return ret ;
}
static int StringToString( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
assert( buf[0].type == TYPE_OBJECT );
if ( args >= 2 )
CallFunctionLocalParent( StringClassID, ident, args, buf );
else
{
DataStruct *top ;
top = StackAlloc( 1 );
top->type = TYPE_OBJECT ;
top->od.ptr = ObjectCopy( buf->od.ptr );
}
return RETURN_RETURN ;
}
/* 連結 */
static int StringCat( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
StringClass *str1, *str2, *ret ;
assert( buf[0].type == TYPE_OBJECT );
str1 = (StringClass*)buf[0].od.ptr ;
ident = IdentSearch( IdentFunction, "tostring" );
CallFunctionLocal( ident, 1, buf+1 );
assert( buf[1].type == TYPE_OBJECT );
str2 = (StringClass*)buf[1].od.ptr ;
ret = StringAlloc( strlen( str1->str ) + strlen( str2->str ) );
strcpy( ret->str, str1->str );
strcat( ret->str, str2->str );
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
/* アスキーコードを得る */
static int ToAscii( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
assert( buf[0].type == TYPE_OBJECT );
StackPushInt( ((StringClass*)buf[0].od.ptr)->str[0] );
return RETURN_RETURN ;
}
/* アスキーコードから文字列を得る */
static int AsciiTo( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
StringClass *ret ;
ArgCheck( "asctostr", args, buf, TYPE_INT, TYPE_NOASN );
ret = StringAlloc( 2 );
ret->str[0] = buf[0].id.i ;
ret->str[1] = '\0' ;
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
/* 比較 */
static int StringComp( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
StringClass *str1, *str2 ;
int ret ;
assert( buf[0].type == TYPE_OBJECT );
if ( ObjectCheck( &buf[1], StringClassID ) == FALSE )
{
ExecError( "比較演算の型が違います。(String)" );
return RETURN_VOID ;
}
str1 = (StringClass*)buf[0].od.ptr ;
str2 = (StringClass*)buf[1].od.ptr ;
switch( ident )
{
case OPE_LSS:
ret = ( strcmp( str1->str, str2->str ) < 0 );
break ;
case OPE_GTR:
ret = ( strcmp( str1->str, str2->str ) > 0 );
break ;
case OPE_LSSEQ:
ret = ( strcmp( str1->str, str2->str ) <= 0 );
break ;
case OPE_GTREQ:
ret = ( strcmp( str1->str, str2->str ) >= 0 );
break ;
case OPE_EQ:
ret = ( strcmp( str1->str, str2->str ) == 0 );
break ;
case OPE_NOTEQ:
ret = ( strcmp( str1->str, str2->str ) != 0 );
break ;
default:
assert( FALSE );
return RETURN_VOID ;
}
StackPushInt( ret );
return RETURN_RETURN ;
}
/* 長さを得る */
static int StringLen( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
StringClass *str ;
assert( buf[0].type == TYPE_OBJECT );
str = (StringClass*)buf[0].od.ptr ;
StackPushInt( strlen( str->str ) );
return RETURN_RETURN ;
}
/* 部分文字列を得る */
static int SubString( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int n, len ;
StringClass *str, *ret ;
ArgCheck( "String:substr", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
str = (StringClass*)buf[0].od.ptr ;
n = buf[1].id.i ;
len = strlen( str->str );
if ( n >= 0 )
{
ret = StringAlloc( n + 1 );
strncpy( ret->str, str->str, n );
ret->str[n] = '\0' ;
}
else
{
n = - n ;
ret = StringAlloc( n + 1 );
strncpy( ret->str, str->str + len - n, n );
ret->str[n] = '\0' ;
}
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
/* 文字列中の部分文字列を検索 */
static int StringSearch( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int i, j ;
char *str1, *str2 ;
ArgCheck( "String:search", args, buf, TYPE_OBJECT, TYPE_OBJECT, TYPE_NOASN );
if ( ObjectCheck( &buf[1], StringClassID ) == FALSE )
{
ExecError( "2番目の引数の型が不正です(String:search)" );
return RETURN_VOID ;
}
str1 = ((StringClass*)buf[0].od.ptr)->str ;
str2 = ((StringClass*)buf[1].od.ptr)->str ;
for( i = 0 ; str1[i] != '\0' ; i++ )
{
if ( str1[i] == str2[0] )
{
for( j = 0 ; str1[i+j] == str2[j] && str2[j] != '\0' ; j++ );
if ( str2[j] == '\0' )
break ;
}
}
if ( str1[i] == '\0' )
i = -1 ;
StackPushInt( i );
return RETURN_RETURN ;
}
/* 整数に変換 */
static int StringToInt( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
StackPushInt( atoi( ((StringClass*)buf[0].od.ptr)->str ) );
return RETURN_RETURN ;
}
/* 実数に変換 */
static int StringToReal( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
StackPushReal( atof( ((StringClass*)buf[0].od.ptr)->str ) );
return RETURN_RETURN ;
}
/* 環境変数を得る */
static int GetEnv( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
char *env ;
StringClass *str, *ret ;
ArgCheck( "getenv", args, buf, TYPE_OBJECT, TYPE_NOASN );
str = (StringClass*)buf[0].od.ptr ;
env = getenv( str->str );
if ( env == NULL )
ret = StringSet( "" );
else
ret = StringSet( env );
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
static int StdAccess( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
int ret, mode = 0 ;
if ( args >= 2 )
{
ArgCheck( "access", args, buf, TYPE_OBJECT, TYPE_INT, TYPE_NOASN );
mode = buf[1].id.i ;
}
if ( access( ((StringClass*)buf[0].od.ptr)->str, mode ) == 0 )
ret = TRUE ;
else
ret = FALSE ;
StackPushBoolean( ret );
return RETURN_RETURN ;
}
/* 文字列を小文字に */
static int StringToLower( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
StringClass *str, *ret ;
char *p, *q;
ArgCheck( "tolower", args, buf, TYPE_OBJECT, TYPE_NOASN );
str = (StringClass*)buf[0].od.ptr ;
ret = StringAlloc( strlen( str->str ) );
for (p = str->str, q = ret->str; *p; ++p, ++q) {
*q = tolower(*p);
}
*q = '\0';
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
/* 文字列を大文字に */
static int StringToUpper( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
StringClass *str, *ret ;
char *p, *q;
ArgCheck( "toupper", args, buf, TYPE_OBJECT, TYPE_NOASN );
str = (StringClass*)buf[0].od.ptr ;
ret = StringAlloc( strlen( str->str ) );
for (p = str->str, q = ret->str; *p; ++p, ++q) {
*q = toupper(*p);
}
*q = '\0';
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}
static int StringSprintf( ident, args, buf )
int ident ;
int args ;
DataStruct *buf ;
{
char tmpbuf[1024];
char fmtbuf[32];
int i, j, flag;
StringClass *ret ;
char *fmt, *p, *q;
fmt = ((StringClass*)buf[0].od.ptr)->str;
i = 1;
flag = FALSE;
q = tmpbuf;
for (p = fmt; *p; p++) {
if (flag == FALSE) {
if (*p == '%') {
j = 0;
fmtbuf[j++] = '%';
flag = TRUE;
} else {
*q++ = *p;
}
} else {
if (*p == '%') {
*q++ = '%';
flag = FALSE;
} else if (!isalpha(*p)) {
fmtbuf[j++] = *p;
} else {
flag = FALSE;
fmtbuf[j++] = *p;
fmtbuf[j] = '\0';
switch (*p) {
case 'S': case 's':
if (!ObjectCheck(&buf[i], StringClassID)) {
ExecError( "%d番目の引数の型が不正です(String:sprintf)", i+1 );
}
sprintf(q, fmtbuf, ((StringClass*)(buf[i].od.ptr))->str);
break;
case 'C': case 'c':
case 'D': case 'd':
case 'X': case 'x':
if (buf[i].type != TYPE_INT && buf[i].type != TYPE_BOOLEAN) {
ExecError( "%d番目の引数の型が不正です(String:sprintf)", i+1 );
}
sprintf(q, fmtbuf, buf[i].id.i);
break;
case 'F': case 'f': case 'E': case 'e':
if (buf[i].type != TYPE_REAL) {
ExecError( "%d番目の引数の型が不正です(String:sprintf)", i+1 );
}
sprintf(q, fmtbuf, buf[i].rd.r);
break;
deafult:
strcpy(q, fmtbuf);
}
i++;
q += strlen(q);
}
}
}
*q = '\0';
ret = StringSet(tmpbuf);
buf = StackAlloc( 1 );
buf->type = TYPE_OBJECT ;
buf->od.ptr = (Object*)ret ;
return RETURN_RETURN ;
}