X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fcaptoinfo.c;h=a0da44dea98938ed79abf6b3396810c595b860f6;hp=da1382683942a21be51a1aaf6cb5cdab925659cb;hb=96d6b16de0d487e5d3aed0302a179dbce11b5d96;hpb=b1f61d9f3aa244512045a6b02e759825d7049d34 diff --git a/ncurses/tinfo/captoinfo.c b/ncurses/tinfo/captoinfo.c index da138268..a0da44de 100644 --- a/ncurses/tinfo/captoinfo.c +++ b/ncurses/tinfo/captoinfo.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998,1999,2000 Free Software Foundation, Inc. * + * Copyright (c) 1998-2009,2010 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -29,6 +29,7 @@ /**************************************************************************** * Author: Zeyd M. Ben-Halim 1992,1995 * * and: Eric S. Raymond * + * and: Thomas E. Dickey 1996-on * ****************************************************************************/ /* @@ -39,7 +40,7 @@ * * There is just one entry point: * - * char *captoinfo(n, s, parametrized) + * char *_nc_captoinfo(n, s, parameterized) * * Convert value s for termcap string capability named n into terminfo * format. @@ -92,7 +93,7 @@ #include #include -MODULE_ID("$Id: captoinfo.c,v 1.37 2000/04/01 20:07:34 tom Exp $") +MODULE_ID("$Id: captoinfo.c,v 1.58 2010/12/04 20:08:19 tom Exp $") #define MAX_PUSHED 16 /* max # args we can push onto the stack */ @@ -115,7 +116,7 @@ init_string(void) if (my_string == 0) my_string = typeMalloc(char, my_length = 256); if (my_string == 0) - _nc_err_abort("Out of memory"); + _nc_err_abort(MSG_NO_MEMORY); *my_string = '\0'; return my_string; @@ -124,23 +125,23 @@ init_string(void) static char * save_string(char *d, const char *const s) { - size_t have = (d - my_string); + size_t have = (size_t) (d - my_string); size_t need = have + strlen(s) + 2; if (need > my_length) { - my_string = (char *) realloc(my_string, my_length = (need + need)); + my_string = (char *) _nc_doalloc(my_string, my_length = (need + need)); if (my_string == 0) - _nc_err_abort("Out of memory"); + _nc_err_abort(MSG_NO_MEMORY); d = my_string + have; } (void) strcpy(d, s); return d + strlen(d); } -static inline char * -save_char(char *s, char c) +static NCURSES_INLINE char * +save_char(char *s, int c) { static char temp[2]; - temp[0] = c; + temp[0] = (char) c; return save_string(s, temp); } @@ -148,7 +149,7 @@ static void push(void) /* push onstack on to the stack */ { - if (stackptr > MAX_PUSHED) + if (stackptr >= MAX_PUSHED) _nc_warning("string too complex to convert"); else stack[stackptr++] = onstack; @@ -182,7 +183,7 @@ cvtchar(register const char *sp) case '$': case '\\': case '%': - c = *sp; + c = (unsigned char) (*sp); len = 2; break; case '\0': @@ -194,23 +195,23 @@ cvtchar(register const char *sp) case '2': case '3': len = 1; - while (isdigit(*sp)) { - c = 8 * c + (*sp++ - '0'); + while (isdigit(UChar(*sp))) { + c = (unsigned char) (8 * c + (*sp++ - '0')); len++; } break; default: - c = *sp; + c = (unsigned char) (*sp); len = 2; break; } break; case '^': - c = (*++sp & 0x1f); + c = (unsigned char) (*++sp & 0x1f); len = 2; break; default: - c = *sp; + c = (unsigned char) (*sp); len = 1; } if (isgraph(c) && c != ',' && c != '\'' && c != '\\' && c != ':') { @@ -268,13 +269,16 @@ getparm(int parm, int n) } } -char * -_nc_captoinfo( -/* convert a termcap string to terminfo format */ - register const char *cap, /* relevant terminfo capability index */ - register const char *s, /* string value of the capability */ - int const parametrized /* do % translations if 1, pad translations if >=0 */ -) +/* + * Convert a termcap string to terminfo format. + * 'cap' is the relevant terminfo capability index. + * 's' is the string value of the capability. + * 'parameterized' tells what type of translations to do: + * % translations if 1 + * pad translations if >=0 + */ +NCURSES_EXPORT(char *) +_nc_captoinfo(const char *cap, const char *s, int const parameterized) { const char *capstart; @@ -291,16 +295,16 @@ _nc_captoinfo( capstart = 0; if (s == 0) s = ""; - if (parametrized >= 0 && isdigit(*s)) + if (parameterized >= 0 && isdigit(UChar(*s))) for (capstart = s;; s++) - if (!(isdigit(*s) || *s == '*' || *s == '.')) + if (!(isdigit(UChar(*s)) || *s == '*' || *s == '.')) break; while (*s != '\0') { switch (*s) { case '%': s++; - if (parametrized < 1) { + if (parameterized < 1) { dp = save_char(dp, '%'); break; } @@ -349,7 +353,7 @@ _nc_captoinfo( break; case 'a': if ((*s == '=' || *s == '+' || *s == '-' - || *s == '*' || *s == '/') + || *s == '*' || *s == '/') && (s[1] == 'p' || s[1] == 'c') && s[2] != '\0') { int l; @@ -461,7 +465,7 @@ _nc_captoinfo( dp = save_char(dp, '%'); s--; _nc_warning("unknown %% code %s (%#x) in %s", - unctrl(*s), (*s) & 0xff, cap); + unctrl((chtype) *s), UChar(*s), cap); break; } break; @@ -542,7 +546,7 @@ _nc_captoinfo( if (capstart) { dp = save_string(dp, "$<"); for (s = capstart;; s++) - if (isdigit(*s) || *s == '*' || *s == '.') + if (isdigit(UChar(*s)) || *s == '*' || *s == '.') dp = save_char(dp, *s); else break; @@ -566,8 +570,8 @@ bcd_expression(const char *str) char ch1, ch2; if (sscanf(str, fmt, &ch1, &ch2) == 2 - && isdigit(ch1) - && isdigit(ch2) + && isdigit(UChar(ch1)) + && isdigit(UChar(ch2)) && (ch1 == ch2)) { len = 28; #ifndef NDEBUG @@ -594,7 +598,7 @@ save_tc_char(char *bufptr, int c1) bufptr = save_char(bufptr, c1); } else { if (c1 == (c1 & 0x1f)) /* iscntrl() returns T on 255 */ - (void) strcpy(temp, unctrl(c1)); + (void) strcpy(temp, unctrl((chtype) c1)); else (void) sprintf(temp, "\\%03o", c1); bufptr = save_string(bufptr, temp); @@ -629,17 +633,17 @@ save_tc_inequality(char *bufptr, int c1, int c2) * %m exclusive-or all parameters with 0177 (not in 4.4BSD) */ -char * -_nc_infotocap( -/* convert a terminfo string to termcap format */ - register const char *cap GCC_UNUSED, /* relevant termcap capability index */ - register const char *str, /* string value of the capability */ - int const parametrized /* do % translations if 1, pad translations if >=0 */ -) +/* + * Convert a terminfo string to termcap format. Parameters are as in + * _nc_captoinfo(). + */ +NCURSES_EXPORT(char *) +_nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameterized) { int seenone = 0, seentwo = 0, saw_m = 0, saw_n = 0; const char *padding; const char *trimmed = 0; + int in0, in1, in2; char ch1 = 0, ch2 = 0; char *bufptr = init_string(); int len; @@ -647,15 +651,15 @@ _nc_infotocap( /* we may have to move some trailing mandatory padding up front */ padding = str + strlen(str) - 1; - if (*padding == '>' && *--padding == '/') { + if (padding > str && *padding == '>' && *--padding == '/') { --padding; - while (isdigit(*padding) || *padding == '.' || *padding == '*') + while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*') padding--; - if (*padding == '<' && *--padding == '$') + if (padding > str && *padding == '<' && *--padding == '$') trimmed = padding; padding += 2; - while (isdigit(*padding) || *padding == '.' || *padding == '*') + while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*') bufptr = save_char(bufptr, *padding++); } @@ -663,17 +667,53 @@ _nc_infotocap( int c1, c2; char *cp = 0; - if (str[0] == '\\' && (str[1] == '^' || str[1] == ',')) { - bufptr = save_char(bufptr, *++str); + if (str[0] == '^') { + if (str[1] == '\0' || (str + 1) == trimmed) { + bufptr = save_string(bufptr, "\\136"); + ++str; + } else { + bufptr = save_char(bufptr, *str++); + bufptr = save_char(bufptr, *str); + } + } else if (str[0] == '\\') { + if (str[1] == '\0' || (str + 1) == trimmed) { + bufptr = save_string(bufptr, "\\134"); + ++str; + } else if (str[1] == '^') { + bufptr = save_string(bufptr, "\\136"); + ++str; + } else if (str[1] == ',') { + bufptr = save_char(bufptr, *++str); + } else { + bufptr = save_char(bufptr, *str++); + bufptr = save_char(bufptr, *str); + } } else if (str[0] == '$' && str[1] == '<') { /* discard padding */ str += 2; - while (isdigit(*str) || *str == '.' || *str == '*' || *str == - '/' || *str == '>') + while (isdigit(UChar(*str)) + || *str == '.' + || *str == '*' + || *str == '/' + || *str == '>') str++; --str; + } else if (sscanf(str, + "[%%?%%p1%%{8}%%<%%t%d%%p1%%d%%e%%p1%%{16}%%<%%t%d%%p1%%{8}%%-%%d%%e%d;5;%%p1%%d%%;m", + &in0, &in1, &in2) == 3 + && ((in0 == 4 && in1 == 10 && in2 == 48) + || (in0 == 3 && in1 == 9 && in2 == 38))) { + /* dumb-down an optimized case from xterm-256color for termcap */ + str = strstr(str, ";m"); + ++str; + if (in2 == 48) { + bufptr = save_string(bufptr, "[48;5;%dm"); + } else { + bufptr = save_string(bufptr, "[38;5;%dm"); + } } else if (str[0] == '%' && str[1] == '%') { /* escaped '%' */ bufptr = save_string(bufptr, "%%"); - } else if (*str != '%' || (parametrized < 1)) { + ++str; + } else if (*str != '%' || (parameterized < 1)) { bufptr = save_char(bufptr, *str); } else if (sscanf(str, "%%?%%{%d}%%>%%t%%{%d}%%+%%;", &c1, &c2) == 2) { str = strchr(str, ';'); @@ -692,7 +732,7 @@ _nc_infotocap( bufptr = save_string(bufptr, "%B"); } else if ((sscanf(str, "%%{%d}%%+%%c", &c1) == 1 || sscanf(str, "%%'%c'%%+%%c", &ch1) == 1) - && (cp = strchr(str, '+'))) { + && (cp = strchr(str, '+'))) { str = cp + 2; bufptr = save_string(bufptr, "%+"); @@ -732,7 +772,7 @@ _nc_infotocap( case '8': case '9': bufptr = save_char(bufptr, '%'); - while (isdigit(*str)) + while (isdigit(UChar(*str))) bufptr = save_char(bufptr, *str++); if (strchr("doxX.", *str)) { if (*str != 'd') /* termcap doesn't have octal, hex */ @@ -781,6 +821,11 @@ _nc_infotocap( } /* endswitch (*str) */ } /* endelse (*str == '%') */ + /* + * 'str' always points to the end of what was scanned in this step, + * but that may not be the end of the string. + */ + assert(str != 0); if (*str == '\0') break; @@ -828,4 +873,13 @@ main(int argc, char *argv[]) } #endif /* MAIN */ -/* captoinfo.c ends here */ +#if NO_LEAKS +NCURSES_EXPORT(void) +_nc_captoinfo_leaks(void) +{ + if (my_string != 0) { + FreeAndNull(my_string); + } + my_length = 0; +} +#endif