"Fossies" - the Fresh Open Source Software Archive

Member "termcap-1.3.1/tparam.c" (25 Feb 2002, 7671 Bytes) of package /linux/misc/old/termcap-1.3.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /* Merge parameters into a termcap entry string.
    2    Copyright (C) 1985, 87, 93, 95, 2000 Free Software Foundation, Inc.
    3 
    4 This program is free software; you can redistribute it and/or modify
    5 it under the terms of the GNU General Public License as published by
    6 the Free Software Foundation; either version 2, or (at your option)
    7 any later version.
    8 
    9 This program is distributed in the hope that it will be useful,
   10 but WITHOUT ANY WARRANTY; without even the implied warranty of
   11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12 GNU General Public License for more details.
   13 
   14 You should have received a copy of the GNU General Public License
   15 along with this program; see the file COPYING.  If not, write to
   16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   17 Boston, MA 02111-1307, USA.  */
   18 
   19 /* Emacs config.h may rename various library functions such as malloc.  */
   20 #ifdef HAVE_CONFIG_H
   21 #include <config.h>
   22 #endif
   23 
   24 #ifdef emacs
   25 #include "lisp.h"       /* for xmalloc */
   26 #else
   27 
   28 #ifdef STDC_HEADERS
   29 #include <stdlib.h>
   30 #include <string.h>
   31 #else
   32 char *malloc ();
   33 char *realloc ();
   34 #endif
   35 
   36 /* Do this after the include, in case string.h prototypes bcopy.  */
   37 #if (defined(HAVE_STRING_H) || defined(STDC_HEADERS)) && !defined(bcopy)
   38 #define bcopy(s, d, n) memcpy ((d), (s), (n))
   39 #endif
   40 
   41 #endif /* not emacs */
   42 
   43 #ifndef NULL
   44 #define NULL (char *) 0
   45 #endif
   46 
   47 #ifndef emacs
   48 static void
   49 memory_out ()
   50 {
   51   write (2, "virtual memory exhausted\n", 25);
   52   exit (1);
   53 }
   54 
   55 static char *
   56 xmalloc (size)
   57      unsigned size;
   58 {
   59   register char *tem = malloc (size);
   60 
   61   if (!tem)
   62     memory_out ();
   63   return tem;
   64 }
   65 
   66 static char *
   67 xrealloc (ptr, size)
   68      char *ptr;
   69      unsigned size;
   70 {
   71   register char *tem = realloc (ptr, size);
   72 
   73   if (!tem)
   74     memory_out ();
   75   return tem;
   76 }
   77 #endif /* not emacs */
   78 
   79 /* Assuming STRING is the value of a termcap string entry
   80    containing `%' constructs to expand parameters,
   81    merge in parameter values and store result in block OUTSTRING points to.
   82    LEN is the length of OUTSTRING.  If more space is needed,
   83    a block is allocated with `malloc'.
   84 
   85    The value returned is the address of the resulting string.
   86    This may be OUTSTRING or may be the address of a block got with `malloc'.
   87    In the latter case, the caller must free the block.
   88 
   89    The fourth and following args to tparam serve as the parameter values.  */
   90 
   91 static char *tparam1 ();
   92 
   93 /* VARARGS 2 */
   94 char *
   95 tparam (string, outstring, len, arg0, arg1, arg2, arg3)
   96      char *string;
   97      char *outstring;
   98      int len;
   99      int arg0, arg1, arg2, arg3;
  100 {
  101   int arg[4];
  102 
  103   arg[0] = arg0;
  104   arg[1] = arg1;
  105   arg[2] = arg2;
  106   arg[3] = arg3;
  107   return tparam1 (string, outstring, len, NULL, NULL, arg);
  108 }
  109 
  110 char *BC;
  111 char *UP;
  112 
  113 static char tgoto_buf[50];
  114 
  115 char *
  116 tgoto (cm, hpos, vpos)
  117      char *cm;
  118      int hpos, vpos;
  119 {
  120   int args[2];
  121   if (!cm)
  122     return NULL;
  123   args[0] = vpos;
  124   args[1] = hpos;
  125   return tparam1 (cm, tgoto_buf, 50, UP, BC, args);
  126 }
  127 
  128 static char *
  129 tparam1 (string, outstring, len, up, left, argp)
  130      char *string;
  131      char *outstring;
  132      int len;
  133      char *up, *left;
  134      register int *argp;
  135 {
  136   register int c;
  137   register char *p = string;
  138   register char *op = outstring;
  139   char *outend;
  140   int outlen = 0;
  141 
  142   register int tem;
  143   int *old_argp = argp;
  144   int doleft = 0;
  145   int doup = 0;
  146 
  147   outend = outstring + len;
  148 
  149   while (1)
  150     {
  151       /* If the buffer might be too short, make it bigger.  */
  152       if (op + 5 >= outend)
  153     {
  154       register char *new;
  155       int offset = op - outstring;
  156 
  157       if (outlen == 0)
  158         {
  159           outlen = len + 40;
  160           new = (char *) xmalloc (outlen);
  161           bcopy (outstring, new, offset);
  162         }
  163       else
  164         {
  165           outlen *= 2;
  166           new = (char *) xrealloc (outstring, outlen);
  167         }
  168       
  169       op = new + offset;
  170       outend = new + outlen;
  171       outstring = new;
  172     }
  173       c = *p++;
  174       if (!c)
  175     break;
  176       if (c == '%')
  177     {
  178       c = *p++;
  179       tem = *argp;
  180       switch (c)
  181         {
  182         case 'd':       /* %d means output in decimal.  */
  183           if (tem < 10)
  184         goto onedigit;
  185           if (tem < 100)
  186         goto twodigit;
  187         case '3':       /* %3 means output in decimal, 3 digits.  */
  188           if (tem > 999)
  189         {
  190           *op++ = tem / 1000 + '0';
  191           tem %= 1000;
  192         }
  193           *op++ = tem / 100 + '0';
  194         case '2':       /* %2 means output in decimal, 2 digits.  */
  195         twodigit:
  196           tem %= 100;
  197           *op++ = tem / 10 + '0';
  198         onedigit:
  199           *op++ = tem % 10 + '0';
  200           argp++;
  201           break;
  202 
  203         case 'C':
  204           /* For c-100: print quotient of value by 96, if nonzero,
  205          then do like %+.  */
  206           if (tem >= 96)
  207         {
  208           *op++ = tem / 96;
  209           tem %= 96;
  210         }
  211         case '+':       /* %+x means add character code of char x.  */
  212           tem += *p++;
  213         case '.':       /* %. means output as character.  */
  214           if (left)
  215         {
  216           /* If want to forbid output of 0 and \n and \t,
  217              and this is one of them, increment it.  */
  218           while (tem == 0 || tem == '\n' || tem == '\t')
  219             {
  220               tem++;
  221               if (argp == old_argp)
  222             doup++, outend -= strlen (up);
  223               else
  224             doleft++, outend -= strlen (left);
  225             }
  226         }
  227           *op++ = tem ? tem : 0200;
  228         case 'f':       /* %f means discard next arg.  */
  229           argp++;
  230           break;
  231 
  232         case 'b':       /* %b means back up one arg (and re-use it).  */
  233           argp--;
  234           break;
  235 
  236         case 'r':       /* %r means interchange following two args.  */
  237           argp[0] = argp[1];
  238           argp[1] = tem;
  239           old_argp++;
  240           break;
  241 
  242         case '>':       /* %>xy means if arg is > char code of x, */
  243           if (argp[0] > *p++) /* then add char code of y to the arg, */
  244         argp[0] += *p;  /* and in any case don't output.  */
  245           p++;      /* Leave the arg to be output later.  */
  246           break;
  247 
  248         case 'a':       /* %a means arithmetic.  */
  249           /* Next character says what operation.
  250          Add or subtract either a constant or some other arg.  */
  251           /* First following character is + to add or - to subtract
  252          or = to assign.  */
  253           /* Next following char is 'p' and an arg spec
  254          (0100 plus position of that arg relative to this one)
  255          or 'c' and a constant stored in a character.  */
  256           tem = p[2] & 0177;
  257           if (p[1] == 'p')
  258         tem = argp[tem - 0100];
  259           if (p[0] == '-')
  260         argp[0] -= tem;
  261           else if (p[0] == '+')
  262         argp[0] += tem;
  263           else if (p[0] == '*')
  264         argp[0] *= tem;
  265           else if (p[0] == '/')
  266         argp[0] /= tem;
  267           else
  268         argp[0] = tem;
  269 
  270           p += 3;
  271           break;
  272 
  273         case 'i':       /* %i means add one to arg, */
  274           argp[0] ++;   /* and leave it to be output later.  */
  275           argp[1] ++;   /* Increment the following arg, too!  */
  276           break;
  277 
  278         case '%':       /* %% means output %; no arg.  */
  279           goto ordinary;
  280 
  281         case 'n':       /* %n means xor each of next two args with 140.  */
  282           argp[0] ^= 0140;
  283           argp[1] ^= 0140;
  284           break;
  285 
  286         case 'm':       /* %m means xor each of next two args with 177.  */
  287           argp[0] ^= 0177;
  288           argp[1] ^= 0177;
  289           break;
  290 
  291         case 'B':       /* %B means express arg as BCD char code.  */
  292           argp[0] += 6 * (tem / 10);
  293           break;
  294 
  295         case 'D':       /* %D means weird Delta Data transformation.  */
  296           argp[0] -= 2 * (tem % 16);
  297           break;
  298 
  299         default:
  300           abort ();
  301         }
  302     }
  303       else
  304     /* Ordinary character in the argument string.  */
  305       ordinary:
  306     *op++ = c;
  307     }
  308   *op = 0;
  309   while (doup-- > 0)
  310     strcat (op, up);
  311   while (doleft-- > 0)
  312     strcat (op, left);
  313   return outstring;
  314 }
  315 
  316 #ifdef DEBUG
  317 
  318 main (argc, argv)
  319      int argc;
  320      char **argv;
  321 {
  322   char buf[50];
  323   int args[3];
  324   args[0] = atoi (argv[2]);
  325   args[1] = atoi (argv[3]);
  326   args[2] = atoi (argv[4]);
  327   tparam1 (argv[1], buf, "LEFT", "UP", args);
  328   printf ("%s\n", buf);
  329   return 0;
  330 }
  331 
  332 #endif /* DEBUG */