home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************
- * *
- * Copyright (c) 1982, Fred Fish *
- * All Rights Reserved *
- * *
- * This software and/or documentation is released for public *
- * distribution for personal, non-commercial use only. *
- * Limited rights to use, modify, and redistribute are hereby *
- * granted for non-commercial purposes, provided that all *
- * copyright notices remain intact and all changes are clearly *
- * documented. The author makes no warranty of any kind with *
- * respect to this product and explicitly disclaims any implied *
- * warranties of merchantability or fitness for any particular *
- * purpose. *
- * *
- ************************************************************************
- */
- /*
- * Modified:
- * 1 May 86 ...!ihnp4!ut-sally!ut-ngp!mic
- * Now forces a '\0' at end of tgoto string. Tgoto wasn't,
- * and this screwed up VT100-style (i.e. variable) cursor
- * addressing.
- *
- * 22 Jan 89 blarson@skat.usc.edu
- * Fix %. so it won't generate '\0'. This requires UP
- * and BC externals. Avoid troucing memory if bad format
- * string given. Make smaller and faster. Some comments
- * on the obvious eliminated to make code easier to read.
- */
-
-
-
- /*
- * LIBRARY FUNCTION
- *
- * tgoto expand cursor addressing string from cm capability
- *
- * KEY WORDS
- *
- * termcap
- *
- * SYNOPSIS
- *
- * extern char *UP;
- * extern char *BC;
- *
- * char *tgoto(cm,destcol,destline)
- * char *cm;
- * int destcol;
- * int destline;
- *
- * DESCRIPTION
- *
- * Returns cursor addressing string, decoded from the cm
- * capability string, to move cursor to column destcol on
- * line destline.
- *
- * The following sequences uses one input argument, either
- * line or column, and place the appropriate substitution
- * in the output string:
- *
- * %d substitute decimal value (in ASCII)
- * %2 like %d but forces field width to 2
- * %3 like %d but forces field width to 3
- * %. like %c
- * %+x like %c but adds ASCII value of x
- *
- * The following sequences cause processing modifications
- * but do not "use up" one of the arguments. If they
- * act on an argument they act on the next one to
- * be converted.
- *
- * %>xy if next value to be converted is
- * greater than value of ASCII char x
- * then add value of ASCII char y.
- * %r reverse substitution of line
- * and column (line is substituted
- * first by default).
- * %i causes input values destcol and
- * destline to be incremented.
- * %% gives single % character in output.
- *
- * BUGS
- *
- * Does not implement some of the more arcane sequences for
- * radically weird terminals (specifically %n, %B, & %D).
- * If you have one of these you deserve whatever happens.
- *
- */
-
- #include <stdio.h>
-
- extern char *UP; /* sequence to goto previous line */
- extern char *BC; /* sequence to goto previous char */
-
- char *tgoto(cm,destcol,destline)
- char *cm;
- int destcol;
- int destline;
- {
- register char *in; /* Internal copy of input string pointer */
- register char *out; /* Pointer to output array */
- register int pcount; /* Count of args processed */
- int args[2]; /* args to convert */
- static char output[64]; /* Converted string */
- int repos; /* flags that UP and BC are needed */
- /* 1 for UP, 2 for BC, 3 for both */
-
- if (cm == NULL) return "OOPS";
- in = cm;
- out = output;
- args[0] = destline;
- args[1] = destcol;
- pcount = 0;
- repos = 0;
- while (*in != '\0') {
- if (*in != '%') {
- *out++ = *in++;
- } else {
- in++;
- switch(*in++) {
- case 'd':
- sprintf(out,"%d",args[pcount]);
- out = &output[strlen(output)];
- pcount ^= 1;
- break;
- case '2':
- sprintf(out,"%02d",args[pcount]);
- out = &output[strlen(output)];
- pcount ^= 1;
- break;
- case '3':
- sprintf(out,"%03d",args[pcount]);
- out = &output[strlen(output)];
- pcount ^= 1;
- break;
- case '.':
- if((*out++ = args[pcount]) == '\0') {
- out[-1]++;
- repos |= pcount+1;
- }
- pcount ^= 1;
- break;
- case '+':
- if((*out++ = args[pcount] + *in++) == '\0') {
- out[-1]++;
- repos |= pcount+1;
- }
- pcount ^= 1;
- break;
- case '>':
- if (args[pcount] > *in++) {
- args[pcount] += *in++;
- } else {
- in++;
- }
- break;
- case 'r':
- pcount ^= 1;
- break;
- case 'i':
- args[0]++;
- args[1]++;
- break;
- case '%':
- *out++ = '%';
- break;
- }
- }
- }
- if(repos) {
- if(repos & 1) {
- if(UP != NULL) {
- in = UP;
- while(*in) *out++ = *in++;
- } /* else the output is screwed up */
- }
- if(repos & 2) {
- if(BC != NULL && *BC != '\0') {
- in = BC;
- while(*in) *out++ = *in++;
- } else {
- *out++ = '\b';
- }
- }
- }
- *out = '\0';
- return output;
- }
-