|
|
1.1 ! root 1: /********************************************************************* ! 2: * COPYRIGHT NOTICE * ! 3: ********************************************************************** ! 4: * This software is copyright (C) 1982 by Pavel Curtis * ! 5: * * ! 6: * Permission is granted to reproduce and distribute * ! 7: * this file by any means so long as no fee is charged * ! 8: * above a nominal handling fee and so long as this * ! 9: * notice is always included in the copies. * ! 10: * * ! 11: * Other rights are reserved except as explicitly granted * ! 12: * by written permission of the author. * ! 13: * Pavel Curtis * ! 14: * Computer Science Dept. * ! 15: * 405 Upson Hall * ! 16: * Cornell University * ! 17: * Ithaca, NY 14853 * ! 18: * * ! 19: * Ph- (607) 256-4934 * ! 20: * * ! 21: * Pavel.Cornell@Udel-Relay (ARPAnet) * ! 22: * decvax!cornell!pavel (UUCPnet) * ! 23: *********************************************************************/ ! 24: ! 25: /* ! 26: * tparm.c ! 27: * ! 28: * $Log: lib_tparm.c,v $ ! 29: * Revision 1.8 93/04/12 14:14:30 bin ! 30: * Udo: third color update ! 31: * ! 32: * Revision 2.4 92/10/23 00:31:38 munk ! 33: * npush(npop()...) does not work with COHERENT's cc ! 34: * because of side effects, use x = npop(); npush(x...) instead. ! 35: * Now hold x and y in register, not level. ! 36: * ! 37: * Revision 1.2 92/04/13 14:38:35 bin ! 38: * update by vlad ! 39: * ! 40: * Revision 2.2 91/04/20 21:54:27 munk ! 41: * Usage of register variables ! 42: * ! 43: * Revision 2.1 82/10/25 14:49:19 pavel ! 44: * Added Copyright Notice ! 45: * ! 46: * Revision 2.0 82/10/24 15:17:53 pavel ! 47: * Beta-one Test Release ! 48: * ! 49: * Revision 1.3 82/08/23 22:30:38 pavel ! 50: * The REAL Alpha-one Release Version ! 51: * ! 52: * Revision 1.2 82/08/19 19:11:33 pavel ! 53: * Alpha Test Release One ! 54: * ! 55: * Revision 1.1 82/08/12 18:45:33 pavel ! 56: * Initial revision ! 57: * ! 58: * ! 59: */ ! 60: ! 61: #ifdef RCSHDR ! 62: static char RCSid[] = ! 63: "$Header: /src386/usr/lib/ncurses/RCS/lib_tparm.c,v 1.8 93/04/12 14:14:30 bin Exp Locker: bin $"; ! 64: #endif ! 65: ! 66: #include "curses.h" ! 67: #include "curses.priv.h" ! 68: #include "term.h" ! 69: ! 70: ! 71: /* ! 72: * char * ! 73: * tparm(string, parms) ! 74: * ! 75: * Substitute the given parameters into the given string by the following ! 76: * rules (taken from terminfo(5)): ! 77: * ! 78: * Cursor addressing and other strings requiring parame- ! 79: * ters in the terminal are described by a parameterized string ! 80: * capability, with like escapes %x in it. For example, to ! 81: * address the cursor, the cup capability is given, using two ! 82: * parameters: the row and column to address to. (Rows and ! 83: * columns are numbered from zero and refer to the physical ! 84: * screen visible to the user, not to any unseen memory.) If ! 85: * the terminal has memory relative cursor addressing, that can ! 86: * be indicated by ! 87: * ! 88: * The parameter mechanism uses a stack and special % ! 89: * codes to manipulate it. Typically a sequence will push one ! 90: * of the parameters onto the stack and then print it in some ! 91: * format. Often more complex operations are necessary. ! 92: * ! 93: * The % encodings have the following meanings: ! 94: * ! 95: * %% outputs `%' ! 96: * %d print pop() like %d in printf() ! 97: * %2d print pop() like %2d in printf() ! 98: * %02d print pop() like %02d in printf() ! 99: * %3d print pop() like %3d in printf() ! 100: * %03d print pop() like %03d in printf() ! 101: * %c print pop() like %c in printf() ! 102: * %s print pop() like %s in printf() ! 103: * ! 104: * %p[1-9] push ith parm ! 105: * %P[a-z] set variable [a-z] to pop() ! 106: * %g[a-z] get variable [a-z] and push it ! 107: * %'c' push char constant c ! 108: * %{nn} push integer constant nn ! 109: * ! 110: * %+ %- %* %/ %m ! 111: * arithmetic (%m is mod): push(pop() op pop()) ! 112: * %& %| %^ bit operations: push(pop() op pop()) ! 113: * %= %> %< logical operations: push(pop() op pop()) ! 114: * %! %~ unary operations push(op pop()) ! 115: * %i add 1 to first two parms (for ANSI terminals) ! 116: * ! 117: * %? expr %t thenpart %e elsepart %; ! 118: * if-then-else, %e elsepart is optional. ! 119: * else-if's are possible ala Algol 68: ! 120: * %? c1 %t b1 %e c2 %t b2 %e c3 %t b3 %e c4 %t b4 %e b5 %; ! 121: * ! 122: * For those of the above operators which are binary and not commutative, ! 123: * the stack works in the usual way, with ! 124: * %gx %gy %m ! 125: * resulting in x mod y, not the reverse. ! 126: */ ! 127: ! 128: #define STACKSIZE 20 ! 129: ! 130: #define npush(x) if (stack_ptr < STACKSIZE) {stack[stack_ptr].num = x;\ ! 131: stack_ptr++;\ ! 132: } ! 133: #define npop() (stack_ptr > 0 ? stack[--stack_ptr].num : 0) ! 134: #define spop() (stack_ptr > 0 ? stack[--stack_ptr].str : (char *) 0) ! 135: ! 136: typedef union ! 137: { ! 138: unsigned int num; ! 139: char *str; ! 140: } stack_frame; ! 141: ! 142: stack_frame stack[STACKSIZE]; ! 143: static int stack_ptr; ! 144: static char buffer[256]; ! 145: static int *param; ! 146: static char *bufptr; ! 147: static int variable[26]; ! 148: ! 149: static char *do_tparm(); ! 150: ! 151: ! 152: char * ! 153: tparm(string, parms) ! 154: register char *string; ! 155: int parms; ! 156: { ! 157: char *strcpy(); ! 158: char len; ! 159: int number; ! 160: int level; ! 161: register int x, y; ! 162: ! 163: param = &parms; ! 164: ! 165: #ifdef TRACE ! 166: if (_tracing) ! 167: _tracef("tparm(%s,%d,%d,%d,%d,%d,%d,%d,%d,%d) called", ! 168: string, param[0], param[1], param[2], param[3], ! 169: param[4], param[5], param[6], param[7], param[8]); ! 170: #endif ! 171: ! 172: stack_ptr = 0; ! 173: bufptr = buffer; ! 174: ! 175: while (*string) ! 176: { ! 177: if (*string != '%') ! 178: *(bufptr++) = *string; ! 179: else ! 180: { ! 181: string++; ! 182: switch (*string) ! 183: { ! 184: default: ! 185: break; ! 186: ! 187: case '%': ! 188: *(bufptr++) = '%'; ! 189: break; ! 190: ! 191: case 'd': ! 192: sprintf(bufptr, "%d", npop()); ! 193: bufptr += strlen(bufptr); ! 194: break; ! 195: ! 196: case '0': ! 197: string++; ! 198: len = *string; ! 199: if ((len == '2' || len == '3') && *++string == 'd') ! 200: { ! 201: if (len == '2') ! 202: sprintf(bufptr, "%02d", npop()); ! 203: else ! 204: sprintf(bufptr, "%03d", npop()); ! 205: ! 206: bufptr += strlen(bufptr); ! 207: } ! 208: break; ! 209: ! 210: case '2': ! 211: string++; ! 212: if (*string == 'd') ! 213: { ! 214: sprintf(bufptr, "%2d", npop()); ! 215: bufptr += strlen(bufptr); ! 216: } ! 217: break; ! 218: ! 219: case '3': ! 220: string++; ! 221: if (*string == 'd') ! 222: { ! 223: sprintf(bufptr, "%3d", npop()); ! 224: bufptr += strlen(bufptr); ! 225: } ! 226: break; ! 227: ! 228: case 'c': ! 229: *(bufptr++) = (char) npop(); ! 230: break; ! 231: ! 232: case 's': ! 233: strcpy(bufptr, spop()); ! 234: bufptr += strlen(bufptr); ! 235: break; ! 236: ! 237: case 'p': ! 238: string++; ! 239: if (*string >= '1' && *string <= '9') ! 240: npush(param[*string - '1']); ! 241: break; ! 242: ! 243: case 'P': ! 244: string++; ! 245: if (*string >= 'a' && *string <= 'z') ! 246: variable[*string - 'a'] = npop(); ! 247: break; ! 248: ! 249: case 'g': ! 250: string++; ! 251: if (*string >= 'a' && *string <= 'z') ! 252: npush(variable[*string - 'a']); ! 253: break; ! 254: ! 255: case '\'': ! 256: string++; ! 257: npush(*string); ! 258: string++; ! 259: break; ! 260: ! 261: case '{': ! 262: number = 0; ! 263: string++; ! 264: while (*string >= '0' && *string <= '9') ! 265: { ! 266: number = number * 10 + *string - '0'; ! 267: string++; ! 268: } ! 269: npush(number); ! 270: break; ! 271: ! 272: case '+': ! 273: y = npop(); ! 274: x = npop(); ! 275: npush(x + y); ! 276: break; ! 277: ! 278: case '-': ! 279: y = npop(); ! 280: x = npop(); ! 281: npush(x - y); ! 282: break; ! 283: ! 284: case '*': ! 285: y = npop(); ! 286: x = npop(); ! 287: npush(x * y); ! 288: break; ! 289: ! 290: case '/': ! 291: y = npop(); ! 292: x = npop(); ! 293: npush(x / y); ! 294: break; ! 295: ! 296: case 'm': ! 297: y = npop(); ! 298: x = npop(); ! 299: npush(x % y); ! 300: break; ! 301: ! 302: case '&': ! 303: y = npop(); ! 304: x = npop(); ! 305: npush(x & y); ! 306: break; ! 307: ! 308: case '|': ! 309: y = npop(); ! 310: x = npop(); ! 311: npush(x | y); ! 312: break; ! 313: ! 314: case '^': ! 315: y = npop(); ! 316: x = npop(); ! 317: npush(x ^ y); ! 318: break; ! 319: ! 320: case '=': ! 321: y = npop(); ! 322: x = npop(); ! 323: npush(x == y); ! 324: break; ! 325: ! 326: case '<': ! 327: y = npop(); ! 328: x = npop(); ! 329: npush(x < y); ! 330: break; ! 331: ! 332: case '>': ! 333: y = npop(); ! 334: x = npop(); ! 335: npush(x > y); ! 336: break; ! 337: ! 338: case '!': ! 339: x = ! npop(); ! 340: npush(x); ! 341: break; ! 342: ! 343: case '~': ! 344: x = ~ npop(); ! 345: npush(x); ! 346: break; ! 347: ! 348: case 'i': ! 349: param[0]++; ! 350: param[1]++; ! 351: break; ! 352: ! 353: case '?': ! 354: break; ! 355: ! 356: case 't': ! 357: x = npop(); ! 358: if (x) ! 359: { ! 360: /* do nothing; keep executing */ ! 361: } ! 362: else ! 363: { ! 364: /* scan forward for %e or %; at level zero */ ! 365: string++; ! 366: level = 0; ! 367: while (*string) ! 368: { ! 369: if (*string == '%') ! 370: { ! 371: string++; ! 372: if (*string == '?') ! 373: level++; ! 374: else if (*string == ';') ! 375: { ! 376: if (level > 0) ! 377: level--; ! 378: else ! 379: break; ! 380: } ! 381: else if (*string == 'e' && level == 0) ! 382: break; ! 383: } ! 384: ! 385: if (*string) ! 386: string++; ! 387: } ! 388: } ! 389: break; ! 390: ! 391: case 'e': ! 392: /* scan forward for a %; at level zero */ ! 393: string++; ! 394: level = 0; ! 395: while (*string) ! 396: { ! 397: if (*string == '%') ! 398: { ! 399: string++; ! 400: if (*string == '?') ! 401: level++; ! 402: else if (*string == ';') ! 403: { ! 404: if (level > 0) ! 405: level--; ! 406: else ! 407: break; ! 408: } ! 409: } ! 410: ! 411: if (*string) ! 412: string++; ! 413: } ! 414: break; ! 415: ! 416: case ';': ! 417: break; ! 418: ! 419: } /* endswitch (*string) */ ! 420: } /* endelse (*string == '%') */ ! 421: ! 422: if (*string == '\0') ! 423: break; ! 424: ! 425: string++; ! 426: } /* endwhile (*string) */ ! 427: ! 428: *bufptr = '\0'; ! 429: return(buffer); ! 430: } ! 431: ! 432: ! 433: /* ! 434: * char * ! 435: * tgoto(string, x, y) ! 436: * ! 437: * Retained solely for upward compatibility. Note the intentional ! 438: * reversing of the last two arguments. ! 439: * ! 440: */ ! 441: ! 442: char * ! 443: tgoto(string, x, y) ! 444: char *string; ! 445: int x, y; ! 446: { ! 447: return(tparm(string, y, x)); ! 448: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.