105 |
7u83 |
1 |
/*
|
|
|
2 |
* Copyright (c) 1980 Regents of the University of California.
|
|
|
3 |
* All rights reserved. The Berkeley software License Agreement
|
|
|
4 |
* specifies the terms and conditions for redistribution.
|
|
|
5 |
*
|
|
|
6 |
* @(#)ex.h 7.7.1.1 (Berkeley) 8/12/86
|
|
|
7 |
*/
|
|
|
8 |
|
|
|
9 |
#ifdef V6
|
|
|
10 |
#include <retrofit.h>
|
|
|
11 |
#endif
|
|
|
12 |
|
|
|
13 |
/*
|
|
|
14 |
* Ex version 3 (see exact version in ex_cmds.c, search for /Version/)
|
|
|
15 |
*
|
|
|
16 |
* Mark Horton, UC Berkeley
|
|
|
17 |
* Bill Joy, UC Berkeley
|
|
|
18 |
* November 1979
|
|
|
19 |
*
|
|
|
20 |
* Changes by Gunnar Ritter, Freiburg i. Br., Germany
|
|
|
21 |
* May 2000
|
|
|
22 |
*
|
|
|
23 |
* This file contains most of the declarations common to a large number
|
|
|
24 |
* of routines. The file ex_vis.h contains declarations
|
|
|
25 |
* which are used only inside the screen editor.
|
|
|
26 |
* The file ex_tune.h contains parameters which can be diddled per installation.
|
|
|
27 |
*
|
|
|
28 |
* The declarations relating to the argument list, regular expressions,
|
|
|
29 |
* the temporary file data structure used by the editor
|
|
|
30 |
* and the data describing terminals are each fairly substantial and
|
|
|
31 |
* are kept in the files ex_{argv,re,temp,tty}.h which
|
|
|
32 |
* we #include separately.
|
|
|
33 |
*
|
|
|
34 |
* If you are going to dig into ex, you should look at the outline of the
|
|
|
35 |
* distribution of the code into files at the beginning of ex.c and ex_v.c.
|
|
|
36 |
* Code which is similar to that of ed is lightly or undocumented in spots
|
|
|
37 |
* (e.g. the regular expression code). Newer code (e.g. open and visual)
|
|
|
38 |
* is much more carefully documented, and still rough in spots.
|
|
|
39 |
*
|
|
|
40 |
* Please forward bug reports to
|
|
|
41 |
*
|
|
|
42 |
* Mark Horton
|
|
|
43 |
* Computer Science Division, EECS
|
|
|
44 |
* EVANS HALL
|
|
|
45 |
* U.C. Berkeley 94704
|
|
|
46 |
* (415) 642-4948
|
|
|
47 |
* (415) 642-1024 (dept. office)
|
|
|
48 |
*
|
|
|
49 |
* or to csvax.mark@berkeley on the ARPA-net. I would particularly like to hear
|
|
|
50 |
* of additional terminal descriptions you add to the termcap data base.
|
|
|
51 |
*/
|
|
|
52 |
|
|
|
53 |
#include <sys/param.h>
|
|
|
54 |
#include <ctype.h>
|
|
|
55 |
#include <errno.h>
|
|
|
56 |
#include <signal.h>
|
|
|
57 |
#include <setjmp.h>
|
|
|
58 |
#include <sys/stat.h>
|
|
|
59 |
|
|
|
60 |
#ifndef var
|
|
|
61 |
#define var extern
|
|
|
62 |
#endif
|
|
|
63 |
/*
|
|
|
64 |
* The following little dance copes with the new USG tty handling.
|
|
|
65 |
* This stuff has the advantage of considerable flexibility, and
|
|
|
66 |
* the disadvantage of being incompatible with anything else.
|
|
|
67 |
* The presence of the symbol USG3TTY will indicate the new code:
|
|
|
68 |
* in this case, we define CBREAK (because we can simulate it exactly),
|
|
|
69 |
* but we won't actually use it, so we set it to a value that will
|
|
|
70 |
* probably blow the compilation if we goof up.
|
|
|
71 |
*/
|
|
|
72 |
#ifdef USG3TTY
|
|
|
73 |
#include <termios.h>
|
|
|
74 |
#define CBREAK xxxxx
|
|
|
75 |
#else
|
|
|
76 |
#include <sgtty.h>
|
|
|
77 |
#endif
|
|
|
78 |
|
|
|
79 |
extern int errno;
|
|
|
80 |
|
|
|
81 |
#ifdef NCURSES
|
|
|
82 |
/*
|
|
|
83 |
* Some of the symbols collide.
|
|
|
84 |
*/
|
|
|
85 |
#define LINES LI_NES
|
|
|
86 |
#define cleanup clean_up
|
|
|
87 |
#define filter fil_ter
|
|
|
88 |
#define getch get_ch
|
|
|
89 |
#define longname long_name
|
|
|
90 |
#define ttytype tty_type
|
|
|
91 |
#define winch win_ch
|
|
|
92 |
#endif
|
|
|
93 |
|
|
|
94 |
#ifndef VMUNIX
|
|
|
95 |
typedef short line;
|
|
|
96 |
#else
|
|
|
97 |
typedef int line;
|
|
|
98 |
#endif
|
|
|
99 |
typedef short bool;
|
|
|
100 |
|
|
|
101 |
#include "ex_tune.h"
|
|
|
102 |
#include "ex_vars.h"
|
|
|
103 |
/*
|
|
|
104 |
* Options in the editor are referred to usually by "value(name)" where
|
|
|
105 |
* name is all uppercase, i.e. "value(PROMPT)". This is actually a macro
|
|
|
106 |
* which expands to a fixed field in a static structure and so generates
|
|
|
107 |
* very little code. The offsets for the option names in the structure
|
|
|
108 |
* are generated automagically from the structure initializing them in
|
|
|
109 |
* ex_data.c... see the shell script "makeoptions".
|
|
|
110 |
*/
|
|
|
111 |
struct option {
|
|
|
112 |
char *oname;
|
|
|
113 |
char *oabbrev;
|
|
|
114 |
short otype; /* Types -- see below */
|
|
|
115 |
short odefault; /* Default value */
|
|
|
116 |
short ovalue; /* Current value */
|
|
|
117 |
char *osvalue;
|
|
|
118 |
};
|
|
|
119 |
|
|
|
120 |
#define ONOFF 0
|
|
|
121 |
#define NUMERIC 1
|
|
|
122 |
#define STRING 2 /* SHELL or DIRECTORY */
|
|
|
123 |
#define OTERM 3
|
|
|
124 |
|
|
|
125 |
#define value(a) options[a].ovalue
|
|
|
126 |
#define svalue(a) options[a].osvalue
|
|
|
127 |
|
|
|
128 |
extern struct option options[NOPTS + 1];
|
|
|
129 |
|
|
|
130 |
|
|
|
131 |
/*
|
|
|
132 |
* The editor does not normally use the standard i/o library. Because
|
|
|
133 |
* we expect the editor to be a heavily used program and because it
|
|
|
134 |
* does a substantial amount of input/output processing it is appropriate
|
|
|
135 |
* for it to call low level read/write primitives directly. In fact,
|
|
|
136 |
* when debugging the editor we use the standard i/o library. In any
|
|
|
137 |
* case the editor needs a printf which prints through "putchar" ala the
|
|
|
138 |
* old version 6 printf. Thus we normally steal a copy of the "printf.c"
|
|
|
139 |
* and "strout" code from the standard i/o library and mung it for our
|
|
|
140 |
* purposes to avoid dragging in the stdio library headers, etc if we
|
|
|
141 |
* are not debugging. Such a modified printf exists in "printf.c" here.
|
|
|
142 |
*/
|
|
|
143 |
#ifdef TRACE
|
|
|
144 |
# include <stdio.h>
|
|
|
145 |
var FILE *trace;
|
|
|
146 |
var bool trubble;
|
|
|
147 |
var bool techoin;
|
|
|
148 |
var char tracbuf[BUFSIZ];
|
|
|
149 |
# undef putchar
|
|
|
150 |
# undef getchar
|
|
|
151 |
#else
|
|
|
152 |
#ifndef BUFSIZ /* GR */
|
|
|
153 |
# ifdef VMUNIX
|
|
|
154 |
# ifdef BIGMEM
|
|
|
155 |
# define BUFSIZ 4096
|
|
|
156 |
# else
|
|
|
157 |
# define BUFSIZ 1024
|
|
|
158 |
# endif
|
|
|
159 |
# else
|
|
|
160 |
# ifdef u370
|
|
|
161 |
# define BUFSIZ 4096
|
|
|
162 |
# else
|
|
|
163 |
# define BUFSIZ 512
|
|
|
164 |
# endif
|
|
|
165 |
# endif
|
|
|
166 |
#endif
|
|
|
167 |
# define NULL 0
|
|
|
168 |
# define EOF -1
|
|
|
169 |
#endif
|
|
|
170 |
|
|
|
171 |
#ifndef MAXBSIZE /* GR */
|
|
|
172 |
#define MAXBSIZE BUFSIZ
|
|
|
173 |
#endif
|
|
|
174 |
|
|
|
175 |
/*
|
|
|
176 |
* Character constants and bits
|
|
|
177 |
*
|
|
|
178 |
* The editor uses the QUOTE bit as a flag to pass on with characters
|
|
|
179 |
* e.g. to the putchar routine. The editor never uses a simple char variable.
|
|
|
180 |
* Only arrays of and pointers to characters are used and parameters and
|
|
|
181 |
* registers are never declared character.
|
|
|
182 |
*/
|
|
|
183 |
#ifndef BIT8
|
|
|
184 |
#define QUOTE 0200
|
|
|
185 |
#define TRIM 0177
|
|
|
186 |
#else
|
|
|
187 |
#define QUOTE 0x200
|
|
|
188 |
#define TRIM 0x1FF
|
|
|
189 |
short *ss_strcpy();
|
|
|
190 |
short *sc_strcpy();
|
|
|
191 |
char *cs_strcpy();
|
|
|
192 |
unsigned int s_strlen();
|
|
|
193 |
short *sc_strcat();
|
|
|
194 |
#endif
|
|
|
195 |
#undef CTRL
|
|
|
196 |
#define CTRL(c) (c & 037)
|
|
|
197 |
#define NL CTRL('j')
|
|
|
198 |
#define CR CTRL('m')
|
|
|
199 |
#define DELETE 0177 /* See also ATTN, QUIT in ex_tune.h */
|
|
|
200 |
#define ESCAPE 033
|
|
|
201 |
|
|
|
202 |
#ifdef ISO
|
|
|
203 |
#define niso(c) ((c) & QUOTE && ((unsigned char)(c)) < (QUOTE + ' '))
|
|
|
204 |
#endif
|
|
|
205 |
|
|
|
206 |
var const char *versionstring;
|
|
|
207 |
|
|
|
208 |
/*
|
|
|
209 |
* Miscellaneous random variables used in more than one place
|
|
|
210 |
*/
|
|
|
211 |
var bool aiflag; /* Append/change/insert with autoindent */
|
|
|
212 |
var bool anymarks; /* We have used '[a-z] */
|
|
|
213 |
var int chng; /* Warn "No write" */
|
|
|
214 |
var char *Command;
|
|
|
215 |
var short defwind; /* -w# change default window size */
|
|
|
216 |
var int dirtcnt; /* When >= MAXDIRT, should sync temporary */
|
|
|
217 |
/*#if defined (TIOCLGET) || defined (__linux__)*/
|
|
|
218 |
var bool dosusp; /* Do SIGTSTP in visual when ^Z typed */
|
|
|
219 |
/*#endif*/
|
|
|
220 |
var bool edited; /* Current file is [Edited] */
|
|
|
221 |
var line *endcore; /* Last available core location */
|
|
|
222 |
extern bool endline; /* Last cmd mode command ended with \n */
|
|
|
223 |
#ifndef VMUNIX
|
|
|
224 |
var short erfile; /* Error message file unit */
|
|
|
225 |
#endif
|
|
|
226 |
var line *fendcore; /* First address in line pointer space */
|
|
|
227 |
var char file[FNSIZE]; /* Working file name */
|
|
|
228 |
var char genbuf[MAXBSIZE]; /* Working buffer when manipulating linebuf */
|
|
|
229 |
var bool hush; /* Command line option - was given, hush up! */
|
|
|
230 |
#ifndef BIT8
|
|
|
231 |
var char *globp; /* (Untyped) input string to command mode */
|
|
|
232 |
#else
|
|
|
233 |
var short *globp; /* (Untyped) input string to command mode */
|
|
|
234 |
#endif
|
|
|
235 |
var bool holdcm; /* Don't cursor address */
|
|
|
236 |
var bool inappend; /* in ex command append mode */
|
|
|
237 |
var bool inglobal; /* Inside g//... or v//... */
|
|
|
238 |
#ifndef BIT8
|
|
|
239 |
var char *initev; /* Initial : escape for visual */
|
|
|
240 |
#else
|
|
|
241 |
var short *initev; /* Initial : escape for visual */
|
|
|
242 |
#endif
|
|
|
243 |
var bool inopen; /* Inside open or visual */
|
|
|
244 |
var char *input; /* Current position in cmd line input buffer */
|
|
|
245 |
var bool intty; /* Input is a tty */
|
|
|
246 |
var short io; /* General i/o unit (auto-closed on error!) */
|
|
|
247 |
extern short lastc; /* Last character ret'd from cmd input */
|
|
|
248 |
var bool laste; /* Last command was an "e" (or "rec") */
|
|
|
249 |
var char lastmac; /* Last macro called for ** */
|
|
|
250 |
var char lasttag[TAGSIZE]; /* Last argument to a tag command */
|
|
|
251 |
var char *linebp; /* Used in substituting in \n */
|
|
|
252 |
var char linebuf[LBSIZE]; /* The primary line buffer */
|
|
|
253 |
var bool listf; /* Command should run in list mode */
|
|
|
254 |
var char *loc1; /* Where re began to match (in linebuf) */
|
|
|
255 |
var char *loc2; /* First char after re match (") */
|
|
|
256 |
var line names['z'-'a'+2]; /* Mark registers a-z,' */
|
|
|
257 |
var int notecnt; /* Count for notify (to visual from cmd) */
|
|
|
258 |
var bool numberf; /* Command should run in number mode */
|
|
|
259 |
var char obuf[BUFSIZ]; /* Buffer for tty output */
|
|
|
260 |
var short oprompt; /* Saved during source */
|
|
|
261 |
extern short o_speed; /* Output speed (from gtty) */
|
|
|
262 |
var int otchng; /* Backup tchng to find changes in macros */
|
|
|
263 |
var short peekc; /* Peek ahead character (cmd mode input) */
|
|
|
264 |
var char *pkill[2]; /* Trim for put with ragged (LISP) delete */
|
|
|
265 |
var bool pfast; /* Have stty -nl'ed to go faster */
|
|
|
266 |
var int pid; /* Process id of child */
|
|
|
267 |
var int ppid; /* Process id of parent (e.g. main ex proc) */
|
|
|
268 |
var jmp_buf resetlab; /* For error throws to top level (cmd mode) */
|
|
|
269 |
var int rpid; /* Pid returned from wait() */
|
|
|
270 |
var bool ruptible; /* Interruptible is normal state */
|
|
|
271 |
var bool seenprompt; /* 1 if have gotten user input */
|
|
|
272 |
var bool shudclob; /* Have a prompt to clobber (e.g. on ^D) */
|
|
|
273 |
var int status; /* Status returned from wait() */
|
|
|
274 |
var int tchng; /* If nonzero, then [Modified] */
|
|
|
275 |
extern short tfile; /* Temporary file unit */
|
|
|
276 |
var bool vcatch; /* Want to catch an error (open/visual) */
|
|
|
277 |
var jmp_buf vreslab; /* For error throws to a visual catch */
|
|
|
278 |
var bool writing; /* 1 if in middle of a file write */
|
|
|
279 |
var int xchng; /* Suppresses multiple "No writes" in !cmd */
|
|
|
280 |
var int bsize; /* Block size for disk i/o */
|
|
|
281 |
|
|
|
282 |
/*
|
|
|
283 |
* Macros
|
|
|
284 |
*/
|
113 |
7u83 |
285 |
/*#define CP(a, b) (ignore(strcpy(a, b)))*/
|
|
|
286 |
#define CP(a,b) error error error
|
|
|
287 |
|
105 |
7u83 |
288 |
/*
|
|
|
289 |
* FIXUNDO: do we want to mung undo vars?
|
|
|
290 |
* Usually yes unless in a macro or global.
|
|
|
291 |
*/
|
|
|
292 |
#define FIXUNDO (inopen >= 0 && (inopen || !inglobal))
|
|
|
293 |
#define ckaw() {if (chng && value(AUTOWRITE)) wop(0);}
|
|
|
294 |
#define copy(a,b,c) Copy((char *) a, (char *) b, c)
|
|
|
295 |
#define eq(a, b) ((a) && (b) && strcmp(a, b) == 0)
|
|
|
296 |
#define getexit(a) copy(a, resetlab, sizeof (jmp_buf))
|
|
|
297 |
#define lastchar() lastc
|
|
|
298 |
#define outchar(c) (*Outchar)(c)
|
|
|
299 |
#define pastwh() (ignore(skipwh()))
|
|
|
300 |
#define pline(no) (*Pline)(no)
|
|
|
301 |
#define reset() longjmp(resetlab,1)
|
|
|
302 |
#define resexit(a) copy(resetlab, a, sizeof (jmp_buf))
|
|
|
303 |
#define setexit() setjmp(resetlab)
|
|
|
304 |
#define setlastchar(c) lastc = c
|
|
|
305 |
#define ungetchar(c) peekc = c
|
|
|
306 |
|
|
|
307 |
#define CATCH vcatch = 1; if (setjmp(vreslab) == 0) {
|
|
|
308 |
#define ONERR } else { vcatch = 0;
|
|
|
309 |
#define ENDCATCH } vcatch = 0;
|
|
|
310 |
|
|
|
311 |
/*
|
|
|
312 |
* Environment like memory
|
|
|
313 |
*/
|
|
|
314 |
var char altfile[FNSIZE]; /* Alternate file name */
|
|
|
315 |
extern char direct[ONMSZ]; /* Temp file goes here */
|
|
|
316 |
extern char shell[ONMSZ]; /* Copied to be settable */
|
|
|
317 |
extern char ttytype[ONMSZ]; /* A long and pretty name */
|
|
|
318 |
var char uxb[UXBSIZE + 2]; /* Last !command for !! */
|
|
|
319 |
|
|
|
320 |
/*
|
|
|
321 |
* The editor data structure for accessing the current file consists
|
|
|
322 |
* of an incore array of pointers into the temporary file tfile.
|
|
|
323 |
* Each pointer is 15 bits (the low bit is used by global) and is
|
|
|
324 |
* padded with zeroes to make an index into the temp file where the
|
|
|
325 |
* actual text of the line is stored.
|
|
|
326 |
*
|
|
|
327 |
* To effect undo, copies of affected lines are saved after the last
|
|
|
328 |
* line considered to be in the buffer, between dol and unddol.
|
|
|
329 |
* During an open or visual, which uses the command mode undo between
|
|
|
330 |
* dol and unddol, a copy of the entire, pre-command buffer state
|
|
|
331 |
* is saved between unddol and truedol.
|
|
|
332 |
*/
|
|
|
333 |
var line *addr1; /* First addressed line in a command */
|
|
|
334 |
var line *addr2; /* Second addressed line */
|
|
|
335 |
var line *dol; /* Last line in buffer */
|
|
|
336 |
var line *dot; /* Current line */
|
|
|
337 |
var line *one; /* First line */
|
|
|
338 |
var line *truedol; /* End of all lines, including saves */
|
|
|
339 |
var line *unddol; /* End of undo saved lines */
|
|
|
340 |
var line *zero; /* Points to empty slot before one */
|
|
|
341 |
|
|
|
342 |
/*
|
|
|
343 |
* Undo information
|
|
|
344 |
*
|
|
|
345 |
* For most commands we save lines changed by salting them away between
|
|
|
346 |
* dol and unddol before they are changed (i.e. we save the descriptors
|
|
|
347 |
* into the temp file tfile which is never garbage collected). The
|
|
|
348 |
* lines put here go back after unddel, and to complete the undo
|
|
|
349 |
* we delete the lines [undap1,undap2).
|
|
|
350 |
*
|
|
|
351 |
* Undoing a move is much easier and we treat this as a special case.
|
|
|
352 |
* Similarly undoing a "put" is a special case for although there
|
|
|
353 |
* are lines saved between dol and unddol we don't stick these back
|
|
|
354 |
* into the buffer.
|
|
|
355 |
*/
|
|
|
356 |
var short undkind;
|
|
|
357 |
|
|
|
358 |
var line *unddel; /* Saved deleted lines go after here */
|
|
|
359 |
var line *undap1; /* Beginning of new lines */
|
|
|
360 |
var line *undap2; /* New lines end before undap2 */
|
|
|
361 |
var line *undadot; /* If we saved all lines, dot reverts here */
|
|
|
362 |
|
|
|
363 |
#define UNDCHANGE 0
|
|
|
364 |
#define UNDMOVE 1
|
|
|
365 |
#define UNDALL 2
|
|
|
366 |
#define UNDNONE 3
|
|
|
367 |
#define UNDPUT 4
|
|
|
368 |
|
|
|
369 |
|
|
|
370 |
/*
|
|
|
371 |
* Function type definitions
|
|
|
372 |
*/
|
|
|
373 |
#define NOSTR (char *) 0
|
|
|
374 |
#define NOLINE (line *) 0
|
|
|
375 |
|
113 |
7u83 |
376 |
extern void (*Outchar)(int);
|
105 |
7u83 |
377 |
extern int (*Pline)();
|
113 |
7u83 |
378 |
extern void (*Putchar)(short);
|
108 |
7u83 |
379 |
void (*oldhup)();
|
113 |
7u83 |
380 |
void (*setlist())();
|
105 |
7u83 |
381 |
int (*setnorm())();
|
|
|
382 |
int (*setnorm())();
|
|
|
383 |
int (*setnumb())();
|
|
|
384 |
line *address();
|
|
|
385 |
char *cgoto();
|
|
|
386 |
char *genindent();
|
|
|
387 |
char *getblock();
|
|
|
388 |
char *getenv();
|
|
|
389 |
line *getmark();
|
|
|
390 |
char *longname();
|
|
|
391 |
char *mesg();
|
|
|
392 |
char *place();
|
|
|
393 |
char *plural();
|
|
|
394 |
line *scanfor();
|
|
|
395 |
line *setin();
|
|
|
396 |
char *strcat();
|
|
|
397 |
char *strcpy();
|
|
|
398 |
char *strend();
|
|
|
399 |
char *tailpath();
|
|
|
400 |
char *tgetstr();
|
|
|
401 |
char *tgoto();
|
|
|
402 |
char *ttyname();
|
|
|
403 |
line *vback();
|
|
|
404 |
char *vfindcol();
|
|
|
405 |
char *vgetline();
|
|
|
406 |
char *vinit();
|
|
|
407 |
char *vpastwh();
|
|
|
408 |
char *vskipwh();
|
109 |
7u83 |
409 |
void put();
|
113 |
7u83 |
410 |
void putreg();
|
105 |
7u83 |
411 |
int YANKreg();
|
|
|
412 |
int delete();
|
|
|
413 |
int execl();
|
|
|
414 |
int filter();
|
|
|
415 |
int getfile();
|
|
|
416 |
int getsub();
|
|
|
417 |
int gettty();
|
|
|
418 |
int join();
|
113 |
7u83 |
419 |
void listchar(short);
|
105 |
7u83 |
420 |
off_t lseek();
|
109 |
7u83 |
421 |
void normchar(short);
|
105 |
7u83 |
422 |
int normline();
|
|
|
423 |
int numbline();
|
|
|
424 |
var void (*oldquit)();
|
|
|
425 |
void onhup();
|
106 |
7u83 |
426 |
void onintr();
|
105 |
7u83 |
427 |
void onsusp();
|
|
|
428 |
int putch();
|
|
|
429 |
int shift();
|
113 |
7u83 |
430 |
void termchar();
|
|
|
431 |
void vfilter();
|
105 |
7u83 |
432 |
#ifdef CBREAK
|
106 |
7u83 |
433 |
void vintr();
|
105 |
7u83 |
434 |
#endif
|
|
|
435 |
int vputch();
|
113 |
7u83 |
436 |
void vshftop();
|
105 |
7u83 |
437 |
int yank();
|
|
|
438 |
|
107 |
7u83 |
439 |
int tgets(char *, int cnt, int fd);
|
|
|
440 |
|
|
|
441 |
|
105 |
7u83 |
442 |
/*
|
|
|
443 |
* C doesn't have a (void) cast, so we have to fake it for lint's sake.
|
|
|
444 |
*/
|
|
|
445 |
#ifdef lint
|
|
|
446 |
# define ignore(a) Ignore((char *) (a))
|
|
|
447 |
# define ignorf(a) Ignorf((int (*) ()) (a))
|
|
|
448 |
#else
|
|
|
449 |
# define ignore(a) a
|
|
|
450 |
# define ignorf(a) a
|
|
|
451 |
#endif
|