From 98b82723a126ca0c40982585c3754aa00bbed51f Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 8 Aug 2001 20:00:25 +0000 Subject: [PATCH] Added function expand_escapes() which handles now escaping /EVAL and input line if /SET expand_escapes is set. Supported escapes are \t, \r, \n, \e (ESC), \x (HEX, \x1b), \c (CTRL char, \cA), \000 (octal, \033) git-svn-id: http://svn.irssi.org/repos/irssi/trunk@1727 dbcabf3a-b0e7-0310-adc4-f8d773084564 --- src/core/misc.c | 44 ++++++++++++++++++++++++++++ src/core/misc.h | 4 +++ src/core/special-vars.c | 23 ++++++++------- src/fe-common/core/chat-completion.c | 17 +++++------ 4 files changed, 68 insertions(+), 20 deletions(-) diff --git a/src/core/misc.c b/src/core/misc.c index 1af327af..112f0bd2 100644 --- a/src/core/misc.c +++ b/src/core/misc.c @@ -725,3 +725,47 @@ GSList *columns_sort_list(GSList *list, int rows) g_slist_length(list), sorted); return sorted; } + +/* Expand escape string, the first character in data should be the + one after '\'. Returns the expanded character or -1 if error. */ +int expand_escape(const char **data) +{ + char digit[4]; + + switch (**data) { + case 't': + return '\t'; + case 'r': + return '\r'; + case 'n': + return '\n'; + case 'e': + return 27; /* ESC */ + + case 'x': + /* hex digit */ + if (!isxdigit((*data)[1]) || !isxdigit((*data)[2])) + return -1; + + digit[0] = (*data)[1]; + digit[1] = (*data)[2]; + digit[2] = '\0'; + *data += 2; + return strtol(digit, NULL, 16); + case 'c': + /* control character (\cA = ^A) */ + (*data)++; + return toupper(**data) - 64; + default: + if (!isdigit(**data)) + return -1; + + /* octal */ + digit[0] = (*data)[0]; + digit[1] = (*data)[1]; + digit[2] = (*data)[2]; + digit[3] = '\0'; + *data += 2; + return strtol(digit, NULL, 8); + } +} diff --git a/src/core/misc.h b/src/core/misc.h index 45c8ce11..804cffc2 100644 --- a/src/core/misc.h +++ b/src/core/misc.h @@ -101,4 +101,8 @@ int get_max_column_count(GSList *items, COLUMN_LEN_FUNC len_func, /* Return a column sorted copy of a list. */ GSList *columns_sort_list(GSList *list, int rows); +/* Expand escape string, the first character in data should be the + one after '\'. Returns the expanded character or -1 if error. */ +int expand_escape(const char **data); + #endif diff --git a/src/core/special-vars.c b/src/core/special-vars.c index 3898fe15..45bad34d 100644 --- a/src/core/special-vars.c +++ b/src/core/special-vars.c @@ -471,7 +471,7 @@ char *parse_special_string(const char *cmd, SERVER_REC *server, void *item, { char code, **arglist, *ret; GString *str; - int need_free; + int need_free, chr; g_return_val_if_fail(cmd != NULL, NULL); g_return_val_if_fail(data != NULL, NULL); @@ -483,16 +483,17 @@ char *parse_special_string(const char *cmd, SERVER_REC *server, void *item, code = 0; str = g_string_new(NULL); while (*cmd != '\0') { - if (code == '\\'){ - switch (*cmd) { - case 't': - g_string_append_c(str, '\t'); - break; - case 'n': - g_string_append_c(str, '\n'); - break; - default: - g_string_append_c(str, *cmd); + if (code == '\\') { + if (*cmd == ';') + g_string_append_c(str, ';'); + else { + chr = expand_escape(&cmd); + if (chr != -1) + g_string_append_c(str, chr); + else { + g_string_append_c(str, '\\'); + g_string_append_c(str, *cmd); + } } code = 0; } else if (code == '$') { diff --git a/src/fe-common/core/chat-completion.c b/src/fe-common/core/chat-completion.c index d1b90694..f580c7c0 100644 --- a/src/fe-common/core/chat-completion.c +++ b/src/fe-common/core/chat-completion.c @@ -703,6 +703,7 @@ static char *expand_escapes(const char *line, SERVER_REC *server, WI_ITEM_REC *item) { char *ptr, *ret; + int chr; ret = ptr = g_malloc(strlen(line)+1); for (; *line != '\0'; line++) { @@ -726,16 +727,14 @@ static char *expand_escapes(const char *line, SERVER_REC *server, signal_emit("send text", 3, ret, server, item); ptr = ret; break; - case 't': - *ptr++ = '\t'; - break; - case '\\': - *ptr++ = '\\'; - break; default: - *ptr++ = '\\'; - *ptr++ = *line; - break; + chr = expand_escape(&line); + if (chr != -1) + *ptr++ = chr; + else { + *ptr++ = '\\'; + *ptr++ = *line; + } } }