You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
163 lines
2.7 KiB
163 lines
2.7 KiB
4 months ago
|
/*
|
||
|
* 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
|