/* $OpenBSD: captoinfo.c,v 1.2 1996/06/02 23:47:01 tholo Exp $ */ /* * Copyright (c) 1996 SigmaSoft, Th. Lockert <tholo@sigmasoft.com> * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by SigmaSoft, Th. Lockert. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef lint static char rcsid[] = "$OpenBSD: captoinfo.c,v 1.2 1996/06/02 23:47:01 tholo Exp $"; #endif #include <stdlib.h> #include <string.h> #include <ctype.h> #include "term.private.h" #define STKSIZ 64 static int stack[STKSIZ]; static int stkidx; static int nflag; static int rflag; static int param; static int onstack; static char *d; static void pop() { if (stkidx > 0) onstack = stack[--stkidx]; else onstack = 0; param++; } static void push() { if (stkidx < STKSIZ) stack[stkidx++] = onstack; } static void getparam(p, n) int p; int n; { if (rflag) if (p == 1) p++; else if (p == 2) p--; if (onstack == p) { if (n > 1) { *d++ = '%'; *d++ = 'P'; *d++ = 'a'; while (n--) { *d++ = '%'; *d++ = 'g'; *d++ = 'a'; } } return; } if (onstack) push(); onstack = p; while (n--) { *d++ = '%'; *d++ = 'p'; *d++ = '0' + p; } if (nflag && p < 3) { *d++ = '%'; *d++ = '{'; *d++ = '9'; *d++ = '6'; *d++ = '}'; *d++ = '%'; *d++ = '^'; } } static int cvtchar(p) const char *p; { unsigned char ch = 0; int len; switch (*p) { case '\\': switch (*++p) { case '\'': case '$': case '\\': case '%': ch = *p; len = 2; break; case '\0': ch = '\\'; len = 1; break; case '0': case '1': case '2': case '3': len = 1; while (isdigit(*p)) { ch = ch * 8 + (*p++ - '0'); len++; } break; default: ch = *p; len = 2; break; } break; case '^': ch = (*++p & 0x1F); len = 2; break; default: ch = *p; len = 1; break; } if (isgraph(ch) && ch != ',' && ch != '\'' && ch != '\\' && ch != ':') { *d++ = '%'; *d++ = '\''; *d++ = ch; *d++ = '\''; } else { *d++ = '%'; *d++ = '{'; if (ch > 99) *d++ = ch / 100 + '0'; if (ch > 9) *d++ = ((int)ch / 10) % 10 + '0'; *d++ = ch % 10 + '0'; *d++ = '}'; } return len; } char * _ti_captoinfo(cap) const char *cap; { char ch, new[4096]; const char *cost; if (cap == NULL) return NULL; stkidx = 0; onstack = 0; nflag = 0; rflag = 0; param = 1; d = new; cost = NULL; if (isdigit(*cap)) for (cost = cap; isdigit(*cap) || *cap == '*' || *cap == '.'; cap++) ; while (*cap) { switch (*cap) { case '%': cap++; switch (ch = *cap++) { case '%': *d++ = '%'; break; case 'r': rflag++; break; case 'n': nflag++; break; case 'i': *d++ = '%'; *d++ = 'i'; break; case '6': case 'B': getparam(param, 2); *d++ = '%'; *d++ = '{'; *d++ = '6'; *d++ = '}'; *d++ = '%'; *d++ = '*'; *d++ = '%'; *d++ = '+'; break; case '8': case 'D': getparam(param, 2); *d++ = '%'; *d++ = '{'; *d++ = '2'; *d++ = '}'; *d++ = '%'; *d++ = '*'; *d++ = '%'; *d++ = '-'; break; case '>': getparam(param, 2); *d++ = '%'; *d++ = '?'; cap += cvtchar(cap); *d++ = '%'; *d++ = '>'; *d++ = '%'; *d++ = 't'; cap += cvtchar(cap); *d++ = '%'; *d++ = '+'; *d++ = '%'; *d++ = ';'; break; case 'a': getparam(param, 1); cap += cvtchar(cap); *d++ = '%'; *d++ = '+'; break; case 'd': case 's': getparam(param, 1); *d++ = '%'; *d++ = ch; pop(); break; case '+': case '-': getparam(param, 1); cap += cvtchar(cap); *d++ = '%'; *d++ = ch; *d++ = '%'; *d++ = 'c'; pop(); break; case '.': getparam(param, 1); *d++ = '%'; *d++ = 'c'; pop(); break; case '2': case '3': getparam(param, 1); *d++ = '%'; *d++ = ch; *d++ = 'd'; pop(); break; case '\\': *d++ = '%'; *d++ = '\\'; break; default: *d++ = '%'; cap--; break; } break; default: *d++ = *cap++; break; } } if (cost) { *d++ = '$'; *d++ = '<'; for (cap = cost;; cap++) if (isdigit(*cap) || *cap == '*' || *cap == '.') *d++ = *cap; else break; *d++ = '/'; *d++ = '>'; } *d = '\0'; return strdup(new); }