X-Git-Url: https://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fcaptoinfo.c;h=dd02d902dc5261a67c4849508d8c15c07ec22b68;hp=faedb58c8690a8b91920c0302bb2016e68b0d172;hb=ee27d238caeccd1ed781a92957afbdb890e1e88f;hpb=0c12f3c8ff417105269bda50a3a2fe06c0bfdebf diff --git a/ncurses/tinfo/captoinfo.c b/ncurses/tinfo/captoinfo.c index faedb58c..dd02d902 100644 --- a/ncurses/tinfo/captoinfo.c +++ b/ncurses/tinfo/captoinfo.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. * + * Copyright (c) 1998-2012,2016 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 * @@ -93,7 +93,7 @@ #include #include -MODULE_ID("$Id: captoinfo.c,v 1.64 2011/07/23 20:36:28 tom Exp $") +MODULE_ID("$Id: captoinfo.c,v 1.78 2016/05/28 23:22:52 tom Exp $") #define MAX_PUSHED 16 /* max # args we can push onto the stack */ @@ -114,9 +114,7 @@ init_string(void) /* initialize 'my_string', 'my_length' */ { if (my_string == 0) - my_string = typeMalloc(char, my_length = 256); - if (my_string == 0) - _nc_err_abort(MSG_NO_MEMORY); + TYPE_MALLOC(char, my_length = 256, my_string); *my_string = '\0'; return my_string; @@ -133,7 +131,7 @@ save_string(char *d, const char *const s) _nc_err_abort(MSG_NO_MEMORY); d = my_string + have; } - (void) strcpy(d, s); + _nc_STRCPY(d, s, my_length - have); return d + strlen(d); } @@ -240,6 +238,12 @@ getparm(int parm, int n) else if (parm == 2) parm = 1; } + + while (n--) { + dp = save_string(dp, "%p"); + dp = save_char(dp, '0' + parm); + } + if (onstack == parm) { if (n > 1) { _nc_warning("string may not be optimal"); @@ -255,11 +259,6 @@ getparm(int parm, int n) onstack = parm; - while (n--) { - dp = save_string(dp, "%p"); - dp = save_char(dp, '0' + parm); - } - if (seenn && parm < 3) { dp = save_string(dp, "%{96}%^"); } @@ -514,7 +513,7 @@ bcd_expression(const char *str) { char buffer[80]; int tst; - sprintf(buffer, fmt, ch1, ch2); + _nc_SPRINTF(buffer, _nc_SLIMIT(sizeof(buffer)) fmt, ch1, ch2); tst = strlen(buffer) - 1; assert(len == tst); } @@ -526,17 +525,20 @@ bcd_expression(const char *str) static char * save_tc_char(char *bufptr, int c1) { - char temp[80]; - if (is7bits(c1) && isprint(c1)) { if (c1 == ':' || c1 == '\\') bufptr = save_char(bufptr, '\\'); bufptr = save_char(bufptr, c1); } else { - if (c1 == (c1 & 0x1f)) /* iscntrl() returns T on 255 */ - (void) strcpy(temp, unctrl((chtype) c1)); - else - (void) sprintf(temp, "\\%03o", c1); + char temp[80]; + + if (c1 == (c1 & 0x1f)) { /* iscntrl() returns T on 255 */ + _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp)) + "%.20s", unctrl((chtype) c1)); + } else { + _nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp)) + "\\%03o", c1); + } bufptr = save_string(bufptr, temp); } return bufptr; @@ -576,7 +578,6 @@ save_tc_inequality(char *bufptr, int c1, int c2) NCURSES_EXPORT(char *) _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameterized) { - int strict_bsd = 1; /* FIXME - consider making this an option */ int seenone = 0, seentwo = 0, saw_m = 0, saw_n = 0; const char *padding; const char *trimmed = 0; @@ -589,8 +590,9 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz /* we may have to move some trailing mandatory padding up front */ padding = str + strlen(str) - 1; - if (padding > str && *padding == '>' && *--padding == '/') { - --padding; + if (padding > str && *padding == '>') { + if (*--padding == '/') + --padding; while (isdigit(UChar(*padding)) || *padding == '.' || *padding == '*') padding--; if (padding > str && *padding == '<' && *--padding == '$') @@ -601,7 +603,7 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz bufptr = save_char(bufptr, *padding++); } - for (; *str && str != trimmed; str++) { + for (; *str && ((trimmed == 0) || (str < trimmed)); str++) { int c1, c2; char *cp = 0; @@ -623,13 +625,15 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz } else if (str[1] == ',') { bufptr = save_char(bufptr, *++str); } else { - int xx1, xx2; + int xx1; bufptr = save_char(bufptr, *str++); xx1 = *str; - if (strict_bsd) { + if (_nc_strict_bsd) { + if (isdigit(UChar(xx1))) { int pad = 0; + int xx2; if (!isdigit(UChar(str[1]))) pad = 2; @@ -652,13 +656,11 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz bufptr = save_char(bufptr, xx2); xx2 = '0'; } - } else if (strchr("E\\:nrtbf", xx1) == 0) { - /* - * Note: termcap documentation claims that ":" must be - * escaped as "\072", however the documentation is - * incorrect - read the code. - */ + } else if (strchr("E\\nrtbf", xx1) == 0) { switch (xx1) { + case 'e': + xx1 = 'E'; + break; case 'l': xx1 = 'n'; break; @@ -667,13 +669,26 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz bufptr = save_char(bufptr, '4'); xx1 = '0'; break; + case ':': + /* + * Note: termcap documentation claims that ":" + * must be escaped as "\072", however the + * documentation is incorrect - read the code. + * The replacement does not work reliably, + * so the advice is not helpful. + */ + bufptr = save_char(bufptr, '0'); + bufptr = save_char(bufptr, '7'); + xx1 = '2'; + break; default: /* should not happen, but handle this anyway */ - sprintf(octal, "%03o", UChar(xx1)); + _nc_SPRINTF(octal, _nc_SLIMIT(sizeof(octal)) + "%03o", UChar(xx1)); bufptr = save_char(bufptr, octal[0]); bufptr = save_char(bufptr, octal[1]); xx1 = octal[2]; - continue; + break; } } } @@ -694,7 +709,8 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz && ((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"); + if ((str = strstr(str, ";m")) == 0) + break; /* cannot happen */ ++str; if (in2 == 48) { bufptr = save_string(bufptr, "[48;5;%dm"); @@ -711,13 +727,13 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz bufptr = save_tc_inequality(bufptr, c1, c2); } else if (sscanf(str, "%%?%%{%d}%%>%%t%%'%c'%%+%%;", &c1, &ch2) == 2) { str = strchr(str, ';'); - bufptr = save_tc_inequality(bufptr, c1, c2); + bufptr = save_tc_inequality(bufptr, c1, ch2); } else if (sscanf(str, "%%?%%'%c'%%>%%t%%{%d}%%+%%;", &ch1, &c2) == 2) { str = strchr(str, ';'); - bufptr = save_tc_inequality(bufptr, c1, c2); + bufptr = save_tc_inequality(bufptr, ch1, c2); } else if (sscanf(str, "%%?%%'%c'%%>%%t%%'%c'%%+%%;", &ch1, &ch2) == 2) { str = strchr(str, ';'); - bufptr = save_tc_inequality(bufptr, c1, c2); + bufptr = save_tc_inequality(bufptr, ch1, ch2); } else if ((len = bcd_expression(str)) != 0) { str += len; bufptr = save_string(bufptr, "%B"); @@ -732,15 +748,15 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz bufptr = save_tc_char(bufptr, c1); } /* FIXME: this "works" for 'delta' */ - else if (strncmp(str, "%{2}%*%-", 8) == 0) { + else if (strncmp(str, "%{2}%*%-", (size_t) 8) == 0) { str += 7; bufptr = save_string(bufptr, "%D"); - } else if (strncmp(str, "%{96}%^", 7) == 0) { + } else if (strncmp(str, "%{96}%^", (size_t) 7) == 0) { str += 6; if (saw_m++ == 0) { bufptr = save_string(bufptr, "%n"); } - } else if (strncmp(str, "%{127}%^", 8) == 0) { + } else if (strncmp(str, "%{127}%^", (size_t) 8) == 0) { str += 7; if (saw_n++ == 0) { bufptr = save_string(bufptr, "%m"); @@ -768,14 +784,14 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz while (isdigit(UChar(*str))) { ch2 = ch1; ch1 = *str++; - if (strict_bsd) { + if (_nc_strict_bsd) { if (ch1 > '3') return 0; } else { bufptr = save_char(bufptr, ch1); } } - if (strict_bsd) { + if (_nc_strict_bsd) { if (ch2 != 0 && ch2 != '0') return 0; if (ch1 < '2') @@ -802,7 +818,7 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz * termcap notation. */ case 's': - if (strict_bsd) + if (_nc_strict_bsd) return 0; bufptr = save_string(bufptr, "%s"); break; @@ -836,7 +852,7 @@ _nc_infotocap(const char *cap GCC_UNUSED, const char *str, int const parameteriz * but that may not be the end of the string. */ assert(str != 0); - if (*str == '\0') + if (str == 0 || *str == '\0') break; } /* endwhile (*str) */