138 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			138 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);
 | |
| }
 |