📄 captoinfo.c
字号:
/**************************************************************************** * Copyright (c) 1998-2003,2004 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 * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, distribute with modifications, sublicense, and/or sell * * copies of the Software, and to permit persons to whom the Software is * * furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included * * in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * * * Except as contained in this notice, the name(s) of the above copyright * * holders shall not be used in advertising or otherwise to promote the * * sale, use or other dealings in this Software without prior written * * authorization. * ****************************************************************************//**************************************************************************** * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * * and: Eric S. Raymond <esr@snark.thyrsus.com> * * and: Thomas E. Dickey 1996-on * ****************************************************************************//* * captoinfo.c --- conversion between termcap and terminfo formats * * The captoinfo() code was swiped from Ross Ridge's mytinfo package, * adapted to fit ncurses by Eric S. Raymond <esr@snark.thyrsus.com>. * * There is just one entry point: * * char *_nc_captoinfo(n, s, parameterized) * * Convert value s for termcap string capability named n into terminfo * format. * * This code recognizes all the standard 4.4BSD %-escapes: * * %% output `%' * %d output value as in printf %d * %2 output value as in printf %2d * %3 output value as in printf %3d * %. output value as in printf %c * %+x add x to value, then do %. * %>xy if value > x then add y, no output * %r reverse order of two parameters, no output * %i increment by one, no output * %n exclusive-or all parameters with 0140 (Datamedia 2500) * %B BCD (16*(value/10)) + (value%10), no output * %D Reverse coding (value - 2*(value%16)), no output (Delta Data). * * Also, %02 and %03 are accepted as synonyms for %2 and %3. * * Besides all the standard termcap escapes, this translator understands * the following extended escapes: * * used by GNU Emacs termcap libraries * %a[+*-/=][cp]x GNU arithmetic. * %m xor the first two parameters by 0177 * %b backup to previous parameter * %f skip this parameter * * used by the University of Waterloo (MFCF) termcap libraries * %-x subtract parameter FROM char x and output it as a char * %ax add the character x to parameter * * If #define WATERLOO is on, also enable these translations: * * %sx subtract parameter FROM the character x * * By default, this Waterloo translations are not compiled in, because * the Waterloo %s conflicts with the way terminfo uses %s in strings for * function programming. * * Note the two definitions of %a: the GNU definition is translated if the * characters after the 'a' are valid for it, otherwise the UW definition * is translated. */#include <curses.priv.h>#include <ctype.h>#include <tic.h>MODULE_ID("$Id: captoinfo.c,v 1.47 2005/06/04 22:06:43 tom Exp $")#define MAX_PUSHED 16 /* max # args we can push onto the stack */static int stack[MAX_PUSHED]; /* the stack */static int stackptr; /* the next empty place on the stack */static int onstack; /* the top of stack */static int seenm; /* seen a %m */static int seenn; /* seen a %n */static int seenr; /* seen a %r */static int param; /* current parameter */static char *dp; /* pointer to end of the converted string */static char *my_string;static size_t my_length;static char *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); *my_string = '\0'; return my_string;}static char *save_string(char *d, const char *const s){ size_t have = (d - my_string); size_t need = have + strlen(s) + 2; if (need > my_length) { my_string = (char *) realloc(my_string, my_length = (need + need)); if (my_string == 0) _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, int c){ static char temp[2]; temp[0] = (char) c; return save_string(s, temp);}static voidpush(void)/* push onstack on to the stack */{ if (stackptr > MAX_PUSHED) _nc_warning("string too complex to convert"); else stack[stackptr++] = onstack;}static voidpop(void)/* pop the top of the stack into onstack */{ if (stackptr == 0) { if (onstack == 0) _nc_warning("I'm confused"); else onstack = 0; } else onstack = stack[--stackptr]; param++;}static intcvtchar(register const char *sp)/* convert a character to a terminfo push */{ unsigned char c = 0; int len; switch (*sp) { case '\\': switch (*++sp) { case '\'': case '$': case '\\': case '%': c = *sp; len = 2; break; case '\0': c = '\\'; len = 1; break; case '0': case '1': case '2': case '3': len = 1; while (isdigit(UChar(*sp))) { c = 8 * c + (*sp++ - '0'); len++; } break; default: c = *sp; len = 2; break; } break; case '^': c = (*++sp & 0x1f); len = 2; break; default: c = *sp; len = 1; } if (isgraph(c) && c != ',' && c != '\'' && c != '\\' && c != ':') { dp = save_string(dp, "%\'"); dp = save_char(dp, c); dp = save_char(dp, '\''); } else { dp = save_string(dp, "%{"); if (c > 99) dp = save_char(dp, c / 100 + '0'); if (c > 9) dp = save_char(dp, ((int) (c / 10)) % 10 + '0'); dp = save_char(dp, c % 10 + '0'); dp = save_char(dp, '}'); } return len;}static voidgetparm(int parm, int n)/* push n copies of param on the terminfo stack if not already there */{ if (seenr) { if (parm == 1) parm = 2; else if (parm == 2) parm = 1; } if (onstack == parm) { if (n > 1) { _nc_warning("string may not be optimal"); dp = save_string(dp, "%Pa"); while (n--) { dp = save_string(dp, "%ga"); } } return; } if (onstack != 0) push(); onstack = parm; while (n--) { dp = save_string(dp, "%p"); dp = save_char(dp, '0' + parm); } if (seenn && parm < 3) { dp = save_string(dp, "%{96}%^"); } if (seenm && parm < 3) { dp = save_string(dp, "%{127}%^"); }}/* * 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; stackptr = 0; onstack = 0; seenm = 0; seenn = 0; seenr = 0; param = 1; dp = init_string(); /* skip the initial padding (if we haven't been told not to) */ capstart = 0; if (s == 0) s = ""; if (parameterized >= 0 && isdigit(UChar(*s))) for (capstart = s;; s++) if (!(isdigit(UChar(*s)) || *s == '*' || *s == '.')) break; while (*s != '\0') { switch (*s) { case '%': s++; if (parameterized < 1) { dp = save_char(dp, '%'); break; } switch (*s++) { case '%': dp = save_char(dp, '%'); break; case 'r': if (seenr++ == 1) { _nc_warning("saw %%r twice in %s", cap); } break; case 'm': if (seenm++ == 1) { _nc_warning("saw %%m twice in %s", cap); } break; case 'n': if (seenn++ == 1) { _nc_warning("saw %%n twice in %s", cap); } break; case 'i': dp = save_string(dp, "%i"); break; case '6': case 'B': getparm(param, 1); dp = save_string(dp, "%{10}%/%{16}%*"); getparm(param, 1); dp = save_string(dp, "%{10}%m%+"); break; case '8': case 'D': getparm(param, 2); dp = save_string(dp, "%{2}%*%-"); break; case '>': getparm(param, 2); /* %?%{x}%>%t%{y}%+%; */ dp = save_string(dp, "%?"); s += cvtchar(s); dp = save_string(dp, "%>%t"); s += cvtchar(s); dp = save_string(dp, "%+%;"); break; case 'a': if ((*s == '=' || *s == '+' || *s == '-' || *s == '*' || *s == '/') && (s[1] == 'p' || s[1] == 'c') && s[2] != '\0') { int l; l = 2; if (*s != '=') getparm(param, 1); if (s[1] == 'p') { getparm(param + s[2] - '@', 1); if (param != onstack) { pop(); param--; } l++; } else l += cvtchar(s + 2); switch (*s) { case '+': dp = save_string(dp, "%+"); break; case '-': dp = save_string(dp, "%-"); break; case '*': dp = save_string(dp, "%*"); break; case '/': dp = save_string(dp, "%/"); break; case '=': if (seenr) { if (param == 1) onstack = 2; else if (param == 2) onstack = 1; else onstack = param; } else onstack = param; break; } s += l; break; } getparm(param, 1); s += cvtchar(s); dp = save_string(dp, "%+"); break; case '+': getparm(param, 1); s += cvtchar(s); dp = save_string(dp, "%+%c"); pop(); break; case 's':#ifdef WATERLOO s += cvtchar(s); getparm(param, 1); dp = save_string(dp, "%-");#else getparm(param, 1); dp = save_string(dp, "%s"); pop();#endif /* WATERLOO */ break; case '-': s += cvtchar(s); getparm(param, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -