Build Fix -- compatibility issue with newer autoconf
[sxemacs] / src / ui / TTY / tparam.c
1 /* Merge parameters into a termcap entry string.
2    Copyright (C) 1985, 1987, 1992, 1993, 1994 Free Software Foundation, Inc.
3
4 This file is part of SXEmacs
5
6 SXEmacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 SXEmacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
18
19
20 /* Synched up with: Not synched with FSF. */
21
22 /* config.h may rename various library functions such as malloc.  */
23 #ifdef emacs
24
25 #include <config.h>
26
27 #include <string.h>
28
29 #define realloc xrealloc
30 #define malloc xmalloc
31 #define free xfree
32 extern void *xmalloc(size_t size);
33 extern void *xrealloc(void *, size_t size);
34
35 #else                           /* emacs */
36
37 #ifdef STDC_HEADERS
38 #include <stdlib.h>
39 #include <string.h>
40 #else
41 extern char *malloc();
42 extern char *realloc();
43 #endif
44
45 #endif                          /* !emacs */
46
47 /* Assuming STRING is the value of a termcap string entry
48    containing `%' constructs to expand parameters,
49    merge in parameter values and store result in block OUTSTRING points to.
50    LEN is the length of OUTSTRING.  If more space is needed,
51    a block is allocated with `malloc'.
52
53    The value returned is the address of the resulting string.
54    This may be OUTSTRING or may be the address of a block got with `malloc'.
55    In the latter case, the caller must free the block.
56
57    The fourth and following args to tparam serve as the parameter values.  */
58
59 static char *tparam1(const char *string, char *outstring, int len,
60                      const char *up, const char *left, int *argp);
61
62 /* XEmacs: renamed this function because just tparam() conflicts with
63    ncurses */
64 char *emacs_tparam(const char *string, char *outstring, int len, int arg1,
65                    int arg2, int arg3, int arg4, int arg5, int arg6, int arg7,
66                    int arg8, int arg9)
67 {
68         int arg[9];
69         arg[0] = arg1;
70         arg[1] = arg2;
71         arg[2] = arg3;
72         arg[3] = arg4;
73         arg[4] = arg5;
74         arg[5] = arg6;
75         arg[6] = arg7;
76         arg[7] = arg8;
77         arg[8] = arg9;
78         return tparam1(string, outstring, len, 0, 0, arg);
79 }
80
81 const char *BC;
82 const char *UP;
83
84 static char tgoto_buf[50];
85
86 char *tgoto(const char *cm, int hpos, int vpos);
87 char *tgoto(const char *cm, int hpos, int vpos)
88 {
89         int args[2];
90         if (!cm)
91                 return 0;
92         args[0] = vpos;
93         args[1] = hpos;
94         return tparam1(cm, tgoto_buf, 50, UP, BC, args);
95 }
96
97 static char *tparam1(const char *string, char *outstring, int len,
98                      const char *up, const char *left, int *argp)
99 {
100         int c;
101         const char *p = string;
102         char *op = outstring;
103         char *outend;
104         int outlen = 0;
105
106         int tem;
107         int *old_argp = argp;
108         int doleft = 0;
109         int doup = 0;
110
111         outend = outstring + len;
112
113         while (1) {
114                 /* If the buffer might be too short, make it bigger.  */
115                 if (op + 5 >= outend) {
116                         char *new;
117                         if (outlen == 0) {
118                                 outlen = len + 40;
119                                 new = (char *)malloc(outlen);
120                                 outend += 40;
121                                 memcpy(new, outstring, op - outstring);
122                         } else {
123                                 outend += outlen;
124                                 outlen *= 2;
125                                 new = (char *)realloc(outstring, outlen);
126                         }
127                         op += new - outstring;
128                         outend += new - outstring;
129                         outstring = new;
130                 }
131                 c = *p++;
132                 if (!c)
133                         break;
134                 if (c == '%') {
135                         c = *p++;
136                         tem = *argp;
137                         switch (c) {
138                         case 'd':       /* %d means output in decimal.  */
139                                 if (tem < 10)
140                                         goto onedigit;
141                                 if (tem < 100)
142                                         goto twodigit;
143                         case '3':       /* %3 means output in decimal, 3 digits.  */
144                                 if (tem > 999) {
145                                         *op++ = tem / 1000 + '0';
146                                         tem %= 1000;
147                                 }
148                                 *op++ = tem / 100 + '0';
149                         case '2':       /* %2 means output in decimal, 2 digits.  */
150                               twodigit:
151                                 tem %= 100;
152                                 *op++ = tem / 10 + '0';
153                               onedigit:
154                                 *op++ = tem % 10 + '0';
155                                 argp++;
156                                 break;
157
158                         case 'C':
159                                 /* For c-100: print quotient of value by 96, if nonzero,
160                                    then do like %+.  */
161                                 if (tem >= 96) {
162                                         *op++ = tem / 96;
163                                         tem %= 96;
164                                 }
165                         case '+':       /* %+x means add character code of char x.  */
166                                 tem += *p++;
167                         case '.':       /* %. means output as character.  */
168                                 if (left) {
169                                         /* If want to forbid output of 0 and \n and \t,
170                                            and this is one of them, increment it.  */
171                                         while (tem == 0 || tem == '\n'
172                                                || tem == '\t') {
173                                                 tem++;
174                                                 if (argp == old_argp)
175                                                         doup++, outend -=
176                                                             strlen(up);
177                                                 else
178                                                         doleft++, outend -=
179                                                             strlen(left);
180                                         }
181                                 }
182                                 *op++ = tem | 0200;
183                         case 'f':       /* %f means discard next arg.  */
184                                 argp++;
185                                 break;
186
187                         case 'b':       /* %b means back up one arg (and re-use it). */
188                                 argp--;
189                                 break;
190
191                         case 'r':       /* %r means interchange following two args. */
192                                 argp[0] = argp[1];
193                                 argp[1] = tem;
194                                 old_argp++;
195                                 break;
196
197                         case '>':       /* %>xy means if arg is > char code of x, */
198                                 if (argp[0] > *p++)     /* then add char code of y to the arg, */
199                                         argp[0] += *p;  /* and in any case don't output. */
200                                 p++;    /* Leave the arg to be output later. */
201                                 break;
202
203                         case 'a':       /* %a means arithmetic. */
204                                 /* Next character says what operation.
205                                    Add or subtract either a constant or some other arg. */
206                                 /* First following character is + to add or - to subtract
207                                    or = to assign.  */
208                                 /* Next following char is 'p' and an arg spec
209                                    (0100 plus position of that arg relative to this one)
210                                    or 'c' and a constant stored in a character. */
211                                 tem = p[2] & 0177;
212                                 if (p[1] == 'p')
213                                         tem = argp[tem - 0100];
214                                 if (p[0] == '-')
215                                         argp[0] -= tem;
216                                 else if (p[0] == '+')
217                                         argp[0] += tem;
218                                 else if (p[0] == '*')
219                                         argp[0] *= tem;
220                                 else if (p[0] == '/')
221                                         argp[0] /= tem;
222                                 else
223                                         argp[0] = tem;
224
225                                 p += 3;
226                                 break;
227
228                         case 'i':       /* %i means add one to arg, */
229                                 argp[0]++;      /* and leave it to be output later. */
230                                 argp[1]++;      /* Increment the following arg, too!  */
231                                 break;
232
233                         case '%':       /* %% means output %; no arg. */
234                                 goto ordinary;
235
236                         case 'n':       /* %n means xor each of next two args with 140. */
237                                 argp[0] ^= 0140;
238                                 argp[1] ^= 0140;
239                                 break;
240
241                         case 'm':       /* %m means xor each of next two args with 177. */
242                                 argp[0] ^= 0177;
243                                 argp[1] ^= 0177;
244                                 break;
245
246                         case 'B':       /* %B means express arg as BCD char code. */
247                                 argp[0] += 6 * (tem / 10);
248                                 break;
249
250                         case 'D':       /* %D means weird Delta Data transformation. */
251                                 argp[0] -= 2 * (tem % 16);
252                                 break;
253                         }
254                 } else
255                         /* Ordinary character in the argument string.  */
256                       ordinary:
257                         *op++ = c;
258         }
259         *op = 0;
260         while (doup-- > 0)
261                 strcat(op, up);
262         while (doleft-- > 0)
263                 strcat(op, left);
264         return outstring;
265 }
266 \f
267 #ifdef DEBUG
268
269 main(argc, argv)
270 int argc;
271 char **argv;
272 {
273         char buf[50];
274         int args[3];
275         args[0] = atoi(argv[2]);
276         args[1] = atoi(argv[3]);
277         args[2] = atoi(argv[4]);
278         tparam1(argv[1], buf, "LEFT", "UP", args);
279         printf("%s\n", buf);
280         return 0;
281 }
282
283 #endif                          /* DEBUG */