You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
4.2 KiB
C
175 lines
4.2 KiB
C
/*
|
|
* binkleyforce -- unix FTN mailer project
|
|
*
|
|
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
typedef struct lextable {
|
|
const char *str;
|
|
int value;
|
|
int retc;
|
|
int len;
|
|
} s_lextable;
|
|
|
|
static bool initialised = FALSE;
|
|
static s_lextable *next = NULL;
|
|
|
|
static s_lextable operators[] =
|
|
{
|
|
{ "==", EQ, AROP, 0 },
|
|
{ "!=", NE, AROP, 0 },
|
|
{ ">", GT, AROP, 0 },
|
|
{ ">=", GE, AROP, 0 },
|
|
{ "<", LT, AROP, 0 },
|
|
{ "<=", LE, AROP, 0 },
|
|
{ "(", OPENB, OPENB, 0 },
|
|
{ ")", CLOSEB, CLOSEB, 0 },
|
|
{ "&&", AND, LOGOP, 0 },
|
|
{ "&", AND, LOGOP, 0 },
|
|
{ "||", OR, LOGOP, 0 },
|
|
{ "|", OR, LOGOP, 0 },
|
|
{ "Xor", XOR, LOGOP, 0 },
|
|
{ "!", NOT, NOT, 0 },
|
|
{ ",", COMMA, COMMA, 0 },
|
|
{ NULL, 0, 0, 0 }
|
|
};
|
|
|
|
s_lextable elements[] =
|
|
{
|
|
{ "TZ", TZ, TZ, 0 },
|
|
{ "Address", ADDRESS, ADDRESS, 0 },
|
|
{ "Time", TIME, TIME, 0 },
|
|
{ "Phone", PHONE, PHONE, 0 },
|
|
{ "Flag", FLAG, FLAG, 0 },
|
|
{ "Incoming", INCOMING, INCOMING, 0 },
|
|
{ "Outgoing", OUTGOING, OUTGOING, 0 },
|
|
{ "Listed", LISTED, LISTED, 0 },
|
|
{ "Protected", PROTECTED, PROTECTED, 0 },
|
|
{ "Connspeed", CONNSPEED, CONNSPEED, 0 },
|
|
{ "Exec", EXEC, EXEC, 0 },
|
|
{ "Exist", EXIST, EXIST, 0 },
|
|
{ "Port", PORT, PORT, 0 },
|
|
{ "Mailer", MAILER, MAILER, 0 },
|
|
{ NULL, 0, 0, 0 }
|
|
};
|
|
|
|
static void expr_inittables(void)
|
|
{
|
|
int i;
|
|
|
|
for( i = 0; operators[i].str; i++ )
|
|
operators[i].len = strlen(operators[i].str);
|
|
|
|
for( i = 0; elements[i].str; i++ )
|
|
elements[i].len = strlen(elements[i].str);
|
|
}
|
|
|
|
static int yylex(void)
|
|
{
|
|
int i, retc = 0;
|
|
s_lextable *entry = NULL;
|
|
|
|
ASSERT(expr_p_pos != NULL);
|
|
|
|
if( !initialised )
|
|
{ expr_inittables(); initialised = TRUE; }
|
|
|
|
if( next )
|
|
{
|
|
/*
|
|
* Found operator left from previous call to yylex()
|
|
*/
|
|
yylval = next->value;
|
|
DEB((D_EVENT, "yylex: got next \"%s\", yylval = %d, ret = %d",
|
|
next->str, next->value, next->retc));
|
|
retc = next->retc;
|
|
next = NULL;
|
|
return retc;
|
|
}
|
|
|
|
while( isspace(*expr_p_pos) ) expr_p_pos++;
|
|
|
|
if( *expr_p_pos == '\0' ) return 0;
|
|
|
|
for( i = 0; operators[i].str; i++ )
|
|
{
|
|
if( strncasecmp(expr_p_pos, operators[i].str, operators[i].len) == 0 )
|
|
{ entry = &operators[i]; break; }
|
|
}
|
|
|
|
if( entry == NULL )
|
|
{
|
|
for( i = 0; elements[i].str; i++ )
|
|
{
|
|
if( strncasecmp(expr_p_pos, elements[i].str, elements[i].len) == 0 )
|
|
{ entry = &elements[i]; break; }
|
|
}
|
|
}
|
|
|
|
if( entry )
|
|
{
|
|
expr_p_pos += entry->len;
|
|
yylval = entry->value;
|
|
DEB((D_EVENT, "yylex: got token \"%s\", yylval = %d, ret = %d",
|
|
entry->str, entry->value, entry->retc));
|
|
return entry->retc;
|
|
}
|
|
else
|
|
{
|
|
|
|
if( *expr_p_pos == '"' )
|
|
{
|
|
expr_p_text = ++expr_p_pos;
|
|
|
|
while( *expr_p_pos != '"' && *expr_p_pos )
|
|
++expr_p_pos;
|
|
}
|
|
else
|
|
{
|
|
expr_p_text = expr_p_pos++;
|
|
|
|
while( !isspace(*expr_p_pos) && *expr_p_pos )
|
|
{
|
|
for( i = 0; operators[i].str; i++ )
|
|
if( strncasecmp(expr_p_pos, operators[i].str, operators[i].len) == 0 )
|
|
{
|
|
next = &operators[i];
|
|
goto enough;
|
|
}
|
|
expr_p_pos++;
|
|
}
|
|
}
|
|
|
|
enough:
|
|
if( *expr_p_pos )
|
|
{
|
|
*expr_p_pos = '\0';
|
|
if( next && next->len > 1 )
|
|
expr_p_pos += next->len;
|
|
else
|
|
expr_p_pos += 1;
|
|
}
|
|
|
|
if( ISDEC(expr_p_text) )
|
|
{
|
|
/* It is decimal number */
|
|
yylval = atol(expr_p_text);
|
|
DEB((D_EVENT, "yylex: got NUMBER %d", yylval));
|
|
return NUMBER;
|
|
}
|
|
else
|
|
{
|
|
/* It is text */
|
|
DEB((D_EVENT, "yylex: got TEXT \"%s\"", expr_p_text));
|
|
return(yylval = TEXT);
|
|
}
|
|
}
|
|
}
|