tgoto.c (5655B)
1 /************************************************************************ 2 * * 3 * Copyright (c) 1982, Fred Fish * 4 * All Rights Reserved * 5 * * 6 * This software and/or documentation is released for public * 7 * distribution for personal, non-commercial use only. * 8 * Limited rights to use, modify, and redistribute are hereby * 9 * granted for non-commercial purposes, provided that all * 10 * copyright notices remain intact and all changes are clearly * 11 * documented. The author makes no warranty of any kind with * 12 * respect to this product and explicitly disclaims any implied * 13 * warranties of merchantability or fitness for any particular * 14 * purpose. * 15 * * 16 ************************************************************************ 17 */ 18 19 20 /* 21 * LIBRARY FUNCTION 22 * 23 * tgoto expand cursor addressing string from cm capability 24 * 25 * KEY WORDS 26 * 27 * termcap 28 * 29 * SYNOPSIS 30 * 31 * char *tgoto(cm,destcol,destline) 32 * char *cm; 33 * int destcol; 34 * int destline; 35 * 36 * DESCRIPTION 37 * 38 * Returns cursor addressing string, decoded from the cm 39 * capability string, to move cursor to column destcol on 40 * line destline. 41 * 42 * The following sequences uses one input argument, either 43 * line or column, and place the appropriate substitution 44 * in the output string: 45 * 46 * %d substitute decimal value (in ASCII) 47 * %2 like %d but forces field width to 2 48 * %3 like %d but forces field width to 3 49 * %. like %c 50 * %+x like %c but adds ASCII value of x 51 * 52 * The following sequences cause processing modifications 53 * but do not "use up" one of the arguments. If they 54 * act on an argument they act on the next one to 55 * be converted. 56 * 57 * %>xy if next value to be converted is 58 * greater than value of ASCII char x 59 * then add value of ASCII char y. 60 * %r reverse substitution of line 61 * and column (line is substituted 62 * first by default). 63 * %i causes input values destcol and 64 * destline to be incremented. 65 * %% gives single % character in output. 66 * 67 * BUGS 68 * 69 * Does not implement some of the more arcane sequences for 70 * radically weird terminals (specifically %n, %B, & %D). 71 * If you have one of these you deserve whatever happens. 72 * 73 */ 74 75 /* 76 * Miscellaneous stuff 77 */ 78 79 #include <stdio.h> 80 81 #define MAXARGS 2 82 83 static char *in; /* Internal copy of input string pointer */ 84 static char *out; /* Pointer to output array */ 85 static int args[MAXARGS]; /* Maximum number of args to convert */ 86 static int pcount; /* Count of args processed */ 87 static char output[64]; /* Converted string */ 88 89 90 /* 91 * PSEUDO CODE 92 * 93 * Begin tgoto 94 * If no string to process then 95 * Return pointer to error string. 96 * Else 97 * Initialize pointer to input string. 98 * Initialize pointer to result string. 99 * First arg is line number by default. 100 * Second arg is col number by default. 101 * No arguments processed yet. 102 * While there is another character to process 103 * If character is a not a % character then 104 * Simply copy to output. 105 * Else 106 * Process the control sequence. 107 * End if 108 * End while 109 * Return pointer to static output string. 110 * End if 111 * End tgoto 112 * 113 */ 114 115 char *tgoto(cm,destcol,destline) 116 char *cm; 117 int destcol; 118 int destline; 119 { 120 if (cm == NULL) { 121 return("OOPS"); 122 } else { 123 in = cm; 124 out = output; 125 args[0] = destline; 126 args[1] = destcol; 127 pcount = 0; 128 while (*in != NULL) { 129 if (*in != '%') { 130 *out++ = *in++; 131 } else { 132 process(); 133 } 134 } 135 return(output); 136 } 137 } 138 139 /* 140 * INTERNAL FUNCTION 141 * 142 * process process the conversion/command sequence 143 * 144 * SYNOPSIS 145 * 146 * static process() 147 * 148 * DESCRIPTION 149 * 150 * Processes the sequence beginning with the % character. 151 * Directly manipulates the input string pointer, the 152 * output string pointer, and the arguments. Leaves 153 * the input string pointer pointing to the next character 154 * to be processed, and the output string pointer pointing 155 * to the next output location. If conversion of 156 * one of the numeric arguments occurs, then the pcount 157 * is incremented. 158 * 159 */ 160 161 /* 162 * PSEUDO CODE 163 * 164 * Begin process 165 * Skip over the % character. 166 * Switch on next character after % 167 * Case 'd': 168 * Process %d type conversion (variable width). 169 * Reinitialize output pointer. 170 * Break; 171 * Case '2': 172 * Process %d type conversion (width 2). 173 * Reinitialize output pointer. 174 * Break; 175 * Case '3': 176 * Process %d type conversion (width 3). 177 * Reinitialize output pointer. 178 * Break; 179 * Case '.' 180 * Process %c type conversion. 181 * Break; 182 * Case '+': 183 * Process %c type conversion with offset. 184 * Break; 185 * Case '>': 186 * Process argument modification. 187 * Break; 188 * Case 'r': 189 * Process argument reversal. 190 * Break; 191 * Case 'i': 192 * Increment argument values. 193 * Break; 194 * Case '%': 195 * Copy to output, incrementing pointers. 196 * Break; 197 * End switch 198 * End process 199 * 200 */ 201 202 203 static process() 204 { 205 int temp; 206 207 in++; 208 switch(*in++) { 209 case 'd': 210 sprintf(out,"%d",args[pcount++]); 211 out = &output[strlen(output)]; 212 break; 213 case '2': 214 sprintf(out,"%02d",args[pcount++]); 215 out = &output[strlen(output)]; 216 break; 217 case '3': 218 sprintf(out,"%03d",args[pcount++]); 219 out = &output[strlen(output)]; 220 break; 221 case '.': 222 *out++ = args[pcount++]; 223 break; 224 case '+': 225 *out++ = args[pcount++] + *in++; 226 break; 227 case '>': 228 if (args[pcount] > *in++) { 229 args[pcount] += *in++; 230 } else { 231 in++; 232 } 233 break; 234 case 'r': 235 temp = args[pcount]; 236 args[pcount] = args[pcount+1]; 237 args[pcount+1] = temp; 238 break; 239 case 'i': 240 args[pcount]++; 241 args[pcount+1]++; 242 break; 243 case '%': 244 *out++ = '%'; 245 break; 246 } 247 }