From: Theodore Ts'o Date: Sat, 28 Jan 2017 17:11:46 +0000 (-0500) Subject: libsupport: add C string printing and parsing functions X-Git-Tag: v1.43.4~22 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=4d5b21be2ebd0ad3ef10ea06be1ff8b6c24cff82;p=tools%2Fe2fsprogs.git libsupport: add C string printing and parsing functions Signed-off-by: Theodore Ts'o --- diff --git a/lib/support/Makefile.in b/lib/support/Makefile.in index 112ba24..cede23e 100644 --- a/lib/support/Makefile.in +++ b/lib/support/Makefile.in @@ -12,7 +12,8 @@ INSTALL = @INSTALL@ all:: -OBJS= mkquota.o \ +OBJS= cstring.o \ + mkquota.o \ plausible.o \ profile.o \ parse_qtype.o \ @@ -24,6 +25,7 @@ OBJS= mkquota.o \ dict.o SRCS= $(srcdir)/argv_parse.c \ + $(srcdir)/cstring.c \ $(srcdir)/mkquota.c \ $(srcdir)/parse_qtype.c \ $(srcdir)/plausible.c \ @@ -67,10 +69,15 @@ test_profile: $(srcdir)/profile.c profile_helpers.o argv_parse.o \ profile_helpers.o argv_parse.o $(STATIC_LIBCOM_ERR) \ $(ALL_CFLAGS) +test_cstring: $(srcdir)/cstring.c + $(E) " CC $@" + $(Q) $(CC) -o test_cstring -DDEBUG_PROGRAM $(srcdir)/cstring.c \ + $(ALL_CFLAGS) + clean:: $(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* \ ../libsupport.a ../libsupport_p.a $(SMANPAGES) \ - prof_err.c prof_err.h test_profile + prof_err.c prof_err.h test_profile test_cstring #check:: tst_uuid # LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_uuid @@ -96,6 +103,8 @@ $(OBJS): # argv_parse.o: $(srcdir)/argv_parse.c $(top_builddir)/lib/config.h \ $(top_builddir)/lib/dirpaths.h $(srcdir)/argv_parse.h +cstring.o: $(srcdir)/cstring.c $(top_builddir)/lib/config.h \ + $(top_builddir)/lib/dirpaths.h mkquota.o: $(srcdir)/mkquota.c $(top_builddir)/lib/config.h \ $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \ $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fs.h \ diff --git a/lib/support/cstring.c b/lib/support/cstring.c new file mode 100644 index 0000000..3250477 --- /dev/null +++ b/lib/support/cstring.c @@ -0,0 +1,161 @@ +/* + * cstring.c -- parse and print strings using the C escape sequences + */ + +#include "config.h" +#include +#include +#include +#ifdef HAVE_GETOPT_H +#include +#endif +#include + +#include "cstring.h" + +int parse_c_string(char *str) +{ + unsigned char *to, *from, ch; + int v; + + to = from = str; + + for (to = from = (unsigned 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 { + ch = *from; + 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 { + ch = *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 - (unsigned 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 diff --git a/lib/support/cstring.h b/lib/support/cstring.h new file mode 100644 index 0000000..7f80f41 --- /dev/null +++ b/lib/support/cstring.h @@ -0,0 +1,6 @@ +/* + * cstring.h -- header file for C string parse/print utilities + */ + +extern int parse_c_string(char *str); +extern void print_c_string(FILE *f, const char *cp, int len);