Mercurial > emacs
annotate src/tparam.c @ 16886:c686d4f3728a
Change all uses of win95, winnt, and win32 into Windows 95, Windows
NT, and W32, respectively.
Expand "win" substring in variables referring to Microsoft Windows
constructs into "windows".
Canonicalize header comments to use same terminology.
author | Geoff Voelker <voelker@cs.washington.edu> |
---|---|
date | Mon, 20 Jan 1997 00:43:16 +0000 |
parents | 6e7bb4bd5010 |
children | cdc89dbad540 |
rev | line source |
---|---|
4687 | 1 /* Merge parameters into a termcap entry string. |
12678
8fc56d171ada
(tparam): Remove arg array and the #ifdef.
David J. MacKenzie <djm@gnu.org>
parents:
4687
diff
changeset
|
2 Copyright (C) 1985, 87, 93, 95 Free Software Foundation, Inc. |
4687 | 3 |
4 This program is free software; you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 2, or (at your option) | |
7 any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
15 along with this program; see the file COPYING. If not, write to | |
14414 | 16 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
17 Boston, MA 02111-1307, USA. */ | |
4687 | 18 |
19 /* Emacs config.h may rename various library functions such as malloc. */ | |
20 #ifdef HAVE_CONFIG_H | |
21 #include <config.h> | |
12994
bd38619285f7
Don't assume that HAVE_CONFIG_H implies emacs.
David J. MacKenzie <djm@gnu.org>
parents:
12678
diff
changeset
|
22 #endif |
4687 | 23 |
12994
bd38619285f7
Don't assume that HAVE_CONFIG_H implies emacs.
David J. MacKenzie <djm@gnu.org>
parents:
12678
diff
changeset
|
24 #ifndef emacs |
4687 | 25 #if defined(HAVE_STRING_H) || defined(STDC_HEADERS) |
26 #define bcopy(s, d, n) memcpy ((d), (s), (n)) | |
27 #endif | |
28 | |
29 #ifdef STDC_HEADERS | |
30 #include <stdlib.h> | |
31 #include <string.h> | |
32 #else | |
33 char *malloc (); | |
34 char *realloc (); | |
35 #endif | |
36 | |
12994
bd38619285f7
Don't assume that HAVE_CONFIG_H implies emacs.
David J. MacKenzie <djm@gnu.org>
parents:
12678
diff
changeset
|
37 #endif /* not emacs */ |
4687 | 38 |
39 #ifndef NULL | |
40 #define NULL (char *) 0 | |
41 #endif | |
42 | |
43 #ifndef emacs | |
44 static void | |
45 memory_out () | |
46 { | |
47 write (2, "virtual memory exhausted\n", 25); | |
48 exit (1); | |
49 } | |
50 | |
51 static char * | |
52 xmalloc (size) | |
53 unsigned size; | |
54 { | |
55 register char *tem = malloc (size); | |
56 | |
57 if (!tem) | |
58 memory_out (); | |
59 return tem; | |
60 } | |
61 | |
62 static char * | |
63 xrealloc (ptr, size) | |
64 char *ptr; | |
65 unsigned size; | |
66 { | |
67 register char *tem = realloc (ptr, size); | |
68 | |
69 if (!tem) | |
70 memory_out (); | |
71 return tem; | |
72 } | |
73 #endif /* not emacs */ | |
74 | |
75 /* Assuming STRING is the value of a termcap string entry | |
76 containing `%' constructs to expand parameters, | |
77 merge in parameter values and store result in block OUTSTRING points to. | |
78 LEN is the length of OUTSTRING. If more space is needed, | |
79 a block is allocated with `malloc'. | |
80 | |
81 The value returned is the address of the resulting string. | |
82 This may be OUTSTRING or may be the address of a block got with `malloc'. | |
83 In the latter case, the caller must free the block. | |
84 | |
85 The fourth and following args to tparam serve as the parameter values. */ | |
86 | |
87 static char *tparam1 (); | |
88 | |
89 /* VARARGS 2 */ | |
90 char * | |
91 tparam (string, outstring, len, arg0, arg1, arg2, arg3) | |
92 char *string; | |
93 char *outstring; | |
94 int len; | |
95 int arg0, arg1, arg2, arg3; | |
96 { | |
97 int arg[4]; | |
12678
8fc56d171ada
(tparam): Remove arg array and the #ifdef.
David J. MacKenzie <djm@gnu.org>
parents:
4687
diff
changeset
|
98 |
4687 | 99 arg[0] = arg0; |
100 arg[1] = arg1; | |
101 arg[2] = arg2; | |
102 arg[3] = arg3; | |
103 return tparam1 (string, outstring, len, NULL, NULL, arg); | |
104 } | |
105 | |
106 char *BC; | |
107 char *UP; | |
108 | |
109 static char tgoto_buf[50]; | |
110 | |
111 char * | |
112 tgoto (cm, hpos, vpos) | |
113 char *cm; | |
114 int hpos, vpos; | |
115 { | |
116 int args[2]; | |
117 if (!cm) | |
118 return NULL; | |
119 args[0] = vpos; | |
120 args[1] = hpos; | |
121 return tparam1 (cm, tgoto_buf, 50, UP, BC, args); | |
122 } | |
123 | |
124 static char * | |
125 tparam1 (string, outstring, len, up, left, argp) | |
126 char *string; | |
127 char *outstring; | |
128 int len; | |
129 char *up, *left; | |
130 register int *argp; | |
131 { | |
132 register int c; | |
133 register char *p = string; | |
134 register char *op = outstring; | |
135 char *outend; | |
136 int outlen = 0; | |
137 | |
138 register int tem; | |
139 int *old_argp = argp; | |
140 int doleft = 0; | |
141 int doup = 0; | |
142 | |
143 outend = outstring + len; | |
144 | |
145 while (1) | |
146 { | |
147 /* If the buffer might be too short, make it bigger. */ | |
148 if (op + 5 >= outend) | |
149 { | |
150 register char *new; | |
151 if (outlen == 0) | |
152 { | |
153 outlen = len + 40; | |
154 new = (char *) xmalloc (outlen); | |
155 outend += 40; | |
156 bcopy (outstring, new, op - outstring); | |
157 } | |
158 else | |
159 { | |
160 outend += outlen; | |
161 outlen *= 2; | |
162 new = (char *) xrealloc (outstring, outlen); | |
163 } | |
164 op += new - outstring; | |
165 outend += new - outstring; | |
166 outstring = new; | |
167 } | |
168 c = *p++; | |
169 if (!c) | |
170 break; | |
171 if (c == '%') | |
172 { | |
173 c = *p++; | |
174 tem = *argp; | |
175 switch (c) | |
176 { | |
177 case 'd': /* %d means output in decimal. */ | |
178 if (tem < 10) | |
179 goto onedigit; | |
180 if (tem < 100) | |
181 goto twodigit; | |
182 case '3': /* %3 means output in decimal, 3 digits. */ | |
183 if (tem > 999) | |
184 { | |
185 *op++ = tem / 1000 + '0'; | |
186 tem %= 1000; | |
187 } | |
188 *op++ = tem / 100 + '0'; | |
189 case '2': /* %2 means output in decimal, 2 digits. */ | |
190 twodigit: | |
191 tem %= 100; | |
192 *op++ = tem / 10 + '0'; | |
193 onedigit: | |
194 *op++ = tem % 10 + '0'; | |
195 argp++; | |
196 break; | |
197 | |
198 case 'C': | |
199 /* For c-100: print quotient of value by 96, if nonzero, | |
200 then do like %+. */ | |
201 if (tem >= 96) | |
202 { | |
203 *op++ = tem / 96; | |
204 tem %= 96; | |
205 } | |
206 case '+': /* %+x means add character code of char x. */ | |
207 tem += *p++; | |
208 case '.': /* %. means output as character. */ | |
209 if (left) | |
210 { | |
211 /* If want to forbid output of 0 and \n and \t, | |
212 and this is one of them, increment it. */ | |
213 while (tem == 0 || tem == '\n' || tem == '\t') | |
214 { | |
215 tem++; | |
216 if (argp == old_argp) | |
217 doup++, outend -= strlen (up); | |
218 else | |
219 doleft++, outend -= strlen (left); | |
220 } | |
221 } | |
222 *op++ = tem ? tem : 0200; | |
223 case 'f': /* %f means discard next arg. */ | |
224 argp++; | |
225 break; | |
226 | |
227 case 'b': /* %b means back up one arg (and re-use it). */ | |
228 argp--; | |
229 break; | |
230 | |
231 case 'r': /* %r means interchange following two args. */ | |
232 argp[0] = argp[1]; | |
233 argp[1] = tem; | |
234 old_argp++; | |
235 break; | |
236 | |
237 case '>': /* %>xy means if arg is > char code of x, */ | |
238 if (argp[0] > *p++) /* then add char code of y to the arg, */ | |
239 argp[0] += *p; /* and in any case don't output. */ | |
240 p++; /* Leave the arg to be output later. */ | |
241 break; | |
242 | |
243 case 'a': /* %a means arithmetic. */ | |
244 /* Next character says what operation. | |
245 Add or subtract either a constant or some other arg. */ | |
246 /* First following character is + to add or - to subtract | |
247 or = to assign. */ | |
248 /* Next following char is 'p' and an arg spec | |
249 (0100 plus position of that arg relative to this one) | |
250 or 'c' and a constant stored in a character. */ | |
251 tem = p[2] & 0177; | |
252 if (p[1] == 'p') | |
253 tem = argp[tem - 0100]; | |
254 if (p[0] == '-') | |
255 argp[0] -= tem; | |
256 else if (p[0] == '+') | |
257 argp[0] += tem; | |
258 else if (p[0] == '*') | |
259 argp[0] *= tem; | |
260 else if (p[0] == '/') | |
261 argp[0] /= tem; | |
262 else | |
263 argp[0] = tem; | |
264 | |
265 p += 3; | |
266 break; | |
267 | |
268 case 'i': /* %i means add one to arg, */ | |
269 argp[0] ++; /* and leave it to be output later. */ | |
270 argp[1] ++; /* Increment the following arg, too! */ | |
271 break; | |
272 | |
273 case '%': /* %% means output %; no arg. */ | |
274 goto ordinary; | |
275 | |
276 case 'n': /* %n means xor each of next two args with 140. */ | |
277 argp[0] ^= 0140; | |
278 argp[1] ^= 0140; | |
279 break; | |
280 | |
281 case 'm': /* %m means xor each of next two args with 177. */ | |
282 argp[0] ^= 0177; | |
283 argp[1] ^= 0177; | |
284 break; | |
285 | |
286 case 'B': /* %B means express arg as BCD char code. */ | |
287 argp[0] += 6 * (tem / 10); | |
288 break; | |
289 | |
290 case 'D': /* %D means weird Delta Data transformation. */ | |
291 argp[0] -= 2 * (tem % 16); | |
292 break; | |
293 } | |
294 } | |
295 else | |
296 /* Ordinary character in the argument string. */ | |
297 ordinary: | |
298 *op++ = c; | |
299 } | |
300 *op = 0; | |
301 while (doup-- > 0) | |
302 strcat (op, up); | |
303 while (doleft-- > 0) | |
304 strcat (op, left); | |
305 return outstring; | |
306 } | |
307 | |
308 #ifdef DEBUG | |
309 | |
310 main (argc, argv) | |
311 int argc; | |
312 char **argv; | |
313 { | |
314 char buf[50]; | |
315 int args[3]; | |
316 args[0] = atoi (argv[2]); | |
317 args[1] = atoi (argv[3]); | |
318 args[2] = atoi (argv[4]); | |
319 tparam1 (argv[1], buf, "LEFT", "UP", args); | |
320 printf ("%s\n", buf); | |
321 return 0; | |
322 } | |
323 | |
324 #endif /* DEBUG */ |