ack/util/ceg/as_parser/conversion.c

139 lines
2.3 KiB
C

/* This file contains functions to handle %d, %$, %dist constructs in the
* as_table.
*/
pr_text_with_conversions( str)
char *str;
{
char *ptr, *next_conversion(), *pr_conversion();
while ( ptr = next_conversion( str)) {
/* ptr points to '%'-sign */
*ptr = '\0';
out( "fprint( outfile, \"");
out_string( str);
out( "\");");
*ptr = '%';
str = pr_conversion( ptr);
}
out( "fprint( outfile, \"");
out_string( str);
out( "\");");
}
out_string( s)
char *s;
{
for ( ; *s != '\0'; s++)
switch ( *s) {
case '"' : out( "\\\"");
break;
case '\\': out( "\\\\");
break;
case '\n': out( "\\n");
break;
default : out( "%c", *s);
}
}
char *next_conversion( str)
char *str;
/* Look for a %-sign, but not in a comment or string! */
{
char *match();
while ( *str && *str != '%') {
switch ( *str++) {
case '\'' : str = match( '\'', str) + 1;
break;
case '"' : str = match( '"', str) + 1;
break;
}
}
return( *str == '%' ? str : (char *)0);
}
char *match( c, str)
char c, *str;
/* Look for charcter 'c', but watch out for things like \n */
{
while ( *str && ( *str != c || *(str-1) == '\\'))
str++;
return( *str ? str : str-1);
}
char *match_bracket( str)
char *str;
/* find ')', but look at nesting '('-')' pairs, return position of ')'.
* Skip strings and comments.
*/
{
int depth;
char *match();
depth = 1;
while ( *str && depth != 0) {
switch ( *str++) {
case '\'' : str = match( '\'', str+1) + 1;
break;
case '"' : str = match( '"', str+1) + 1;
break;
case '(' : depth++;
break;
case ')' : depth--;
break;
}
}
return( str-1);
}
char *find( c, str)
char c, *str;
{
while ( *str && *str != c)
str++;
return( str);
}
char *pr_conversion( str)
char *str;
/* str points to '%'-sign, returns pointer to first character AFTER the
* conversion. %$ will result in a call of eval(), %d will call dist().
*/
{
char *start, *ptr, *match_bracket(), *find();
start = find( '(', str+1);
*start++ = '\0';
ptr = match_bracket( start);
*ptr = '\0';
if ( *(str+1) == '$')
out( "eval( %s);", start);
else if ( strncmp( str+1, "dist", 4) == 0)
out( "dist( %s);", start);
else
out( "fprint( outfile, \"%%%s\", %s);", str+1, start);
return( ptr+1);
}