tgetstr.c (6266B)
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 * tgetstr extract string capability from termcap entry 24 * 25 * KEY WORDS 26 * 27 * termcap 28 * 29 * SYNOPSIS 30 * 31 * char *tgetstr(id,area) 32 * char *id; 33 * char **area; 34 * 35 * DESCRIPTION 36 * 37 * Gets the string capability for <id>, placing it in 38 * the buffer at *area, and advancing *area to point 39 * to next available storage. 40 * 41 * For example, if the following capabilities are 42 * in the termcap file: 43 * 44 * ZZ=zzzz 45 * YY=yyyyyy 46 * WW=www 47 * 48 * then successive calls using YY, ZZ, and WW will 49 * build the following buffer: 50 * 51 * yyyyyy0zzzz0www0 52 * 53 * The first call will return a pointer to yyyyyy, the 54 * second will return a pointer to zzzz and the third 55 * will return a pointer to www. Note that each 56 * string is null terminated, as are all C strings. 57 * 58 * Characters preceded by the carot character (\136) 59 * are mapped into the corresponding control character. 60 * For example, the two character sequence ^A becomes 61 * a single control-A (\001) character. 62 * 63 * The escape character is the normal C backslash and 64 * the normal C escape sequences are recognized, along 65 * with a special sequence for the ASCII escape character 66 * (\033). The recognized sequences are: 67 * 68 * \E => '\033' (ASCII escape character) 69 * \b => '\010' (ASCII backspace character) 70 * \f => '\014' (ASCII form feed character) 71 * \n => '\012' (ASCII newline/linefeed char) 72 * \r => '\015' (ASCII carriage return char) 73 * \t => '\011' (ASCII tab character) 74 * \ddd => '\ddd' (arbitrary ASCII digit) 75 * \x => 'x' (ordinary ASCII character) 76 * 77 */ 78 79 #include <stdio.h> 80 # ifdef MSDOS 81 # define index strchr 82 # endif 83 84 extern char *_tcpbuf; /* Termcap entry buffer pointer */ 85 86 /* 87 * PSEUDO CODE 88 * 89 * Begin tgetstr 90 * Initialize pointer to the termcap entry buffer. 91 * While there is a field to process 92 * Skip over the field separator character. 93 * If this is the entry we want then 94 * If the entry is not a string then 95 * Return NULL. 96 * Else 97 * Transfer string and rtn pointer. 98 * End if 99 * End if 100 * End while 101 * Return NULL 102 * End tgetstr 103 * 104 */ 105 106 char *tgetstr(id,area) 107 char *id; 108 char **area; 109 { 110 char *bp; 111 extern char *index(); 112 char *decode(); 113 114 bp = _tcpbuf; 115 while ((bp = index(bp,':')) != NULL) { 116 bp++; 117 if (*bp++ == id[0] && *bp != NULL && *bp++ == id[1]) { 118 if (*bp != NULL && *bp++ != '=') { 119 return(NULL); 120 } else { 121 return(decode(bp,area)); 122 } 123 } 124 } 125 return(NULL); 126 } 127 128 /* 129 * INTERNAL FUNCTION 130 * 131 * decode transfer string capability, decoding escapes 132 * 133 * SYNOPSIS 134 * 135 * static char *decode(bp,area) 136 * char *bp; 137 * char **area; 138 * 139 * DESCRIPTION 140 * 141 * Transfers the string capability, up to the next ':' 142 * character, or null, to the buffer pointed to by 143 * the pointer in *area. Note that the initial 144 * value of *area and *area is updated to point 145 * to the next available location after the null 146 * terminating the transfered string. 147 * 148 * BUGS 149 * 150 * There is no overflow checking done on the destination 151 * buffer, so it better be large enough to hold 152 * all expected strings. 153 * 154 */ 155 156 /* 157 * PSEUDO CODE 158 * 159 * Begin decode 160 * Initialize the transfer pointer. 161 * While there is an input character left to process 162 * Switch on input character 163 * Case ESCAPE: 164 * Decode and xfer the escaped sequence. 165 * Break 166 * Case CONTROLIFY: 167 * Controlify and xfer the next character. 168 * Advance the buffer pointer. 169 * Break 170 * Default: 171 * Xfer a normal character. 172 * End switch 173 * End while 174 * Null terminate the output string. 175 * Remember where the output string starts. 176 * Update the output buffer pointer. 177 * Return pointer to the output string. 178 * End decode 179 * 180 */ 181 182 static char *decode(bp,area) 183 char *bp; 184 char **area; 185 { 186 char *cp, *bgn; 187 char *do_esc(); 188 189 cp = *area; 190 while (*bp != NULL && *bp != ':') { 191 switch(*bp) { 192 case '\\': 193 bp = do_esc(cp++,++bp); 194 break; 195 case '^': 196 *cp++ = *++bp & 037; 197 bp++; 198 break; 199 default: 200 *cp++ = *bp++; 201 break; 202 } 203 } 204 *cp++ = NULL; 205 bgn = *area; 206 *area = cp; 207 return(bgn); 208 } 209 210 /* 211 * INTERNAL FUNCTION 212 * 213 * do_esc process an escaped sequence 214 * 215 * SYNOPSIS 216 * 217 * char *do_esc(out,in); 218 * char *out; 219 * char *in; 220 * 221 * DESCRIPTION 222 * 223 * Processes an escape sequence pointed to by 224 * in, transfering it to location pointed to 225 * by out, and updating the pointer to in. 226 * 227 */ 228 229 /* 230 * PSEUDO CODE 231 * 232 * Begin do_esc 233 * If the first character is not a NULL then 234 * If is a digit then 235 * Set value to zero. 236 * For up to 3 digits 237 * Accumulate the sum. 238 * End for 239 * Transfer the sum. 240 * Else if character is in remap list then 241 * Transfer the remapped character. 242 * Advance the input pointer once. 243 * Else 244 * Simply transfer the character. 245 * End if 246 * End if 247 * Return updated input pointer. 248 * End do_esc 249 * 250 */ 251 252 static char *maplist = { 253 "E\033b\bf\fn\nr\rt\t" 254 }; 255 256 char *do_esc(out,in) 257 char *out; 258 char *in; 259 { 260 int count; 261 char ch; 262 char *cp; 263 extern int isdigit(); 264 265 if (*in != NULL) { 266 if (isdigit(*in)) { 267 ch = 0; 268 for (count = 0; count < 3 && isdigit(*in); in++) { 269 ch <<= 3; 270 ch |= (*in - '0'); 271 } 272 *out++ = ch; 273 } else if ((cp = index(maplist,*in)) != NULL) { 274 *out++ = *++cp; 275 in++; 276 } else { 277 *out++ = *in++; 278 } 279 } 280 return(in); 281 }