163 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * cstring.c -- parse and print strings using the C escape sequences
 | 
						|
 */
 | 
						|
 | 
						|
#include "config.h"
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <ctype.h>
 | 
						|
#ifdef HAVE_GETOPT_H
 | 
						|
#include <getopt.h>
 | 
						|
#endif
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#include "cstring.h"
 | 
						|
 | 
						|
int parse_c_string(char *str)
 | 
						|
{
 | 
						|
	char *to, *from, ch;
 | 
						|
	int v;
 | 
						|
 | 
						|
	to = from = str;
 | 
						|
 | 
						|
	for (to = from = (char *) str;
 | 
						|
	     *from && *from != '"'; to++, from++) {
 | 
						|
		if (*from == '\\') {
 | 
						|
			ch = *(++from);
 | 
						|
			switch (ch) {
 | 
						|
			case 'a':
 | 
						|
				*to = '\a';
 | 
						|
				break;
 | 
						|
			case 'b':
 | 
						|
				*to = '\b';
 | 
						|
				break;
 | 
						|
			case 'f':
 | 
						|
				*to = '\f';
 | 
						|
				break;
 | 
						|
			case 'n':
 | 
						|
				*to = '\n';
 | 
						|
				break;
 | 
						|
			case 't':
 | 
						|
				*to = '\t';
 | 
						|
				break;
 | 
						|
			case 'v':
 | 
						|
				*to = '\v';
 | 
						|
				break;
 | 
						|
			case 'x':
 | 
						|
				ch = *(from + 1);
 | 
						|
				if (ch >= 'a' && ch <= 'f')
 | 
						|
					ch = ch - 'a' + 'A';
 | 
						|
				if (ch >= '0' && ch <= '9')
 | 
						|
					v = ch - '0';
 | 
						|
				else if (ch >= 'A' && ch <= 'F')
 | 
						|
					v = ch + 10 - 'A';
 | 
						|
				else {
 | 
						|
					*to = 'x';
 | 
						|
					break;
 | 
						|
				}
 | 
						|
				from++;
 | 
						|
				ch = *(from + 1);
 | 
						|
				if (ch >= 'a' && ch <= 'f')
 | 
						|
					ch = ch - 'a' + 'A';
 | 
						|
				if (ch >= '0' && ch <= '9')
 | 
						|
					v = (v * 16) + (ch - '0');
 | 
						|
				else if (ch >= 'A' && ch <= 'F')
 | 
						|
					v = (v * 16) + (ch + 10 - 'A');
 | 
						|
				else {
 | 
						|
					*to = 'x';
 | 
						|
					from--;
 | 
						|
					break;
 | 
						|
				}
 | 
						|
				from++;
 | 
						|
				*to = v;
 | 
						|
				break;
 | 
						|
			default:
 | 
						|
				if (ch >= '0' && ch <= '9') {
 | 
						|
					v = ch - '0';
 | 
						|
					ch = *(from + 1);
 | 
						|
					if (ch >= '0' && ch <= '9') {
 | 
						|
						from++;
 | 
						|
						v = (8 * v) + (ch - '0');
 | 
						|
						ch = *(from + 1);
 | 
						|
						if (ch >= '0' && ch <= '9') {
 | 
						|
							from++;
 | 
						|
							v = (8 * v) + (ch - '0');
 | 
						|
						}
 | 
						|
					}
 | 
						|
					ch = v;
 | 
						|
				}
 | 
						|
				*to = ch;
 | 
						|
			}
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
		*to = *from;
 | 
						|
	}
 | 
						|
	*to = '\0';
 | 
						|
	return to - (char *) str;
 | 
						|
}
 | 
						|
 | 
						|
void print_c_string(FILE *f, const char *cp, int len)
 | 
						|
{
 | 
						|
	unsigned char	ch;
 | 
						|
 | 
						|
	if (len < 0)
 | 
						|
		len = strlen(cp);
 | 
						|
 | 
						|
	while (len--) {
 | 
						|
		ch = *cp++;
 | 
						|
		if (ch == '\a')
 | 
						|
			fputs("\\a", f);
 | 
						|
		else if (ch == '\b')
 | 
						|
			fputs("\\b", f);
 | 
						|
		else if (ch == '\f')
 | 
						|
			fputs("\\f", f);
 | 
						|
		else if (ch == '\n')
 | 
						|
			fputs("\\n", f);
 | 
						|
		else if (ch == '\t')
 | 
						|
			fputs("\\t", f);
 | 
						|
		else if (ch == '\v')
 | 
						|
			fputs("\\v", f);
 | 
						|
		else if (ch == '\\')
 | 
						|
			fputs("\\\\", f);
 | 
						|
		else if (ch == '\'')
 | 
						|
			fputs("\\\'", f);
 | 
						|
		else if (ch == '\"')
 | 
						|
			fputs("\\\"", f);
 | 
						|
		else if ((ch < 32) || (ch > 126))
 | 
						|
			fprintf(f, "\\%03o", ch);
 | 
						|
		else
 | 
						|
			fputc(ch, f);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
#ifdef DEBUG_PROGRAM
 | 
						|
int main(int argc, char **argv)
 | 
						|
{
 | 
						|
	char buf[4096];
 | 
						|
	int c, raw = 0;
 | 
						|
 | 
						|
	while ((c = getopt(argc, argv, "r")) != EOF) {
 | 
						|
		switch (c) {
 | 
						|
		case 'r':
 | 
						|
			raw++;
 | 
						|
			break;
 | 
						|
		default:
 | 
						|
			fprintf(stderr, "Usage: %s [-r]\n", argv[0]);
 | 
						|
			exit(1);
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	while (!feof(stdin)) {
 | 
						|
		if (fgets(buf, sizeof(buf), stdin) == NULL)
 | 
						|
			break;
 | 
						|
		c = parse_c_string(buf);
 | 
						|
		if (raw)
 | 
						|
			fputs(buf, stdout);
 | 
						|
		else {
 | 
						|
			print_c_string(stdout, buf, c);
 | 
						|
			printf(" <%d>\n", c);
 | 
						|
		}
 | 
						|
	}
 | 
						|
}	
 | 
						|
#endif
 |