sigar-test 0.7.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/NOTICE +117 -0
  4. data/README +2 -0
  5. data/Rakefile +105 -0
  6. data/bindings/SigarBuild.pm +301 -0
  7. data/bindings/SigarWrapper.pm +3025 -0
  8. data/bindings/ruby/extconf.rb +131 -0
  9. data/bindings/ruby/rbsigar.c +888 -0
  10. data/include/sigar.h +984 -0
  11. data/include/sigar_fileinfo.h +157 -0
  12. data/include/sigar_format.h +65 -0
  13. data/include/sigar_getline.h +18 -0
  14. data/include/sigar_log.h +80 -0
  15. data/include/sigar_private.h +429 -0
  16. data/include/sigar_ptql.h +53 -0
  17. data/include/sigar_util.h +197 -0
  18. data/src/os/aix/aix_sigar.c +2168 -0
  19. data/src/os/aix/sigar_os.h +73 -0
  20. data/src/os/darwin/Info.plist.in +27 -0
  21. data/src/os/darwin/darwin_sigar.c +3718 -0
  22. data/src/os/darwin/sigar_os.h +80 -0
  23. data/src/os/hpux/hpux_sigar.c +1361 -0
  24. data/src/os/hpux/sigar_os.h +49 -0
  25. data/src/os/linux/linux_sigar.c +2810 -0
  26. data/src/os/linux/sigar_os.h +82 -0
  27. data/src/os/solaris/get_mib2.c +321 -0
  28. data/src/os/solaris/get_mib2.h +127 -0
  29. data/src/os/solaris/kstats.c +181 -0
  30. data/src/os/solaris/procfs.c +97 -0
  31. data/src/os/solaris/sigar_os.h +224 -0
  32. data/src/os/solaris/solaris_sigar.c +2732 -0
  33. data/src/os/win32/peb.c +212 -0
  34. data/src/os/win32/sigar.rc.in +40 -0
  35. data/src/os/win32/sigar_os.h +685 -0
  36. data/src/os/win32/sigar_pdh.h +47 -0
  37. data/src/os/win32/win32_sigar.c +4109 -0
  38. data/src/sigar.c +2444 -0
  39. data/src/sigar_cache.c +253 -0
  40. data/src/sigar_fileinfo.c +815 -0
  41. data/src/sigar_format.c +696 -0
  42. data/src/sigar_getline.c +1849 -0
  43. data/src/sigar_ptql.c +1976 -0
  44. data/src/sigar_signal.c +216 -0
  45. data/src/sigar_util.c +1060 -0
  46. data/src/sigar_version.c.in +22 -0
  47. data/src/sigar_version_autoconf.c.in +22 -0
  48. data/version.properties +11 -0
  49. metadata +91 -0
@@ -0,0 +1,1849 @@
1
+ /*
2
+ * Copyright (C) 1991, 1992 by Chris Thewalt (thewalt@ce.berkeley.edu)
3
+ *
4
+ * Permission to use, copy, modify, and distribute this software
5
+ * for any purpose and without fee is hereby granted, provided
6
+ * that the above copyright notices appear in all copies and that both the
7
+ * copyright notice and this permission notice appear in supporting
8
+ * documentation. This software is provided "as is" without express or
9
+ * implied warranty.
10
+ */
11
+ /*
12
+ *************************** Motivation **********************************
13
+
14
+ Many interactive programs read input line by line, but would like to
15
+ provide line editing and history functionality to the end-user that
16
+ runs the program.
17
+
18
+ The input-edit package provides that functionality. As far as the
19
+ programmer is concerned, the program only asks for the next line
20
+ of input. However, until the user presses the RETURN key they can use
21
+ emacs-style line editing commands and can traverse the history of lines
22
+ previously typed.
23
+
24
+ Other packages, such as GNU's readline, have greater capability but are
25
+ also substantially larger. Input-edit is small, since it uses neither
26
+ stdio nor any termcap features, and is also quite portable. It only uses
27
+ \b to backspace and \007 to ring the bell on errors. Since it cannot
28
+ edit multiple lines it scrolls long lines left and right on the same line.
29
+
30
+ Input edit uses classic (not ANSI) C, and should run on any Unix
31
+ system (BSD or SYSV), PC's with the MSC compiler, or Vax/VMS (untested by me).
32
+ Porting the package to new systems basicaly requires code to read a
33
+ character when it is typed without echoing it, everything else should be OK.
34
+
35
+ I have run the package on:
36
+
37
+ DECstation 5000, Ultrix 4.2 with cc and gcc
38
+ Sun Sparc 2, SunOS 4.1.1, with cc
39
+ SGI Iris, IRIX System V.3, with cc
40
+ PC, DRDOS 5.0, with MSC 6.0
41
+
42
+ The description below is broken into two parts, the end-user (editing)
43
+ interface and the programmer interface. Send bug reports, fixes and
44
+ enhancements to:
45
+
46
+ Chris Thewalt (thewalt@ce.berkeley.edu)
47
+ 2/4/92
48
+
49
+ PS: I don't have, and don't want to add, a vi mode, sorry.
50
+
51
+ ************************** End-User Interface ***************************
52
+
53
+ Entering printable keys generally inserts new text into the buffer (unless
54
+ in overwrite mode, see below). Other special keys can be used to modify
55
+ the text in the buffer. In the description of the keys below, ^n means
56
+ Control-n, or holding the CONTROL key down while pressing "n". M-B means
57
+ Meta-B (or Alt-B). Errors will ring the terminal bell.
58
+
59
+ ^A/^E : Move cursor to beginning/end of the line.
60
+ ^F/^B : Move cursor forward/backward one character.
61
+ ^D : Delete the character under the cursor.
62
+ ^H, DEL : Delete the character to the left of the cursor.
63
+ ^K : Kill from the cursor to the end of line.
64
+ ^L : Redraw current line.
65
+ ^O : Toggle overwrite/insert mode. Initially in insert mode. Text
66
+ added in overwrite mode (including yanks) overwrite
67
+ existing text, while insert mode does not overwrite.
68
+ ^P/^N : Move to previous/next item on history list.
69
+ ^R/^S : Perform incremental reverse/forward search for string on
70
+ the history list. Typing normal characters adds to the current
71
+ search string and searches for a match. Typing ^R/^S marks
72
+ the start of a new search, and moves on to the next match.
73
+ Typing ^H or DEL deletes the last character from the search
74
+ string, and searches from the starting location of the last search.
75
+ Therefore, repeated DEL's appear to unwind to the match nearest
76
+ the point at which the last ^R or ^S was typed. If DEL is
77
+ repeated until the search string is empty the search location
78
+ begins from the start of the history list. Typing ESC or
79
+ any other editing character accepts the current match and
80
+ loads it into the buffer, terminating the search.
81
+ ^T : Toggle the characters under and to the left of the cursor.
82
+ ^U : Kill from beginning to the end of the line.
83
+ ^Y : Yank previously killed text back at current location. Note that
84
+ this will overwrite or insert, depending on the current mode.
85
+ M-F/M-B : Move cursor forward/backward one word.
86
+ M-D : Delete the word under the cursor.
87
+ ^SPC : Set mark.
88
+ ^W : Kill from mark to point.
89
+ ^X : Exchange mark and point.
90
+ TAB : By default adds spaces to buffer to get to next TAB stop
91
+ (just after every 8th column), although this may be rebound by the
92
+ programmer, as described below.
93
+ NL, CR : returns current buffer to the program.
94
+
95
+ DOS and ANSI terminal arrow key sequences are recognized, and act like:
96
+
97
+ up : same as ^P
98
+ down : same as ^N
99
+ left : same as ^B
100
+ right : same as ^F
101
+
102
+ ************************** Programmer Interface ***************************
103
+
104
+ The programmer accesses input-edit through five functions, and optionally
105
+ through three additional function pointer hooks. The five functions are:
106
+
107
+ char *Getline(char *prompt)
108
+
109
+ Prints the prompt and allows the user to edit the current line. A
110
+ pointer to the line is returned when the user finishes by
111
+ typing a newline or a return. Unlike GNU readline, the returned
112
+ pointer points to a static buffer, so it should not be free'd, and
113
+ the buffer contains the newline character. The user enters an
114
+ end-of-file by typing ^D on an empty line, in which case the
115
+ first character of the returned buffer is '\0'. Getline never
116
+ returns a NULL pointer. The getline function sets terminal modes
117
+ needed to make it work, and resets them before returning to the
118
+ caller. The getline function also looks for characters that would
119
+ generate a signal, and resets the terminal modes before raising the
120
+ signal condition. If the signal handler returns to getline,
121
+ the screen is automatically redrawn and editing can continue.
122
+ Getline now requires both the input and output stream be connected
123
+ to the terminal (not redirected) so the main program should check
124
+ to make sure this is true. If input or output have been redirected
125
+ the main program should use buffered IO (stdio) rather than
126
+ the slow 1 character read()s that getline uses (note: this limitation
127
+ has been removed).
128
+
129
+ char *Getlinem(int mode, char *prompt)
130
+
131
+ mode: -1 = init, 0 = line mode, 1 = one char at a time mode, 2 = cleanup
132
+
133
+ More specialized version of the previous function. Depending on
134
+ the mode, it behaves differently. Its main use is to allow
135
+ character by character input from the input stream (useful when
136
+ in an X eventloop). It will return NULL as long as no newline
137
+ has been received. Its use is typically as follows:
138
+ 1) In the program initialization part one calls: Getlinem(-1,"prompt>")
139
+ 2) In the X inputhandler: if ((line = Getlinem(1,NULL))) {
140
+ 3) In the termination routine: Getlinem(2,NULL)
141
+ With mode=0 the function behaves exactly like the previous function.
142
+
143
+ void Gl_config(const char *which, int value)
144
+
145
+ Set some config options. Which can be:
146
+ "noecho": do not echo characters (used for passwd input)
147
+ "erase": do erase line after return (used for text scrollers)
148
+
149
+ void Gl_setwidth(int width)
150
+
151
+ Set the width of the terminal to the specified width. The default
152
+ width is 80 characters, so this function need only be called if the
153
+ width of the terminal is not 80. Since horizontal scrolling is
154
+ controlled by this parameter it is important to get it right.
155
+
156
+ void Gl_histinit(char *file)
157
+
158
+ This function reads a history list from file. So lines from a
159
+ previous session can be used again.
160
+
161
+ void Gl_histadd(char *buf)
162
+
163
+ The Gl_histadd function checks to see if the buf is not empty or
164
+ whitespace, and also checks to make sure it is different than
165
+ the last saved buffer to avoid repeats on the history list.
166
+ If the buf is a new non-blank string a copy is made and saved on
167
+ the history list, so the caller can re-use the specified buf.
168
+
169
+ The main loop in testgl.c, included in this directory, shows how the
170
+ input-edit package can be used:
171
+
172
+ extern char *Getline();
173
+ extern void Gl_histadd();
174
+ main()
175
+ {
176
+ char *p;
177
+ Gl_histinit(".hist");
178
+ do {
179
+ p = Getline("PROMPT>>>> ");
180
+ Gl_histadd(p);
181
+ fputs(p, stdout);
182
+ } while (*p != 0);
183
+ }
184
+
185
+ In order to allow the main program to have additional access to the buffer,
186
+ to implement things such as completion or auto-indent modes, three
187
+ function pointers can be bound to user functions to modify the buffer as
188
+ described below. By default gl_in_hook and gl_out_hook are set to NULL,
189
+ and gl_tab_hook is bound to a function that inserts spaces until the next
190
+ logical tab stop is reached. The user can reassign any of these pointers
191
+ to other functions. Each of the functions bound to these hooks receives
192
+ the current buffer as the first argument, and must return the location of
193
+ the leftmost change made in the buffer. If the buffer isn't modified the
194
+ functions should return -1. When the hook function returns the screen is
195
+ updated to reflect any changes made by the user function.
196
+
197
+ int (*gl_in_hook)(char *buf)
198
+
199
+ If gl_in_hook is non-NULL the function is called each time a new
200
+ buffer is loaded. It is called when getline is entered, with an
201
+ empty buffer, it is called each time a new buffer is loaded from
202
+ the history with ^P or ^N, and it is called when an incremental
203
+ search string is accepted (when the search is terminated). The
204
+ buffer can be modified and will be redrawn upon return to Getline().
205
+
206
+ int (*gl_out_hook)(char *buf)
207
+
208
+ If gl_out_hook is non-NULL it is called when a line has been
209
+ completed by the user entering a newline or return. The buffer
210
+ handed to the hook does not yet have the newline appended. If the
211
+ buffer is modified the screen is redrawn before getline returns the
212
+ buffer to the caller.
213
+
214
+ int (*gl_tab_hook)(char *buf, int prompt_width, int *cursor_loc)
215
+
216
+ If gl_tab_hook is non-NULL, it is called whenever a tab is typed.
217
+ In addition to receiving the buffer, the current prompt width is
218
+ given (needed to do tabbing right) and a pointer to the cursor
219
+ offset is given, where a 0 offset means the first character in the
220
+ line. Not only does the cursor_loc tell the programmer where the
221
+ TAB was received, but it can be reset so that the cursor will end
222
+ up at the specified location after the screen is redrawn.
223
+ */
224
+
225
+ /* forward reference needed for gl_tab_hook */
226
+ static int gl_tab(char *buf, int offset, int *loc);
227
+
228
+ /********************* exported interface ********************************/
229
+
230
+ static int (*gl_in_hook)(char *buf) = 0;
231
+ static int (*gl_out_hook)(char *buf) = 0;
232
+ static int (*gl_tab_hook)(char *buf, int prompt_width, int *loc) = gl_tab;
233
+
234
+ /******************** imported interface *********************************/
235
+ #ifdef DMALLOC
236
+ /* reports leaks, which is the history buffer. dont care */
237
+ #undef DMALLOC
238
+ #endif
239
+ #include "sigar_getline.h"
240
+ #include "sigar_private.h"
241
+ #include "sigar_util.h"
242
+ #include <string.h>
243
+ #include <ctype.h>
244
+ #include <errno.h>
245
+ #include <signal.h>
246
+ #include <stdlib.h>
247
+ #include <stdio.h>
248
+
249
+ /******************** internal interface *********************************/
250
+
251
+ static char *sigar_getlinem(int mode, char *prompt); /* allows reading char by char */
252
+
253
+ static void sigar_getline_config(const char *which, int value); /* set some options */
254
+
255
+ static void sigar_getline_clear_screen(void);
256
+
257
+ #define BUF_SIZE 8096
258
+
259
+ static int gl_init_done = -1; /* terminal mode flag */
260
+ static int gl_notty = 0; /* 1 when not a tty */
261
+ static int gl_eof = 0; /* 1 when not a tty and read() == -1 */
262
+ static int gl_termw = 80; /* actual terminal width */
263
+ static int gl_scroll = 27; /* width of EOL scrolling region */
264
+ static int gl_width = 0; /* net size available for input */
265
+ static int gl_extent = 0; /* how far to redraw, 0 means all */
266
+ static int gl_overwrite = 0; /* overwrite mode */
267
+ static int gl_no_echo = 0; /* do not echo input characters */
268
+ static int gl_passwd = 0; /* do not echo input characters */
269
+ static int gl_erase_line = 0; /* erase line before returning */
270
+ static int gl_pos, gl_cnt = 0; /* position and size of input */
271
+ static char gl_buf[BUF_SIZE]; /* input buffer */
272
+ static char gl_killbuf[BUF_SIZE]=""; /* killed text */
273
+ static char *gl_prompt; /* to save the prompt string */
274
+ static char gl_intrc = 0; /* keyboard SIGINT char */
275
+ static char gl_quitc = 0; /* keyboard SIGQUIT char */
276
+ static char gl_suspc = 0; /* keyboard SIGTSTP char */
277
+ static char gl_dsuspc = 0; /* delayed SIGTSTP char */
278
+ static int gl_search_mode = 0; /* search mode flag */
279
+ static int gl_bell_enabled = 0; /* bell mode */
280
+ static int gl_savehist = 0; /* # of lines to save in hist file */
281
+ static char gl_histfile[256]; /* name of history file */
282
+
283
+ static void gl_init(); /* prepare to edit a line */
284
+ static void gl_bell(); /* ring bell */
285
+ static void gl_cleanup(); /* to undo gl_init */
286
+ static void gl_char_init(); /* get ready for no echo input */
287
+ static void gl_char_cleanup(); /* undo gl_char_init */
288
+
289
+ static void gl_addchar(int c); /* install specified char */
290
+ static void gl_del(int loc); /* del, either left (-1) or cur (0) */
291
+ static void gl_error(char *buf); /* write error msg and die */
292
+ static void gl_fixup(char *p, int c, int cur); /* fixup state variables and screen */
293
+ static int gl_getc(); /* read one char from terminal */
294
+ static void gl_kill(); /* delete to EOL */
295
+ static void gl_newline(); /* handle \n or \r */
296
+ static void gl_putc(int c); /* write one char to terminal */
297
+ static void gl_puts(char *buf); /* write a line to terminal */
298
+ static void gl_transpose(); /* transpose two chars */
299
+ static void gl_yank(); /* yank killed text */
300
+
301
+ static int is_whitespace(char c); /* "whitespace" very loosely interpreted */
302
+ static void gl_back_1_word(); /* move cursor back one word */
303
+ static void gl_kill_1_word(); /* kill to end of word */
304
+ static void gl_kill_region(int i, int j); /* kills from i to j */
305
+ static void gl_fwd_1_word(); /* move cursor forward one word */
306
+ static void gl_set_mark(); /* sets mark to be at point */
307
+ static void gl_exch(); /* exchanges point and mark */
308
+ static void gl_wipe(); /* kills from mark to point */
309
+ static int gl_mark = -1; /* position of mark. gl_mark<0 if not set */
310
+
311
+ static void hist_init(); /* initializes hist pointers */
312
+ static char *hist_next(); /* return ptr to next item */
313
+ static char *hist_prev(); /* return ptr to prev item */
314
+ static char *hist_save(char *p); /* makes copy of a string, without NL */
315
+
316
+ static void search_addchar(int c); /* increment search string */
317
+ static void search_term(); /* reset with current contents */
318
+ static void search_back(int s); /* look back for current string */
319
+ static void search_forw(int s); /* look forw for current string */
320
+
321
+ /************************ nonportable part *********************************/
322
+
323
+ #ifdef MSDOS
324
+ #include <bios.h>
325
+ #endif
326
+
327
+ #ifdef WIN32
328
+ # define MSDOS
329
+ # include <io.h>
330
+ # include <windows.h>
331
+ #endif /* WIN32 */
332
+
333
+ #ifdef __MWERKS__
334
+ #define R__MWERKS
335
+ #endif
336
+
337
+ #ifdef R__MWERKS
338
+ # include <unistd.h>
339
+ #endif
340
+
341
+ #if defined(_AIX) || defined(__Lynx__) || defined(__APPLE__)
342
+ #define unix
343
+ #endif
344
+
345
+ #if defined(__hpux) || defined(__osf__) /* W.Karig@gsi.de */
346
+ #ifndef unix
347
+ #define unix
348
+ #endif
349
+ #endif
350
+
351
+ #ifdef unix
352
+ #include <unistd.h>
353
+ #if !defined(__osf__) && !defined(_AIX) /* W.Karig@gsi.de */
354
+ #include <sys/ioctl.h>
355
+ #endif
356
+
357
+ #if defined(__linux__) && defined(__powerpc__)
358
+ # define R__MKLINUX // = linux on PowerMac
359
+ #endif
360
+ #if defined(__linux__) && defined(__alpha__)
361
+ # define R__ALPHALINUX // = linux on Alpha
362
+ #endif
363
+
364
+ #if defined(TIOCGETP) && !defined(__sgi) && !defined(R__MKLINUX) && \
365
+ !defined(R__ALPHALINUX) /* use BSD interface if possible */
366
+ #include <sgtty.h>
367
+ static struct sgttyb new_tty, old_tty;
368
+ static struct tchars tch;
369
+ static struct ltchars ltch;
370
+ #else
371
+ #ifdef SIGTSTP /* need POSIX interface to handle SUSP */
372
+ #include <termios.h>
373
+ #if defined(__sun) || defined(__sgi) || defined(R__MKLINUX) || \
374
+ defined(R__ALPHALINUX)
375
+ #undef TIOCGETP /* Solaris and SGI define TIOCGETP in <termios.h> */
376
+ #undef TIOCSETP
377
+ #endif
378
+ static struct termios new_termios, old_termios;
379
+ #else /* use SYSV interface */
380
+ #include <termio.h>
381
+ static struct termio new_termio, old_termio;
382
+ #endif
383
+ #endif
384
+ #endif /* unix */
385
+
386
+ #ifdef VMS
387
+ #include <descrip.h>
388
+ #include <ttdef.h>
389
+ #include <iodef.h>
390
+ #include <starlet.h>
391
+ #include <unistd.h>
392
+ #include unixio
393
+
394
+ static int setbuff[2]; /* buffer to set terminal attributes */
395
+ static short chan = -1; /* channel to terminal */
396
+ struct dsc$descriptor_s descrip; /* VMS descriptor */
397
+ #endif
398
+
399
+ static void
400
+ sigar_getline_config(const char *which, int value)
401
+ {
402
+ if (strcmp(which, "noecho") == 0)
403
+ gl_no_echo = value;
404
+ else if (strcmp(which, "erase") == 0)
405
+ gl_erase_line = value;
406
+ else
407
+ printf("gl_config: %s ?\n", which);
408
+ }
409
+
410
+ static void
411
+ gl_char_init() /* turn off input echo */
412
+ {
413
+ if (gl_notty) return;
414
+ #ifdef unix
415
+ #ifdef TIOCGETP /* BSD */
416
+ ioctl(0, TIOCGETC, &tch);
417
+ ioctl(0, TIOCGLTC, &ltch);
418
+ gl_intrc = tch.t_intrc;
419
+ gl_quitc = tch.t_quitc;
420
+ gl_suspc = ltch.t_suspc;
421
+ gl_dsuspc = ltch.t_dsuspc;
422
+ ioctl(0, TIOCGETP, &old_tty);
423
+ new_tty = old_tty;
424
+ new_tty.sg_flags |= RAW;
425
+ new_tty.sg_flags &= ~ECHO;
426
+ ioctl(0, TIOCSETP, &new_tty);
427
+ #else
428
+ #ifdef SIGTSTP /* POSIX */
429
+ tcgetattr(0, &old_termios);
430
+ gl_intrc = old_termios.c_cc[VINTR];
431
+ gl_quitc = old_termios.c_cc[VQUIT];
432
+ #ifdef VSUSP
433
+ gl_suspc = old_termios.c_cc[VSUSP];
434
+ #endif
435
+ #ifdef VDSUSP
436
+ gl_dsuspc = old_termios.c_cc[VDSUSP];
437
+ #endif
438
+ new_termios = old_termios;
439
+ new_termios.c_iflag &= ~(BRKINT|ISTRIP|IXON|IXOFF);
440
+ new_termios.c_iflag |= (IGNBRK|IGNPAR);
441
+ new_termios.c_lflag &= ~(ICANON|ISIG|IEXTEN|ECHO);
442
+ new_termios.c_cc[VMIN] = 1;
443
+ new_termios.c_cc[VTIME] = 0;
444
+ tcsetattr(0, TCSANOW, &new_termios);
445
+ #else /* SYSV */
446
+ ioctl(0, TCGETA, &old_termio);
447
+ gl_intrc = old_termio.c_cc[VINTR];
448
+ gl_quitc = old_termio.c_cc[VQUIT];
449
+ new_termio = old_termio;
450
+ new_termio.c_iflag &= ~(BRKINT|ISTRIP|IXON|IXOFF);
451
+ new_termio.c_iflag |= (IGNBRK|IGNPAR);
452
+ new_termio.c_lflag &= ~(ICANON|ISIG|ECHO);
453
+ new_termio.c_cc[VMIN] = 1;
454
+ new_termio.c_cc[VTIME] = 0;
455
+ ioctl(0, TCSETA, &new_termio);
456
+ #endif
457
+ #endif
458
+ #endif /* unix */
459
+
460
+ #ifdef MSDOS
461
+ gl_intrc = 'C' - '@';
462
+ gl_quitc = 'Q' - '@';
463
+ // gl_suspc = ltch.t_suspc;
464
+ #endif /* MSDOS */
465
+
466
+ #ifdef R__MWERKS
467
+ gl_intrc = 'C' - '@';
468
+ gl_quitc = 'Q' - '@';
469
+ #endif
470
+
471
+ #ifdef vms
472
+ descrip.dsc$w_length = strlen("tt:");
473
+ descrip.dsc$b_dtype = DSC$K_DTYPE_T;
474
+ descrip.dsc$b_class = DSC$K_CLASS_S;
475
+ descrip.dsc$a_pointer = "tt:";
476
+ (void)sys$assign(&descrip,&chan,0,0);
477
+ (void)sys$qiow(0,chan,IO$_SENSEMODE,0,0,0,setbuff,8,0,0,0,0);
478
+ setbuff[1] |= TT$M_NOECHO;
479
+ (void)sys$qiow(0,chan,IO$_SETMODE,0,0,0,setbuff,8,0,0,0,0);
480
+ #endif /* vms */
481
+ }
482
+
483
+ static void
484
+ gl_char_cleanup() /* undo effects of gl_char_init */
485
+ {
486
+ if (gl_notty) return;
487
+ #ifdef unix
488
+ #ifdef TIOCSETP /* BSD */
489
+ ioctl(0, TIOCSETP, &old_tty);
490
+ #else
491
+ #ifdef SIGTSTP /* POSIX */
492
+ tcsetattr(0, TCSANOW, &old_termios);
493
+ #else /* SYSV */
494
+ ioctl(0, TCSETA, &old_termio);
495
+ #endif
496
+ #endif
497
+ #endif /* unix */
498
+
499
+ #ifdef vms
500
+ setbuff[1] &= ~TT$M_NOECHO;
501
+ (void)sys$qiow(0,chan,IO$_SETMODE,0,0,0,setbuff,8,0,0,0,0);
502
+ sys$dassgn(chan);
503
+ chan = -1;
504
+ #endif
505
+ }
506
+
507
+ #if defined(MSDOS) && !defined(WIN32)
508
+ // +DECK, PAUSE, T=XCC, IF=WINNT. (from KERNDOS.CAR )
509
+ # include <conio.h>
510
+ int pause_()
511
+ {
512
+ int first_char;
513
+ first_char = _getch();
514
+ if (first_char == 0 || first_char == 0xE0) first_char = -_getch();
515
+ return first_char;
516
+ }
517
+ #endif
518
+
519
+ #if defined(MSDOS) && defined(WIN32)
520
+ //______________________________________________________________________________
521
+ int pause_()
522
+ {
523
+ static HANDLE hConsoleInput = NULL;
524
+ static iCharCount = 0;
525
+ static int chLastChar = 0;
526
+
527
+ DWORD cRead;
528
+
529
+ INPUT_RECORD pirBuffer;
530
+ KEY_EVENT_RECORD *KeyEvent= (KEY_EVENT_RECORD *)&(pirBuffer.Event);
531
+
532
+ if (!hConsoleInput) hConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
533
+
534
+ if (iCharCount) iCharCount--; // Whether several symbols had been read
535
+ else {
536
+ chLastChar = 0;
537
+ while (chLastChar == 0) {
538
+ if (!ReadConsoleInput(hConsoleInput, // handle of a console input buffer
539
+ &pirBuffer, // address of the buffer for read data
540
+ 1, // number of records to read
541
+ &cRead // address of number of records read
542
+ )) return 0;
543
+
544
+ if (pirBuffer.EventType == KEY_EVENT && KeyEvent->bKeyDown == TRUE){
545
+ iCharCount = KeyEvent->wRepeatCount - 1;
546
+ chLastChar = ((int) (KeyEvent->uChar).AsciiChar & 0xffff);
547
+ if (chLastChar)
548
+ OemToCharBuff((char const *)&chLastChar,(char *)&chLastChar,1);
549
+ else
550
+ chLastChar = - (KeyEvent->wVirtualScanCode);
551
+ // chLastChar = - (KeyEvent->wVirtualKeyCode);
552
+ }
553
+ }
554
+ }
555
+ return chLastChar;
556
+
557
+ }
558
+ #endif
559
+
560
+ static int
561
+ gl_getc()
562
+ /* get a character without echoing it to screen */
563
+ {
564
+ #ifdef MSDOS
565
+ # define k_ctrl_C 3
566
+ # define k_ctrl_Z 26
567
+ # define k_ctrl_Q 17
568
+ # define k_ctrl_K 11
569
+ # define k_rt_arr -77
570
+ # define k_lt_arr -75
571
+ # define k_up_arr -72
572
+ # define k_dn_arr -80
573
+ # define k_PGUP -73
574
+ # define k_PGDW -81
575
+ # define k_HOME -71
576
+ # define k_END -79
577
+ # define k_INS -82
578
+ # define k_DEL -83
579
+ # define k_ENTER 13
580
+ # define k_CR 13
581
+ # define k_BS 8
582
+ # define k_ESC 27
583
+ # define k_alt_H -35
584
+ # define k_beep 7
585
+ # ifndef WIN32
586
+ int get_cursor__(int *,int *);
587
+ int display_off__(int *);
588
+ int display_on__();
589
+ int locate_(int *,int *);
590
+ int ixc, iyc;
591
+ # endif
592
+ int pause_();
593
+ #endif
594
+
595
+ int c;
596
+
597
+ #if defined(unix)
598
+ unsigned char ch;
599
+ while ((c = (read(0, &ch, 1) > 0) ? ch : -1) == -1 && errno == EINTR)
600
+ errno = 0;
601
+ #endif
602
+
603
+ #if defined(R__MWERKS)
604
+ c = getchar();
605
+ #endif
606
+
607
+ #ifdef MSDOS
608
+ c = pause_();
609
+ if (c < 0) {
610
+ switch (c) {
611
+ case k_up_arr: c = 'P' - '@'; /* up -> ^P = 16 */
612
+ break;
613
+ case k_dn_arr: c = 'N' - '@'; /* down -> ^N = 14 */
614
+ break;
615
+ case k_lt_arr: c = 'B' - '@'; /* left -> ^B =2 */
616
+ break;
617
+ case k_rt_arr: c = 'F' - '@'; /* right -> ^F = 6*/
618
+ break;
619
+ case k_INS: c = 'O' - '@'; /* right -> ^O = 15*/
620
+ break;
621
+ case k_DEL: c = 'D' - '@'; /* Delete character under cursor = 4*/
622
+ break;
623
+ case k_END: c = 'E' - '@'; /* Moves cursor to end of line * = 5 */
624
+ break;
625
+ case k_HOME: c = 'A' - '@'; /* Moves cursor to beginning of line = 1*/
626
+ break;
627
+ default: c = 0; /* make it garbage */
628
+ }
629
+ }
630
+ else {
631
+ switch(c) {
632
+ case k_ESC: c = 'U' - '@'; /* Clear full line -> ^U */
633
+ break;
634
+ default:
635
+ break;
636
+ }
637
+ }
638
+ #endif
639
+
640
+ #ifdef vms
641
+ if(chan < 0) {
642
+ c='\0';
643
+ }
644
+ (void)sys$qiow(0,chan,IO$_TTYREADALL,0,0,0,&c,1,0,0,0,0);
645
+ c &= 0177; /* get a char */
646
+ #endif
647
+ return c;
648
+ }
649
+
650
+ static void
651
+ gl_putc(int c)
652
+ {
653
+ char ch = c;
654
+
655
+ if (gl_notty) return;
656
+
657
+ if ( !gl_passwd || !isgraph(c))
658
+ {
659
+ #ifdef WIN32
660
+ CharToOemBuff((char const *)&c,&ch,1);
661
+ #endif
662
+
663
+ sigar_write(1, &ch, 1);
664
+ }
665
+ #if defined(unix) || defined(MSDOS) || defined(WIN32) || defined(R__MWERKS)
666
+ #ifdef TIOCSETP /* BSD in RAW mode, map NL to NL,CR */
667
+ if (ch == '\n') {
668
+ ch = '\r';
669
+ sigar_write(1, &ch, 1);
670
+ }
671
+ #endif
672
+ #endif
673
+ }
674
+
675
+ /******************** fairly portable part *********************************/
676
+
677
+ static void
678
+ gl_puts(char *buf)
679
+ {
680
+ int len = strlen(buf);
681
+
682
+ if (gl_notty) return;
683
+ #ifdef WIN32
684
+ {
685
+ char *OemBuf = (char *)malloc(2*len);
686
+ CharToOemBuff(buf,OemBuf,len);
687
+ sigar_write(1, OemBuf, len);
688
+ free(OemBuf);
689
+ }
690
+ #else
691
+ sigar_write(1, buf, len);
692
+ #endif
693
+ }
694
+
695
+ static void
696
+ gl_error(char *buf)
697
+ {
698
+ int len = strlen(buf);
699
+
700
+ gl_cleanup();
701
+ #ifdef WIN32
702
+ {
703
+ char *OemBuf = (char *)malloc(2*len);
704
+ CharToOemBuff(buf,OemBuf,len);
705
+ sigar_write(2, OemBuf, len);
706
+ free(OemBuf);
707
+ }
708
+ #else
709
+ sigar_write(2, buf, len);
710
+ #endif
711
+ exit(1);
712
+ }
713
+
714
+ static void
715
+ gl_init()
716
+ /* set up variables and terminal */
717
+ {
718
+ if (gl_init_done < 0) { /* -1 only on startup */
719
+ hist_init();
720
+ }
721
+ if (sigar_isatty(0) == 0 || sigar_isatty(1) == 0)
722
+ gl_notty = 1;
723
+ gl_char_init();
724
+ gl_init_done = 1;
725
+ }
726
+
727
+ static void
728
+ gl_bell()
729
+ {
730
+ if (gl_bell_enabled) {
731
+ gl_putc('\007');
732
+ }
733
+ }
734
+
735
+ static void
736
+ gl_cleanup()
737
+ /* undo effects of gl_init, as necessary */
738
+ {
739
+ if (gl_init_done > 0)
740
+ gl_char_cleanup();
741
+ gl_init_done = 0;
742
+ }
743
+
744
+ SIGAR_DECLARE(void)
745
+ sigar_getline_setwidth(int w)
746
+ {
747
+ if (w > 20) {
748
+ gl_termw = w;
749
+ gl_scroll = w / 3;
750
+ } else {
751
+ gl_error("\n*** Error: minimum screen width is 21\n");
752
+ }
753
+ }
754
+
755
+ SIGAR_DECLARE(void)
756
+ sigar_getline_windowchanged()
757
+ {
758
+ #ifdef TIOCGWINSZ
759
+ if (sigar_isatty(0)) {
760
+ static char lenv[32], cenv[32];
761
+ struct winsize wins;
762
+ ioctl(0, TIOCGWINSZ, &wins);
763
+
764
+ if (wins.ws_col == 0) wins.ws_col = 80;
765
+ if (wins.ws_row == 0) wins.ws_row = 24;
766
+
767
+ sigar_getline_setwidth(wins.ws_col);
768
+
769
+ sprintf(lenv, "LINES=%d", wins.ws_row);
770
+ putenv(lenv);
771
+ sprintf(cenv, "COLUMNS=%d", wins.ws_col);
772
+ putenv(cenv);
773
+ }
774
+ #endif
775
+ }
776
+
777
+ /* -1 = init, 0 = line mode, 1 = one char at a time mode, 2 = cleanup */
778
+
779
+ static char *
780
+ sigar_getlinem(int mode, char *prompt)
781
+ {
782
+ int c, loc, tmp;
783
+ int sig;
784
+
785
+ if (mode == 2) {
786
+ gl_cleanup();
787
+ return NULL;
788
+ }
789
+
790
+ if (mode < 1) {
791
+ if (mode == -1) {
792
+ sigar_getline_config("noecho", 0);
793
+ sigar_getline_config("erase", 0);
794
+ }
795
+ gl_init();
796
+ gl_prompt = (prompt)? prompt : (char*)"";
797
+ gl_buf[0] = 0;
798
+ if (gl_in_hook)
799
+ gl_in_hook(gl_buf);
800
+ gl_fixup(gl_prompt, -2, BUF_SIZE);
801
+ if (mode == -1) return NULL;
802
+ }
803
+ while ((c = gl_getc()) >= 0) {
804
+ gl_extent = 0; /* reset to full extent */
805
+ #ifndef WIN32
806
+ if (isprint(c)) {
807
+ #else
808
+ if (c >= ' ') {
809
+ #endif
810
+ if (gl_search_mode)
811
+ search_addchar(c);
812
+ else
813
+ gl_addchar(c);
814
+ } else {
815
+ if (gl_search_mode) {
816
+ if (c == '\033' || c == '\016' || c == '\020') {
817
+ search_term();
818
+ c = 0; /* ignore the character */
819
+ } else if (c == '\010' || c == '\177') {
820
+ search_addchar(-1); /* unwind search string */
821
+ c = 0;
822
+ } else if (c != '\022' && c != '\023') {
823
+ search_term(); /* terminate and handle char */
824
+ }
825
+ }
826
+ /* NOTE:
827
+ * sometimes M-x turns on bit 8 ( M-x --> 'x' + 128 )
828
+ * sometimes M-x prepends an escape character ( M-x --> '\033','x' )
829
+ * both cases are handled ...
830
+ */
831
+ switch (c)
832
+ {
833
+ case 'b'+128: /* M-b */
834
+ case 'B'+128: /* M-B */
835
+ gl_back_1_word();
836
+ break;
837
+ case 'd'+128: /* M-d */
838
+ case 'D'+128: /* M-D */
839
+ gl_kill_1_word();
840
+ break;
841
+ case 'f'+128: /* M-f */
842
+ case 'F'+128: /* M-F */
843
+ gl_fwd_1_word();
844
+ break;
845
+ case '\000': /* ^SPC */
846
+ gl_set_mark();
847
+ break;
848
+ case '\027': /* ^W */
849
+ gl_wipe();
850
+ break;
851
+ case '\030': /* ^X */
852
+ gl_exch();
853
+ break;
854
+ case '\n': /* newline */
855
+ case '\r':
856
+ gl_newline();
857
+ gl_cleanup();
858
+ return gl_buf;
859
+ /*NOTREACHED*/
860
+ break;
861
+ case '\001': gl_fixup(gl_prompt, -1, 0); /* ^A */
862
+ break;
863
+ case '\002': gl_fixup(gl_prompt, -1, gl_pos-1); /* ^B */
864
+ break;
865
+ case '\004': /* ^D */
866
+ if (gl_cnt == 0) {
867
+ gl_buf[0] = 0;
868
+ gl_cleanup();
869
+ gl_putc('\n');
870
+ return gl_buf;
871
+ } else {
872
+ gl_del(0);
873
+ }
874
+ break;
875
+ case '\005': gl_fixup(gl_prompt, -1, gl_cnt); /* ^E */
876
+ break;
877
+ case '\006': gl_fixup(gl_prompt, -1, gl_pos+1); /* ^F */
878
+ break;
879
+ case '\010': case '\177': gl_del(-1); /* ^H and DEL */
880
+ break;
881
+ case '\t': /* TAB */
882
+ if (gl_tab_hook) {
883
+ tmp = gl_pos;
884
+ loc = gl_tab_hook(gl_buf, strlen(gl_prompt), &tmp);
885
+ if (loc >= 0 || tmp != gl_pos || loc == -2)
886
+ gl_fixup(gl_prompt, loc, tmp);
887
+ }
888
+ break;
889
+ case '\013': gl_kill(); /* ^K */
890
+ break;
891
+ case '\014': sigar_getline_clear_screen(); /* ^L */
892
+ break;
893
+ case '\016': /* ^N */
894
+ strcpy(gl_buf, hist_next());
895
+ if (gl_in_hook)
896
+ gl_in_hook(gl_buf);
897
+ gl_fixup(gl_prompt, 0, BUF_SIZE);
898
+ break;
899
+ case '\017': gl_overwrite = !gl_overwrite; /* ^O */
900
+ break;
901
+ case '\020': /* ^P */
902
+ strcpy(gl_buf, hist_prev());
903
+ if (gl_in_hook)
904
+ gl_in_hook(gl_buf);
905
+ gl_fixup(gl_prompt, 0, BUF_SIZE);
906
+ break;
907
+ case '\022': search_back(1); /* ^R */
908
+ break;
909
+ case '\023': search_forw(1); /* ^S */
910
+ break;
911
+ case '\024': gl_transpose(); /* ^T */
912
+ break;
913
+ case '\025': gl_fixup(gl_prompt,-1,0); gl_kill(); /* ^U */
914
+ break;
915
+ case '\031': gl_yank(); /* ^Y */
916
+ break;
917
+ case '\033':
918
+ switch(c = gl_getc())
919
+ {
920
+ case 'b': /* M-b */
921
+ case 'B': /* M-B */
922
+ gl_back_1_word();
923
+ break;
924
+ case 'd': /* M-d */
925
+ case 'D': /* M-D */
926
+ gl_kill_1_word();
927
+ break;
928
+ case 'f': /* M-f */
929
+ case 'F': /* M-F */
930
+ gl_fwd_1_word();
931
+ break;
932
+ case '[': /* ansi arrow keys */
933
+ case 'O': /* xterm arrow keys */
934
+ switch(c = gl_getc())
935
+ {
936
+ case 'A': /* up */
937
+ strcpy(gl_buf, hist_prev());
938
+ if (gl_in_hook)
939
+ gl_in_hook(gl_buf);
940
+ gl_fixup(gl_prompt, 0, BUF_SIZE);
941
+ break;
942
+ case 'B': /* down */
943
+ strcpy(gl_buf, hist_next());
944
+ if (gl_in_hook)
945
+ gl_in_hook(gl_buf);
946
+ gl_fixup(gl_prompt, 0, BUF_SIZE);
947
+ break;
948
+ case 'C': gl_fixup(gl_prompt, -1, gl_pos+1); /* right */
949
+ break;
950
+ case 'D': gl_fixup(gl_prompt, -1, gl_pos-1); /* left */
951
+ break;
952
+ default: /* who knows */
953
+ gl_bell();
954
+ break;
955
+ }
956
+ break;
957
+ default:
958
+ gl_bell();
959
+ }
960
+ break;
961
+ default: /* check for a terminal signal */
962
+
963
+ #if defined(unix) || defined(WIN32) || defined(R__MWERKS)
964
+ if (c > 0) { /* ignore 0 (reset above) */
965
+ sig = 0;
966
+ #ifdef SIGINT
967
+ if (c == gl_intrc)
968
+ sig = SIGINT;
969
+ #endif
970
+ #ifdef SIGQUIT
971
+ if (c == gl_quitc)
972
+ sig = SIGQUIT;
973
+ #endif
974
+ #ifdef SIGTSTP
975
+ if (c == gl_suspc || c == gl_dsuspc)
976
+ sig = SIGTSTP;
977
+ #endif
978
+ if (sig != 0) {
979
+ gl_cleanup();
980
+ #if !defined(WIN32)
981
+ raise(sig);
982
+ #endif
983
+ #ifdef WIN32
984
+ if (sig == SIGINT) GenerateConsoleCtrlEvent(CTRL_C_EVENT,0);
985
+ else raise(sig);
986
+ #endif
987
+ gl_init();
988
+ sigar_getline_redraw();
989
+ c = 0;
990
+ }
991
+ }
992
+ #endif /* unix */
993
+ if (c > 0)
994
+ gl_bell();
995
+ break;
996
+ }
997
+ }
998
+ if (mode == 1) return NULL;
999
+ }
1000
+ if (c == -1 && gl_notty)
1001
+ gl_eof = 1;
1002
+ else
1003
+ gl_eof = 0;
1004
+
1005
+ gl_cleanup();
1006
+ gl_buf[0] = 0;
1007
+ return gl_buf;
1008
+ }
1009
+
1010
+ SIGAR_DECLARE(int)
1011
+ sigar_getline_eof()
1012
+ {
1013
+ return gl_eof;
1014
+ }
1015
+
1016
+ SIGAR_DECLARE(char *)
1017
+ sigar_getline(char *prompt)
1018
+ {
1019
+ return sigar_getlinem(0, prompt);
1020
+ }
1021
+
1022
+ static void
1023
+ gl_addchar(int c)
1024
+ /* adds the character c to the input buffer at current location */
1025
+ {
1026
+ int i;
1027
+
1028
+ if (gl_cnt >= BUF_SIZE - 1)
1029
+ gl_error("\n*** Error: sigar_getline(): input buffer overflow\n");
1030
+ if (gl_overwrite == 0 || gl_pos == gl_cnt) {
1031
+ for (i=gl_cnt; i >= gl_pos; i--)
1032
+ gl_buf[i+1] = gl_buf[i];
1033
+ gl_buf[gl_pos] = c;
1034
+ gl_fixup(gl_prompt, gl_pos, gl_pos+1);
1035
+ } else {
1036
+ gl_buf[gl_pos] = c;
1037
+ gl_extent = 1;
1038
+ gl_fixup(gl_prompt, gl_pos, gl_pos+1);
1039
+ }
1040
+ }
1041
+
1042
+ static void
1043
+ gl_yank()
1044
+ /* adds the kill buffer to the input buffer at current location */
1045
+ {
1046
+ int i, len;
1047
+
1048
+ len = strlen(gl_killbuf);
1049
+ if (len > 0) {
1050
+ gl_mark = gl_pos;
1051
+ if (gl_overwrite == 0) {
1052
+ if (gl_cnt + len >= BUF_SIZE - 1)
1053
+ gl_error("\n*** Error: sigar_getline(): input buffer overflow\n");
1054
+ for (i=gl_cnt; i >= gl_pos; i--)
1055
+ gl_buf[i+len] = gl_buf[i];
1056
+ for (i=0; i < len; i++)
1057
+ gl_buf[gl_pos+i] = gl_killbuf[i];
1058
+ gl_fixup(gl_prompt, gl_pos, gl_pos+len);
1059
+ } else {
1060
+ if (gl_pos + len > gl_cnt) {
1061
+ if (gl_pos + len >= BUF_SIZE - 1)
1062
+ gl_error("\n*** Error: sigar_getline(): input buffer overflow\n");
1063
+ gl_buf[gl_pos + len] = 0;
1064
+ }
1065
+ for (i=0; i < len; i++)
1066
+ gl_buf[gl_pos+i] = gl_killbuf[i];
1067
+ gl_extent = len;
1068
+ gl_fixup(gl_prompt, gl_pos, gl_pos+len);
1069
+ }
1070
+ } else
1071
+ gl_bell();
1072
+ }
1073
+
1074
+ static void
1075
+ gl_transpose()
1076
+ /* switch character under cursor and to left of cursor */
1077
+ {
1078
+ int c;
1079
+
1080
+ if (gl_pos > 0 && gl_cnt > gl_pos) {
1081
+ c = gl_buf[gl_pos-1];
1082
+ gl_buf[gl_pos-1] = gl_buf[gl_pos];
1083
+ gl_buf[gl_pos] = c;
1084
+ gl_extent = 2;
1085
+ gl_fixup(gl_prompt, gl_pos-1, gl_pos);
1086
+ } else
1087
+ gl_bell();
1088
+ }
1089
+
1090
+ static void
1091
+ gl_newline()
1092
+ /*
1093
+ * Cleans up entire line before returning to caller. A \n is appended.
1094
+ * If line longer than screen, we redraw starting at beginning
1095
+ */
1096
+ {
1097
+ int change = gl_cnt;
1098
+ int len = gl_cnt;
1099
+ int loc = gl_width - 5; /* shifts line back to start position */
1100
+
1101
+ if (gl_cnt >= BUF_SIZE - 1)
1102
+ gl_error("\n*** Error: sigar_getline(): input buffer overflow\n");
1103
+ if (gl_out_hook) {
1104
+ change = gl_out_hook(gl_buf);
1105
+ len = strlen(gl_buf);
1106
+ }
1107
+ if (gl_erase_line) {
1108
+ char gl_buf0 = gl_buf[0];
1109
+ gl_buf[0] = '\0';
1110
+ gl_fixup("", 0, 0);
1111
+ gl_buf[0] = gl_buf0;
1112
+ }
1113
+ else {
1114
+ if (loc > len)
1115
+ loc = len;
1116
+ gl_fixup(gl_prompt, change, loc); /* must do this before appending \n */
1117
+ gl_putc('\n');
1118
+ }
1119
+ #if 0
1120
+ gl_buf[len] = '\n';
1121
+ gl_buf[len+1] = '\0';
1122
+ #endif
1123
+ gl_mark = -1;
1124
+ }
1125
+
1126
+ static void
1127
+ gl_del(int loc)
1128
+ /*
1129
+ * Delete a character. The loc variable can be:
1130
+ * -1 : delete character to left of cursor
1131
+ * 0 : delete character under cursor
1132
+ */
1133
+ {
1134
+ int i;
1135
+
1136
+ if ((loc == -1 && gl_pos > 0) || (loc == 0 && gl_pos < gl_cnt)) {
1137
+ for (i=gl_pos+loc; i < gl_cnt; i++)
1138
+ gl_buf[i] = gl_buf[i+1];
1139
+ gl_fixup(gl_prompt, gl_pos+loc, gl_pos+loc);
1140
+ } else
1141
+ gl_bell();
1142
+ }
1143
+
1144
+ static void
1145
+ gl_kill()
1146
+ /* delete from current position to the end of line */
1147
+ {
1148
+ if (gl_pos < gl_cnt) {
1149
+ strcpy(gl_killbuf, gl_buf + gl_pos);
1150
+ gl_buf[gl_pos] = '\0';
1151
+ gl_fixup(gl_prompt, gl_pos, gl_pos);
1152
+ } else
1153
+ gl_bell();
1154
+ }
1155
+
1156
+ SIGAR_DECLARE(void) sigar_getline_redraw(void)
1157
+ /* emit a newline, reset and redraw prompt and current input line */
1158
+ {
1159
+ if (gl_init_done > 0) {
1160
+ gl_putc('\n');
1161
+ gl_fixup(gl_prompt, -2, gl_pos);
1162
+ }
1163
+ }
1164
+
1165
+ #define CLEAR_SCREEN "\033[2J"
1166
+
1167
+ static void sigar_getline_clear_screen(void)
1168
+ {
1169
+ if (gl_init_done > 0) {
1170
+ gl_putc('\n');
1171
+ /* XXX what to do for non-ansi term? */
1172
+ gl_puts(CLEAR_SCREEN);
1173
+ gl_fixup(gl_prompt, -2, gl_pos);
1174
+ }
1175
+ }
1176
+
1177
+ SIGAR_DECLARE(void) sigar_getline_reset(void)
1178
+ {
1179
+ gl_fixup(gl_prompt,-1,0);
1180
+ gl_kill();
1181
+ }
1182
+
1183
+ static void
1184
+ gl_fixup(char *prompt, int change, int cursor)
1185
+ /*
1186
+ * This function is used both for redrawing when input changes or for
1187
+ * moving within the input line. The parameters are:
1188
+ * prompt: compared to last_prompt[] for changes;
1189
+ * change : the index of the start of changes in the input buffer,
1190
+ * with -1 indicating no changes, -2 indicating we're on
1191
+ * a new line, redraw everything.
1192
+ * cursor : the desired location of the cursor after the call.
1193
+ * A value of BUF_SIZE can be used to indicate the cursor should
1194
+ * move just past the end of the input line.
1195
+ */
1196
+ {
1197
+ static int gl_shift; /* index of first on screen character */
1198
+ static int off_right; /* true if more text right of screen */
1199
+ static int off_left; /* true if more text left of screen */
1200
+ static char last_prompt[BUF_SIZE] = "";
1201
+ int left = 0, right = -1; /* bounds for redraw */
1202
+ int padl; /* how much to erase at end of line */
1203
+ int backup; /* how far to backup before fixing */
1204
+ int new_shift; /* value of shift based on cursor */
1205
+ int extra; /* adjusts when shift (scroll) happens */
1206
+ int i;
1207
+ int new_right = -1; /* alternate right bound, using gl_extent */
1208
+ int l1, l2;
1209
+
1210
+ if (change == -2) { /* reset */
1211
+ gl_pos = gl_cnt = gl_shift = off_right = off_left = 0;
1212
+ gl_passwd = 0;
1213
+ gl_puts(prompt);
1214
+ gl_passwd = gl_no_echo;
1215
+ strcpy(last_prompt, prompt);
1216
+ change = 0;
1217
+ gl_width = gl_termw - strlen(prompt);
1218
+ } else if (strcmp(prompt, last_prompt) != 0) {
1219
+ l1 = strlen(last_prompt);
1220
+ l2 = strlen(prompt);
1221
+ gl_cnt = gl_cnt + l1 - l2;
1222
+ strcpy(last_prompt, prompt);
1223
+ backup = gl_pos - gl_shift + l1;
1224
+ for (i=0; i < backup; i++)
1225
+ gl_putc('\b');
1226
+ gl_passwd = 0;
1227
+ gl_puts(prompt);
1228
+ gl_passwd = gl_no_echo;
1229
+ gl_pos = gl_shift;
1230
+ gl_width = gl_termw - l2;
1231
+ change = 0;
1232
+ }
1233
+ padl = (off_right)? gl_width - 1 : gl_cnt - gl_shift; /* old length */
1234
+ backup = gl_pos - gl_shift;
1235
+ if (change >= 0) {
1236
+ gl_cnt = strlen(gl_buf);
1237
+ if (change > gl_cnt)
1238
+ change = gl_cnt;
1239
+ }
1240
+ if (cursor > gl_cnt) {
1241
+ if (cursor != BUF_SIZE) /* BUF_SIZE means end of line */
1242
+ gl_bell();
1243
+ cursor = gl_cnt;
1244
+ }
1245
+ if (cursor < 0) {
1246
+ gl_bell();
1247
+ cursor = 0;
1248
+ }
1249
+ if (off_right || (off_left && cursor < gl_shift + gl_width - gl_scroll / 2))
1250
+ extra = 2; /* shift the scrolling boundary */
1251
+ else
1252
+ extra = 0;
1253
+ new_shift = cursor + extra + gl_scroll - gl_width;
1254
+ if (new_shift > 0) {
1255
+ new_shift /= gl_scroll;
1256
+ new_shift *= gl_scroll;
1257
+ } else
1258
+ new_shift = 0;
1259
+ if (new_shift != gl_shift) { /* scroll occurs */
1260
+ gl_shift = new_shift;
1261
+ off_left = (gl_shift)? 1 : 0;
1262
+ off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
1263
+ left = gl_shift;
1264
+ new_right = right = (off_right)? gl_shift + gl_width - 2 : gl_cnt;
1265
+ } else if (change >= 0) { /* no scroll, but text changed */
1266
+ if (change < gl_shift + off_left) {
1267
+ left = gl_shift;
1268
+ } else {
1269
+ left = change;
1270
+ backup = gl_pos - change;
1271
+ }
1272
+ off_right = (gl_cnt > gl_shift + gl_width - 1)? 1 : 0;
1273
+ right = (off_right)? gl_shift + gl_width - 2 : gl_cnt;
1274
+ new_right = (gl_extent && (right > left + gl_extent))?
1275
+ left + gl_extent : right;
1276
+ }
1277
+ padl -= (off_right)? gl_width - 1 : gl_cnt - gl_shift;
1278
+ padl = (padl < 0)? 0 : padl;
1279
+ if (left <= right) { /* clean up screen */
1280
+ for (i=0; i < backup; i++)
1281
+ gl_putc('\b');
1282
+ if (left == gl_shift && off_left) {
1283
+ gl_putc('$');
1284
+ left++;
1285
+ }
1286
+ for (i=left; i < new_right; i++)
1287
+ gl_putc(gl_buf[i]);
1288
+ gl_pos = new_right;
1289
+ if (off_right && new_right == right) {
1290
+ gl_putc('$');
1291
+ gl_pos++;
1292
+ } else {
1293
+ for (i=0; i < padl; i++) /* erase remains of prev line */
1294
+ gl_putc(' ');
1295
+ gl_pos += padl;
1296
+ }
1297
+ }
1298
+ i = gl_pos - cursor; /* move to final cursor location */
1299
+ if (i > 0) {
1300
+ while (i--)
1301
+ gl_putc('\b');
1302
+ } else {
1303
+ for (i=gl_pos; i < cursor; i++)
1304
+ gl_putc(gl_buf[i]);
1305
+ }
1306
+ gl_pos = cursor;
1307
+ }
1308
+
1309
+ static int
1310
+ gl_tab(char *buf, int offset, int *loc)
1311
+ /* default tab handler, acts like tabstops every 8 cols */
1312
+ {
1313
+ int i, count, len;
1314
+
1315
+ len = strlen(buf);
1316
+ count = 8 - (offset + *loc) % 8;
1317
+ for (i=len; i >= *loc; i--)
1318
+ buf[i+count] = buf[i];
1319
+ for (i=0; i < count; i++)
1320
+ buf[*loc+i] = ' ';
1321
+ i = *loc;
1322
+ *loc = i + count;
1323
+ return i;
1324
+ }
1325
+
1326
+ /******************* History stuff **************************************/
1327
+
1328
+ #ifndef HIST_SIZE
1329
+ #define HIST_SIZE 100
1330
+ #endif
1331
+
1332
+ static int hist_pos = 0, hist_last = 0;
1333
+ static char *hist_buf[HIST_SIZE];
1334
+
1335
+ static void
1336
+ hist_init()
1337
+ {
1338
+ int i;
1339
+
1340
+ if (gl_savehist) return;
1341
+
1342
+ hist_buf[0] = "";
1343
+ for (i=1; i < HIST_SIZE; i++)
1344
+ hist_buf[i] = (char *)0;
1345
+ }
1346
+
1347
+ SIGAR_DECLARE(void) sigar_getline_completer_set(sigar_getline_completer_t func)
1348
+ {
1349
+ if (func) {
1350
+ gl_tab_hook = func;
1351
+ }
1352
+ else {
1353
+ gl_tab_hook = gl_tab;
1354
+ }
1355
+ }
1356
+
1357
+ SIGAR_DECLARE(void)
1358
+ sigar_getline_histinit(char *file)
1359
+ {
1360
+ char line[256];
1361
+ FILE *fp;
1362
+ int nline = 1; /* prevent from becoming 0 */
1363
+
1364
+ gl_savehist = 0;
1365
+
1366
+ hist_init();
1367
+
1368
+ if (!strcmp(file, "-")) return;
1369
+
1370
+ sprintf(gl_histfile, "%s", file);
1371
+
1372
+ fp = fopen(gl_histfile, "r");
1373
+ if (fp)
1374
+ while (fgets(line, 256, fp)) {
1375
+ nline++;
1376
+ sigar_getline_histadd(line);
1377
+ }
1378
+ else
1379
+ fp = fopen(gl_histfile, "w");
1380
+
1381
+ if (fp) fclose(fp);
1382
+
1383
+ gl_savehist = nline;
1384
+ }
1385
+
1386
+ SIGAR_DECLARE(void)
1387
+ sigar_getline_histadd(char *buf)
1388
+ {
1389
+ static char *prev = 0;
1390
+ char *p = buf;
1391
+ int len;
1392
+
1393
+ while (*p == ' ' || *p == '\t' || *p == '\n')
1394
+ p++;
1395
+ if (*p) {
1396
+ len = strlen(buf);
1397
+ if (strchr(p, '\n')) /* previously line already has NL stripped */
1398
+ len--;
1399
+ if (prev == 0 || strlen(prev) != len ||
1400
+ strncmp(prev, buf, len) != 0) {
1401
+ hist_buf[hist_last] = hist_save(buf);
1402
+ prev = hist_buf[hist_last];
1403
+ hist_last = (hist_last + 1) % HIST_SIZE;
1404
+ if (hist_buf[hist_last] && *hist_buf[hist_last]) {
1405
+ free(hist_buf[hist_last]);
1406
+ }
1407
+ hist_buf[hist_last] = "";
1408
+
1409
+ /* append command to history file */
1410
+ if (gl_savehist) {
1411
+ FILE *fp;
1412
+ fp = fopen(gl_histfile, "a+");
1413
+ if (fp) {
1414
+ fprintf(fp, "%s\n", prev);
1415
+ gl_savehist++;
1416
+ fclose(fp);
1417
+ }
1418
+
1419
+ /* if more than HIST_SIZE lines, safe last 60 command and delete rest */
1420
+ if (gl_savehist > HIST_SIZE) {
1421
+ FILE *ftmp;
1422
+ char tname[L_tmpnam];
1423
+ char line[BUFSIZ];
1424
+
1425
+ fp = fopen(gl_histfile, "r");
1426
+ tmpnam(tname);
1427
+ ftmp = fopen(tname, "w");
1428
+ if (fp && ftmp) {
1429
+ int nline = 0;
1430
+ while (fgets(line, BUFSIZ, fp)) {
1431
+ nline++;
1432
+ gl_savehist = 1; /* prevent from becoming 0 */
1433
+ if (nline > HIST_SIZE-60) {
1434
+ gl_savehist++;
1435
+ fprintf(ftmp, "%s", line);
1436
+ }
1437
+ }
1438
+ }
1439
+ if (fp) fclose(fp);
1440
+ if (ftmp) fclose(ftmp);
1441
+
1442
+ /* copy back to history file */
1443
+ fp = fopen(gl_histfile, "w");
1444
+ ftmp = fopen(tname, "r");
1445
+ if (fp && ftmp)
1446
+ while (fgets(line, BUFSIZ, ftmp))
1447
+ fprintf(fp, "%s", line);
1448
+
1449
+ if (fp) fclose(fp);
1450
+ if (ftmp) fclose(ftmp);
1451
+ remove(tname);
1452
+ }
1453
+ }
1454
+ }
1455
+ }
1456
+ hist_pos = hist_last;
1457
+ }
1458
+
1459
+ static char *
1460
+ hist_prev()
1461
+ /* loads previous hist entry into input buffer, sticks on first */
1462
+ {
1463
+ char *p = 0;
1464
+ int next = (hist_pos - 1 + HIST_SIZE) % HIST_SIZE;
1465
+
1466
+ if (hist_buf[hist_pos] != 0 && next != hist_last) {
1467
+ hist_pos = next;
1468
+ p = hist_buf[hist_pos];
1469
+ }
1470
+ if (p == 0) {
1471
+ p = "";
1472
+ gl_bell();
1473
+ }
1474
+ return p;
1475
+ }
1476
+
1477
+ static char *
1478
+ hist_next()
1479
+ /* loads next hist entry into input buffer, clears on last */
1480
+ {
1481
+ char *p = 0;
1482
+
1483
+ if (hist_pos != hist_last) {
1484
+ hist_pos = (hist_pos+1) % HIST_SIZE;
1485
+ p = hist_buf[hist_pos];
1486
+ }
1487
+ if (p == 0) {
1488
+ p = "";
1489
+ gl_bell();
1490
+ }
1491
+ return p;
1492
+ }
1493
+
1494
+ static char *
1495
+ hist_save(char *p)
1496
+ /* makes a copy of the string */
1497
+ {
1498
+ char *s = 0;
1499
+ int len = strlen(p);
1500
+ char *nl = strchr(p, '\n');
1501
+
1502
+ if (nl) {
1503
+ if ((s = (char *)malloc(len)) != 0) {
1504
+ strncpy(s, p, len-1);
1505
+ s[len-1] = 0;
1506
+ }
1507
+ } else {
1508
+ if ((s = (char *)malloc(len+1)) != 0) {
1509
+ strcpy(s, p);
1510
+ }
1511
+ }
1512
+ if (s == 0)
1513
+ gl_error("\n*** Error: hist_save() failed on malloc\n");
1514
+ return s;
1515
+ }
1516
+
1517
+ /******************* Search stuff **************************************/
1518
+
1519
+ static char search_prompt[101]; /* prompt includes search string */
1520
+ static char search_string[100];
1521
+ static int search_pos = 0; /* current location in search_string */
1522
+ static int search_forw_flg = 0; /* search direction flag */
1523
+ static int search_last = 0; /* last match found */
1524
+
1525
+ static void
1526
+ search_update(int c)
1527
+ {
1528
+ if (c == 0) {
1529
+ search_pos = 0;
1530
+ search_string[0] = 0;
1531
+ search_prompt[0] = '?';
1532
+ search_prompt[1] = ' ';
1533
+ search_prompt[2] = 0;
1534
+ } else if (c > 0) {
1535
+ search_string[search_pos] = c;
1536
+ search_string[search_pos+1] = 0;
1537
+ search_prompt[search_pos] = c;
1538
+ search_prompt[search_pos+1] = '?';
1539
+ search_prompt[search_pos+2] = ' ';
1540
+ search_prompt[search_pos+3] = 0;
1541
+ search_pos++;
1542
+ } else {
1543
+ if (search_pos > 0) {
1544
+ search_pos--;
1545
+ search_string[search_pos] = 0;
1546
+ search_prompt[search_pos] = '?';
1547
+ search_prompt[search_pos+1] = ' ';
1548
+ search_prompt[search_pos+2] = 0;
1549
+ } else {
1550
+ gl_bell();
1551
+ hist_pos = hist_last;
1552
+ }
1553
+ }
1554
+ }
1555
+
1556
+ static void
1557
+ search_addchar(int c)
1558
+ {
1559
+ char *loc;
1560
+
1561
+ search_update(c);
1562
+ if (c < 0) {
1563
+ if (search_pos > 0) {
1564
+ hist_pos = search_last;
1565
+ } else {
1566
+ gl_buf[0] = 0;
1567
+ hist_pos = hist_last;
1568
+ }
1569
+ strcpy(gl_buf, hist_buf[hist_pos]);
1570
+ }
1571
+ if ((loc = strstr(gl_buf, search_string)) != 0) {
1572
+ gl_fixup(search_prompt, 0, loc - gl_buf);
1573
+ } else if (search_pos > 0) {
1574
+ if (search_forw_flg) {
1575
+ search_forw(0);
1576
+ } else {
1577
+ search_back(0);
1578
+ }
1579
+ } else {
1580
+ gl_fixup(search_prompt, 0, 0);
1581
+ }
1582
+ }
1583
+
1584
+ static void
1585
+ search_term()
1586
+ {
1587
+ gl_search_mode = 0;
1588
+ if (gl_buf[0] == 0) /* not found, reset hist list */
1589
+ hist_pos = hist_last;
1590
+ if (gl_in_hook)
1591
+ gl_in_hook(gl_buf);
1592
+ gl_fixup(gl_prompt, 0, gl_pos);
1593
+ }
1594
+
1595
+ static void
1596
+ search_back(int new_search)
1597
+ {
1598
+ int found = 0;
1599
+ char *p, *loc;
1600
+
1601
+ search_forw_flg = 0;
1602
+ if (gl_search_mode == 0) {
1603
+ search_last = hist_pos = hist_last;
1604
+ search_update(0);
1605
+ gl_search_mode = 1;
1606
+ gl_buf[0] = 0;
1607
+ gl_fixup(search_prompt, 0, 0);
1608
+ } else if (search_pos > 0) {
1609
+ while (!found) {
1610
+ p = hist_prev();
1611
+ if (*p == 0) { /* not found, done looking */
1612
+ gl_buf[0] = 0;
1613
+ gl_fixup(search_prompt, 0, 0);
1614
+ found = 1;
1615
+ } else if ((loc = strstr(p, search_string)) != 0) {
1616
+ strcpy(gl_buf, p);
1617
+ gl_fixup(search_prompt, 0, loc - p);
1618
+ if (new_search)
1619
+ search_last = hist_pos;
1620
+ found = 1;
1621
+ }
1622
+ }
1623
+ } else {
1624
+ gl_bell();
1625
+ }
1626
+ }
1627
+
1628
+ static void
1629
+ search_forw(int new_search)
1630
+ {
1631
+ int found = 0;
1632
+ char *p, *loc;
1633
+
1634
+ search_forw_flg = 1;
1635
+ if (gl_search_mode == 0) {
1636
+ search_last = hist_pos = hist_last;
1637
+ search_update(0);
1638
+ gl_search_mode = 1;
1639
+ gl_buf[0] = 0;
1640
+ gl_fixup(search_prompt, 0, 0);
1641
+ } else if (search_pos > 0) {
1642
+ while (!found) {
1643
+ p = hist_next();
1644
+ if (*p == 0) { /* not found, done looking */
1645
+ gl_buf[0] = 0;
1646
+ gl_fixup(search_prompt, 0, 0);
1647
+ found = 1;
1648
+ } else if ((loc = strstr(p, search_string)) != 0) {
1649
+ strcpy(gl_buf, p);
1650
+ gl_fixup(search_prompt, 0, loc - p);
1651
+ if (new_search)
1652
+ search_last = hist_pos;
1653
+ found = 1;
1654
+ }
1655
+ }
1656
+ } else {
1657
+ gl_bell();
1658
+ }
1659
+ }
1660
+ #if 0
1661
+ /***********************************************************************
1662
+ * *
1663
+ * Strip blanks from both sides of a string. Space for the new *
1664
+ * string is allocated and a pointer to it is returned. *
1665
+ * *
1666
+ ***********************************************************************/
1667
+ char *strip(char *s)
1668
+ {
1669
+ char *r, *t1, *t2;
1670
+ int l;
1671
+
1672
+ l = strlen(s);
1673
+ r = (char *)calloc(l+1, 1);
1674
+
1675
+ if (l == 0) {
1676
+ *r = '\0';
1677
+ return r;
1678
+ }
1679
+
1680
+ /* get rid of leading blanks */
1681
+ t1 = s;
1682
+ while (*t1 == ' ')
1683
+ t1++;
1684
+
1685
+ t2 = s + l - 1;
1686
+ while (*t2 == ' ' && t2 > s)
1687
+ t2--;
1688
+
1689
+ if (t1 > t2) {
1690
+ *r = '\0';
1691
+ return r;
1692
+ }
1693
+ strncpy(r, t1, (size_t) (t2-t1+1));
1694
+
1695
+ return r;
1696
+ }
1697
+ #endif
1698
+ /*****************************************************************************/
1699
+ /* Extra routine provided by Christian Lacunza <lacunza@cdfsg5.lbl.gov> */
1700
+ /*****************************************************************************/
1701
+
1702
+ /* move cursor back to beginning of _current_ word */
1703
+ /* unless it's already at the beginning, */
1704
+ /* in which case it moves back to the beginning */
1705
+ /* of the _previous_ word. */
1706
+ static void gl_back_1_word( void )
1707
+ {
1708
+ int i = gl_pos;
1709
+
1710
+ /* if we're at the beginning of a word, */
1711
+ /* slip back into the preceeding whitespace */
1712
+ if( i>0 && is_whitespace(gl_buf[i-1]) ) {
1713
+ i-=1;
1714
+ }
1715
+
1716
+ /* now move back over all consecutive whitespace */
1717
+ while( i>0 && is_whitespace(gl_buf[i]) ) {
1718
+ i-=1;
1719
+ }
1720
+
1721
+ /* now keep moving back over all consecutive non-whitespace */
1722
+ /* until we find the beginning of this word. */
1723
+ /* ie. stop just before more whitespace shows up. */
1724
+ while( i>0 && !is_whitespace(gl_buf[i-1]) ) {
1725
+ i-=1;
1726
+ }
1727
+
1728
+ /* move the cursor here */
1729
+ gl_fixup(gl_prompt, -1, i);
1730
+ }
1731
+
1732
+ /* kills from current position to end of word */
1733
+ static void gl_kill_1_word( void )
1734
+ {
1735
+ int i = gl_pos;
1736
+ int j = gl_pos;
1737
+
1738
+ /* delete this: */
1739
+ #if 0
1740
+ /* not sure what to do with "punctuation" */
1741
+ if( is_whitespace(gl_buf[j]) && gl_buf[j]!=' ' ) {
1742
+ return;
1743
+ }
1744
+ /* first find a word */
1745
+ while( j<gl_cnt && gl_buf[j]==' ' ) {
1746
+ j+=1;
1747
+ }
1748
+ #endif
1749
+
1750
+ /* first find a word */
1751
+ while( j<gl_cnt && is_whitespace(gl_buf[j]) ) {
1752
+ j+=1;
1753
+ }
1754
+
1755
+ /* next, find the end of this word. */
1756
+ while( j<gl_cnt && !is_whitespace(gl_buf[j+1]) ) {
1757
+ j+=1;
1758
+ }
1759
+
1760
+ /* kill */
1761
+ gl_kill_region( i, j );
1762
+
1763
+ /* fixup */
1764
+ gl_fixup(gl_prompt, gl_pos, gl_pos);
1765
+ }
1766
+
1767
+ static void gl_kill_region( int i, int j )
1768
+ {
1769
+ /* copy to kill buffer */
1770
+ strncpy( gl_killbuf, gl_buf+i, j-i+1 );
1771
+ gl_killbuf[j-i+1]='\0';
1772
+
1773
+ /* remove from gl_buf */
1774
+ while( j<gl_cnt ) {
1775
+ gl_buf[i]=gl_buf[j+1];
1776
+ i+=1;
1777
+ j+=1;
1778
+ }
1779
+ gl_buf[i]='\0';
1780
+ }
1781
+
1782
+ /* move cursor forward to the beginning of the next word. */
1783
+ static void gl_fwd_1_word( void )
1784
+ {
1785
+ int i = gl_pos;
1786
+
1787
+ /* move past all non-whitespace into the whitespace between words. */
1788
+ while( i<gl_cnt && !is_whitespace(gl_buf[i]) ) {
1789
+ i+=1;
1790
+ }
1791
+
1792
+ /* move past this whitespace to the beginning of the next word. */
1793
+ while( i<gl_cnt && is_whitespace(gl_buf[i]) ) {
1794
+ i+=1;
1795
+ }
1796
+
1797
+ /* move the cursor here. */
1798
+ gl_fixup(gl_prompt, -1, i);
1799
+ }
1800
+
1801
+ /* NOTE: "whitespace" is very loosely defined. */
1802
+ static int is_whitespace( char c )
1803
+ {
1804
+ int decent_character;
1805
+
1806
+ decent_character = sigar_isalpha(c) || sigar_isdigit(c) || c=='_';
1807
+
1808
+ return !decent_character;
1809
+ }
1810
+
1811
+ /* sets mark to be at point */
1812
+ static void gl_set_mark( void )
1813
+ {
1814
+ gl_mark = gl_pos;
1815
+ }
1816
+
1817
+ /* kills from mark to point */
1818
+ static void gl_wipe( void )
1819
+ {
1820
+ int left, right;
1821
+
1822
+ if( gl_mark < 0 ) return;
1823
+ if( gl_mark == gl_pos ) return;
1824
+
1825
+ if( gl_mark < gl_pos ) {
1826
+ left = gl_mark;
1827
+ right = gl_pos;
1828
+ }
1829
+ else {
1830
+ left = gl_pos;
1831
+ right = gl_mark;
1832
+ }
1833
+
1834
+ gl_kill_region( left, right-1 );
1835
+ gl_fixup( gl_prompt, left, left );
1836
+ }
1837
+
1838
+ /* echanges point and mark */
1839
+ static void gl_exch( void )
1840
+ {
1841
+ int tmp;
1842
+
1843
+ /* make sure mark is set */
1844
+ if( gl_mark < 0 ) return;
1845
+
1846
+ tmp = gl_pos;
1847
+ gl_fixup( gl_prompt, -1, gl_mark );
1848
+ gl_mark = tmp;
1849
+ }