1: /* Merge parameters into a termcap entry string. 2: Copyright (C) 1985 Richard M. Stallman. 3: 4: This file is part of GNU Emacs. 5: 6: GNU Emacs is distributed in the hope that it will be useful, 7: but WITHOUT ANY WARRANTY. No author or distributor 8: accepts responsibility to anyone for the consequences of using it 9: or for whether it serves any particular purpose or works at all, 10: unless he says so in writing. Refer to the GNU Emacs General Public 11: License for full details. 12: 13: Everyone is granted permission to copy, modify and redistribute 14: GNU Emacs, but only under the conditions described in the 15: GNU Emacs General Public License. A copy of this license is 16: supposed to have been given to you along with GNU Emacs so you 17: can know your rights and responsibilities. It should be in a 18: file named COPYING. Among other things, the copyright notice 19: and this notice must be preserved on all copies. */ 20: 21: 22: /* Assuming `string' is the value of a termcap string entry 23: containing `%' constructs to expand parameters, 24: merge in parameter values and store result in block `outstring' points to. 25: No check is made for overflowing `outstring'; 26: the caller is wise to allocate space for it based on the size of 27: `string', knowing that the size can increase by at most a couple 28: of characters per parameter. 29: The third and following args to tparam serve as the parameter values. */ 30: 31: /* VARARGS 2 */ 32: tparam (string, outstring, arg) 33: char *string; 34: char *outstring; 35: int arg; 36: { 37: tparam1 (string, outstring, 0, 0, &arg); 38: } 39: 40: char *BC; 41: char *UP; 42: 43: static char tgoto_buf[50]; 44: 45: char * 46: tgoto (cm, hpos, vpos) 47: char *cm; 48: int hpos, vpos; 49: { 50: int args[2]; 51: if (!cm) 52: return 0; 53: args[0] = vpos; 54: args[1] = hpos; 55: tparam1 (cm, tgoto_buf, BC, UP, args); 56: return tgoto_buf; 57: } 58: 59: tparam1 (string, outstring, up, left, argp) 60: char *string; 61: register char *outstring; 62: char *up, *left; 63: register int *argp; 64: { 65: register int c; 66: register char *p = string; 67: 68: register int tem; 69: int *oargp = argp; 70: char *oleft = left; 71: 72: while (c = *p++) 73: { 74: if (c == '%') 75: { 76: c = *p++; 77: tem = *argp; 78: switch (c) 79: { 80: case 'd': /* %d means output in decimal */ 81: if (tem < 10) 82: goto onedigit; 83: if (tem < 100) 84: goto twodigit; 85: case '3': /* %3 means output in decimal, 3 digits. */ 86: *outstring++ = tem / 100 + '0'; 87: case '2': /* %2 means output in decimal, 2 digits. */ 88: twodigit: 89: tem %= 100; 90: *outstring++ = tem / 10 + '0'; 91: onedigit: 92: *outstring++ = tem % 10 + '0'; 93: argp++; 94: break; 95: 96: case 'C': 97: /* For c-100: print quotient of value by 96, if nonzero, 98: then do like %+ */ 99: if (tem >= 96) 100: { 101: *outstring++ = tem / 96; 102: tem %= 96; 103: } 104: case '+': /* %+x means add character code of char x */ 105: tem += *p++; 106: case '.': /* %. means output as character */ 107: if (oleft) 108: { 109: /* If want to forbid output of 0 and \n, 110: and this is one, increment it. */ 111: if (tem == 0 || tem == '\n') 112: tem++; 113: /* If this isn't one, cancel the compensation string 114: that would otherwise compensate for 115: the incrementation that we are not going to do. */ 116: else 117: { 118: if (argp == oargp) 119: left = 0; 120: else 121: up = 0; 122: } 123: } 124: *outstring++ = tem | 0200; 125: case 'f': /* %f means discard next arg */ 126: argp++; 127: break; 128: 129: case 'b': /* %b means back up one arg (and re-use it) */ 130: argp--; 131: break; 132: 133: case 'r': /* %r means interchange following two args */ 134: argp[0] = argp[1]; 135: argp[1] = tem; 136: oargp++; 137: break; 138: 139: case '>': /* %>xy means if arg is > char code of x, */ 140: if (argp[0] > *p++) /* then add char code of y to the arg, */ 141: argp[0] += *p; /* and in any case don't output. */ 142: p++; /* Leave the arg to be output later. */ 143: break; 144: 145: case 'a': /* %a means arithmetic */ 146: /* Next character says what operation. 147: Add or subtract either a constant or some other arg */ 148: /* First following character is + to add or - to subtract 149: or = to assign. */ 150: /* Next following char is 'p' and an arg spec 151: (0100 plus position of that arg relative to this one) 152: or 'c' and a constant stored in a character */ 153: tem = p[2] & 0177; 154: if (p[1] == 'p') 155: tem = argp[tem - 0100]; 156: if (p[0] == '-') 157: argp[0] -= tem; 158: else if (p[0] == '+') 159: argp[0] += tem; 160: else 161: argp[0] = tem; 162: 163: p += 3; 164: break; 165: 166: case 'i': /* %i means add one to arg, */ 167: argp[0] ++; /* and leave it to be output later. */ 168: argp[1] ++; /* Increment the following arg, too! */ 169: break; 170: 171: case '%': /* %% means output %; no arg. */ 172: goto ordinary; 173: 174: case 'n': /* %n means xor each of next two args with 140 */ 175: argp[0] ^= 0140; 176: argp[1] ^= 0140; 177: break; 178: 179: case 'm': /* %m means xor each of next two args with 177 */ 180: argp[0] ^= 0177; 181: argp[1] ^= 0177; 182: break; 183: 184: case 'B': /* %B means express arg as BCD char code. */ 185: argp[0] += 6 * (tem / 10); 186: break; 187: 188: case 'D': /* %D means weird Delta Data transformation */ 189: argp[0] -= 2 * (tem % 16); 190: break; 191: } 192: } 193: else 194: /* Ordinary character in the argument string. */ 195: ordinary: 196: *outstring++ = c; 197: } 198: *outstring = 0; 199: if (left) 200: strcat (outstring, left); 201: if (up) 202: strcat (outstring, up); 203: } 204: 205: #ifdef DEBUG 206: 207: main (argc, argv) 208: int argc; 209: char **argv; 210: { 211: char buf[50]; 212: int args[3]; 213: args[0] = atoi (argv[2]); 214: args[1] = atoi (argv[3]); 215: args[2] = atoi (argv[4]); 216: tparam1 (argv[1], buf, "LEFT", "UP", args); 217: printf ("%s\n", buf); 218: return 0; 219: } 220: 221: #endif /* DEBUG */