aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2011-10-11 15:05:38 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2011-10-11 15:05:38 +0200
commit1efec3952b780cc675ae111313017c3b91d20a01 (patch)
tree8a2d77b52e2c558976c8d2d362edf8837e2066ea
downloaderlang-slang-fork-1efec3952b780cc675ae111313017c3b91d20a01.tar.gz
initial commit based on erlang-slang 1.0 release (debian tar ball)
-rw-r--r--Makefile22
-rw-r--r--README32
-rw-r--r--TODO17
-rw-r--r--c_src/Makefile28
-rw-r--r--c_src/slang_drv.c921
-rw-r--r--config/config.cache16
-rwxr-xr-xconfig/config.guess890
-rw-r--r--config/config.log8
-rwxr-xr-xconfig/config.status169
-rwxr-xr-xconfig/config.sub952
-rwxr-xr-xconfig/configure1077
-rw-r--r--config/configure.in89
-rwxr-xr-xconfig/install-sh250
-rw-r--r--demo/Makefile20
-rw-r--r--demo/ex1.erl31
-rw-r--r--demo/ex2.c28
-rw-r--r--demo/ex2.erl52
-rw-r--r--demo/ex3.c40
-rw-r--r--demo/pager.erl351
-rw-r--r--doc/cref.txt4870
-rw-r--r--doc/cslang.txt3300
-rw-r--r--doc/erlslang.txt2143
-rw-r--r--ebin/.gitignore1
-rw-r--r--include.mk15
-rw-r--r--include.mk.in15
-rw-r--r--include/slang.hrl84
-rw-r--r--mk.include0
-rw-r--r--priv/.gitignore1
-rw-r--r--slang.pub11
-rw-r--r--src/Makefile23
-rw-r--r--src/slang.app.src8
-rw-r--r--src/slang.erl644
-rw-r--r--src/slang_int.hrl180
-rw-r--r--src/slang_lib.erl15
-rw-r--r--vsn.mk1
35 files changed, 16304 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..a8a4c78
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+
+DIRS = src c_src demo
+
+all clean:
+ @set -e ; \
+ for d in $(DIRS) ; do \
+ if [ -d $$d ]; then ( cd $$d && $(MAKE) $@ ) || exit 1 ; fi ; \
+ done
+
+debug:
+ @set -e ; \
+ for d in $(DIRS) ; do \
+ if [ -d $$d ]; then ( cd $$d && $(MAKE) TYPE=debug ) || exit 1 ; fi ; \
+ done
+
+
+
+# possibly with --with-slang-include arg
+conf:
+ (cd config; ./configure)
+
+
diff --git a/README b/README
new file mode 100644
index 0000000..5752879
--- /dev/null
+++ b/README
@@ -0,0 +1,32 @@
+
+This is slang, an erlang interface to the amazing highly portable tty
+interface that gave us such nice tty applications as mutt and slrn
+
+It's distributed as an erlang application (without a start mod) which makes
+it possible to integrate into a larger buld environment.
+We use this at bluetail to have a terminal application onto our
+actual target machine. It can be used to to anything that's possible
+to di with the slang lib itself.
+
+It's know to compile and run with slang version 1.4.2
+
+The API is one-to-one withe the normal C-api to slanglib.
+
+
+demo: contains some various demos
+doc: well .. yes guess what
+config: contains configure scripts and stuff
+
+To compile:
+
+$ (cd config; ./configure)
+$ make
+
+
+
+
+
+
+
+
+
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..d022a86
--- /dev/null
+++ b/TODO
@@ -0,0 +1,17 @@
+
+
+Not happy with the signal handling yet.
+
+erlangify docs
+
+make more demos
+
+implement read_line routines
+
+make sure it runs on more machines, sofar I've only tried linux
+
+windows
+
+implement the getline routines
+
+
diff --git a/c_src/Makefile b/c_src/Makefile
new file mode 100644
index 0000000..358a1b6
--- /dev/null
+++ b/c_src/Makefile
@@ -0,0 +1,28 @@
+
+
+
+ifeq ($(TYPE),debug)
+EXTRA_FLAGS = -g
+else
+EXTRA_FLAGS =
+endif
+
+include ../include.mk
+PIC=-fpic
+ERL = $(ERLDIR)/usr/include
+
+
+all: ../priv/slang_drv.so
+
+
+slang_drv.o: slang_drv.c
+ $(CC) -o slang_drv.o -c $(PIC) $(EXTRA_FLAGS) -I$(ERL) \
+ -I$(SLANG_INCLUDE) -I/usr/local/include slang_drv.c
+
+../priv/slang_drv.so: slang_drv.o
+ mkdir -p ../priv
+ $(LD_SHARED) -o ../priv/slang_drv.so slang_drv.o \
+ -L/usr/local/lib -lslang
+
+clean:
+ -rm -f *.o ../priv/*.so *~ 2> /dev/null
diff --git a/c_src/slang_drv.c b/c_src/slang_drv.c
new file mode 100644
index 0000000..f2e343b
--- /dev/null
+++ b/c_src/slang_drv.c
@@ -0,0 +1,921 @@
+
+#include <stdio.h>
+#include "driver.h"
+#include <slang.h>
+#include <signal.h>
+
+
+#if (SLANG_VERSION < 10400 )
+#define SLsmg_Char_Type unsigned short
+#endif
+
+
+
+/* Standard set of integer macros .. */
+
+#define get_int32(s) ((((unsigned char*) (s))[0] << 24) | \
+ (((unsigned char*) (s))[1] << 16) | \
+ (((unsigned char*) (s))[2] << 8) | \
+ (((unsigned char*) (s))[3]))
+
+#define put_int32(i, s) {((char*)(s))[0] = (char)((i) >> 24) & 0xff; \
+ ((char*)(s))[1] = (char)((i) >> 16) & 0xff; \
+ ((char*)(s))[2] = (char)((i) >> 8) & 0xff; \
+ ((char*)(s))[3] = (char)((i) & 0xff);}
+
+#define get_int16(s) ((((unsigned char*) (s))[0] << 8) | \
+ (((unsigned char*) (s))[1]))
+
+
+#define put_int16(i, s) {((unsigned char*)(s))[0] = ((i) >> 8) & 0xff; \
+ ((unsigned char*)(s))[1] = (i) & 0xff;}
+
+#define get_int8(s) ((((unsigned char*) (s))[0] ))
+
+
+#define put_int8(i, s) { ((unsigned char*)(s))[0] = (i) & 0xff;}
+
+
+
+#define INIT_TTY 1
+#define SET_ABORT_FUNCTION 2
+#define GETKEY 3
+#define RESET_TTY 4
+#define KP_GETKEY 5
+#define UNGETKEY 6
+#define SETVAR 7
+#define GETVAR 8
+#define KP_INIT 9
+
+/* screen mgmt */
+
+#define SMG_FILL_REGION 10
+#define SMG_SET_CHAR_SET 11
+#define SMG_SUSPEND_SMG 12
+#define SMG_RESUME_SMG 13
+#define SMG_ERASE_EOL 14
+#define SMG_GOTORC 15
+#define SMG_ERASE_EOS 16
+#define SMG_REVERSE_VIDEO 17
+#define SMG_SET_COLOR 18
+#define SMG_NORMAL_VIDEO 19
+#define SMG_PRINTF 20
+#define SMG_VPRINTF 21
+#define SMG_WRITE_STRING 22
+#define SMG_WRITE_NSTRING 23
+#define SMG_WRITE_CHAR 24
+#define SMG_WRITE_NCHARS 25
+#define SMG_WRITE_WRAPPED_STRING 26
+#define SMG_CLS 27
+#define SMG_REFRESH 28
+#define SMG_TOUCH_LINES 29
+#define SMG_TOUCH_SCREEN 30
+#define SMG_INIT_SMG 31
+#define SMG_REINIT_SMG 32
+#define SMG_RESET_SMG 33
+#define SMG_CHAR_AT 34
+#define SMG_SET_SCREEN_START 35
+#define SMG_DRAW_HLINE 36
+#define SMG_DRAW_VLINE 37
+#define SMG_DRAW_OBJECT 38
+#define SMG_DRAW_BOX 39
+#define SMG_GET_COLUMN 40
+#define SMG_GET_ROW 41
+#define SMG_FORWARD 42
+#define SMG_WRITE_COLOR_CHARS 43
+#define SMG_READ_RAW 44
+#define SMG_WRITE_RAW 45
+#define SMG_SET_COLOR_IN_REGION 46
+
+
+
+
+/* ops for all the tt_ functions */
+
+#define TT_FLUSH_OUTPUT 50
+#define TT_SET_SCROLL_REGION 51
+#define TT_RESET_SCROLL_REGION 52
+#define TT_REVERSE_VIDEO 53
+#define TT_BOLD_VIDEO 54
+#define TT_BEGIN_INSERT 55
+#define TT_END_INSERT 56
+#define TT_DEL_EOL 57
+#define TT_GOTO_RC 58
+#define TT_DELETE_NLINES 59
+#define TT_DELETE_CHAR 60
+#define TT_ERASE_LINE 61
+#define TT_NORMAL_VIDEO 62
+#define TT_CLS 63
+#define TT_BEEP 64
+#define TT_REVERSE_INDEX 65
+#define TT_SMART_PUTS 66
+#define TT_WRITE_STRING 67
+#define TT_PUTCHAR 68
+#define TT_INIT_VIDEO 69
+#define TT_RESET_VIDEO 70
+#define TT_GET_TERMINFO 71
+#define TT_GET_SCREEN_SIZE 72
+#define TT_SET_CURSOR_VISIBILITY 73
+#define TT_SET_MOUSE_MODE 74
+
+#define TT_INITIALIZE 75
+#define TT_ENABLE_CURSOR_KEYS 76
+#define TT_SET_TERM_VTXXX 77
+#define TT_SET_COLOR_ESC 78
+#define TT_WIDE_WIDTH 79
+#define TT_NARROW_WIDTH 80
+#define TT_SET_ALT_CHAR_SET 81
+#define TT_WRITE_TO_STATUS_LINE 82
+#define TT_DISABLE_STATUS_LINE 83
+
+
+#define TT_TGETSTR 84
+#define TT_TGETNUM 85
+#define TT_TGETFLAG 86
+#define TT_TIGETENT 87
+#define TT_TIGETSTR 88
+#define TT_TIGETNUM 89
+
+#define SLTT_GET_COLOR_OBJECT 90
+#define TT_SET_COLOR_OBJECT 91
+#define TT_SET_COLOR 92
+#define TT_SET_MONO 93
+#define TT_ADD_COLOR_ATTRIBUTE 94
+#define TT_SET_COLOR_FGBG 95
+
+
+/* aux tty functions */
+#define ISATTY 100
+#define EFORMAT 101
+#define SIGNAL 102
+#define SIGNAL_CHECK 103
+
+
+
+
+/* read/write global variables */
+#define esl_baud_rate 1
+#define esl_read_fd 2
+#define esl_abort_char 3
+#define esl_ignore_user_abort 4
+#define esl_input_buffer_len 5
+#define esl_keyboard_quit 6
+#define esl_last_key_char 7
+#define esl_rl_eof_char 8
+#define esl_rline_quit 9
+#define esl_screen_rows 10
+#define esl_screen_cols 11
+#define esl_tab_width 12
+#define esl_newline_behaviour 13
+#define esl_error 14
+#define esl_version 15
+#define esl_backspace_moves 16
+#define esl_display_eight_bit 17
+
+/* signals */
+#define SL_SIGINT 1
+#define SL_SIGTSTP 2
+#define SL_SIGQUIT 3
+#define SL_SIGTTOU 4
+#define SL_SIGTTIN 5
+#define SL_SIGWINCH 6
+
+
+
+
+
+static long sl_start();
+static int sl_stop(), sl_read();
+static struct driver_entry sl_driver_entry;
+
+
+static int wait_for = 0;
+static int signal_cought = 0;
+
+
+
+static int sig_to_x(int x)
+{
+ switch (x ) {
+ case SIGINT: return SL_SIGINT;
+ case SIGTSTP: return SL_SIGTSTP;
+ case SIGQUIT: return SL_SIGQUIT;
+ case SIGTTOU: return SL_SIGTTOU;
+ case SIGTTIN: return SL_SIGTTIN;
+ case SIGWINCH: return SL_SIGWINCH;
+ default: return -1;
+ }
+}
+
+
+static void sig_handler(int sig)
+{
+ signal_cought = sig_to_x(sig);
+}
+
+
+
+static int x_to_sig(int x)
+{
+ switch (x ) {
+ case SL_SIGINT: return SIGINT;
+ case SL_SIGTSTP: return SIGTSTP;
+ case SL_SIGQUIT: return SIGQUIT;
+ case SL_SIGTTOU: return SIGTTOU;
+ case SL_SIGTTIN: return SIGTTIN;
+ case SL_SIGWINCH: return SIGWINCH;
+ default: return -1;
+ }
+}
+
+
+SLsmg_Char_Type *decode_smg_char_type(char **buf)
+{
+ static SLsmg_Char_Type mbuf[256];
+ int i;
+ char *b = *buf;
+ int len = get_int32(*buf); *buf+=4;
+ for(i=0; i<len; i++) {
+ mbuf[i++] = get_int16(*buf); *buf+=2;
+ }
+ return mbuf;
+}
+
+
+static long sl_start(long port, char *buf)
+{
+ return port;
+}
+
+
+static int sl_stop(int port)
+{
+ return 1;
+}
+
+static int ret_int_int(int port, int i, int j)
+{
+ char buf[9];
+ buf[0] = 1;
+ put_int32(i, buf+1);
+ put_int32(j, buf+5);
+ driver_output(port, buf, 9);
+ return i;
+}
+
+
+static int ret_int(int port, int ret)
+{
+ char buf[5];
+ buf[0] = 1;
+ put_int32(ret, buf+1);
+ driver_output(port, buf, 5);
+ return ret;
+}
+
+
+static int ret_string(int port, char *str)
+{
+ str[-1] = 1;
+ driver_output(port, str, 1+strlen(str));
+ return 1;
+}
+
+
+static int sl_output(int port, char *buf, int len)
+{
+ int x,y,z,v,w;
+ char *str, *t1, *t2, *t3;
+ int ret;
+ char ch;
+
+
+ /* check for signals */
+
+ if (signal_cought != 0) { /* async out signal */
+ char xxx[5];
+
+ xxx[0] = 0;
+ put_int32(signal_cought, xxx+1);
+ driver_output(port, xxx, 5);
+ signal_cought = 0;
+ }
+
+ switch (*buf++) {
+ case INIT_TTY: {
+ int abort_char, flow_ctl, opost;
+ abort_char = get_int32(buf); buf+=4;
+ flow_ctl = get_int32(buf); buf+= 4;
+ opost = get_int32(buf); buf+= 4;
+ ret = SLang_init_tty (abort_char,flow_ctl, opost);
+ return ret_int(port, ret);
+ }
+
+ case SET_ABORT_FUNCTION: {
+ SLang_set_abort_signal (NULL);
+ return ret_int(port, 0);
+ }
+ case GETKEY: {
+ unsigned int key;
+ if (SLang_input_pending (0) == 0) {
+ wait_for = GETKEY;
+ driver_select(port, 0, DO_READ, 1);
+ return 0;
+ }
+ x = SLang_getkey ();
+ return ret_int(port, x);
+ }
+ /* read a symbol */
+ case KP_GETKEY: {
+ if (SLang_input_pending (0) == 0) {
+ wait_for = KP_GETKEY;
+ driver_select(port, 0, DO_READ, 1);
+ return 0;
+ }
+ x = SLkp_getkey ();
+ return ret_int(port, x);
+ }
+ case UNGETKEY: {
+ unsigned char key = (unsigned char) *buf;
+ SLang_ungetkey (key);
+ return 0;
+ }
+ case RESET_TTY: {
+ SLang_reset_tty();
+ return 0;
+ }
+ case KP_INIT: {
+ return ret_int(port, SLkp_init ());
+ }
+ case SETVAR: {
+ x = get_int32(buf);buf+= 4;
+ y = get_int32(buf);
+ switch (x) {
+ case esl_baud_rate:
+ SLang_TT_Baud_Rate = y; return 0;
+ case esl_read_fd:
+ return 0;
+ case esl_abort_char:
+ SLang_Abort_Char = y; return 0;
+ case esl_ignore_user_abort:
+ SLang_Ignore_User_Abort=y; return 0;
+ case esl_input_buffer_len :
+ SLang_Input_Buffer_Len=y; return 0;
+ case esl_keyboard_quit:
+ SLKeyBoard_Quit=y; return 0;
+ case esl_last_key_char:
+ SLang_Last_Key_Char=y; return 0;
+ case esl_rl_eof_char:
+ SLang_RL_EOF_Char=y; return 0;
+ case esl_rline_quit:
+ SLang_Rline_Quit=y; return 0;
+ case esl_screen_rows:
+ case esl_screen_cols :
+ return 0;
+ case esl_tab_width:
+ SLsmg_Tab_Width=y; return 0;
+ case esl_newline_behaviour:
+ SLsmg_Newline_Behavior=y; return 0;
+ case esl_error:
+ SLang_Error=y; return 0;
+ case esl_version:
+ return 0;
+ case esl_backspace_moves :
+ SLsmg_Backspace_Moves=y; return 0;
+ case esl_display_eight_bit:
+ SLsmg_Display_Eight_Bit=y; return 0;
+ default:
+ return 0;
+ }
+ }
+
+ case GETVAR: {
+ x = get_int32(buf);
+ switch (x) {
+ case esl_baud_rate:
+ return ret_int(port, SLang_TT_Baud_Rate);
+ case esl_read_fd:
+ return ret_int(port, SLang_TT_Read_FD);
+ case esl_abort_char:
+ return (ret_int(port, SLang_Abort_Char));
+ case esl_ignore_user_abort:
+ return ret_int(port, SLang_Ignore_User_Abort);
+ case esl_input_buffer_len :
+ return ret_int(port, SLang_Input_Buffer_Len);
+ case esl_keyboard_quit:
+ return ret_int(port, SLKeyBoard_Quit);
+ case esl_last_key_char:
+ return ret_int(port, SLang_Last_Key_Char);
+ case esl_rl_eof_char:
+ return ret_int(port, SLang_RL_EOF_Char);
+ case esl_rline_quit:
+ return ret_int(port, SLang_Rline_Quit);
+ case esl_screen_rows:
+ return ret_int(port, SLtt_Screen_Rows);
+ case esl_screen_cols :
+ return ret_int(port, SLtt_Screen_Cols);
+ case esl_tab_width:
+ return ret_int(port, SLsmg_Tab_Width);
+ case esl_newline_behaviour:
+ return ret_int(port, SLsmg_Newline_Behavior);
+ case esl_error:
+ return ret_int(port, SLang_Error);
+ case esl_version:
+ return ret_int(port, SLang_Version);
+ case esl_backspace_moves :
+ return ret_int(port, SLsmg_Backspace_Moves);
+ case esl_display_eight_bit:
+ return ret_int(port, SLsmg_Display_Eight_Bit);
+ default:
+ return ret_int(port, -1);
+ }
+ }
+
+
+
+ /*{{{ SLsmg Screen Management Functions */
+
+
+
+ case SMG_FILL_REGION: {
+ x = get_int32(buf); buf+= 4;
+ y = get_int32(buf); buf+= 4;
+ z = get_int32(buf); buf+= 4;
+ v = get_int32(buf); buf+= 4;
+ ch = *buf;
+ SLsmg_fill_region(x, y,z,v,ch);
+ return 0;
+ }
+ case SMG_SET_CHAR_SET: {
+ x = get_int32(buf); buf+= 4;
+ SLsmg_set_char_set(x);
+ return 0;
+ }
+ case SMG_SUSPEND_SMG: {
+ return ret_int(port, SLsmg_suspend_smg());
+ }
+ case SMG_RESUME_SMG: {
+ ret_int(port, SLsmg_resume_smg());
+ }
+ case SMG_ERASE_EOL: {
+ SLsmg_erase_eol();
+ return 0;
+ }
+ case SMG_GOTORC: {
+ x = get_int32(buf); buf+= 4;
+ y = get_int32(buf); buf+= 4;
+ SLsmg_gotorc(x, y);
+ return 0;
+ }
+ case SMG_ERASE_EOS: {
+ SLsmg_erase_eos();
+ return 0;
+ }
+ case SMG_REVERSE_VIDEO: {
+ SLsmg_reverse_video();
+ return 0;
+ }
+ case SMG_SET_COLOR: {
+ x = get_int32(buf); buf+= 4;
+ SLsmg_set_color(x);
+ return 0;
+ }
+ case SMG_NORMAL_VIDEO: {
+ SLsmg_normal_video();
+ return 0;
+ }
+ case SMG_WRITE_STRING: {
+ SLsmg_write_string(buf);
+ return 0;
+ }
+ case SMG_WRITE_CHAR: {
+ ch = *buf;
+ SLsmg_write_char(ch);
+ return 0;
+ }
+ case SMG_WRITE_WRAPPED_STRING: {
+ t1 = buf;
+ buf += strlen(t1) + 1;
+ x = get_int32(buf); buf+= 4;
+ y = get_int32(buf); buf+= 4;
+ z = get_int32(buf); buf+= 4;
+ v = get_int32(buf); buf+= 4;
+ w = get_int32(buf); buf+= 4;
+ SLsmg_write_wrapped_string(t1, x,y,z,v,w);
+ return 0;
+ }
+ case SMG_CLS: {
+ SLsmg_cls();
+ return 0;
+ }
+ case SMG_REFRESH: {
+ SLsmg_refresh();
+ return 0;
+ }
+ case SMG_TOUCH_LINES: {
+ x = get_int32(buf); buf+= 4;
+ y = get_int32(buf); buf+= 4;
+ SLsmg_touch_lines(x, y);
+ return 0;
+ }
+ case SMG_TOUCH_SCREEN: {
+#if (SLANG_VERSION < 10400 )
+ return ret_int(port, -1);
+#else
+ SLsmg_touch_screen();
+#endif
+ return 0;
+ }
+ case SMG_INIT_SMG: {
+ return ret_int(port, SLsmg_init_smg());
+ }
+ case SMG_REINIT_SMG: {
+#if (SLANG_VERSION < 10400 )
+ return ret_int(port, -1);
+#else
+ return ret_int(port, SLsmg_reinit_smg());
+#endif
+ }
+ case SMG_RESET_SMG: {
+ SLsmg_reset_smg();
+ return 0;
+ }
+ case SMG_CHAR_AT: {
+ return ret_int(port, SLsmg_char_at());
+ }
+ case SMG_SET_SCREEN_START: {
+ int *ip1, *ip2;
+ *ip1 = get_int32(buf); buf+= 4;
+ *ip2 = get_int32(buf); buf+= 4;
+
+ SLsmg_set_screen_start(ip1, ip2);
+ return ret_int_int(port, *ip1, *ip2);
+ }
+ case SMG_DRAW_HLINE: {
+ x = get_int32(buf); buf+= 4;
+ SLsmg_draw_hline(x);
+ return 0;
+ }
+ case SMG_DRAW_VLINE: {
+ x = get_int32(buf); buf+= 4;
+ SLsmg_draw_vline(x);
+ return 0;
+ }
+ case SMG_DRAW_OBJECT: {
+ x = get_int32(buf); buf+= 4;
+ y = get_int32(buf); buf+= 4;
+ x = get_int32(buf); buf+= 4;
+ SLsmg_draw_object(x, y,z);
+ return 0;
+ }
+ case SMG_DRAW_BOX: {
+ x = get_int32(buf); buf+= 4;
+ y = get_int32(buf); buf+= 4;
+ z = get_int32(buf); buf+= 4;
+ v = get_int32(buf); buf+= 4;
+ SLsmg_draw_box(x, y,z,v);
+ return 0;
+ }
+ case SMG_GET_COLUMN: {
+ return ret_int(port, SLsmg_get_column());
+ }
+ case SMG_GET_ROW: {
+ return ret_int(port, SLsmg_get_row());
+ }
+
+ case SMG_FORWARD: {
+ x = get_int32(buf); buf+= 4;
+ SLsmg_forward(x);
+ return 0;
+ }
+ case SMG_WRITE_COLOR_CHARS: {
+ SLsmg_Char_Type * sl;
+ sl = decode_smg_char_type(&buf);
+ x = get_int32(buf); buf+= 4;
+ SLsmg_write_color_chars(sl, x);
+ return 0;
+ }
+ case SMG_READ_RAW: {
+ x = get_int32(buf); buf+= 4;
+ t1 = malloc((2*x) + 2 + 1);
+ y = SLsmg_read_raw((unsigned short*)t1 +1, x);
+ t1[1] = 1;
+ driver_output(port, t1, y+1);
+ free(t1);
+ return 0;
+ }
+ case SMG_WRITE_RAW: {
+ SLsmg_Char_Type * sl;
+ sl = decode_smg_char_type(&buf);
+ x = get_int32(buf);
+ y = SLsmg_write_raw(sl, x);
+ return ret_int(port, y);
+ }
+ case SMG_SET_COLOR_IN_REGION: {
+ x = get_int32(buf); buf+= 4;
+ y = get_int32(buf); buf+= 4;
+ z = get_int32(buf); buf+= 4;
+ v = get_int32(buf); buf+= 4;
+ w = get_int32(buf); buf+= 4;
+ SLsmg_set_color_in_region(x, y,z,v,w);
+ return 0;
+ }
+
+
+
+
+
+
+ /* all the tt_functions */
+
+ case TT_FLUSH_OUTPUT: {
+ ret = SLtt_flush_output();
+ return ret_int(port, ret);
+ }
+ case TT_SET_SCROLL_REGION: {
+
+ x = get_int32(buf); buf+=4;
+ y = get_int32(buf); buf+=4;
+ SLtt_set_scroll_region(x, y);
+ return 0;
+ }
+ case TT_RESET_SCROLL_REGION: {
+ SLtt_reset_scroll_region();
+ return 0;
+ }
+ case TT_REVERSE_VIDEO: {
+ SLtt_reverse_video (get_int32(buf));
+ return 0;
+ }
+ case TT_BOLD_VIDEO: {
+ SLtt_begin_insert();
+ return 0;
+ }
+ case TT_BEGIN_INSERT: {
+ SLtt_begin_insert();
+ return 0;
+ }
+ case TT_END_INSERT: {
+ SLtt_end_insert();
+ return 0;
+ }
+ case TT_DEL_EOL: {
+ SLtt_del_eol();
+ return 0;
+ }
+ case TT_GOTO_RC: {
+ x = get_int32(buf); buf+=4;
+ y = get_int32(buf); buf+=4;
+ SLtt_goto_rc (x, y);
+ return 0;
+ }
+ case TT_DELETE_NLINES: {
+ SLtt_delete_nlines(get_int32(buf));
+ return 0;
+ }
+ case TT_DELETE_CHAR: {
+ SLtt_delete_char();
+ return 0;
+ }
+ case TT_ERASE_LINE: {
+ SLtt_erase_line();
+ return 0;
+ }
+ case TT_NORMAL_VIDEO: {
+ SLtt_normal_video();
+ return 0;
+ }
+ case TT_CLS: {
+ SLtt_cls();
+ return 0;
+ }
+ case TT_BEEP: {
+ SLtt_beep();
+ return 0;
+ }
+ case TT_REVERSE_INDEX: {
+ SLtt_reverse_index(get_int32(buf));
+ return 0;
+ }
+ case TT_SMART_PUTS: {
+ SLsmg_Char_Type *t1 ;
+ SLsmg_Char_Type *t2;
+
+ t1 = decode_smg_char_type(&buf);
+ t2 = decode_smg_char_type(&buf);
+ x = get_int32(buf); buf+=4;
+ y = get_int32(buf); buf+=4;
+ SLtt_smart_puts(t1, t2,x,y);
+ return 0;
+ }
+ case TT_WRITE_STRING: {
+ SLtt_write_string (buf);
+ return 0;
+ }
+ case TT_PUTCHAR: {
+ SLtt_putchar((char) get_int32(buf));
+ return 0;
+ }
+ case TT_INIT_VIDEO: {
+ ret = SLtt_init_video ();
+ return ret_int(port, ret);
+ }
+ case TT_RESET_VIDEO: {
+ SLtt_reset_video ();
+ return 0;
+ }
+ case TT_GET_TERMINFO: {
+ SLtt_get_terminfo();
+ return 0;
+ }
+ case TT_GET_SCREEN_SIZE: {
+ SLtt_get_screen_size ();
+ return 0;
+ }
+ case TT_SET_CURSOR_VISIBILITY: {
+ ret = SLtt_set_cursor_visibility (get_int32(buf));
+ return ret_int(port, ret);
+ }
+ case TT_SET_MOUSE_MODE: {
+ x = get_int32(buf); buf+=4;
+ y = get_int32(buf); buf+=4;
+ ret = SLtt_set_mouse_mode (x,y);
+ return ret_int(port, ret);
+ }
+
+ case TT_INITIALIZE: {
+ ret =SLtt_initialize (buf);
+ return ret_int(port, ret);
+ }
+ case TT_ENABLE_CURSOR_KEYS: {
+ SLtt_enable_cursor_keys();
+ return 0;
+ }
+ case TT_SET_TERM_VTXXX: {
+
+ return 0;
+ }
+ case TT_SET_COLOR_ESC: {
+ x = get_int32(buf); buf+=4;
+ SLtt_set_color_esc (x, buf);
+ return 0;
+ }
+ case TT_WIDE_WIDTH: {
+ SLtt_narrow_width();
+ return 0;
+ }
+ case TT_NARROW_WIDTH: {
+ SLtt_narrow_width();
+ return 0;
+ }
+ case TT_SET_ALT_CHAR_SET: {
+ SLtt_set_alt_char_set (get_int32(buf));
+ return 0;
+ }
+ case TT_WRITE_TO_STATUS_LINE: {
+ x = get_int32(buf); buf+=4;
+ SLtt_write_to_status_line (buf, x);
+ return 0;
+ }
+ case TT_DISABLE_STATUS_LINE: {
+ SLtt_disable_status_line ();
+ return 0;
+ }
+
+
+ case TT_TGETSTR: {
+ str = SLtt_tgetstr (buf);
+ return ret_string(port, str);
+ }
+ case TT_TGETNUM: {
+ x = SLtt_tgetnum (buf);
+ return ret_int(port, x);
+ }
+ case TT_TGETFLAG: {
+ x = SLtt_tgetflag (buf);
+ return ret_int(port, x);
+ }
+ case TT_TIGETENT: {
+ str = SLtt_tigetent (buf);
+ return ret_string(port, str);
+ }
+ case TT_TIGETSTR: {
+
+ return 0;
+ }
+ case TT_TIGETNUM: {
+
+ return 0;
+ }
+
+ case SLTT_GET_COLOR_OBJECT: {
+ x = get_int32(buf); buf+=4;
+ y = SLtt_get_color_object (x);
+ return ret_int(port, y);
+ return 0;
+ }
+ case TT_SET_COLOR_OBJECT: {
+ x = get_int32(buf); buf+=4;
+ y = get_int32(buf); buf+=4;
+ SLtt_set_color_object (x, y);
+ return 0;
+ }
+ case TT_SET_COLOR: {
+ x = get_int32(buf); buf+=4;
+ t1 = buf;
+ t2 = buf + (strlen(t1) + 1);
+ t3 = buf + (strlen(t1) + strlen(t2) + 2);
+ SLtt_set_color (x, t1, t2, t3);
+ return 0;
+ }
+ case TT_SET_MONO: {
+ x = get_int32(buf); buf+=4;
+ t1 = buf;
+ buf += strlen(t1) + 1;
+ y = get_int32(buf);
+ SLtt_set_mono (x, t1, y);
+ return 0;
+ }
+ case TT_ADD_COLOR_ATTRIBUTE: {
+ x = get_int32(buf); buf+=4;
+ y = get_int32(buf); buf+=4;
+ SLtt_add_color_attribute (x, y);
+ return 0;
+ }
+ case TT_SET_COLOR_FGBG: {
+ x = get_int32(buf); buf+=4;
+ y = get_int32(buf); buf+=4;
+ z = get_int32(buf); buf+=4;
+ SLtt_set_color_fgbg (x, y, z);
+ return 0;
+ }
+ case ISATTY: {
+ x = get_int32(buf); buf+=4;
+ return ret_int(port, isatty(x));
+ }
+ case EFORMAT: {
+ fprintf(stderr, "%s", buf);
+ fflush(stderr);
+ return 0;
+ }
+ case SIGNAL: {
+ x = get_int32(buf); buf+=4;
+ SLsignal(x_to_sig(x), sig_handler);
+ return 0;
+ }
+ case SIGNAL_CHECK: {
+ /* polled */
+ if (signal_cought != 0)
+ signal_cought = 0;
+ return ret_int(port, signal_cought);
+ }
+
+ default:
+ return 0;
+ }
+}
+
+
+
+
+/* pending getkey request */
+sl_ready_input(int port, int fd)
+{
+ unsigned int key;
+ driver_select(port, 0, DO_READ, 0);
+ switch (wait_for) {
+ case GETKEY: {
+ key = SLang_getkey ();
+ return ret_int(port, key);
+ }
+ case KP_GETKEY: {
+ key = SLkp_getkey ();
+ return ret_int(port, key);
+ }
+ return 0;
+ }
+}
+
+
+
+/*
+ * Initialize and return a driver entry struct
+ */
+
+struct driver_entry *driver_init(void *handle)
+{
+ sl_driver_entry.init = null_func; /* Not used */
+ sl_driver_entry.start = sl_start;
+ sl_driver_entry.stop = sl_stop;
+ sl_driver_entry.output = sl_output;
+ sl_driver_entry.ready_input = sl_ready_input;
+ sl_driver_entry.ready_output = null_func;
+ sl_driver_entry.driver_name = "slang_drv";
+ sl_driver_entry.finish = null_func;
+ sl_driver_entry.handle = handle; /* MUST set this!!! */
+ return &sl_driver_entry;
+}
+
+
+
+
diff --git a/config/config.cache b/config/config.cache
new file mode 100644
index 0000000..874acfe
--- /dev/null
+++ b/config/config.cache
@@ -0,0 +1,16 @@
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+ac_cv_path_ERL=${ac_cv_path_ERL=/usr/local/bin/erl}
+ac_cv_path_ERLC=${ac_cv_path_ERLC=/usr/local/bin/erlc}
diff --git a/config/config.guess b/config/config.guess
new file mode 100755
index 0000000..30230b3
--- /dev/null
+++ b/config/config.guess
@@ -0,0 +1,890 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >dummy.s
+ .globl main
+ .ent main
+main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
+ amiga:NetBSD:*:*)
+ echo m68k-cbm-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ arm32:NetBSD:*:*)
+ echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:NetBSD:*:*)
+ echo m68k-atari-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:NetBSD:*:*)
+ echo m68k-sun-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:NetBSD:*:*)
+ echo m68k-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >dummy.c
+ int main (argc, argv) int argc; char **argv; {
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy \
+ && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i?86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:4)
+ if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=4.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[3478]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
+ 9000/8?? ) HP_ARCH=hppa1.0 ;;
+ esac
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
+ hp3[0-9][05]:NetBSD:*:*)
+ echo m68k-hp-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:NetBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin32
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin32
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:Linux:*:*)
+ # uname on the ARM produces all sorts of strangeness, and we need to
+ # filter it out.
+ case "$UNAME_MACHINE" in
+ arm* | sa110*) UNAME_MACHINE="arm" ;;
+ esac
+
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us.
+ ld_help_string=`ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
+ i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
+ sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ sed 's/^ //' <<EOF >dummy.s
+ .globl main
+ .ent main
+ main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ LIBC=""
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+
+ objdump --private-headers dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >dummy.c <<EOF
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i?86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i?86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ pc:*:*:*)
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i?86:LynxOS:2.*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+ printf ("vax-dec-bsd\n"); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/config/config.log b/config/config.log
new file mode 100644
index 0000000..0609d04
--- /dev/null
+++ b/config/config.log
@@ -0,0 +1,8 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+configure:576: checking host system type
+configure:597: checking target system type
+configure:615: checking build system type
+configure:701: checking for erl
+configure:752: checking for erlc
diff --git a/config/config.status b/config/config.status
new file mode 100755
index 0000000..f3da4fd
--- /dev/null
+++ b/config/config.status
@@ -0,0 +1,169 @@
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host robin:
+#
+# ./configure
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: ./config.status [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion"
+ exec ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "./config.status generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "$ac_cs_usage"; exit 0 ;;
+ *) echo "$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=.
+
+trap 'rm -fr ../include.mk conftest*; exit 1' 1 2 15
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\&%]/\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
+/^[ ]*VPATH[ ]*=[^:]*$/d
+
+s%@SHELL@%/bin/sh%g
+s%@CFLAGS@%%g
+s%@CPPFLAGS@%%g
+s%@CXXFLAGS@%%g
+s%@FFLAGS@%%g
+s%@DEFS@% -DCPU_VENDOR_OS=\"i686-pc-linux-gnu\" -DLINUX=1 %g
+s%@LDFLAGS@%%g
+s%@LIBS@%%g
+s%@exec_prefix@%${prefix}%g
+s%@prefix@%/usr/local%g
+s%@program_transform_name@%s,x,x,%g
+s%@bindir@%${exec_prefix}/bin%g
+s%@sbindir@%${exec_prefix}/sbin%g
+s%@libexecdir@%${exec_prefix}/libexec%g
+s%@datadir@%${prefix}/share%g
+s%@sysconfdir@%${prefix}/etc%g
+s%@sharedstatedir@%${prefix}/com%g
+s%@localstatedir@%${prefix}/var%g
+s%@libdir@%${exec_prefix}/lib%g
+s%@includedir@%${prefix}/include%g
+s%@oldincludedir@%/usr/include%g
+s%@infodir@%${prefix}/info%g
+s%@mandir@%${prefix}/man%g
+s%@host@%i686-pc-linux-gnu%g
+s%@host_alias@%i686-pc-linux-gnu%g
+s%@host_cpu@%i686%g
+s%@host_vendor@%pc%g
+s%@host_os@%linux-gnu%g
+s%@target@%i686-pc-linux-gnu%g
+s%@target_alias@%i686-pc-linux-gnu%g
+s%@target_cpu@%i686%g
+s%@target_vendor@%pc%g
+s%@target_os@%linux-gnu%g
+s%@build@%i686-pc-linux-gnu%g
+s%@build_alias@%i686-pc-linux-gnu%g
+s%@build_cpu@%i686%g
+s%@build_vendor@%pc%g
+s%@build_os@%linux-gnu%g
+s%@SLANG_INCLUDE@%/usr/include/slang%g
+s%@LD_SHARED@%ld -shared%g
+s%@ERL@%/usr/local/bin/erl%g
+s%@ERLC@%/usr/local/bin/erlc%g
+s%@ERLDIR@%/usr/local/lib/erlang%g
+
+CEOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+
+CONFIG_FILES=${CONFIG_FILES-"../include.mk"}
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+
+
+exit 0
diff --git a/config/config.sub b/config/config.sub
new file mode 100755
index 0000000..e24b850
--- /dev/null
+++ b/config/config.sub
@@ -0,0 +1,952 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+ echo Configuration name missing. 1>&2
+ echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+ echo "or $0 ALIAS" 1>&2
+ echo where ALIAS is a recognized configuration type. 1>&2
+ exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+ *local*)
+ echo $1
+ exit 0
+ ;;
+ *)
+ ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
+ os=
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 \
+ | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
+ | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+ | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+ | mipstx39 | mipstx39el \
+ | sparc | sparclet | sparclite | sparc64 | v850)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[34567]86)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+ | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
+ | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+ | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mipstx39-* | mipstx39el-* \
+ | f301-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-cbm
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-cbm
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-cbm
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i[34567]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i[34567]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i[34567]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i[34567]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | nexen)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | k6 | 6x86)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | nexen-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | k6-* | 6x86-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=rs6000-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sparc)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f301-fujitsu)
+ os=-uxpv
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
diff --git a/config/configure b/config/configure
new file mode 100755
index 0000000..c80f9bc
--- /dev/null
+++ b/config/configure
@@ -0,0 +1,1077 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --with-slang-include=DIR installed slang library"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=../src/slang.erl
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in `pwd` $srcdir/`pwd`; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in `pwd` $srcdir/`pwd`" 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+
+
+# Do some error checking and defaulting for the host and target type.
+# The inputs are:
+# configure --host=HOST --target=TARGET --build=BUILD NONOPT
+#
+# The rules are:
+# 1. You are not allowed to specify --host, --target, and nonopt at the
+# same time.
+# 2. Host defaults to nonopt.
+# 3. If nonopt is not specified, then host defaults to the current host,
+# as determined by config.guess.
+# 4. Target and build default to nonopt.
+# 5. If nonopt is not specified, then target and build default to host.
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+case $host---$target---$nonopt in
+NONE---*---* | *---NONE---* | *---*---NONE) ;;
+*) { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } ;;
+esac
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:576: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking target system type""... $ac_c" 1>&6
+echo "configure:597: checking target system type" >&5
+
+target_alias=$target
+case "$target_alias" in
+NONE)
+ case $nonopt in
+ NONE) target_alias=$host_alias ;;
+ *) target_alias=$nonopt ;;
+ esac ;;
+esac
+
+target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias`
+target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$target" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:615: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+test "$host_alias" != "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+cat >> confdefs.h <<EOF
+#define CPU_VENDOR_OS "$target"
+EOF
+
+
+
+
+
+
+# Check whether --with-slang-include or --without-slang-include was given.
+if test "${with_slang_include+set}" = set; then
+ withval="$with_slang_include"
+ SLANG_INCLUDE=$withval
+else
+ echo XX $withval XX
+ if test "x$SLANG_INCLUDE" = x; then
+ SLANG_INCLUDE=/usr/include/slang
+ fi
+ echo DD $SLANG_INCLUDE DD
+
+fi
+
+
+
+
+case "$target_os" in
+ *cygwin*)
+ :
+ ;;
+ linux*)
+ cat >> confdefs.h <<\EOF
+#define LINUX 1
+EOF
+
+ LD_SHARED="ld -shared"
+ ;;
+ *bsd*)
+ cat >> confdefs.h <<\EOF
+#define BSD 1
+EOF
+
+ LD_SHARED="ld -Bshareable"
+ ;;
+ *solaris*)
+ cat >> confdefs.h <<\EOF
+#define SOLARIS 1
+EOF
+
+ LD_SHARED="ld -G"
+ ;;
+ *)
+ LD_SHARED="ld -shared"
+ ;;
+esac
+
+
+
+
+
+
+
+ # Extract the first word of "erl", so it can be a program name with args.
+set dummy erl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:701: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_ERL'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$ERL" in
+ /*)
+ ac_cv_path_ERL="$ERL" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_ERL="$ERL" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_ERL="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_ERL" && ac_cv_path_ERL="no"
+ ;;
+esac
+fi
+ERL="$ac_cv_path_ERL"
+if test -n "$ERL"; then
+ echo "$ac_t""$ERL" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ case $ERL in
+ /*)
+ # Ok
+ ;;
+ no)
+ # Not found
+ { echo "configure: error: "ERL not found in path!"" 1>&2; exit 1; }
+ ;;
+ *)
+ # Not an absoluet path
+ { echo "configure: error: "Could not find absolute path to ERL"" 1>&2; exit 1; }
+ ;;
+ esac
+
+
+ # Extract the first word of "erlc", so it can be a program name with args.
+set dummy erlc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:752: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_ERLC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case "$ERLC" in
+ /*)
+ ac_cv_path_ERLC="$ERLC" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ ac_cv_path_ERLC="$ERLC" # Let the user override the test with a dos path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_path_ERLC="$ac_dir/$ac_word"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_ERLC" && ac_cv_path_ERLC="no"
+ ;;
+esac
+fi
+ERLC="$ac_cv_path_ERLC"
+if test -n "$ERLC"; then
+ echo "$ac_t""$ERLC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ case $ERLC in
+ /*)
+ # Ok
+ ;;
+ no)
+ # Not found
+ { echo "configure: error: "ERLC not found in path!"" 1>&2; exit 1; }
+ ;;
+ *)
+ # Not an absoluet path
+ { echo "configure: error: "Could not find absolute path to ERLC"" 1>&2; exit 1; }
+ ;;
+ esac
+
+
+echo ERL $ERL
+
+ERLDIR=`awk -F= '/ROOTDIR=/ { print $2; exit; }' $ERL`
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "../include.mk" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@target@%$target%g
+s%@target_alias@%$target_alias%g
+s%@target_cpu@%$target_cpu%g
+s%@target_vendor@%$target_vendor%g
+s%@target_os@%$target_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@SLANG_INCLUDE@%$SLANG_INCLUDE%g
+s%@LD_SHARED@%$LD_SHARED%g
+s%@ERL@%$ERL%g
+s%@ERLC@%$ERLC%g
+s%@ERLDIR@%$ERLDIR%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"../include.mk"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
+
diff --git a/config/configure.in b/config/configure.in
new file mode 100644
index 0000000..1c3ac53
--- /dev/null
+++ b/config/configure.in
@@ -0,0 +1,89 @@
+dnl Process this file with autoconf to produce a configure script.
+
+dnl while debugging configure.in
+dnl it's good to disable the cache
+
+dnl define([AC_CACHE_LOAD], )dnl
+dnl define([AC_CACHE_SAVE], )dnl
+
+AC_INIT(../src/slang.erl)
+
+AC_CONFIG_AUX_DIR(`pwd`)
+
+dnl work out who the cpu, vendor and OS are
+AC_CANONICAL_SYSTEM
+AC_DEFINE_UNQUOTED(CPU_VENDOR_OS, "$target")
+
+dnl ===============================================================
+dnl Checks for programs.
+dnl ===============================================================
+
+
+
+
+AC_ARG_WITH(slang-include, [ --with-slang-include=DIR installed slang library],
+ SLANG_INCLUDE=$withval,
+ if test "x$SLANG_INCLUDE" = x; then
+ SLANG_INCLUDE=/usr/include/slang
+ fi
+ echo using $SLANG_INCLUDE
+ )
+
+AC_SUBST(SLANG_INCLUDE)
+
+case "$target_os" in
+ *cygwin*)
+ :
+ dnl fix this later
+ ;;
+ linux*)
+ AC_DEFINE(LINUX)
+ LD_SHARED="ld -shared"
+ ;;
+ *bsd*)
+ AC_DEFINE(BSD)
+ LD_SHARED="ld -Bshareable"
+ ;;
+ *solaris*)
+ AC_DEFINE(SOLARIS)
+ LD_SHARED="ld -G"
+ ;;
+ *)
+ LD_SHARED="ld -shared"
+ ;;
+esac
+
+AC_SUBST(LD_SHARED)
+
+
+AC_DEFUN(BT_REQUIRE_PATH_PROG,
+[
+ AC_PATH_PROG($1, $2, no, $3)
+ case [$]$1 in
+ /*)
+ # Ok
+ ;;
+ no)
+ # Not found
+ AC_MSG_ERROR("$1 not found in path!")
+ ;;
+ *)
+ # Not an absoluet path
+ AC_MSG_ERROR("Could not find absolute path to $1")
+ ;;
+ esac
+])dnl
+
+
+BT_REQUIRE_PATH_PROG(ERL, erl)
+BT_REQUIRE_PATH_PROG(ERLC, erlc)
+
+echo ERL $ERL
+
+ERLDIR=`awk -F= '/ROOTDIR=/ { print [$]2; exit; }' $ERL`
+AC_SUBST(ERLDIR)
+
+
+AC_OUTPUT(../include.mk)
+
+
diff --git a/config/install-sh b/config/install-sh
new file mode 100755
index 0000000..e843669
--- /dev/null
+++ b/config/install-sh
@@ -0,0 +1,250 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/demo/Makefile b/demo/Makefile
new file mode 100644
index 0000000..7039b4a
--- /dev/null
+++ b/demo/Makefile
@@ -0,0 +1,20 @@
+
+
+ifeq ($(TYPE),debug)
+DEBUG_FLAGS = -Ddebug
+else
+DEBUG_FLAGS =
+endif
+
+include ../include.mk
+
+ERLC_FLAGS+=-W $(DEBUG_FLAGS)
+MODULES = ex2 ex1
+
+
+TARGETS = $(MODULES:%=%.beam)
+
+all debug: $(TARGETS)
+
+clean:
+ rm -f $(TARGETS)
diff --git a/demo/ex1.erl b/demo/ex1.erl
new file mode 100644
index 0000000..a3e861a
--- /dev/null
+++ b/demo/ex1.erl
@@ -0,0 +1,31 @@
+%%%----------------------------------------------------------------------
+%%% File : ex1.erl
+%%% Author : Claes Wikstrom <klacke@kaja.hemma.net>
+%%% Purpose :
+%%% Created : 22 Nov 2000 by Claes Wikstrom <klacke@kaja.hemma.net>
+%%%----------------------------------------------------------------------
+
+-module(ex1).
+-author('klacke@kaja.hemma.net').
+
+-compile(export_all).
+
+run() ->
+ slang:init_tty(7,0,1),
+ slang:set_abort_signal(null),
+ loop().
+
+loop() ->
+ io:format("Press any key to quit press ctl_G ",[]),
+ X = slang:getkey(),
+ io:format("Got key ~p~n", [X]),
+ case X of
+ 7 ->
+ slang:reset_tty(),
+ halt(),
+ 7;
+ _ ->
+ loop()
+ end.
+
+
diff --git a/demo/ex2.c b/demo/ex2.c
new file mode 100644
index 0000000..bbfa980
--- /dev/null
+++ b/demo/ex2.c
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <slang.h>
+
+int main ()
+{
+ int abort_char = 7; /* For MSDOS, use 34 as scan code */
+ unsigned int ch;
+
+ if (-1 == SLang_init_tty (abort_char, 0, 1))
+ {
+ fprintf (stderr, "Unable to initialize the terminal.\n");
+ exit (-1);
+ }
+ SLang_set_abort_signal (NULL);
+
+ fflush (stdout);
+
+ ch = SLang_getkey ();
+
+ printf("<< %c >> %d ",ch, SLang_Error);
+
+ SLang_reset_tty ();
+ return 0;
+}
+
+
+
+
diff --git a/demo/ex2.erl b/demo/ex2.erl
new file mode 100644
index 0000000..613a3ec
--- /dev/null
+++ b/demo/ex2.erl
@@ -0,0 +1,52 @@
+%%%----------------------------------------------------------------------
+%%% File : ex2.erl
+%%% Author : Claes Wikstrom <klacke@kaja.hemma.net>
+%%% Purpose :
+%%% Created : 30 Nov 2000 by Claes Wikstrom <klacke@kaja.hemma.net>
+%%%----------------------------------------------------------------------
+
+-module(ex2).
+-author('klacke@kaja.hemma.net').
+
+-compile(export_all).
+
+start() ->
+ slang:tt_get_terminfo(),
+ slang:kp_init(),
+ slang:init_tty(7, 0, 1),
+ slang:smg_init_smg (),
+
+ draw_stuff2(),
+
+ Key = slang:kp_getkey(),
+ slang:smg_printf("Just got key ~p~n", [Key]),
+ slang:smg_refresh (),
+
+ slang:kp_getkey(),
+
+ slang:smg_reset_smg (),
+ slang:reset_tty(),
+ halt().
+
+
+draw_stuff2() ->
+ slang:smg_normal_video (),
+ slang:smg_gotorc (5, 0),
+ slang:smg_write_string ("Hello "),
+ slang:smg_erase_eol (),
+ slang:smg_refresh ().
+
+
+draw_stuff(Pos) ->
+ case slang:getkey() of
+ $q ->
+ ok;
+ Key ->
+ slang:smg_gotorc(4+Pos,6),
+ slang:smg_printf("Hello there ~n",[]),
+ draw_stuff(Pos+1)
+ end.
+
+
+
+
diff --git a/demo/ex3.c b/demo/ex3.c
new file mode 100644
index 0000000..0e9c7ff
--- /dev/null
+++ b/demo/ex3.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <slang.h>
+
+
+stuff()
+{
+ SLsmg_normal_video ();
+ SLsmg_gotorc (5, 0);
+ SLsmg_write_string ("Hello ");
+ SLsmg_erase_eol ();
+ SLsmg_refresh ();
+}
+
+
+int main ()
+{
+ SLtt_get_terminfo ();
+ SLkp_init ();
+ SLang_init_tty (-1, 0, 0);
+ SLsmg_init_smg ();
+
+
+ stuff();
+
+ SLkp_getkey ();
+
+ /* do stuff .... */
+
+ SLsmg_reset_smg ();
+ SLang_reset_tty ();
+ return 0;
+}
+
+
+
+
+
+
+
+
diff --git a/demo/pager.erl b/demo/pager.erl
new file mode 100644
index 0000000..37f6a14
--- /dev/null
+++ b/demo/pager.erl
@@ -0,0 +1,351 @@
+%%%----------------------------------------------------------------------
+%%% File : pager.erl
+%%% Author : Claes Wikstrom <klacke@kaja.hemma.net>
+%%% Purpose :
+%%% Created : 1 Dec 2000 by Claes Wikstrom <klacke@kaja.hemma.net>
+%%%----------------------------------------------------------------------
+
+-module(pager).
+-author('klacke@kaja.hemma.net').
+
+-compile(export_all).
+
+-include ("slang.hrl").
+
+-record(file_line, {next,
+ prev,
+ data}).
+
+
+
+
+
+demolib_exit (Signal) ->
+
+ slang:reset_tty (),
+ slang:smg_reset_smg (),
+
+ if
+ Signal == 0 ->
+ halt();
+ true ->
+ io:format("Exiting on signal ~p\n", [Signal]),
+ halt()
+ end.
+
+
+sigint_handler (Signal) ->
+ demolib_exit (Signal).
+
+
+
+% static void init_signals (void)
+% {
+% #ifdef SIGTSTP
+% SLsignal (SIGTSTP, sigtstp_handler);
+% #endif
+% #ifdef SIGINT
+% SLsignal (SIGINT, sigint_handler);
+% #endif
+% }
+
+exit_error_hook (Fmt, Args) ->
+
+ slang:reset_tty (),
+ slang:reset_smg (),
+
+ io:format(Fmt, Args),
+ io:nl(),
+ halt().
+
+
+
+
+demolib_init_terminal () ->
+
+ %% SLang_Exit_Error_Hook = exit_error_hook
+ % It is wise to block the occurance of display related
+ %signals while we are
+ %initializing.
+
+
+ %SLsig_block_signals (),
+
+ slang:tt_get_terminfo (),
+
+ %% SLkp_init assumes that SLtt_get_terminfo has been called.
+
+ case slang:kp_init() of
+ -1 ->
+ -1;
+ Ret ->
+
+ slang:init_tty (-1, 0, 1),
+ %slang:tty_set_suspend_state (1),
+
+ case slang:smg_init_smg () of
+ -1 ->
+ -1;
+ _ ->
+ 0
+ end
+ end.
+
+
+main() ->
+ File="tmp/test",
+
+
+
+
+int main (int argc, char **argv)
+{
+ if (argc == 2)
+ {
+ File_Name = argv[1];
+ }
+ else if ((argc != 1) || (1 == isatty (fileno(stdin))))
+ usage (argv[0]);
+
+
+ if (-1 == read_file (File_Name))
+ {
+ fprintf (stderr, "Unable to read %s\n", File_Name);
+ return 1;
+ }
+
+ /* This sets up the terminal, signals, screen management routines, etc... */
+ if (-1 == demolib_init_terminal (1, 1))
+ {
+ fprintf (stderr, "Unable to initialize terminal.");
+ return 1;
+ }
+
+#define APP_KEY_EOB 0x1001
+#define APP_KEY_BOB 0x1002
+
+ /* Add a few application defined keysyms. 0x1000 and above are for
+ * applications.
+ */
+ (void) SLkp_define_keysym ("\033>", APP_KEY_EOB);
+ (void) SLkp_define_keysym ("\033<", APP_KEY_BOB);
+
+ main_loop (); /* should not return */
+ return 1;
+}
+
+
+/* The SLscroll routines will be used for pageup/down commands. They assume
+ * a linked list of lines. The first element of the structure MUST point to
+ * the NEXT line, the second MUST point to the PREVIOUS line.
+ */
+typedef struct _File_Line_Type
+{
+ struct _File_Line_Type *next;
+ struct _File_Line_Type *prev;
+ char *data; /* pointer to line data */
+}
+File_Line_Type;
+
+static File_Line_Type *File_Lines;
+
+/* The SLscroll routines will use this structure. */
+static SLscroll_Window_Type Line_Window;
+
+static void free_lines (void)
+{
+ File_Line_Type *line, *next;
+
+ line = File_Lines;
+ while (line != NULL)
+ {
+ next = line->next;
+ if (line->data != NULL) free (line->data);
+ free (line);
+ line = next;
+ }
+ File_Lines = NULL;
+}
+
+static File_Line_Type *create_line (char *buf)
+{
+ File_Line_Type *line;
+
+ line = (File_Line_Type *) malloc (sizeof (File_Line_Type));
+ if (line == NULL) return NULL;
+
+ memset ((char *) line, sizeof (File_Line_Type), 0);
+
+ line->data = SLmake_string (buf); /* use a slang routine */
+ if (line->data == NULL)
+ {
+ free (line);
+ return NULL;
+ }
+
+ return line;
+}
+
+
+static int read_file (char *file)
+{
+ FILE *fp;
+ char buf [1024];
+ File_Line_Type *line, *last_line;
+ unsigned int num_lines;
+
+ if (file == NULL)
+ fp = stdin;
+ else fp = fopen (file, "r");
+
+ if (fp == NULL) return -1;
+
+ last_line = NULL;
+ num_lines = 0;
+
+ while (NULL != fgets (buf, sizeof(buf), fp))
+ {
+ num_lines++;
+
+ if (NULL == (line = create_line (buf)))
+ {
+ fprintf (stderr, "Out of memory.");
+ free_lines ();
+ return -1;
+ }
+
+ if (last_line == NULL)
+ File_Lines = line;
+ else
+ last_line->next = line;
+
+ line->prev = last_line;
+ line->next = NULL;
+
+ last_line = line;
+ }
+
+ memset ((char *)&Line_Window, 0, sizeof (SLscroll_Window_Type));
+
+ Line_Window.current_line = (SLscroll_Type *) File_Lines;
+ Line_Window.lines = (SLscroll_Type *) File_Lines;
+ Line_Window.line_num = 1;
+ Line_Window.num_lines = num_lines;
+
+ return 0;
+}
+
+
+static void update_display (void)
+{
+ unsigned int row, nrows;
+ File_Line_Type *line;
+
+ /* All well behaved applications should block signals that may affect
+ * the display while performing screen update.
+ */
+ SLsig_block_signals ();
+
+ Line_Window.nrows = nrows = SLtt_Screen_Rows - 1;
+
+ /* Always make the current line equal to the top window line. */
+ if (Line_Window.top_window_line != NULL)
+ Line_Window.current_line = Line_Window.top_window_line;
+
+ SLscroll_find_top (&Line_Window);
+
+ row = 0;
+ line = (File_Line_Type *) Line_Window.top_window_line;
+
+ SLsmg_normal_video ();
+
+ while (row < Line_Window.nrows)
+ {
+ SLsmg_gotorc (row, 0);
+
+ if (line != NULL)
+ {
+ SLsmg_write_string (line->data);
+ line = line->next;
+ }
+ SLsmg_erase_eol ();
+ row++;
+ }
+
+ SLsmg_gotorc (row, 0);
+ SLsmg_reverse_video ();
+ SLsmg_printf ("%s", (File_Name == NULL) ? "<stdin>" : File_Name);
+ SLsmg_erase_eol ();
+ SLsmg_refresh ();
+
+ SLsig_unblock_signals ();
+}
+
+static int Screen_Start;
+
+static void main_loop (void)
+{
+ int screen_start;
+
+ while (1)
+ {
+ update_display ();
+ switch (SLkp_getkey ())
+ {
+ case SL_KEY_ERR:
+ case 'q':
+ case 'Q':
+ demolib_exit (0);
+ break;
+
+ case SL_KEY_RIGHT:
+ Screen_Start += 1;
+ screen_start = Screen_Start;
+ SLsmg_set_screen_start (NULL, &screen_start);
+ break;
+
+ case SL_KEY_LEFT:
+ Screen_Start -= 1;
+ if (Screen_Start < 0) Screen_Start = 0;
+ screen_start = Screen_Start;
+ SLsmg_set_screen_start (NULL, &screen_start);
+ break;
+
+ case SL_KEY_UP:
+ SLscroll_prev_n (&Line_Window, 1);
+ Line_Window.top_window_line = Line_Window.current_line;
+ break;
+
+ case '\r':
+ case SL_KEY_DOWN:
+ SLscroll_next_n (&Line_Window, 1);
+ Line_Window.top_window_line = Line_Window.current_line;
+ break;
+
+ case SL_KEY_NPAGE:
+ case ' ': case 4:
+ SLscroll_pagedown (&Line_Window);
+ break;
+
+ case SL_KEY_PPAGE:
+ case 127: case 21:
+ SLscroll_pageup (&Line_Window);
+ break;
+
+ case APP_KEY_BOB:
+ while (-1 != SLscroll_pageup (&Line_Window))
+ ;
+ break;
+
+ case APP_KEY_EOB:
+ while (-1 != SLscroll_pagedown (&Line_Window))
+ ;
+ break;
+
+ default:
+ SLtt_beep ();
+ }
+ }
+}
+
+
diff --git a/doc/cref.txt b/doc/cref.txt
new file mode 100644
index 0000000..2871973
--- /dev/null
+++ b/doc/cref.txt
@@ -0,0 +1,4870 @@
+SLsmg_fill_region
+
+ SYNOPSIS
+ Fill a rectangular region with a character
+
+ USAGE
+ void SLsmg_fill_region (r, c, nr, nc, ch)
+
+ int r
+ int c
+ unsigned int nr
+ unsigned int nc
+ unsigned char ch
+
+
+ DESCRIPTION
+ The `SLsmg_fill_region' function may be used to a
+ rectangular region with the character `ch' in the current color.
+ The rectangle's upper left corner is at row `r' and column
+ `c', and spans `nr' rows and `nc' columns. The position
+ of the virtual cursor will be left at (`r', `c').
+
+ SEE ALSO
+ SLsmg_write_char, SLsmg_set_color
+--------------------------------------------------------------
+
+SLsmg_set_char_set
+
+ SYNOPSIS
+ Turn on or off line drawing characters
+
+ USAGE
+ void SLsmg_set_char_set (int a);
+
+ DESCRIPTION
+ `SLsmg_set_char_set' may be used to select or deselect the line drawing
+ character set as the current character set. If `a' is non-zero,
+ the line drawing character set will be selected. Otherwise, the
+ standard character set will be selected.
+
+ NOTES
+ There is no guarantee that this function will actually enable the
+ use of line drawing characters. All it does is cause subsequent
+ characters to be rendered using the terminal's alternate character
+ set. Such character sets usually contain line drawing characters.
+
+ SEE ALSO
+ SLsmg_write_char, SLtt_get_terminfo
+--------------------------------------------------------------
+
+int SLsmg_Scroll_Hash_Border;
+
+ SYNOPSIS
+ Set the size of the border for the scroll hash
+
+ USAGE
+ int SLsmg_Scroll_Hash_Border = 0;
+
+ DESCRIPTION
+ This variable may be used to ignore the characters that occur at the
+ beginning and the end of a row when performing the hash calculation
+ to determine whether or not a line has scrolled. The default value
+ is zero which means that all the characters on a line will be used.
+
+ SEE ALSO
+ SLsmg_refresh
+--------------------------------------------------------------
+
+SLsmg_suspend_smg
+
+ SYNOPSIS
+ Suspend screen management
+
+ USAGE
+ int SLsmg_suspend_smg (void)
+
+ DESCRIPTION
+ `SLsmg_suspend_smg' can be used to suspend the state of the
+ screen management facility during suspension of the program. Use of
+ this function will reset the display back to its default state. The
+ funtion `SLsmg_resume_smg' should be called after suspension.
+
+ It returns zero upon success, or -1 upon error.
+
+ This function is similar to `SLsmg_reset_smg' except that the
+ state of the display prior to calling `SLsmg_suspend_smg' is saved.
+
+ SEE ALSO
+ SLsmg_resume_smg, SLsmg_reset_smg
+--------------------------------------------------------------
+
+SLsmg_resume_smg
+
+ SYNOPSIS
+ Resume screen management
+
+ USAGE
+ int SLsmg_resume_smg (void)
+
+ DESCRIPTION
+ `SLsmg_resume_smg' should be called after
+ `SLsmg_suspend_smg' to redraw the display exactly like it was
+ before `SLsmg_suspend_smg' was called. It returns zero upon
+ success, or -1 upon error.
+
+ SEE ALSO
+ SLsmg_suspend_smg
+--------------------------------------------------------------
+
+SLsmg_erase_eol
+
+ SYNOPSIS
+ Erase to the end of the row
+
+ USAGE
+ void SLsmg_erase_eol (void);
+
+ DESCRIPTION
+ `SLsmg_erase_eol' erases all characters from the current
+ position to the end of the line. The newly created space is given
+ the color of the current color. This function has no effect on the
+ position of the virtual cursor.
+
+ SEE ALSO
+ SLsmg_gotorc, SLsmg_erase_eos, SLsmg_fill_region
+--------------------------------------------------------------
+
+SLsmg_gotorc
+
+ SYNOPSIS
+ Move the virtual cursor
+
+ USAGE
+ void SLsmg_gotorc (int r, int c)
+
+ DESCRIPTION
+ The `SLsmg_gotorc' function moves the virtual cursor to the row
+ `r' and column `c'. The first row and first column is
+ specified by `r = 0' and `c = 0'.
+
+ SEE ALSO
+ SLsmg_refresh
+--------------------------------------------------------------
+
+SLsmg_erase_eos
+
+ SYNOPSIS
+ Erase to the end of the screen
+
+ USAGE
+ void SLsmg_erase_eos (void);
+
+ DESCRIPTION
+ The `SLsmg_erase_eos' is like `SLsmg_erase_eol' except that
+ it erases all text from the current position to the end of the
+ display. The current color will be used to set the background of
+ the erased area.
+
+ SEE ALSO
+ SLsmg_erase_eol
+--------------------------------------------------------------
+
+SLsmg_reverse_video
+
+ SYNOPSIS
+ Set the current color to 1
+
+ USAGE
+ void SLsmg_reverse_video (void);
+
+ DESCRIPTION
+ This function is nothing more than `SLsmg_set_color(1)'.
+
+ SEE ALSO
+ SLsmg_set_color
+--------------------------------------------------------------
+
+SLsmg_set_color (int)
+
+ SYNOPSIS
+ Set the current color
+
+ USAGE
+ void SLsmg_set_color (int c);
+
+ DESCRIPTION
+ `SLsmg_set_color' is used to set the current color. The
+ parameter `c' is really a color object descriptor. Actual
+ foreground and background colors as well as other visual attributes
+ may be associated with a color descriptor via the
+ `SLtt_set_color' function.
+
+ EXAMPLE
+ This example defines color `7' to be green foreground on black
+ background and then displays some text in this color:
+
+ SLtt_set_color (7, NULL, "green", "black");
+ SLsmg_set_color (7);
+ SLsmg_write_string ("Hello");
+ SLsmg_refresh ();
+
+
+ NOTES
+ It is important to understand that the screen managment routines
+ know nothing about the actual colors associated with a color
+ descriptor. Only the descriptor itself is used by the `SLsmg'
+ routines. The lower level `SLtt' interface converts the color
+ descriptors to actual colors. Thus
+
+ SLtt_set_color (7, NULL, "green", "black");
+ SLsmg_set_color (7);
+ SLsmg_write_string ("Hello");
+ SLtt_set_color (7, NULL, "red", "blue");
+ SLsmg_write_string ("World");
+ SLsmg_refresh ();
+
+ will result in `"hello"' displayed in red on blue and _not_
+ green on black.
+
+ SEE ALSO
+ SLtt_set_color, SLtt_set_color_object
+--------------------------------------------------------------
+
+SLsmg_normal_video
+
+ SYNOPSIS
+ Set the current color to 0
+
+ USAGE
+ void SLsmg_normal_video (void);
+
+ DESCRIPTION
+ `SLsmg_normal_video' sets the current color descriptor to `0'.
+
+ SEE ALSO
+ SLsmg_set_color
+--------------------------------------------------------------
+
+SLsmg_printf
+
+ SYNOPSIS
+ Format a string on the virtual display
+
+ USAGE
+ void SLsmg_printf (char *fmt, ...)
+
+ DESCRIPTION
+ `SLsmg_printf' format a `printf' style variable argument
+ list and writes it on the virtual display. The virtual cursor will
+ be moved to the end of the string.
+
+ SEE ALSO
+ SLsmg_write_string, SLsmg_vprintf
+--------------------------------------------------------------
+
+SLsmg_vprintf
+
+ SYNOPSIS
+ Format a string on the virtual display
+
+ USAGE
+ void SLsmg_vprintf (char *fmt, va_list ap)
+
+ DESCRIPTION
+ `SLsmg_vprintf' formats a string in the manner of _vprintf_
+ and writes the result to the display. The virtual cursor is
+ advanced to the end of the string.
+
+ SEE ALSO
+ SLsmg_write_string, SLsmg_printf
+--------------------------------------------------------------
+
+SLsmg_write_string
+
+ SYNOPSIS
+ Write a character string on the display
+
+ USAGE
+ void SLsmg_write_string (char *s)
+
+ DESCRIPTION
+ The function `SLsmg_write_string' displays the string `s' on
+ the virtual display at the current position and moves the position
+ to the end of the string.
+
+ SEE ALSO
+ SLsmg_printf, SLsmg_write_nstring
+--------------------------------------------------------------
+
+SLsmg_write_nstring
+
+ SYNOPSIS
+ Write the first n characters of a string on the display
+
+ USAGE
+ void SLsmg_write_nstring (char *s, unsigned int n);
+
+ DESCRIPTION
+ `SLsmg_write_nstring' writes the first `n' characters of
+ `s' to this virtual display. If the length of the string
+ `s' is less than `n', the spaces will used until
+ `n' characters have been written. `s' can be `NULL', in
+ which case `n' spaces will be written.
+
+ SEE ALSO
+ SLsmg_write_string, SLsmg_write_nchars
+--------------------------------------------------------------
+
+SLsmg_write_char
+
+ SYNOPSIS
+ Write a character to the virtual display
+
+ USAGE
+ void SLsmg_write_char (char ch);
+
+ DESCRIPTION
+ `SLsmg_write_char' writes the character `ch' to the virtual
+ display.
+
+ SEE ALSO
+ SLsmg_write_nchars, SLsmg_write_string
+--------------------------------------------------------------
+
+SLsmg_write_nchars
+
+ SYNOPSIS
+ Write n characters to the virtual display
+
+ USAGE
+ void SLsmg_write_nchars (char *s, unsigned int n);
+
+ DESCRIPTION
+ `SLsmg_write_nchars' writes at most `n' characters from the
+ string `s' to the display. If the length of `s' is less
+ than `n', the whole length of the string will get written.
+
+ This function differs from `SLsmg_write_nstring' in that
+ `SLsmg_write_nstring' will pad the string to write exactly
+ `n' characters. `SLsmg_write_nchars' does not perform any
+ padding.
+
+ SEE ALSO
+ SLsmg_write_nchars, SLsmg_write_nstring
+--------------------------------------------------------------
+
+SLsmg_write_wrapped_string
+
+ SYNOPSIS
+ Write a string to the display with wrapping
+
+ USAGE
+ void SLsmg_write_wrapped_string (s, r, c, nr, nc, fill)
+
+ char *s
+ int r, c
+ unsigned int nr, nc
+ int fill
+
+
+ DESCRIPTION
+ `SLsmg_write_wrapped_string' writes the string `s' to the
+ virtual display. The string will be confined to the rectangular
+ region whose upper right corner is at row `r' and column `c',
+ and consists of `nr' rows and `nc' columns. The string will
+ be wrapped at the boundaries of the box. If `fill' is non-zero,
+ the last line to which characters have been written will get padded
+ with spaces.
+
+ NOTES
+ This function does not wrap on word boundaries. However, it will
+ wrap when a newline charater is encountered.
+
+ SEE ALSO
+ SLsmg_write_string
+--------------------------------------------------------------
+
+SLsmg_cls
+
+ SYNOPSIS
+ Clear the virtual display
+
+ USAGE
+ void SLsmg_cls (void)
+
+ DESCRIPTION
+ `SLsmg_cls' erases the virtual display using the current color.
+ This will cause the physical display to get cleared the next time
+ `SLsmg_refresh' is called.
+
+ NOTES
+ This function is not the same as
+
+ SLsmg_gotorc (0,0); SLsmg_erase_eos ();
+
+ since these statements do not guarantee that the physical screen
+ will get cleared.
+
+ SEE ALSO
+ SLsmg_refresh, SLsmg_erase_eos
+--------------------------------------------------------------
+
+SLsmg_refresh
+
+ SYNOPSIS
+ Update physical screen
+
+ USAGE
+ void SLsmg_refresh (void)
+
+ DESCRIPTION
+ The `SLsmg_refresh' function updates the physical display to
+ look like the virtual display.
+
+ SEE ALSO
+ SLsmg_suspend_smg, SLsmg_init_smg, SLsmg_reset_smg
+--------------------------------------------------------------
+
+SLsmg_touch_lines
+
+ SYNOPSIS
+ Mark lines on the virtual display for redisplay
+
+ USAGE
+ void SLsmg_touch_lines (int r, unsigned int nr)
+
+ DESCRIPTION
+ `SLsmg_touch_lines' marks the `nr' lines on the virtual
+ display starting at row `r' for redisplay upon the next call to
+ `SLsmg_refresh'.
+
+ NOTES
+ This function should rarely be called, if ever. If you find that
+ you need to call this function, then your application should be
+ modified to properly use the `SLsmg' screen management routines.
+ This function is provided only for curses compatibility.
+
+ SEE ALSO
+ SLsmg_refresh
+--------------------------------------------------------------
+
+SLsmg_init_smg
+
+ SYNOPSIS
+ Initialize the var{SLsmg
+
+ USAGE
+ int SLsmg_init_smg (void)
+
+ DESCRIPTION
+ The `SLsmg_init_smg' function initializes the `SLsmg' screen
+ management routines. Specifically, this function allocates space
+ for the virtual display and calls `SLtt_init_video' to put the
+ terminal's physical display in the proper state. It is up to the
+ caller to make sure that the `SLtt' routines are initialized via
+ `SLtt_get_terminfo' before calling `SLsmg_init_smg'.
+
+ This function should also be called any time the size of the
+ physical display has changed so that it can reallocate a new virtual
+ display to match the physical display.
+
+ It returns zero upon success, or -1 upon failure.
+
+ SEE ALSO
+ SLsmg_reset_smg
+--------------------------------------------------------------
+
+SLsmg_reset_smg
+
+ SYNOPSIS
+ Reset the var{SLsmg
+
+ USAGE
+ int SLsmg_reset_smg (void);
+
+ DESCRIPTION
+ `SLsmg_reset_smg' resets the `SLsmg' screen management
+ routines by freeing all memory allocated while it was active. It
+ also calls `SLtt_reset_video' to put the terminal's display in
+ it default state.
+
+ SEE ALSO
+ SLsmg_init_smg
+--------------------------------------------------------------
+
+SLsmg_char_at
+
+ SYNOPSIS
+ Get the character at the current position on the virtual display
+
+ USAGE
+ unsigned short SLsmg_char_at(void)
+
+ DESCRIPTION
+ The `SLsmg_char_at' function returns the character and its color
+ at the current position on the virtual display.
+
+ SEE ALSO
+ SLsmg_read_raw, SLsmg_write_char
+--------------------------------------------------------------
+
+SLsmg_set_screen_start
+
+ SYNOPSIS
+ Set the origin of the virtual display
+
+ USAGE
+ void SLsmg_set_screen_start (int *r, int *c)
+
+ DESCRIPTION
+ `SLsmg_set_screen_start' sets the origin of the virtual display
+ to the row `*r' and the column `*c'. If either `r' or `c'
+ is `NULL', then the corresponding value will be set to `0'.
+ Otherwise, the location specified by the pointers will be updated to
+ reflect the old origin.
+
+ See \tt{slang/demo/pager.c} for how this function may be used to
+ scroll horizontally.
+
+ SEE ALSO
+ SLsmg_init_smg
+--------------------------------------------------------------
+
+SLsmg_draw_hline
+
+ SYNOPSIS
+ Draw a horizontal line
+
+ USAGE
+ void SLsmg_draw_hline (unsigned int len)
+
+ DESCRIPTION
+ The `SLsmg_draw_hline' function draws a horizontal line of
+ length `len' on the virtual display. The position of the
+ virtual cursor is left at the end of the line.
+
+ SEE ALSO
+ SLsmg_draw_vline
+--------------------------------------------------------------
+
+SLsmg_draw_vline
+
+ SYNOPSIS
+ Draw a vertical line
+
+ USAGE
+ void SLsmg_draw_vline (unsigned int len);
+
+ DESCRIPTION
+ The `SLsmg_draw_vline' function draws a vertical line of
+ length `len' on the virtual display. The position of the
+ virtual cursor is left at the end of the line.
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLsmg_draw_object
+
+ SYNOPSIS
+ Draw an object from the alternate character set
+
+ USAGE
+ void SLsmg_draw_object (int r, int c, unsigned char obj)
+
+ DESCRIPTION
+ The `SLsmg_draw_object' function may be used to place the object
+ specified by `obj' at row `r' and column `c'. The
+ object is really a character from the alternate character set and
+ may be specified using one of the following constants:
+
+ SLSMG_HLINE_CHAR Horizontal line
+ SLSMG_VLINE_CHAR Vertical line
+ SLSMG_ULCORN_CHAR Upper left corner
+ SLSMG_URCORN_CHAR Upper right corner
+ SLSMG_LLCORN_CHAR Lower left corner
+ SLSMG_LRCORN_CHAR Lower right corner
+ SLSMG_CKBRD_CHAR Checkboard character
+ SLSMG_RTEE_CHAR Right Tee
+ SLSMG_LTEE_CHAR Left Tee
+ SLSMG_UTEE_CHAR Up Tee
+ SLSMG_DTEE_CHAR Down Tee
+ SLSMG_PLUS_CHAR Plus or Cross character
+
+
+ SEE ALSO
+ SLsmg_draw_vline, SLsmg_draw_hline, SLsmg_draw_box
+--------------------------------------------------------------
+
+SLsmg_draw_box
+
+ SYNOPSIS
+ Draw a box on the virtual display
+
+ USAGE
+ void SLsmg_draw_box (int r, int c, unsigned int dr, unsigned int dc)
+
+ DESCRIPTION
+ `SLsmg_draw_box' uses the `SLsmg_draw_hline' and
+ `SLsmg_draw_vline' functions to draw a rectangular box on the
+ virtual display. The box's upper left corner is placed at row
+ `r' and column `c'. The width and length of the box is
+ specified by `dc' and `dr', respectively.
+
+ SEE ALSO
+ SLsmg_draw_vline, SLsmg_draw_hline, SLsmg_draw_object
+--------------------------------------------------------------
+
+SLsmg_set_color_in_region
+
+ SYNOPSIS
+ Change the color of a specifed region
+
+ USAGE
+ void SLsmg_set_color_in_region (color, r, c, dr, dc)
+
+ int color;
+ int r, c;
+ unsigned int dr, dc;
+
+
+ DESCRIPTION
+ `SLsmg_set_color_in_region' may be used to change the color of a
+ rectangular region whose upper left corner is given by
+ (`r',`c'), and whose width and height is given by `dc'
+ and `dr', respectively. The color of the region is given by the
+ `color' parameter.
+
+ SEE ALSO
+ SLsmg_draw_box, SLsmg_set_color
+--------------------------------------------------------------
+
+SLsmg_get_column
+
+ SYNOPSIS
+ Get the column of the virtual cursor
+
+ USAGE
+ int SLsmg_get_column(void);
+
+ DESCRIPTION
+ The `SLsmg_get_column' function returns the current column of
+ the virtual cursor on the virtual display.
+
+ SEE ALSO
+ SLsmg_get_row, SLsmg_gotorc
+--------------------------------------------------------------
+
+SLsmg_get_row
+
+ SYNOPSIS
+ Get the row of the virtual cursor
+
+ USAGE
+ int SLsmg_get_row(void);
+
+ DESCRIPTION
+ The `SLsmg_get_row' function returns the current row of the
+ virtual cursor on the virtual display.
+
+ SEE ALSO
+ SLsmg_get_column, SLsmg_gotorc
+--------------------------------------------------------------
+
+SLsmg_forward
+
+ SYNOPSIS
+ Move the virtual cursor forward n columns
+
+ USAGE
+ void SLsmg_forward (int n);
+
+ DESCRIPTION
+ The `SLsmg_forward' function moves the virtual cursor forward
+ `n' columns.
+
+ SEE ALSO
+ SLsmg_gotorc
+--------------------------------------------------------------
+
+SLsmg_write_color_chars
+
+ SYNOPSIS
+ Write characters with color descriptors to virtual display
+
+ USAGE
+ void SLsmg_write_color_chars (unsigned short *s, unsigned int len)
+
+ DESCRIPTION
+ The `SLsmg_write_color_chars' function may be used to write
+ `len' characters, each with a different color descriptor to the
+ virtual display. Each character and its associated color are
+ encoded as an `unsigned short' such that the lower eight bits
+ form the character and the next eight bits form the color.
+
+ SEE ALSO
+ SLsmg_char_at, SLsmg_write_raw
+--------------------------------------------------------------
+
+SLsmg_read_raw
+
+ SYNOPSIS
+ Read characters from the virtual display
+
+ USAGE
+ unsigned int SLsmg_read_raw (unsigned short *buf, unsigned int len)
+
+ DESCRIPTION
+ `SLsmg_read_raw' attempts to read `len' characters from the
+ current position on the virtual display into the buffer specified by
+ `buf'. It returns the number of characters actually read. This
+ number will be less than `len' if an attempt is made to read
+ past the right margin of the display.
+
+ NOTES
+ The purpose of the pair of functions, `SLsmg_read_raw' and
+ `SLsmg_write_raw', is to permit one to copy the contents of one
+ region of the virtual display to another region.
+
+ SEE ALSO
+ SLsmg_char_at, SLsmg_write_raw
+--------------------------------------------------------------
+
+SLsmg_write_raw
+
+ SYNOPSIS
+ Write characters directly to the virtual display
+
+ USAGE
+ unsigned int SLsmg_write_raw (unsigned short *buf, unsigned int len)
+
+ DESCRIPTION
+ The `SLsmg_write_raw' function attempts to write `len'
+ characters specified by `buf' to the display at the current
+ position. It returns the number of characters successfully written,
+ which will be less than `len' if an attempt is made to write
+ past the right margin.
+
+ NOTES
+ The purpose of the pair of functions, `SLsmg_read_raw' and
+ `SLsmg_write_raw', is to permit one to copy the contents of one
+ region of the virtual display to another region.
+
+ SEE ALSO
+ SLsmg_read_raw
+--------------------------------------------------------------
+
+SLallocate_load_type
+
+ SYNOPSIS
+ Allocate a SLang_Load_Type object
+
+ USAGE
+ SLang_Load_Type *SLallocate_load_type (char *name)
+
+ DESCRIPTION
+ The `SLallocate_load_type' function allocates and initializes
+ space for a `SLang_Load_Type' object and returns it. Upon
+ failure, the function returns `NULL'. The parameter `name'
+ must uniquely identify the object. For example, if the object
+ represents a file, then `name' could be the absolute path name
+ of the file.
+
+ SEE ALSO
+ SLdeallocate_load_type, SLang_load_object
+--------------------------------------------------------------
+
+SLdeallocate_load_type
+
+ SYNOPSIS
+ Free a SLang_Load_Type object
+
+ USAGE
+ void SLdeallocate_load_type (SLang_Load_Type *slt)
+
+ DESCRIPTION
+ This function frees the memory associated with a
+ `SLang_Load_Type' object that was acquired from a call to the
+ `SLallocate_load_type' function.
+
+ SEE ALSO
+ SLallocate_load_type, SLang_load_object
+--------------------------------------------------------------
+
+SLang_load_object
+
+ SYNOPSIS
+ Load an object into the interpreter
+
+ USAGE
+ int SLang_load_object (SLang_Load_Type *obj)
+
+ DESCRIPTION
+ The function `SLang_load_object' is a generic function that may
+ be used to loaded an object of type `SLang_Load_Type' into the
+ interpreter. For example, the functions `SLang_load_file' and
+ `SLang_load_string' are wrappers around this function to load a
+ file and a string, respectively.
+
+ SEE ALSO
+ SLang_load_file, SLang_load_string, SLallocate_load_type
+--------------------------------------------------------------
+
+SLclass_allocate_class
+
+ SYNOPSIS
+ Allocate a class for a new data type
+
+ USAGE
+ SLang_Class_Type *SLclass_allocate_class (char *name)
+
+ DESCRIPTION
+ The purpose of this function is to allocate and initialize space
+ that defines a new data type or class called `name'. If
+ successful, a pointer to the class is returned, or upon failure the
+ function returns `NULL'.
+
+ This function does not automatically create the new data type.
+ Callback functions must first be associated with the data type via
+ functions such as `SLclass_set_push_function', and the the data
+ type must be registered with the interpreter via
+ `SLclass_register_class'. See the S-Lang library programmer's
+ guide for more information.
+
+ SEE ALSO
+ SLclass_register_class, SLclass_set_push_function
+--------------------------------------------------------------
+
+SLclass_register_class
+
+ SYNOPSIS
+ Register a new data type with the interpreter
+
+ USAGE
+ int SLclass_register_class (cl, type, sizeof_type, class_type)
+
+ SLang_Class_Type *cl
+ unsigned char type
+ unsigned int sizeof_type
+ unsigned char class_type
+
+
+ DESCRIPTION
+ The `SLclass_register_class' function is used to register a new
+ class or data type with the interpreter. If successful, the
+ function returns `0', or upon failure, it returns `-1'.
+
+ The first parameter, `cl', must have been previously obtained
+ via the `SLclass_allocate_class' function.
+
+ The second parameter, `type' specifies the data type of the new
+ class. It must be an unsigned character with value greater that
+ `127'. The values in the range `0-127' are reserved for
+ internal use by the library.
+
+ The size that the data type represents in bytes is specified by the
+ third parameter, `sizeof_type'. This value should not be
+ confused with the sizeof the structure that represents the data
+ type, unless the data type is of class `SLANG_CLASS_TYPE_VECTOR'
+ or `SLANG_CLASS_TYPE_SCALAR'. For pointer objects, the value
+ of this parameter is just `sizeof(void *)'.
+
+ The final parameter specifies the class type of the data type. It must
+ be one of the values:
+
+ SLANG_CLASS_TYPE_SCALAR
+ SLANG_CLASS_TYPE_VECTOR
+ SLANG_CLASS_TYPE_PTR
+ SLANG_CLASS_TYPE_MMT
+
+ The `SLANG_CLASS_TYPE_SCALAR' indicates that the new data type
+ is a scalar. Examples of scalars in `SLANG_INT_TYPE' and
+ `SLANG_DOUBLE_TYPE'.
+
+ Setting `class_type' to SLANG_CLASS_TYPE_VECTOR implies that the
+ new data type is a vector, or a 1-d array of scalar types. An
+ example of a data type of this class is the
+ `SLANG_COMPLEX_TYPE', which represents complex numbers.
+
+ `SLANG_CLASS_TYPE_PTR' specifies the data type is of a pointer
+ type. Examples of data types of this class include
+ `SLANG_STRING_TYPE' and `SLANG_ARRAY_TYPE'. Such types must
+ provide for their own memory management.
+
+ Data types of class `SLANG_CLASS_TYPE_MMT' are pointer types
+ except that the memory management, i.e., creation and destruction of
+ the type, is handled by the interpreter. Such a type is called a
+ _memory managed type_. An example of this data type is the
+ `SLANG_FILEPTR_TYPE'.
+
+ NOTES
+ See the \slang-c-programmers-guide for more information.
+
+ SEE ALSO
+ SLclass_allocate_class
+--------------------------------------------------------------
+
+SLclass_set_string_function
+
+ SYNOPSIS
+ Set a data type's string representation callback
+
+ USAGE
+ int SLclass_set_string_function (cl, sfun)
+
+ SLang_Class_Type *cl
+ char *(*sfun) (unsigned char, VOID_STAR);
+
+
+ DESCRIPTION
+ The `SLclass_set_string_function' routine is used to define a
+ callback function, `sfun', that that will be used when a string
+ representation of an object of the data type represented by `cl'
+ is needed. `cl' must have already been obtained via a call to
+ `SLclass_allocate_class'. When called, `sfun' will be
+ passed two arguments: a unsigned char which represents the data
+ type, and the address of the object for which a string represetation
+ is required. The callback function must return a _malloced_
+ string.
+
+ Upon success, `SLclass_set_string_function' returns zero, or
+ upon error it returns -1.
+
+ EXAMPLE
+ A callback function that handles both `SLANG_STRING_TYPE' and
+ `SLANG_INT_TYPE' variables looks like:
+
+ char *string_and_int_callback (unsigned char type, VOID_STAR addr)
+ {
+ char buf[64];
+
+ switch (type)
+ {
+ case SLANG_STRING_TYPE:
+ return SLmake_string (*(char **)addr);
+
+ case SLANG_INTEGER_TYPE:
+ sprintf (buf, "%d", *(int *)addr);
+ return SLmake_string (buf);
+ }
+ return NULL;
+ }
+
+
+ NOTES
+ The default string callback simply returns the name of the data type.
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLclass_set_destroy_function
+
+ SYNOPSIS
+ Set the destroy method callback for a data type
+
+ USAGE
+ int SLclass_set_destroy_function (cl, destroy_fun)
+
+ SLang_Class_Type *cl
+ void (*destroy_fun) (unsigned char, VOID_STAR);
+
+
+ DESCRIPTION
+ `SLclass_set_destroy_function' is used to set the destroy
+ callback for a data type. The data type's class `cl' must have
+ been previously obtained via a call to `SLclass_allocate_class'.
+ When called, `destroy_fun' will be passed two arguments: a
+ unsigned char which represents the data type, and the address of the
+ object to be destroyed.
+
+ `SLclass_set_destroy_function' returns zero upon success, and
+ -1 upon failure.
+
+ EXAMPLE
+ The destroy method for `SLANG_STRING_TYPE' looks like:
+
+ static void string_destroy (unsigned char type, VOID_STAR ptr)
+ {
+ char *s = *(char **) ptr;
+ if (s != NULL) SLang_free_slstring (*(char **) s);
+ }
+
+
+ NOTES
+ Data types of class SLANG_CLASS_TYPE_SCALAR do not require a destroy
+ callback. However, other classes do.
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLclass_set_push_function
+
+ SYNOPSIS
+ Set the push callback for a new data type
+
+ USAGE
+ int SLclass_set_push_function (cl, push_fun)
+
+ SLang_Class_Type *cl
+ int (*push_fun) (unsigned char, VOID_STAR);
+
+
+ DESCRIPTION
+ `SLclass_set_push_function' is used to set the push callback
+ for a new data type specified by `cl', which must have been
+ previously obtained via `SLclass_allocate_class'.
+
+ The parameter `push_fun' is a pointer to the push callback. It
+ is required to take two arguments: an unsigned character
+ representing the data type, and the address of the object to be
+ pushed. It must return zero upon success, or -1 upon failure.
+
+ `SLclass_set_push_function' returns zero upon success, or -1
+ upon failure.
+
+ EXAMPLE
+ The push callback for `SLANG_COMPLEX_TYPE' looks like:
+
+ static int complex_push (unsigned char type, VOID_STAR ptr)
+ {
+ double *z = *(double **) ptr;
+ return SLang_push_complex (z[0], z[1]);
+ }
+
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLclass_set_pop_function
+
+ SYNOPSIS
+ Set the pop callback for a new data type
+
+ USAGE
+ int SLclass_set_pop_function (cl, pop_fun)
+
+ SLang_Class_Type *cl
+ int (*pop_fun) (unsigned char, VOID_STAR);
+
+
+ DESCRIPTION
+ `SLclass_set_pop_function' is used to set the callback for
+ popping an object from the stack for a new data type specified by
+ `cl', which must have been previously obtained via
+ `SLclass_allocate_class'.
+
+ The parameter `pop_fun' is a pointer to the pop callback
+ function, which is required to take two arguments: an unsigned
+ character representing the data type, and the address of the object
+ to be popped. It must return zero upon success, or -1 upon
+ failure.
+
+ `SLclass_set_pop_function' returns zero upon success, or -1
+ upon failure.
+
+ EXAMPLE
+ The pop callback for `SLANG_COMPLEX_TYPE' looks like:
+
+ static int complex_push (unsigned char type, VOID_STAR ptr)
+ {
+ double *z = *(double **) ptr;
+ return SLang_pop_complex (&z[0], &z[1]);
+ }
+
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLclass_get_datatype_name
+
+ SYNOPSIS
+ Get the name of a data type
+
+ USAGE
+ char *SLclass_get_datatype_name (unsigned char type)
+
+ DESCRIPTION
+ The `SLclass_get_datatype_name' function returns the name of the
+ data type specified by `type'. For example, if `type' is
+ `SLANG_INT_TYPE', the string `"Integer_Type"' will be
+ returned.
+
+ This function returns a pointer that should not be modified or freed.
+
+ SEE ALSO
+ SLclass_allocate_class, SLclass_register_class
+--------------------------------------------------------------
+
+SLang_free_mmt
+
+ SYNOPSIS
+ Free a memory managed type
+
+ USAGE
+ void SLang_free_mmt (SLang_MMT_Type *mmt)
+
+ DESCRIPTION
+ The `SLang_MMT_Type' function is used to free a memory managed
+ data type.
+
+ SEE ALSO
+ SLang_object_from_mmt, SLang_create_mmt
+--------------------------------------------------------------
+
+SLang_object_from_mmt
+
+ SYNOPSIS
+ Get a pointer to the value of a memory managed type
+
+ USAGE
+ VOID_STAR SLang_object_from_mmt (SLang_MMT_Type *mmt)
+
+ DESCRIPTION
+ The `SLang_object_from_mmt' function returns a pointer the the
+ actually object whose memory is being managed by the interpreter.
+
+ SEE ALSO
+ SLang_free_mmt, SLang_create_mmt
+--------------------------------------------------------------
+
+SLang_create_mmt
+
+ SYNOPSIS
+ Create a memory managed data type
+
+ USAGE
+ SLang_MMT_Type *SLang_create_mmt (unsigned char t, VOID_STAR ptr)
+
+ DESCRIPTION
+ The `SLang_create_mmt' function returns a pointer to a new
+ memory managed object. This object contains information necessary
+ to manage the memory associated with the pointer `ptr' which
+ represents the application defined data type of type `t'.
+
+ SEE ALSO
+ SLang_object_from_mmt, SLang_push_mmt, SLang_free_mmt
+--------------------------------------------------------------
+
+SLang_push_mmt
+
+ SYNOPSIS
+ Push a memory managed type
+
+ USAGE
+ int SLang_push_mmt (SLang_MMT_Type *mmt)
+
+ DESCRIPTION
+ This function is used to push a memory managed type onto the
+ interpreter stack. It returns zero upon success, or `-1' upon
+ failure.
+
+ SEE ALSO
+ SLang_create_mmt, SLang_pop_mmt
+--------------------------------------------------------------
+
+SLang_pop_mmt
+
+ SYNOPSIS
+ Pop a memory managed data type
+
+ USAGE
+ SLang_MMT_Type *SLang_pop_mmt (unsigned char t)
+
+ DESCRIPTION
+ The `SLang_pop_mmt' function may be used to pop a memory managed
+ type of type `t' from the stack. It returns a pointer to the
+ memory managed object upon success, or `NULL' upon failure. The
+ function `SLang_object_from_mmt' should be used to access the
+ actual pointer to the data type.
+
+ SEE ALSO
+ SLang_object_from_mmt, SLang_push_mmt
+--------------------------------------------------------------
+
+SLang_inc_mmt
+
+ SYNOPSIS
+ Increment a memory managed type reference count
+
+ USAGE
+ void SLang_inc_mmt (SLang_MMT_Type *mmt);
+
+ DESCRIPTION
+ The `SLang_inc_mmt' function may be used to increment the
+ reference count associated with the memory managed data type given
+ by `mmt'.
+
+ SEE ALSO
+ SLang_free_mmt, SLang_create_mmt, SLang_pop_mmt, SLang_pop_mmt
+--------------------------------------------------------------
+
+SLang_vmessage
+
+ SYNOPSIS
+ Display a message to the message device
+
+ USAGE
+ void SLang_vmessage (char *fmt, ...)
+
+ DESCRIPTION
+ This function prints a `printf' style formatted variable
+ argument list to the message device. The default message device is
+ `stdout'.
+
+ SEE ALSO
+ SLang_verror
+--------------------------------------------------------------
+
+SLang_exit_error
+
+ SYNOPSIS
+ Exit the program and display an error message
+
+ USAGE
+ void SLang_exit_error (char *fmt, ...)
+
+ DESCRIPTION
+ The `SLang_exit_error' function terminates the program and
+ displays an error message using a `printf' type variable
+ argument list. The default behavior to this function is to write
+ the message to `stderr' and exit with the `exit' system
+ call.
+
+ If the the function pointer `SLang_Exit_Error_Hook' is
+ non-NULL, the function to which it points will be called. This
+ permits an application to perform whatever cleanup is necessary.
+ This hook has the prototype:
+
+ void (*SLang_Exit_Error_Hook)(char *, va_list);
+
+
+ SEE ALSO
+ SLang_verror, exit
+--------------------------------------------------------------
+
+SLang_init_slang
+
+ SYNOPSIS
+ Initialize the interpreter
+
+ USAGE
+ int SLang_init_slang (void)
+
+ DESCRIPTION
+ The `SLang_init_slang' function must be called by all
+ applications that use the S-Lang interpreter. It initializes the
+ interpreter, defines the built-in data types, and adds a set of core
+ intrinsic functions.
+
+ The function returns `0' upon success, or `-1' upon failure.
+
+ SEE ALSO
+ SLang_init_slfile, SLang_init_slmath, SLang_init_slunix
+--------------------------------------------------------------
+
+SLang_init_slfile
+
+ SYNOPSIS
+ Initialize the interpreter file I/O intrinsics
+
+ USAGE
+ int SLang_init_slfile (void)
+
+ DESCRIPTION
+ This function initializes the interpreters file I/O intrinsic
+ functions. This function adds intrinsic functions such as
+ `fopen', `fclose', and `fputs' to the interpreter.
+ It returns `0' if successful, or `-1' upon error.
+
+ NOTES
+ Before this function can be called, it is first necessary to call
+ `SLang_init_slang'. It also adds
+ the preprocessor symbol `__SLFILE__' to the interpreter.
+
+ SEE ALSO
+ SLang_init_slang, SLang_init_slunix, SLang_init_slmath
+--------------------------------------------------------------
+
+SLang_init_slmath
+
+ SYNOPSIS
+ Initialize the interpreter math intrinsics
+
+ USAGE
+ int SLang_init_slmath (void)
+
+ DESCRIPTION
+ The `SLang_init_slmath' function initializes the interpreter's
+ mathematical intrinsic functions and makes them available to the
+ language. The intrinsic functions include `sin', `cos',
+ `tan', etc... It returns `0' if successful, or `-1'
+ upon failure.
+
+ NOTES
+ This function must be called after `SLang_init_slang'. It adds
+ the preprocessor symbol `__SLMATH__' to the interpreter.
+
+ SEE ALSO
+ SLang_init_slang, SLang_init_slfile, SLang_init_slunix
+--------------------------------------------------------------
+
+SLang_init_slunix
+
+ SYNOPSIS
+ Make available some unix system calls to the interpreter
+
+ USAGE
+ int SLang_init_slunix (void)
+
+ DESCRIPTION
+ The `SLang_init_slunix' function initializes the interpreter's
+ unix system call intrinsic functions and makes them available to the
+ language. Examples of functions made available by
+ `SLang_init_slunix' include `chmod', `chown', and
+ `stat_file'. It returns `0' if successful, or `-1'
+ upon failure.
+
+ NOTES
+ This function must be called after `SLang_init_slang'. It adds
+ the preprocessor symbol `__SLUNIX__' to the interpreter.
+
+ SEE ALSO
+ SLang_init_slang, SLang_init_slfile, SLang_init_slmath
+--------------------------------------------------------------
+
+SLadd_intrin_fun_table
+
+ SYNOPSIS
+ Add a table of intrinsic functions to the interpreter
+
+ USAGE
+ int SLadd_intrin_fun_table(SLang_Intrin_Fun_Type *tbl, char *pp_name);
+
+ DESCRIPTION
+ The `SLadd_intrin_fun_table' function adds an array, or table, of
+ `SLang_Intrin_Fun_Type' objects to the interpreter. The first
+ parameter, `tbl' specifies the table to be added. The second
+ parameter `pp_name', if non-NULL will be added to the list of
+ preprocessor symbols.
+
+ This function returns -1 upon failure or zero upon success.
+
+ NOTES
+ A table should only be loaded one time and it is considered to be an
+ error on the part of the application if it loads a table more than
+ once.
+
+ SEE ALSO
+ SLadd_intrin_var_table, SLadd_intrinsic_function, SLdefine_for_ifdef
+--------------------------------------------------------------
+
+SLadd_intrin_var_table
+
+ SYNOPSIS
+ Add a table of intrinsic variables to the interpreter
+
+ USAGE
+ int SLadd_intrin_var_table (SLang_Intrin_Var_Type *tbl, char *pp_name);
+
+ DESCRIPTION
+ The `SLadd_intrin_var_table' function adds an array, or table, of
+ `SLang_Intrin_Var_Type' objects to the interpreter. The first
+ parameter, `tbl' specifies the table to be added. The second
+ parameter `pp_name', if non-NULL will be added to the list of
+ preprocessor symbols.
+
+ This function returns -1 upon failure or zero upon success.
+
+ NOTES
+ A table should only be loaded one time and it is considered to be an
+ error on the part of the application if it loads a table more than
+ once.
+
+ SEE ALSO
+ SLadd_intrin_var_table, SLadd_intrinsic_function, SLdefine_for_ifdef
+--------------------------------------------------------------
+
+SLang_load_file
+
+ SYNOPSIS
+ Load a file into the interpreter
+
+ USAGE
+ int SLang_load_file (char *fn)
+
+ DESCRIPTION
+ The `SLang_load_file' function opens the file whose name is
+ specified by `fn' and feeds it to the interpreter, line by line,
+ for execution. If `fn' is `NULL', the function will take
+ input from `stdin'.
+
+ If no error occurs, it returns `0'; otherwise,
+ it returns `-1', and sets `SLang_Error' accordingly. For
+ example, if it fails to open the file, it will return `-1' with
+ `SLang_Error' set to `SL_OBJ_NOPEN'.
+
+ NOTES
+ If the hook `SLang_Load_File_Hook' declared as
+
+ int (*SLang_Load_File_Hook)(char *);
+
+ is non-NULL, the function point to by it will be used to load the
+ file. For example, the jed editor uses this hook to load files
+ via its own routines.
+
+ SEE ALSO
+ SLang_load_object, SLang_load_string
+--------------------------------------------------------------
+
+SLang_restart
+
+ SYNOPSIS
+ Reset the interpreter after an error
+
+ USAGE
+ void SLang_restart (int full)
+
+ DESCRIPTION
+ The `SLang_restart' function should be called by the
+ application at top level if an error occurs. If the parameter
+ `full' is non-zero, any objects on the S-Lang run time stack
+ will be removed from the stack; otherwise, the stack will be left
+ intact. Any time the stack is believed to be trashed, this routine
+ should be called with a non-zero argument (e.g., if
+ `setjmp'/`longjmp' is called).
+
+ Calling `SLang_restart' does not reset the global variable
+ `SLang_Error' to zero. It is up to the application to reset
+ that variable to zero after calling `SLang_restart'.
+
+ EXAMPLE
+
+ while (1)
+ {
+ if (SLang_Error)
+ {
+ SLang_restart (1);
+ SLang_Error = 0;
+ }
+ (void) SLang_load_file (NULL);
+ }
+
+
+ SEE ALSO
+ SLang_init_slang, SLang_load_file
+--------------------------------------------------------------
+
+SLang_byte_compile_file
+
+ SYNOPSIS
+ Byte-compile a file for faster loading
+
+ USAGE
+ int SLang_byte_compile_file(char *fn, int reserved)
+
+ DESCRIPTION
+ The `SLang_byte_compile_file' function ``byte-compiles'' the
+ file `fn' for faster loading by the interpreter. This produces
+ a new file whose filename is equivalent to the one specified by
+ `fn', except that a `'c'' is appended to the name. For
+ example, if `fn' is set to `init.sl', then the new file
+ will have the name exmp{init.slc}. The meaning of the second
+ parameter, `reserved', is reserved for future use. For now, set
+ it to `0'.
+
+ The function returns zero upon success, or `-1' upon error and
+ sets SLang_Error accordingly.
+
+ SEE ALSO
+ SLang_load_file, SLang_init_slang
+--------------------------------------------------------------
+
+SLang_autoload
+
+ SYNOPSIS
+ Autoload a function from a file
+
+ USAGE
+ int SLang_autoload(char *funct, char *filename)
+
+ DESCRIPTION
+ The `SLang_autoload' function may be used to associate a
+ `slang' function name `funct' with the file `filename'
+ such that if `funct' has not already been defined when needed,
+ it will be loaded from `filename'.
+
+ `SLang_autoload' has no effect if `funct' has already been
+ defined. Otherwise it declares `funct' as a user-defined S-Lang
+ function. It returns `0' upon success, or `-1' upon error.
+
+ SEE ALSO
+ SLang_load_file, SLang_is_defined
+--------------------------------------------------------------
+
+SLang_load_string
+
+ SYNOPSIS
+ Interpret a string
+
+ USAGE
+ int SLang_load_string(char *str)
+
+ DESCRIPTION
+ The `SLang_load_string' function feeds the string specified by
+ `str' to the interpreter for execution. It returns zero upon
+ success, or `-1' upon failure.
+
+ SEE ALSO
+ SLang_load_file, SLang_load_object
+--------------------------------------------------------------
+
+SLdo_pop
+
+ SYNOPSIS
+ Delete an object from the stack
+
+ USAGE
+ int SLdo_pop(void)
+
+ DESCRIPTION
+ This function removes an object from the top of the interpeter's
+ run-time stack and frees any memory associated with it. It returns
+ zero upon success, or `-1' upon error (most likely due to a
+ stack-underflow).
+
+ SEE ALSO
+ SLdo_pop_n, SLang_pop_integer, SLang_pop_string
+--------------------------------------------------------------
+
+SLdo_pop_n
+
+ SYNOPSIS
+ Delete n objects from the stack
+
+ USAGE
+ int SLdo_pop_n (unsigned int n)
+
+ DESCRIPTION
+ The `SLdo_pop_n' function removes the top `n' objects from
+ the interpreter's run-time stack and frees all memory associated
+ with the objects. It returns zero upon success, or `-1' upon
+ error (most likely due to a stack-underflow).
+
+ SEE ALSO
+ SLdo_pop, SLang_pop_integer, SLang_pop_string
+--------------------------------------------------------------
+
+SLang_pop_integer
+
+ SYNOPSIS
+ Pop an integer off the stack
+
+ USAGE
+ int SLang_pop_integer (int *i)
+
+ DESCRIPTION
+ The `SLang_pop_integer' function removes an integer from the
+ top of the interpreter's run-time stack and returns its value via
+ the pointer `i'. If successful, it returns zero. However, if
+ the top stack item is not of type `SLANG_INT_TYPE', or the
+ stack is empty, the function will return `-1' and set
+ `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_push_integer, SLang_pop_double
+--------------------------------------------------------------
+
+SLpop_string
+
+ SYNOPSIS
+ Pop a string from the stack
+
+ USAGE
+ int SLpop_string (char **strptr);
+
+ DESCRIPTION
+ The `SLpop_string' function pops a string from the stack and
+ returns it as a malloced pointer. It is up to the calling routine
+ to free this string via a call to `free' or `SLfree'. If
+ successful, `SLpop_string' returns zero. However, if the top
+ stack item is not of type `SLANG_STRING_TYPE', or the stack is
+ empty, the function will return `-1' and set
+ `SLang_Error' accordingly.
+
+ EXAMPLE
+
+ define print_string (void)
+ {
+ char *s;
+ if (-1 == SLpop_string (&s))
+ return;
+ fputs (s, stdout);
+ SLfree (s);
+ }
+
+
+ NOTES
+ This function should not be confused with `SLang_pop_slstring',
+ which pops a _hashed_ string from the stack.
+
+ SEE ALSO
+ SLang_pop_slstring. SLfree
+--------------------------------------------------------------
+
+SLang_pop_string
+
+ SYNOPSIS
+ Pop a string from the stack
+
+ USAGE
+ int SLang_pop_string(char **strptr, int *do_free)
+
+ DESCRIPTION
+ The `SLpop_string' function pops a string from the stack and
+ returns it as a malloced pointer via `strptr'. After the
+ function returns, the integer pointed to by the second parameter
+ will be set to a non-zero value if `*strptr' should be freed via
+ `free' or `SLfree'. If successful, `SLpop_string'
+ returns zero. However, if the top stack item is not of type
+ `SLANG_STRING_TYPE', or the stack is empty, the function will
+ return `-1' and set `SLang_Error' accordingly.
+
+ NOTES
+ This function is considered obsolete and should not be used by
+ applications. If one requires a malloced string for modification,
+ `SLpop_string' should be used. If one requires a constant
+ string that will not be modifed by the application,
+ `SLang_pop_slstring' should be used.
+
+ SEE ALSO
+ SLang_pop_slstring, SLpop_string
+--------------------------------------------------------------
+
+SLang_pop_slstring
+
+ SYNOPSIS
+ Pop a hashed string from the stack
+
+ USAGE
+ int SLang_pop_slstring (char **s_ptr)
+
+ DESCRIPTION
+ The `SLang_pop_slstring' function pops a hashed string from the
+ S-Lang run-time stack and returns it via `s_ptr'. It returns
+ zero if successful, or -1 upon failure. The resulting string
+ should be freed via a call to `SLang_free_slstring' after use.
+
+ EXAMPLE
+
+ void print_string (void)
+ {
+ char *s;
+ if (-1 == SLang_pop_slstring (&s))
+ return;
+ fprintf (stdout, "%s\n", s);
+ SLang_free_slstring (s);
+ }
+
+
+ NOTES
+ `SLang_free_slstring' is the preferred function for popping
+ strings. This is a result of the fact that the interpreter uses
+ hashed strings as the native representation for string data.
+
+ One must _never_ free a hashed string using `free' or
+ `SLfree'. In addition, one must never make any attempt to
+ modify a hashed string and doing so will result in memory
+ corruption.
+
+ SEE ALSO
+ SLang_free_slstring, SLpop_string
+--------------------------------------------------------------
+
+SLang_pop_double
+
+ SYNOPSIS
+ Pop a double from the stack
+
+ USAGE
+ int SLang_pop_double (double *dptr, int *iptr, int *conv)
+
+ DESCRIPTION
+ The `SLang_pop_double' function pops a double precision number
+ from the stack and returns it via `dptr'. If the number was
+ derived from an integer, `*conv' will be set to `1' upon
+ return, otherwise, `*conv' will be set to `0'. This
+ function returns 0 upon success, otherwise it returns -1 and sets
+ `SLang_Error' accordingly.
+
+ NOTES
+ If one does not care whether or not `*dptr' was derived from
+ an integer, `iptr' and `conv' may be passed as `NULL'
+ pointers.
+
+ SEE ALSO
+ SLang_pop_integer, SLang_push_double
+--------------------------------------------------------------
+
+SLang_pop_complex
+
+ SYNOPSIS
+ Pop a complex number from the stack
+
+ USAGE
+ int SLang_pop_complex (double *re, double *im)
+
+ DESCRIPTION
+ `SLang_pop_complex' pops a complex number from the stack and
+ returns it via the parameters `re' and `im' as the real and
+ imaginary parts of the complex number, respectively. This function
+ automatically converts objects of type `SLANG_DOUBLE_TYPE' and
+ `SLANG_INT_TYPE' to `SLANG_COMPLEX_TYPE', if necessary.
+ It returns zero upon sucess, or -1 upon error setting
+ `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_pop_integer, SLang_pop_double, SLang_push_complex
+--------------------------------------------------------------
+
+SLang_push_complex
+
+ SYNOPSIS
+ Push a complex number onto the stack
+
+ USAGE
+ int SLang_push_complex (double re, double im)
+
+ DESCRIPTION
+ `SLang_push_complex' may be used to push the complex number
+ whose real and imaginary parts are given by `re' and `im',
+ respectively. It returns zero upon sucess, or -1 upon error
+ setting `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_pop_complex, SLang_push_double
+--------------------------------------------------------------
+
+SLang_push_double
+
+ SYNOPSIS
+ Push a double onto the stack
+
+ USAGE
+ int SLang_push_double(double d)
+
+ DESCRIPTION
+ `SLang_push_double' may be used to push the double precision
+ floating point number `d' onto the interpreter's run-time
+ stack. It returns zero upon success, or -1 upon error setting
+ `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_pop_double, SLang_push_integer
+--------------------------------------------------------------
+
+SLang_push_string
+
+ SYNOPSIS
+ Push a string onto the stack
+
+ USAGE
+ int SLang_push_string (char *s)
+
+ DESCRIPTION
+ `SLang_push_string' pushes a copy of the string specified by
+ `s' onto the interpreter's run-time stack. It returns zero
+ upon success, or -1 upon error setting `SLang_Error'
+ accordingly.
+
+ NOTES
+ If `s' is `NULL', this function pushes `NULL'
+ (`SLANG_NULL_TYPE') onto the stack.
+
+ SEE ALSO
+ SLang_push_malloced_string
+--------------------------------------------------------------
+
+SLang_push_integer
+
+ SYNOPSIS
+ Push an integer onto the stack
+
+ USAGE
+ int SLang_push_integer (int i)
+
+ DESCRIPTION
+ `SLang_push_integer' the integer `i' onto the interpreter's
+ run-time stack. It returns zero upon success, or -1 upon error
+ setting `SLang_Error' accordingly.
+
+ SEE ALSO
+ SLang_pop_integer, SLang_push_double, SLang_push_string
+--------------------------------------------------------------
+
+SLang_push_malloced_string
+
+ SYNOPSIS
+ Push a malloced string onto the stack
+
+ USAGE
+ int SLang_push_malloced_string (char *s);
+
+ DESCRIPTION
+ `SLang_push_malloced_string' may be used to push a malloced
+ string onto the interpreter's run-time stack. It returns zero upon
+ success, or -1 upon error setting `SLang_Error' accordingly.
+
+ EXAMPLE
+ The following example illustrates that it is up to the calling
+ routine to free the string if `SLang_push_malloced_string' fails:
+
+ int push_hello (void)
+ {
+ char *s = malloc (6);
+ if (s == NULL) return -1;
+ strcpy (s, "hello");
+ if (-1 == SLang_push_malloced_string (s))
+ {
+ free (s);
+ return -1;
+ }
+ return 0;
+ }
+
+
+ EXAMPLE
+ The function `SLang_create_slstring' returns a hashed string.
+ Such a string may not be malloced and should not be passed to
+ `SLang_push_malloced_string'.
+
+ NOTES
+ If `s' is `NULL', this function pushes `NULL'
+ (`SLANG_NULL_TYPE') onto the stack.
+
+ SEE ALSO
+ SLang_push_string, SLmake_string
+--------------------------------------------------------------
+
+SLang_is_defined
+
+ SYNOPSIS
+ Check to see if the interpreter defines an object
+
+ USAGE
+ int SLang_is_defined (char *nm)
+
+ DESCRIPTION
+ The `SLang_is_defined' function may be used to determine
+ whether or not a variable or function whose name is given by
+ `em' has been defined. It returns zero if no such object has
+ been defined. Othewise it returns a non-zero value whose meaning
+ is given by the following table:
+
+ 1 intrinsic function (SLANG_INTRINSIC)
+ 2 user-defined slang function (SLANG_FUNCTION)
+ -1 intrinsic variable (SLANG_IVARIABLE)
+ -2 user-defined global variable (SLANG_GVARIABLE)
+
+
+ SEE ALSO
+ SLadd_intrinsic_function, SLang_run_hooks, SLang_execute_function
+--------------------------------------------------------------
+
+SLang_run_hooks
+
+ SYNOPSIS
+ Run a user-defined hook with arguments
+
+ USAGE
+ int SLang_run_hooks (char *fname, unsigned int n, ...)
+
+ DESCRIPTION
+ The `SLang_run_hooks' function may be used to execute a
+ user-defined function named `fname'. Before execution of the
+ function, the `n' string arguments specified by the variable
+ parameter list are pushed onto the stack. If the function
+ `fname' does not exist, `SLang_run_hooks' returns zero;
+ otherwise, it returns `1' upon successful execution of the
+ function, or -1 if an error occurred.
+
+ EXAMPLE
+ The jed editor uses `SLang_run_hooks' to setup the mode of a
+ buffer based on the filename extension of the file associated with
+ the buffer:
+
+ char *ext = get_filename_extension (filename);
+ if (ext == NULL) return -1;
+ if (-1 == SLang_run_hooks ("mode_hook", 1, ext))
+ return -1;
+ return 0;
+
+
+ SEE ALSO
+ SLang_is_defined, SLang_execute_function
+--------------------------------------------------------------
+
+SLang_execute_function
+
+ SYNOPSIS
+ Execute a user or intrinsic function
+
+ USAGE
+ int SLang_execute_function (char *fname)
+
+ DESCRIPTION
+ This function may be used to execute either a user-defined function
+ or an intrinisic function. The name of the function is specified
+ by `fname'. It returns zero if `fname' is not defined, or
+ `1' if the function was successfully executed, or -1 upon
+ error.
+
+ NOTES
+ The function `SLexecute_function' may be a better alternative
+ for some uses.
+
+ SEE ALSO
+ SLang_run_hooks, SLexecute_function, SLang_is_defined
+--------------------------------------------------------------
+
+SLang_verror
+
+ SYNOPSIS
+ Signal an error with a message
+
+ USAGE
+ void SLang_verror (int code, char *fmt, ...);
+
+ DESCRIPTION
+ The `SLang_verror' function sets `SLang_Error' to
+ `code' if `SLang_Error' is 0. It also displays the error
+ message implied by the `printf' variable argument list using
+ `fmt' as the format.
+
+ EXAMPLE
+
+ FILE *open_file (char *file)
+ {
+ char *file = "my_file.dat";
+ if (NULL == (fp = fopen (file, "w")))
+ SLang_verror (SL_INTRINSIC_ERROR, "Unable to open %s", file);
+ return fp;
+ }
+
+
+ SEE ALSO
+ SLang_vmessage, SLang_exit_error
+--------------------------------------------------------------
+
+SLang_doerror
+
+ SYNOPSIS
+ Signal an error
+
+ USAGE
+ void SLang_doerror (char *err_str)
+
+ DESCRIPTION
+ The `SLang_doerror' function displays the string `err_str'
+ to the error device and signals a S-Lang error.
+
+ NOTES
+ `SLang_doerror' is considered to obsolete. Applications should
+ use the `SLang_verror' function instead.
+
+ SEE ALSO
+ SLang_verror, SLang_exit_error
+--------------------------------------------------------------
+
+SLang_get_function
+
+ SYNOPSIS
+ Get a pointer to a slang function
+
+ USAGE
+ SLang_Name_Type *SLang_get_function (char *fname)
+
+ DESCRIPTION
+ This function returns a pointer to the internal S-Lang table entry
+ of a function whose name is given by `fname'. It returns
+ `NULL' upon failure. The value returned by this function can be
+ used used `SLexecute_function' to call the function directly
+ from C.
+
+ SEE ALSO
+ SLexecute_function
+--------------------------------------------------------------
+
+SLexecute_function
+
+ SYNOPSIS
+ Execute a slang or intrinsic function
+
+ USAGE
+ int SLexecute_function (SLang_Name_Type *nt)
+
+ DESCRIPTION
+ The `SLexecute_function' allows an application to call the
+ S-Lang function specified by the `SLang_Name_Type' pointer
+ `nt'. This parameter must be non `NULL' and must have been
+ previously obtained by a call to `SLang_get_function'.
+
+ EXAMPLE
+ Consider the S-Lang function:
+
+ define my_fun (x)
+ {
+ return x^2 - 2;
+ }
+
+ Suppose that it is desired to call this function many times with
+ different values of x. There are at least two ways to do this.
+ The easiest way is to use `SLang_execute_function' by passing
+ the string `"my_fun"'. A better way that is much faster is to
+ use `SLexecute_function':
+
+ int sum_a_function (char *fname, double *result)
+ {
+ double sum, x, y;
+ SLang_Name_Type *nt;
+
+ if (NULL == (nt = SLang_get_function (fname)))
+ return -1;
+
+ sum = 0;
+ for (x = 0; x < 10.0; x += 0.1)
+ {
+ SLang_start_arg_list ();
+ if (-1 == SLang_push_double (x))
+ return -1;
+ SLang_end_arg_list ();
+ if (-1 == SLexecute_function (nt))
+ return -1;
+ if (-1 == SLang_pop_double (&y, NULL, NULL))
+ return -1;
+
+ sum += y;
+ }
+ return sum;
+ }
+
+ Although not necessary in this case, `SLang_start_arg_list' and
+ `SLang_end_arg_list' were used to provide the function with
+ information about the number of parameters passed to it.
+
+ SEE ALSO
+ SLang_get_function, SLang_start_arg_list, SLang_end_arg_list
+--------------------------------------------------------------
+
+SLang_peek_at_stack
+
+ SYNOPSIS
+ Find the type of object on the top of the stack
+
+ USAGE
+ int SLang_peek_at_stack (void)
+
+ DESCRIPTION
+ The `SLang_peek_at_stack' function is useful for determining the
+ data type of the object at the top of the stack. It returns the
+ data type, or -1 upon a stack-underflow error. It does not remove
+ anything from the stack.
+
+ SEE ALSO
+ SLang_pop_string, SLang_pop_integer
+--------------------------------------------------------------
+
+SLmake_string
+
+ SYNOPSIS
+ Duplicate a string
+
+ USAGE
+ char *SLmake_string (char *s)
+
+ DESCRIPTION
+ The `SLmake_string' function creates a new copy of the string
+ `s', via `malloc', and returns it. Upon failure it returns
+ `NULL'. Since the resulting string is malloced, it should be
+ freed when nolonger needed via a call to either `free' or
+ `SLfree'.
+
+ NOTES
+ `SLmake_string' should not be confused with the function
+ `SLang_create_slstring', which performs a similar function.
+
+ SEE ALSO
+ SLmake_nstring, SLfree, SLmalloc, SLang_create_slstring
+--------------------------------------------------------------
+
+SLmake_nstring
+
+ SYNOPSIS
+ Duplicate a substring
+
+ USAGE
+ char *SLmake_nstring (char *s, unsigned int n)
+
+ DESCRIPTION
+ This function is like `SLmake_nstring' except that it creates a
+ null terminated string formed from the first `n' characters of
+ `s'. Upon failure, it returns `NULL', otherwise it returns
+ the new string. When nolonger needed, the returned string should be
+ freed with either `free' or `SLfree'.
+
+ SEE ALSO
+ SLmake_nstring, SLfree, SLang_create_nslstring
+--------------------------------------------------------------
+
+SLang_create_nslstring
+
+ SYNOPSIS
+ Created a hashed substring
+
+ USAGE
+ char *SLang_create_nslstring (char *s, unsigned int n)
+
+ DESCRIPTION
+ `SLang_create_nslstring' is like `SLang_create_slstring'
+ except that only the first `n' characters of `s' are used to
+ perform the string. Upon error, it returns `NULL', otherwise it
+ returns the hashed substring. Such a string must be freed by the
+ function `SLang_free_slstring'.
+
+ NOTES
+ Do not use `free' or `SLfree' to free the string returned by
+ `SLang_create_slstring' or `SLang_create_nslstring'. Also
+ it is important that no attempt is made to modify the hashed string
+ returned by either of these functions. If one needs to modify a
+ string, the functions `SLmake_string' or `SLmake_nstring'
+ should be used instead.
+
+ SEE ALSO
+ SLang_free_slstring, SLang_create_slstring, SLmake_nstring
+--------------------------------------------------------------
+
+SLang_create_slstring
+
+ SYNOPSIS
+ Create a hashed string
+
+ USAGE
+ char *SLang_create_slstring (char *s)
+
+ DESCRIPTION
+ The `SLang_create_slstring' creates a copy of `s' and
+ returns it as a hashed string. Upon error, the function returns
+ `NULL', otherwise it returns the hashed string. Such a string
+ must only be freed via the `SLang_free_slstring' function.
+
+ NOTES
+ Do not use `free' or `SLfree' to free the string returned by
+ `SLang_create_slstring' or `SLang_create_nslstring'. Also
+ it is important that no attempt is made to modify the hashed string
+ returned by either of these functions. If one needs to modify a
+ string, the functions `SLmake_string' or `SLmake_nstring'
+ should be used instead.
+
+ SEE ALSO
+ SLang_free_slstring, SLang_create_nslstring, SLmake_string
+--------------------------------------------------------------
+
+SLang_free_slstring
+
+ SYNOPSIS
+ Free a hashed string
+
+ USAGE
+ void SLang_free_slstring (char *s)
+
+ DESCRIPTION
+ The `SLang_free_slstring' function is used to free a hashed
+ string such as one returned by `SLang_create_slstring',
+ `SLang_create_nslstring', or `SLang_create_static_slstring'.
+ If `s' is `NULL', the routine does nothing.
+
+ SEE ALSO
+ SLang_create_slstring, SLang_create_nslstring, SLang_create_static_slstring
+--------------------------------------------------------------
+
+SLang_concat_slstrings
+
+ SYNOPSIS
+ Concatenate two strings to produce a hashed string
+
+ USAGE
+ char *SLang_concat_slstrings (char *a, char *b)
+
+ DESCRIPTION
+ The `SLang_concat_slstrings' function concatenates two strings,
+ `a' and `b', and returns the result as a hashed string.
+ Upon failure, `NULL' is returned.
+
+ NOTES
+ A hashed string can only be freed using `SLang_free_slstring'.
+ Never use either `free' or `SLfree' to free a hashed string,
+ otherwise memory corruption will result.
+
+ SEE ALSO
+ SLang_free_slstring, SLang_create_slstring
+--------------------------------------------------------------
+
+SLang_create_static_slstring
+
+ SYNOPSIS
+ Create a hashed string
+
+ USAGE
+ char *SLang_create_static_slstring (char *s_literal)
+
+ DESCRIPTION
+ The `SLang_create_static_slstring' creates a hashed string from
+ the string literal `s_literal' and returns the result. Upon
+ failure it returns `NULL'.
+
+ EXAMPLE
+
+ char *create_hello (void)
+ {
+ return SLang_create_static_slstring ("hello");
+ }
+
+
+ NOTES
+ This function should only be used with string literals.
+
+ SEE ALSO
+ SLang_create_slstring, SLang_create_nslstring
+--------------------------------------------------------------
+
+SLmalloc
+
+ SYNOPSIS
+ Allocate some memory
+
+ USAGE
+ char *SLmalloc (unsigned int nbytes)
+
+ DESCRIPTION
+ This function uses `malloc' to allocate `nbytes' of memory.
+ Upon error it returns `NULL'; otherwise it returns a pointer to
+ the allocated memory. One should use `SLfree' to free the
+ memory after used.
+
+ SEE ALSO
+ SLfree, SLrealloc, SLcalloc
+--------------------------------------------------------------
+
+SLcalloc
+
+ SYNOPSIS
+ Allocate some memory
+
+ USAGE
+ char *SLcalloc (unsigned int num_elem, unsigned int elem_size)
+
+ DESCRIPTION
+ This function uses `calloc' to allocate memory for
+ `num_elem' objects with each of size `elem_size' and returns
+ the result. In addition, the newly allocated memory is zeroed.
+ Upon error it returns `NULL'; otherwise it returns a pointer to
+ the allocated memory. One should use `SLfree' to free the
+ memory after used.
+
+ SEE ALSO
+ SLmalloc, SLrealloc, SLfree
+--------------------------------------------------------------
+
+SLfree
+
+ SYNOPSIS
+ Free some allocated memory
+
+ USAGE
+ void SLfree (char *ptr)
+
+ DESCRIPTION
+ The `SLfree' function uses `free' to deallocate the memory
+ specified by `ptr', which may be `NULL' in which case the
+ function does nothing.
+
+ NOTES
+ Never use this function to free a hashed string returned by one of
+ the family of `slstring' functions, e.g.,
+ `SLang_pop_slstring'.
+
+ SEE ALSO
+ SLmalloc, SLcalloc, SLrealloc, SLmake_string
+--------------------------------------------------------------
+
+SLrealloc
+
+ SYNOPSIS
+ Resize a dynamic memory block
+
+ USAGE
+ char *SLrealloc (char *ptr, unsigned int new_size)
+
+ DESCRIPTION
+ The `SLrealloc' uses the `realloc' function to resize the
+ memory block specified by `ptr' to the new size `new_size'.
+ If `ptr' is `NULL', the function call is equivalent to
+ `SLmalloc(new_size)'. Similarly, if `new_size' is zero,
+ the function call is equivalent to `SLfree(ptr)'.
+
+ If the function fails, or if `new_size' is zero, `NULL' is
+ returned. Otherwise a pointer is returned to the (possibly moved)
+ new block of memory.
+
+ SEE ALSO
+ SLfree, SLmalloc, SLcalloc
+--------------------------------------------------------------
+
+SLcurrent_time_string
+
+ SYNOPSIS
+ Get the current time as a string
+
+ USAGE
+ char *SLcurrent_time_string (void)
+
+ DESCRIPTION
+ The `SLcurrent_time_string' function uses the C library function
+ call `ctime' to obtain a string representation of the the
+ current date and time in the form
+
+ "Wed Dec 10 12:50:28 1997"
+
+ However, unlike the `ctime' function, a newline character is not
+ present in the string.
+
+ The returned value points to a statically allocated memory block
+ which may get overwritten on subsequent function calls.
+
+ SEE ALSO
+ SLmake_string
+--------------------------------------------------------------
+
+SLatoi
+
+ SYNOPSIS
+ Convert a text string to an integer
+
+ USAGE
+ int SLatoi(unsigned char *str
+
+ DESCRIPTION
+ `SLatoi' parses the string `str' to interpret it as an
+ integer value. Unlike `atoi', `SLatoi' can also parse
+ strings containing integers expressed in
+ hexidecimal (e.g., `"0x7F"') and octal (e.g., `"012"'.)
+ notation.
+
+ SEE ALSO
+ SLang_guess_type
+--------------------------------------------------------------
+
+SLang_pop_fileptr
+
+ SYNOPSIS
+ Pop a file pointer
+
+ USAGE
+ int SLang_pop_fileptr (SLang_MMT_Type **mmt, FILE **fp)
+
+ DESCRIPTION
+ `SLang_pop_fileptr' pops a file pointer from the S-Lang
+ run-time stack. It returns zero upon success, or -1 upon failure.
+
+ A S-Lang file pointer (SLANG_FILEPTR_TYPE) is actually a memory
+ managed object. For this reason, `SLang_pop_fileptr' also
+ returns the memory managed object via the argument list. It is up
+ to the calling routine to call `SLang_free_mmt' to free the
+ object.
+
+ EXAMPLE
+ The following example illustrates an application defined intrinsic
+ function that writes a user defined double precision number to a
+ file. Note the use of `SLang_free_mmt':
+
+ int write_double (void)
+ {
+ double t;
+ SLang_MMT_Type *mmt;
+ FILE *fp;
+ int status;
+
+ if (-1 == SLang_pop_double (&d, NULL, NULL))
+ return -1;
+ if (-1 == SLang_pop_fileptr (&mmt, &fp))
+ return -1;
+
+ status = fwrite (&d, sizeof (double), 1, fp);
+ SLang_free_mmt (mmt);
+ return status;
+ }
+
+ This function can be used by a S-Lang function as follows:
+
+ define write_some_values ()
+ {
+ variable fp, d;
+
+ fp = fopen ("myfile.dat", "wb");
+ if (fp == NULL)
+ error ("file failed to open");
+ for (d = 0; d < 10.0; d += 0.1)
+ {
+ if (-1 == write_double (fp, d))
+ error ("write failed");
+ }
+ if (-1 == fclose (fp))
+ error ("fclose failed");
+ }
+
+
+ SEE ALSO
+ SLang_free_mmt, SLang_pop_double
+--------------------------------------------------------------
+
+SLadd_intrinsic_function
+
+ SYNOPSIS
+ Add a new intrinsic function to the interpreter
+
+ USAGE
+ int SLadd_intrinsic_function (name, f, type, nargs, ...)
+
+ char *name
+ FVOID_STAR f
+ unsigned char type
+ unsigned int nargs
+
+
+ DESCRIPTION
+ The `SLadd_intrinsic_function' function may be used to add a new
+ intrinsic function. The S-Lang name of the function is specified by
+ `name' and the actual function pointer is given by `f', cast
+ to `FVOID_STAR'. The third parameter, `type' specifies the
+ return type of the function and must be one of the following values:
+
+ SLANG_VOID_TYPE (returns nothing)
+ SLANG_INT_TYPE (returns int)
+ SLANG_DOUBLE_TYPE (returns double)
+ SLANG_STRING_TYPE (returns char *)
+
+ The `nargs' parameter specifies the number of parameters to pass
+ to the function. The variable argument list following `nargs'
+ must consists of `nargs' integers which specify the data type of
+ each argument.
+
+ The function returns zero upon success or -1 upon failure.
+
+ EXAMPLE
+ The jed editor uses this function to change the `system'
+ intrinsic function to the following:
+
+ static int jed_system (char *cmd)
+ {
+ if (Jed_Secure_Mode)
+ {
+ msg_error ("Access denied.");
+ return -1;
+ }
+ return SLsystem (cmd);
+ }
+
+ After initializing the interpreter with `SLang_init_slang',
+ jed calls `SLadd_intrinsic_function' to substitute the above
+ definition for the default S-Lang definition:
+
+ if (-1 == SLadd_intrinsic_function ("system", (FVOID_STAR)jed_system,
+ SLANG_INT_TYPE, 1,
+ SLANG_STRING_TYPE))
+ return -1;
+
+
+ SEE ALSO
+ SLadd_intrinsic_variable, SLadd_intrinsic_array
+--------------------------------------------------------------
+
+SLadd_intrinsic_variable
+
+ SYNOPSIS
+ Add an intrinsic variable to the interpreter
+
+ USAGE
+ int SLadd_intrinsic_variable (name, addr, type, rdonly)
+
+ char *name
+ VOID_STAR type
+ unsigned char type
+ int rdonly
+
+
+ DESCRIPTION
+ The `SLadd_intrinsic_variable' function adds an intrinsic
+ variable called `name' to the interpeter. The second parameter
+ `addr' specifies the address of the variable (cast to
+ `VOID_STAR'). The third parameter, `type', specifies the
+ data type of the variable. If the fourth parameter, `rdonly',
+ is non-zero, the variable will interpreted by the interpreter as
+ read-only.
+
+ If successful, `SLadd_intrinsic_variable' returns zero,
+ otherwise it returns -1.
+
+ EXAMPLE
+ Suppose that `My_Global_Int' is a global variable (at least not
+ a local one):
+
+ int My_Global_Int;
+
+ It can be added to the interpreter via the function call
+
+ if (-1 == SLadd_intrinsic_variable ("MyGlobalInt",
+ (VOID_STAR)&My_Global_Int,
+ SLANG_INT_TYPE, 0))
+ exit (1);
+
+
+ NOTES
+ The current implementation requires all pointer type intrinsic
+ variables to be read-only. For example,
+
+ char *My_Global_String;
+
+ is of type `SLANG_STRING_TYPE', and must be declared as
+ read-only. Finally, not that
+
+ char My_Global_Char_Buf[256];
+
+ is _not_ a `SLANG_STRING_TYPE' object. This difference is
+ very important because internally the interpreter dereferences the
+ address passed to it to get to the value of the variable.
+
+ SEE ALSO
+ SLadd_intrinsic_function, SLadd_intrinsic_array
+--------------------------------------------------------------
+
+SLclass_add_unary_op
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_unary_op (unsigned char,int (*) (int, unsigned char, VOID_STAR, unsigned int, VOID_STAR), int (*) (int, unsigned char, unsigned char *));
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLclass_add_app_unary_op
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_app_unary_op (unsigned char, int (*) (int,unsigned char, VOID_STAR, unsigned int,VOID_STAR),int (*) (int, unsigned char, unsigned char *));
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLclass_add_binary_op
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_binary_op (unsigned char, unsigned char,int (*)(int, unsigned char, VOID_STAR, unsigned int,unsigned char, VOID_STAR, unsigned int,VOID_STAR),int (*) (int, unsigned char, unsigned char, unsigned char *));
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLclass_add_math_op
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_math_op (unsigned char,int (*)(int,unsigned char, VOID_STAR, unsigned int,VOID_STAR),int (*)(int, unsigned char, unsigned char *));
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLclass_add_typecast
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLclass_add_typecast (unsigned char, unsigned char int (*)_PROTO((unsigned char, VOID_STAR, unsigned int,unsigned char, VOID_STAR)),int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLang_init_tty
+
+ SYNOPSIS
+ Initialize the terminal keyboard interface
+
+ USAGE
+ int SLang_init_tty (int intr_ch, int no_flow_ctrl, int opost)
+
+ DESCRIPTION
+ `SLang_init_tty' initializes the terminal for single character
+ input. If the first parameter `intr_ch' is in the range 0-255,
+ it will be used as the interrupt character, e.g., under Unix this
+ character will generate a `SIGINT' signal. Otherwise, if it is
+ `-1', the interrupt character will be left unchanged.
+
+ If the second parameter `no_flow_ctrl' is non-zero, flow control
+ (`XON'/`XOFF') processing will be
+ enabled.
+
+ If the last parmeter `opost' is non-zero, output processing by the
+ terminal will be enabled. If one intends to use this function in
+ conjunction with the S-Lang screen management routines
+ (`SLsmg'), this paramete shold be set to zero.
+
+ `SLang_init_tty' returns zero upon success, or -1 upon error.
+
+ NOTES
+ Terminal I/O is a complex subject. The S-Lang interface presents a
+ simplification that the author has found useful in practice. For
+ example, the only special character processing that
+ `SLang_init_tty' enables is that of the `SIGINT' character,
+ and the generation of other signals via the keyboard is disabled.
+ However, generation of the job control signal `SIGTSTP' is possible
+ via the `SLtty_set_suspend_state' function.
+
+ Under Unix, the integer variable `SLang_TT_Read_FD' is used to
+ specify the input descriptor for the terminal. If
+ `SLang_TT_Read_FD' represents a terminal device as determined
+ via the `isatty' system call, then it will be used as the
+ terminal file descriptor. Otherwise, the terminal device
+ `/dev/tty' will used as the input device. The default value of
+ `SLang_TT_Read_FD' is -1 which causes `/dev/tty' to be
+ used. So, if you prefer to use `stdin' for input, then set
+ `SLang_TT_Read_FD' to `fileno(stdin)' _before_ calling
+ `SLang_init_tty'.
+
+ If the variable `SLang_TT_Baud_Rate' is zero when this function
+ is called, the function will attempt to determine the baud rate by
+ querying the terminal driver and set `SLang_TT_Baud_Rate' to
+ that value.
+
+ SEE ALSO
+ SLang_reset_tty, SLang_getkey, SLtty_set_suspend_state
+--------------------------------------------------------------
+
+SLang_reset_tty
+
+ SYNOPSIS
+ Reset the terminal
+
+ USAGE
+ void SLang_reset_tty (void)
+
+ DESCRIPTION
+ `SLang_reset_tty' resets the terminal interface back to the
+ state it was in before `SLang_init_tty' was called.
+
+ SEE ALSO
+ SLang_init_tty
+--------------------------------------------------------------
+
+SLtty_set_suspend_state
+
+ SYNOPSIS
+ Enable or disable keyboard suspension
+
+ USAGE
+ void SLtty_set_suspend_state (int s)
+
+ DESCRIPTION
+ The `SLtty_set_suspend_state' function may be used to enable or
+ disable keyboard generation of the `SIGTSTP' job control signal.
+ If `s' is non-zero, generation of this signal via the terminal
+ interface will be enabled, otherwise it will be disabled.
+
+ This function should only be called after the terminal driver has be
+ initialized via `SLang_init_tty'. The `SLang_init_tty'
+ always disables the generation of `SIGTSTP' via the keyboard.
+
+ SEE ALSO
+ SLang_init_tty
+--------------------------------------------------------------
+
+SLang_getkey
+
+ SYNOPSIS
+ Read a character from the keyboard
+
+ USAGE
+ unsigned int SLang_getkey (void);
+
+ DESCRIPTION
+ The `SLang_getkey' reads a single character from the terminal
+ and returns it. The terminal must first be initialized via a call
+ to `SLang_init_tty' before this function can be called. Upon
+ success, `SLang_getkey' returns the character read from the
+ terminal, otherwise it returns `SLANG_GETKEY_ERROR'.
+
+ SEE ALSO
+ SLang_init_tty, SLang_input_pending, SLang_ungetkey
+--------------------------------------------------------------
+
+SLang_ungetkey_string
+
+ SYNOPSIS
+ Unget a key string
+
+ USAGE
+ int SLang_ungetkey_string (unsigned char *buf, unsigned int n)
+
+ DESCRIPTION
+ The `SLang_ungetkey_string' function may be used to push the
+ `n' characters pointed to by `buf' onto the buffered input
+ stream that `SLgetkey' uses. If there is not enough room for
+ the characters, -1 is returned and none are buffered. Otherwise,
+ it returns zero.
+
+ NOTES
+ The difference between `SLang_buffer_keystring' and
+ `SLang_ungetkey_string' is that the `SLang_buffer_keystring'
+ appends the characters to the end of the getkey buffer, whereas
+ `SLang_ungetkey_string' inserts the characters at the beginning
+ of the input buffer.
+
+ SEE ALSO
+ SLang_ungetkey, SLang_getkey
+--------------------------------------------------------------
+
+SLang_buffer_keystring
+
+ SYNOPSIS
+ Append a keystring to the input buffer
+
+ USAGE
+ int SLang_buffer_keystring (unsigned char *b, unsigned int len)
+
+ DESCRIPTION
+ `SLang_buffer_keystring' places the `len' characters
+ specified by `b' at the _end_ of the buffer that
+ `SLang_getkey' uses. Upon success it returns 0; otherwise, no
+ characters are buffered and it returns -1.
+
+ NOTES
+ The difference between `SLang_buffer_keystring' and
+ `SLang_ungetkey_string' is that the `SLang_buffer_keystring'
+ appends the characters to the end of the getkey buffer, whereas
+ `SLang_ungetkey_string' inserts the characters at the beginning
+ of the input buffer.
+
+ SEE ALSO
+ SLang_getkey, SLang_ungetkey, SLang_ungetkey_string
+--------------------------------------------------------------
+
+SLang_ungetkey
+
+ SYNOPSIS
+ Push a character back onto the input buffer
+
+ USAGE
+ int SLang_ungetkey (unsigned char ch)
+
+ DESCRIPTION
+ `SLang_ungetkey' pushes the character `ch' back onto the
+ `SLgetkey' input stream. Upon success, it returns zero,
+ otherwise it returns 1.
+
+ EXAMPLE
+ This function is implemented as:
+
+ int SLang_ungetkey (unsigned char ch)
+ {
+ return SLang_ungetkey_string(&ch, 1);
+ }
+
+
+ SEE ALSO
+ SLang_getkey, SLang_ungetkey_string
+--------------------------------------------------------------
+
+SLang_flush_input
+
+ SYNOPSIS
+ Discard all keyboard input waiting to be read
+
+ USAGE
+ void SLang_flush_input (void)
+
+ DESCRIPTION
+ `SLang_flush_input' discards all input characters waiting to be
+ read by the `SLang_getkey' function.
+
+ SEE ALSO
+ SLang_getkey
+--------------------------------------------------------------
+
+SLang_input_pending
+
+ SYNOPSIS
+ Check to see if input is pending
+
+ USAGE
+ int SLang_input_pending (int tsecs)
+
+ DESCRIPTION
+ `SLang_input_pending' may be used to see if an input character
+ is available to be read without causing `SLang_getkey' to block.
+ It will wait up to `tsecs' tenths of a second if no characters
+ are immediately available for reading. If `tsecs' is less than
+ zero, then `SLang_input_pending' will wait `-tsecs'
+ milliseconds for input, otherwise `tsecs' represents `1/10'
+ of a second intervals.
+
+ NOTES
+ Not all systems support millisecond resolution.
+
+ SEE ALSO
+ SLang_getkey
+--------------------------------------------------------------
+
+SLang_set_abort_signal
+
+ SYNOPSIS
+ Set the signal to trap SIGINT
+
+ USAGE
+ void SLang_set_abort_signal (void (*f)(int));
+
+ DESCRIPTION
+ `SLang_set_abort_signal' sets the function that gets
+ triggered when the user presses the interrupt key (`SIGINT') to
+ the function `f'. If `f' is `NULL' the default handler
+ will get installed.
+
+ EXAMPLE
+ The default interrupt handler on a Unix system is:
+
+ static void default_sigint (int sig)
+ {
+ SLKeyBoard_Quit = 1;
+ if (SLang_Ignore_User_Abort == 0) SLang_Error = SL_USER_BREAK;
+ SLsignal_intr (SIGINT, default_sigint);
+ }
+
+
+ NOTES
+ For Unix programmers, the name of this function may appear
+ misleading since it is associated with `SIGINT' and not
+ `SIGABRT'. The origin of the name stems from the original intent
+ of the function: to allow the user to abort the running of a S-Lang
+ interpreter function.
+
+ SEE ALSO
+ SLang_init_tty, SLsignal_intr
+--------------------------------------------------------------
+
+SLkm_define_key
+
+ SYNOPSIS
+ Define a key in a keymap
+
+ USAGE
+ int SLkm_define_key (char *seq, FVOID_STAR f, SLKeyMap_List_Type *km)
+
+ DESCRIPTION
+ `SLkm_define_key' associates the key sequence `seq' with the
+ function pointer `f' in the keymap specified by `km'. Upon
+ success, it returns zero, otherwise it returns a negative integer
+ upon error.
+
+ SEE ALSO
+ SLkm_define_keysym, SLang_define_key
+--------------------------------------------------------------
+
+SLang_define_key
+
+ SYNOPSIS
+ Define a key in a keymap
+
+ USAGE
+ int SLang_define_key(char *seq, char *fun, SLKeyMap_List_Type *km)
+
+ DESCRIPTION
+ `SLang_define_key' associates the key sequence `seq' with
+ the function whose name is `fun' in the keymap specified by
+ `km'.
+
+ SEE ALSO
+ SLkm_define_keysym, SLkm_define_key
+--------------------------------------------------------------
+
+SLkm_define_keysym
+
+ SYNOPSIS
+ Define a keysym in a keymap
+
+ USAGE
+ int SLkm_define_keysym (seq, ks, km)
+
+ char *seq;
+ unsigned int ks;
+ SLKeyMap_List_Type *km;
+
+
+ DESCRIPTION
+ `SLkm_define_keysym' associates the key sequence `seq' with
+ the keysym `ks' in the keymap `km'. Keysyms whose value is
+ less than or equal to `0x1000' is reserved by the library and
+ should not be used.
+
+ SEE ALSO
+ SLkm_define_key, SLang_define_key
+--------------------------------------------------------------
+
+SLang_undefine_key
+
+ SYNOPSIS
+ Undefined a key from a keymap
+
+ USAGE
+ void SLang_undefine_key(char *seq, SLKeyMap_List_Type *km);
+
+ DESCRIPTION
+ `SLang_undefine_key' removes the key sequence `seq' from the
+ keymap `km'.
+
+ SEE ALSO
+ SLang_define_key
+--------------------------------------------------------------
+
+SLang_create_keymap
+
+ SYNOPSIS
+ Create a new keymap
+
+ USAGE
+ SLKeyMap_List_Type *SLang_create_keymap (name, km)
+
+ char *name;
+ SLKeyMap_List_Type *km;
+
+
+ DESCRIPTION
+ `SLang_create_keymap' creates a new keymap called `name' by
+ copying the key definitions from the keymap `km'. If `km'
+ is `NULL', the newly created keymap will be empty and it is up
+ to the calling routine to initialize it via the
+ `SLang_define_key' and `SLkm_define_keysym' functions.
+ `SLang_create_keymap' returns a pointer to the new keymap, or
+ `NULL' upon failure.
+
+ SEE ALSO
+ SLang_define_key, SLkm_define_keysym
+--------------------------------------------------------------
+
+SLang_do_key
+
+ SYNOPSIS
+ Read a keysequence and return its keymap entry
+
+ USAGE
+ SLang_Key_Type *SLang_do_key (kml, getkey)
+
+ SLKeyMap_List_Type *kml;
+ int (*getkey)(void);
+
+
+ DESCRIPTION
+ The `SLang_do_key' function reads characters using the function
+ specified by the `getkey' function pointer and uses the
+ key sequence to return the appropriate entry in the keymap specified
+ by `kml'.
+
+ `SLang_do_key' returns `NULL' if the key sequence is not
+ defined by the keymap, otherwise it returns a pointer to an object
+ of type `SLang_Key_Type', which is defined in `slang.h' as
+
+ #define SLANG_MAX_KEYMAP_KEY_SEQ 14
+ typedef struct SLang_Key_Type
+ {
+ struct SLang_Key_Type *next;
+ union
+ {
+ char *s;
+ FVOID_STAR f;
+ unsigned int keysym;
+ }
+ f;
+ unsigned char type; /* type of function */
+ #define SLKEY_F_INTERPRET 0x01
+ #define SLKEY_F_INTRINSIC 0x02
+ #define SLKEY_F_KEYSYM 0x03
+ unsigned char str[SLANG_MAX_KEYMAP_KEY_SEQ + 1];/* key sequence */
+ }
+ SLang_Key_Type;
+
+
+ The `type' field specifies which field of the union `f'
+ should be used. If `type' is `SLKEY_F_INTERPRET', then
+ `f.s' is a string that should be passed to the interpreter for
+ evaluation. If `type' is `SLKEY_F_INTRINSIC', then
+ `f.f' refers to function that should be called. Otherwise,
+ `type' is `SLKEY_F_KEYSYM' and `f.keysym' represents the
+ value of the keysym that is associated with the key sequence.
+
+ SEE ALSO
+ SLkm_define_keysym, SLkm_define_key
+--------------------------------------------------------------
+
+SLang_find_key_function
+
+ SYNOPSIS
+ Obtain a function pointer associated with a keymap
+
+ USAGE
+ FVOID_STAR SLang_find_key_function (fname, km);
+
+ char *fname;
+ SLKeyMap_List_Type *km;
+
+
+ DESCRIPTION
+ The `SLang_find_key_function' routine searches through the
+ `SLKeymap_Function_Type' list of functions associated with the
+ keymap `km' for the function with name `fname'.
+ If a matching function is found, a pointer to the function will
+ be returned, otherwise `SLang_find_key_function' will return
+ `NULL'.
+
+ SEE ALSO
+ SLang_create_keymap, SLang_find_keymap
+--------------------------------------------------------------
+
+SLang_find_keymap
+
+ SYNOPSIS
+ Find a keymap
+
+ USAGE
+ SLKeyMap_List_Type *SLang_find_keymap (char *keymap_name);
+
+ DESCRIPTION
+ The `SLang_find_keymap' function searches through the list of
+ keymaps looking for one whose name is `keymap_name'. If a
+ matching keymap is found, the function returns a pointer to the
+ keymap. It returns `NULL' if no such keymap exists.
+
+ SEE ALSO
+ SLang_create_keymap, SLang_find_key_function
+--------------------------------------------------------------
+
+SLang_process_keystring
+
+ SYNOPSIS
+ Un-escape a key-sequence
+
+ USAGE
+ char *SLang_process_keystring (char *kseq);
+
+ DESCRIPTION
+ The `SLang_process_keystring' function converts an escaped key
+ sequence to its raw form by converting two-character combinations
+ such as `^A' to the _single_ character `Ctrl-A' (ASCII
+ 1). In addition, if the key sequence contains constructs such as
+ `^(XX)', where `XX' represents a two-character termcap
+ specifier, the termcap escape sequence will be looked up and
+ substituted.
+
+ Upon success, `SLang_process_keystring' returns a raw
+ key-sequence whose first character represents the total length of
+ the key-sequence, including the length specifier itself. It returns
+ `NULL' upon failure.
+
+ EXAMPLE
+ Consider the following examples:
+
+ SLang_process_keystring ("^X^C");
+ SLang_process_keystring ("^[[A");
+
+ The first example will return a pointer to a buffer of three characters
+ whose ASCII values are given by `{3,24,3}'. Similarly, the
+ second example will return a pointer to the four characters
+ `{4,27,91,65}'. Finally, the result of
+
+ SLang_process_keystring ("^[^(ku)");
+
+ will depend upon the termcap/terminfo capability `"ku"', which
+ represents the escape sequence associated with the terminal's UP
+ arrow key. For an ANSI terminal whose UP arrow produces
+ `"ESC [ A"', the result will be `5,27,27,91,65'.
+
+ NOTES
+ `SLang_process_keystring' returns a pointer to a static area
+ that will be overwritten on subsequent calls.
+
+ SEE ALSO
+ SLang_define_key, SLang_make_keystring
+--------------------------------------------------------------
+
+SLang_make_keystring
+
+ SYNOPSIS
+ Make a printable key sequence
+
+ USAGE
+ char *SLang_make_keystring (unsigned char *ks);
+
+ DESCRIPTION
+ The `SLang_make_keystring' function takes a raw key sequence
+ `ks' and converts it to a printable form by converting
+ characters such as ASCII 1 (ctrl-A) to `^A'. That is, it
+ performs the opposite function of `SLang_process_keystring'.
+
+ NOTES
+ This function returns a pointer to a static area that will be
+ overwritten on the next call to `SLang_make_keystring'.
+
+ SEE ALSO
+ SLang_process_keystring
+--------------------------------------------------------------
+
+SLextract_list_element
+
+ SYNOPSIS
+ Extract a substring of a delimited string
+
+ USAGE
+ int SLextract_list_element (dlist, nth, delim, buf, buflen)
+
+ char *dlist;
+ unsigned int nth;
+ char delim;
+ char *buf;
+ unsigned int buflen;
+
+
+ DESCRIPTION
+ `SLextract_list_element' may be used to obtain the `nth'
+ element of a list of strings, `dlist', that are delimited by the
+ character `delim'. The routine copies the `nth' element of
+ `dlist' to the buffer `buf' whose size is `buflen'
+ characters. It returns zero upon success, or -1 if `dlist'
+ does not contain an `nth' element.
+
+ EXAMPLE
+ A delimited list of strings may be turned into an array of strings
+ as follows. For conciseness, all malloc error checking has been
+ omitted.
+
+ int list_to_array (char *list, char delim, char ***ap)
+ {
+ unsigned int nth;
+ char **a;
+ char buf[1024];
+
+ /* Determine the size of the array */
+ nth = 0;
+ while (0 == SLextract_list_element (list, nth, delim, buf, sizeof(buf)))
+ nth++;
+
+ ap = (char **) SLmalloc ((nth + 1) * sizeof (char **));
+ nth = 0;
+ while (0 == SLextract_list_element (list, nth, delim, buf, sizeof(buf)))
+ {
+ a[nth] = SLmake_string (buf);
+ nth++;
+ }
+ a[nth] = NULL;
+ *ap = a;
+ return 0;
+ }
+
+
+ SEE ALSO
+ SLmalloc, SLmake_string
+--------------------------------------------------------------
+
+SLprep_open_prep
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLprep_open_prep (SLPreprocess_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLprep_close_prep
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLprep_close_prep (SLPreprocess_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLprep_line_ok
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLprep_line_ok (char *, SLPreprocess_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLdefine_for_ifdef
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLdefine_for_ifdef (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLang_Read_Line_Type * SLang_rline_save_line (SLang_RLine_Info_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ SLang_Read_Line_Type * SLang_rline_save_line (SLang_RLine_Info_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_init_readline (SLang_RLine_Info_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_init_readline (SLang_RLine_Info_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_read_line (SLang_RLine_Info_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_read_line (SLang_RLine_Info_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_rline_insert (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_rline_insert (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLrline_redraw (SLang_RLine_Info_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLrline_redraw (SLang_RLine_Info_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_flush_output (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_flush_output (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_scroll_region(int, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_scroll_region(int, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_reset_scroll_region(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_reset_scroll_region(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_reverse_video (int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_reverse_video (int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_bold_video (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_bold_video (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_begin_insert(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_begin_insert(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_end_insert(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_end_insert(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_del_eol(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_del_eol(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_goto_rc (int, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_goto_rc (int, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_delete_nlines(int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_delete_nlines(int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_delete_char(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_delete_char(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_erase_line(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_erase_line(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_normal_video(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_normal_video(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_cls(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_cls(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_beep(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_beep(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_reverse_index(int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_reverse_index(int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_smart_puts(unsigned short *, unsigned short *, int, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_smart_puts(unsigned short *, unsigned short *, int, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_write_string (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_write_string (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_putchar(char);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_putchar(char);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_init_video (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_init_video (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_reset_video (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_reset_video (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_get_terminfo(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_get_terminfo(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_get_screen_size (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_get_screen_size (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_set_cursor_visibility (int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_set_cursor_visibility (int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_initialize (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_initialize (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_enable_cursor_keys(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_enable_cursor_keys(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_term_vtxxx(int *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_term_vtxxx(int *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_color_esc (int, char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_color_esc (int, char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_wide_width(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_wide_width(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_narrow_width(void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_narrow_width(void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_set_mouse_mode (int, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_set_mouse_mode (int, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_alt_char_set (int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_alt_char_set (int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_write_to_status_line (char *, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_write_to_status_line (char *, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_disable_status_line (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_disable_status_line (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLtt_tgetstr (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLtt_tgetstr (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_tgetnum (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_tgetnum (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_tgetflag (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_tgetflag (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLtt_tigetent (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLtt_tigetent (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLtt_tigetstr (char *, char **);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLtt_tigetstr (char *, char **);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLtt_tigetnum (char *, char **);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLtt_tigetnum (char *, char **);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLtt_Char_Type SLtt_get_color_object (int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ SLtt_Char_Type SLtt_get_color_object (int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_color_object (int, SLtt_Char_Type);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_color_object (int, SLtt_Char_Type);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_color (int, char *, char *, char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_color (int, char *, char *, char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_mono (int, char *, SLtt_Char_Type);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_mono (int, char *, SLtt_Char_Type);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_add_color_attribute (int, SLtt_Char_Type);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_add_color_attribute (int, SLtt_Char_Type);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLtt_set_color_fgbg (int, SLtt_Char_Type, SLtt_Char_Type);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLtt_set_color_fgbg (int, SLtt_Char_Type, SLtt_Char_Type);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLkp_define_keysym (char *, unsigned int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLkp_define_keysym (char *, unsigned int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLkp_init (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLkp_init (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLkp_getkey (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLkp_getkey (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLscroll_find_top (SLscroll_Window_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLscroll_find_top (SLscroll_Window_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLscroll_find_line_num (SLscroll_Window_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLscroll_find_line_num (SLscroll_Window_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+unsigned int SLscroll_next_n (SLscroll_Window_Type *, unsigned int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ unsigned int SLscroll_next_n (SLscroll_Window_Type *, unsigned int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+unsigned int SLscroll_prev_n (SLscroll_Window_Type *, unsigned int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ unsigned int SLscroll_prev_n (SLscroll_Window_Type *, unsigned int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLscroll_pageup (SLscroll_Window_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLscroll_pageup (SLscroll_Window_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLscroll_pagedown (SLscroll_Window_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLscroll_pagedown (SLscroll_Window_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLSig_Fun_Type *SLsignal (int, SLSig_Fun_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ SLSig_Fun_Type *SLsignal (int, SLSig_Fun_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLSig_Fun_Type *SLsignal_intr (int, SLSig_Fun_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ SLSig_Fun_Type *SLsignal_intr (int, SLSig_Fun_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLsig_block_signals (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLsig_block_signals (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLsig_unblock_signals (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLsig_unblock_signals (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLsystem (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLsystem (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLadd_at_handler (long *, char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLadd_at_handler (long *, char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLang_define_case(int *, int *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLang_define_case(int *, int *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLang_init_case_tables (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLang_init_case_tables (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+unsigned char *SLang_regexp_match(unsigned char *, unsigned int, SLRegexp_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ unsigned char *SLang_regexp_match(unsigned char *, unsigned int, SLRegexp_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_regexp_compile (SLRegexp_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_regexp_compile (SLRegexp_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLregexp_quote_string (char *, char *, unsigned int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLregexp_quote_string (char *, char *, unsigned int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLcmd_execute_string (char *, SLcmd_Cmd_Table_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLcmd_execute_string (char *, SLcmd_Cmd_Table_Type *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLsearch_init (char *, int, int, SLsearch_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLsearch_init (char *, int, int, SLsearch_Type *);
+
+ DESCRIPTION
+ ??
+ /* This routine must first be called before any search can take place.
+ * The second parameter specifies the direction of the search: greater than
+ * zero for a forwrd search and less than zero for a backward search. The
+ * third parameter specifies whether the search is case sensitive or not.
+ * The last parameter is a pointer to a structure that is filled by this
+ * function and it is this structure that must be passed to SLsearch.
+ */
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+unsigned char *SLsearch (unsigned char *, unsigned char *, SLsearch_Type *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ unsigned char *SLsearch (unsigned char *, unsigned char *, SLsearch_Type *);
+
+ DESCRIPTION
+ ??
+ /* To use this routine, you must first call 'SLsearch_init'. Then the first
+ * two parameters p1 and p2 serve to define the region over which the search
+ * is to take place. The third parameter is the structure that was previously
+ * initialized by SLsearch_init.
+ *
+ * The routine returns a pointer to the match if found otherwise it returns
+ * NULL.
+ */
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+SLcomplex_abs
+
+ SYNOPSIS
+ Returns the norm of a complex number
+
+ USAGE
+ double SLcomplex_abs (double *z)
+
+ DESCRIPTION
+ The `SLcomplex_abs' function returns the absolute value or the
+ norm of the complex number given by `z'.
+
+ SEE ALSO
+ SLcomplex_times
+--------------------------------------------------------------
+
+double *SLcomplex_times (double *, double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_times (double *, double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_divide (double *, double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_divide (double *, double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_sin (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_sin (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_cos (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_cos (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_tan (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_tan (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_asin (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_asin (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_acos (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_acos (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_atan (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_atan (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_exp (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_exp (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_log (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_log (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_log10 (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_log10 (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_sqrt (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_sqrt (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_sinh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_sinh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_cosh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_cosh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_tanh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_tanh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_pow (double *, double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_pow (double *, double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double SLmath_hypot (double x, double y);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double SLmath_hypot (double x, double y);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_acosh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_acosh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+double *SLcomplex_atanh (double *, double *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ double *SLcomplex_atanh (double *, double *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLdebug_malloc (unsigned long);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLdebug_malloc (unsigned long);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLdebug_calloc (unsigned long, unsigned long);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLdebug_calloc (unsigned long, unsigned long);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLdebug_realloc (char *, unsigned long);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLdebug_realloc (char *, unsigned long);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLdebug_free (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLdebug_free (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLmalloc_dump_statistics (void);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLmalloc_dump_statistics (void);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLstrcpy(register char *, register char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLstrcpy(register char *, register char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLstrcmp(register char *, register char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLstrcmp(register char *, register char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+char *SLstrncpy(char *, register char *, register int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ char *SLstrncpy(char *, register char *, register int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLmemset (char *, char, int);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLmemset (char *, char, int);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLexpand_escaped_string (register char *, register char *, register char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLexpand_escaped_string (register char *, register char *, register char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+void SLmake_lut (unsigned char *, unsigned char *, unsigned char);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ void SLmake_lut (unsigned char *, unsigned char *, unsigned char);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
+int SLang_guess_type (char *);
+
+ SYNOPSIS
+ ??
+
+ USAGE
+ int SLang_guess_type (char *);
+
+ DESCRIPTION
+ ??
+
+ SEE ALSO
+ ??
+--------------------------------------------------------------
+
diff --git a/doc/cslang.txt b/doc/cslang.txt
new file mode 100644
index 0000000..f9dbc4f
--- /dev/null
+++ b/doc/cslang.txt
@@ -0,0 +1,3300 @@
+ S-Lang Library C Programmer's Guide, V1.4.0
+ John E. Davis, davis@space.mit.edu
+ Fri Apr 21 21:48:16 2000
+ ____________________________________________________________
+
+ Table of Contents
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Preface
+
+ 1. A Brief History of
+
+ 2. Acknowledgements
+
+ 2. Introduction
+
+ 2. Interpreter Interface
+
+ 3. Embedding the Interpreter
+
+ 4. Calling the Interpreter
+
+ 5. Intrinsic Functions
+
+ 5.1 Restrictions on Intrinsic Functions
+ 5.2 Adding a New Intrinsic
+ 5.3 More Complicated Intrinsics
+
+ 6. Intrinsic Variables
+
+ 7. Aggregate Data Objects
+
+ 7.1 Arrays
+ 7.2 Structures
+ 7.2.1 Interpreter Structures
+ 7.2.2 Intrinsic Structures
+ 7.2.2 Keyboard Interface
+
+ 8. Initializing the Keyboard Interface
+
+ 9. Resetting the Keyboard Interface
+
+ 10. Initializing the
+
+ 11. Setting the Interrupt Handler
+
+ 12. Reading Keyboard Input with SLang[lowbar]getkey
+
+ 13. Reading Keyboard Input with SLkp[lowbar]getkey
+
+ 14. Buffering Input
+
+ 15. Global Variables
+
+ 15. Screen Management
+
+ 16. Initialization
+
+ 17. Resetting SLsmg
+
+ 18. Handling Screen Resize Events
+
+ 19. SLsmg Functions
+
+ 19.1 Positioning the cursor
+ 19.2 Writing to the Display
+ 19.3 Erasing the Display
+ 19.4 Setting Character Attributes
+ 19.5 Lines and Alternate Character Sets
+ 19.6 Miscellaneous Functions
+
+ 20. Variables
+
+ 21. Hints for using SLsmg
+ 21. Signal Functions
+
+ 21. Searching Functions
+
+ 22. Regular Expressions
+
+ 23. Simple Searches
+
+ 24. Initialization
+
+ 25. SLsearch
+
+ 25. Copyright
+
+ 26. The GNU Public License
+
+ 27. The Artistic License
+
+
+
+ ______________________________________________________________________
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1. Preface
+
+
+
+ S-Lang is an interpreted language that was designed from the start to
+ be easily embedded into a program to provide it with a powerful
+ extension language. Examples of programs that use S-Lang as an
+ extension language include the jed text editor, the slrn newsreader,
+ and sldxe (unreleased), a numerical computation program. For this
+ reason, S-Lang does not exist as a separate application and many of
+ the examples in this document are presented in the context of one of
+ the above applications.
+
+ S-Lang is also a programmer's library that permits a programmer to
+ develop sophisticated platform-independent software. In addition to
+ providing the S-Lang extension language, the library provides
+ facilities for screen management, keymaps, low-level terminal I/O,
+ etc. However, this document is concerned only with the extension
+ language and does not address these other features of the S-Lang
+ library. For information about the other components of the library,
+ the reader is referred to the The S-Lang Library Reference.
+
+
+ 1.1. A Brief History of S-Lang
+
+
+
+ I first began working on S-Lang sometime during the fall of 1992. At
+ that time I was writing a text editor (jed), which I wanted to endow
+ with a macro language. It occured to me that an application-
+ independent language that could be embedded into the editor would
+ prove more useful because I could envision embedding it into other
+ programs. As a result, S-Lang was born.
+
+ S-Lang was originally a stack language that supported a postscript-
+ like syntax. For that reason, I named it S-Lang, where the S was
+ supposed to emphasize its stack-based nature. About a year later, I
+ began to work on a preparser that would allow one to write using a
+ more traditional infix syntax making it easier to use for those
+ unfamiliar with stack based languages. Currently, the syntax of the
+ language resembles C, nevertheless some postscript-like features still
+ remain, e.g., the `%' character is still used as a comment delimiter.
+
+
+
+ 1.2. Acknowledgements
+
+
+
+ Since I first released S-Lang, I have received a lot feedback about
+ the library and the language from many people. This has given me the
+ opportunity and pleasure to interact with several people to make the
+ library portable and easy to use. In particular, I would like to
+ thank the following individuals:
+
+ Luchesar Ionkov <lionkov@sf.cit.bg> for his comments and criticisms of
+ the syntax of the language. He was the person who made me realize
+ that the low-level byte-code engine should be totally type-
+ independent. He also improved the tokenizer and preparser and
+ impressed upon me that the language needed a grammar.
+
+ Mark Olesen <olesen@weber.me.queensu.ca> for his many patches to
+ various aspects of the library and his support on AIX. He also
+ contributed a lot to the pre-processing (SLprep) routines.
+
+
+ John Burnell <j.burnell@irl.cri.nz> for the OS/2 port of the video and
+ keyboard routines. He also made value suggestions regarding the
+ interpreter interface.
+
+ Darrel Hankerson <hankedr@mail.auburn.edu> for cleaning up and
+ unifying some of the code and the makefiles.
+
+ Dominik Wujastyk <ucgadkw@ucl.ac.uk> who was always willing to test
+ new releases of the library.
+
+ Michael Elkins <me@muddcs.cs.hmc.edu> for his work on the curses
+ emulation.
+
+ Ulli Horlacher <framstag@belwue.de> and Oezguer Kesim <kesim@math.fu-
+ berlin.de> for the S-Lang newsgroup and mailing list.
+
+ Hunter Goatley, Andy Harper <Andy.Harper@kcl.ac.uk>, and Martin P.J.
+ Zinser <zinser@decus.decus.de> for their VMS support.
+
+ Dave Sims <sims@usa.acsys.com> and Chin Huang <cthuang@vex.net> for
+ Windows 95 and Windows NT support.
+
+ Lloyd Zusman <ljz@asfast.com> and Rich Roth <rich@on-the-net.com> for
+ creating and maintaining www.s-lang.org.
+
+ I am also grateful to many other people who send in bug-reports and
+ bug-fixes, for without such community involvement, S-Lang would not be
+ as well-tested and stable as it is. Finally, I would like to thank my
+ wife for her support and understanding while I spent long weekend
+ hours developing the library.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2. Introduction
+
+
+
+ S-Lang is a C programmer's library that includes routines for the
+ rapid development of sophisticated, user friendly, multi-platform
+ applications. The S-Lang library includes the following:
+
+
+ o Low level tty input routines for reading single characters at a
+ time.
+
+ o Keymap routines for defining keys and manipulating multiple
+ keymaps.
+
+ o A high-level keyprocessing interface (SLkp) for handling function
+ and arrow keys.
+
+ o High level screen management routines for manipulating both
+ monochrome and color terminals. These routines are very efficient.
+ (SLsmg)
+
+ o Low level terminal-independent routines for manipulating the
+ display of a terminal. (SLtt)
+
+ o Routines for reading single line input with line editing and recall
+ capabilities. (SLrline)
+
+ o Searching functions: both ordinary searches and regular expression
+ searches. (SLsearch)
+
+ o An embedded stack-based language interpreter with a C-like syntax.
+
+
+ The library is currently available for OS/2, MSDOS, Unix, and VMS
+ systems. For the most part, the interface to library routines has
+ been implemented in such a way that it appears to be platform
+ independent from the point of view of the application. In addition,
+ care has been taken to ensure that the routines are ``independent'' of
+ one another as much as possible. For example, although the keymap
+ routines require keyboard input, they are not tied to S-Lang's
+ keyboard input routines--- one can use a different keyboard getkey
+ routine if one desires. This also means that linking to only part of
+ the S-Lang library does not pull the whole library into the
+ application. Thus, S-Lang applications tend to be relatively small in
+ comparison to programs that use libraries with similar capabilities.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3. Interpreter Interface
+
+
+
+ The S-Lang library provides an interpreter that when embedded into an
+ application, makes the application extensible. Examples of programs
+ that embed the interpreter include the jed editor and the slrn
+ newsreader.
+
+ Embedding the interpreter is easy. The hard part is to decide what
+ application specific built-in or intrinsic functions should be
+ provided by the application. The S-Lang library provides some pre-
+ defined intrinsic functions, such as string processing functions, and
+ simple file input-output routines. However, the basic philosophy
+ behind the interpreter is that it is not a standalone program and it
+ derives much of its power from the application that embeds it.
+
+
+ 3.1. Embedding the Interpreter
+
+
+
+ Only one function needs to be called to embed the S-Lang interpreter
+ into an application: SLang_init_slang. This function initializes the
+ interpreter's data structures and adds some intrinsic functions:
+
+
+ if (-1 == SLang_init_slang ())
+ exit (EXIT_FAILURE);
+
+
+
+
+ This function does not provide file input output intrinsic nor does it
+ provide mathematical functions. To make these as well as some posix
+ system calls available use
+
+
+ if ((-1 == SLang_init_slang ()) /* basic interpreter functions */
+ || (-1 == SLang_init_slmath ()) /* sin, cos, etc... */
+ || (-1 == SLang_init_stdio ()) /* stdio file I/O */
+ || (-1 == SLang_init_posix_dir ()) /* mkdir, stat, etc. */
+ || (-1 == SLang_init_posix_process ()) /* getpid, umask, etc. */
+ )
+ exit (EXIT_FAILURE);
+
+
+
+
+ If you intend to enable all intrinsic functions, then it is simpler to
+ initialize the interpreter via
+
+
+ if (-1 == SLang_init_all ())
+ exit (EXIT_FAILURE);
+
+
+
+
+ See the \slang-run-time-library for more information about the intrin-
+ sic functions.
+
+
+
+
+
+ 3.2. Calling the Interpreter
+
+
+
+ There are several ways of calling the interpreter. The most common
+ method used by both jed and slrn is to use the SLang_load_file
+ function to interprete a file. For example, jed starts by loading a
+ file called site.sl:
+
+
+ if (-1 == SLang_load_file ("site.sl"))
+ {
+ SLang_restart (1);
+ SLang_Error = 0;
+ }
+
+
+
+
+ The SLang_load_file function returns zero upon if successful, or -1
+ upon failure. The SLang_restart function resets the interpreter back
+ to its default state; however, it does not reset SLang_Error to zero.
+ It is up to the application to re-initialize the SLang_Error variable.
+
+ There are several other mechanisms for interacting with the
+ interpreter. For example, the SLang_load_string function loads a
+ string into the interpreter and interprets it:
+
+
+ if (-1 == SLang_load_string ("message (\"hello\");"))
+ {
+ SLang_restart (1);
+ SLang_Error = 0;
+ }
+
+
+
+
+ Typically, an interactive application will load a file via
+ SLang_load_file and then go into a loop that consists of reading lines
+ of input and sending them to the interpreter, e.g.,
+
+
+ while (EOF != fgets (buf, sizeof (buf), stdin))
+ {
+ if (-1 == SLang_load_string (buf))
+ SLang_restart (1);
+ SLang_Error = 0;
+ }
+
+
+
+
+ Both jed and slrn use another method of interacting with the
+ interpreter. They read key sequences from the keyboard and map those
+ key sequences to interpreter functions via the S-Lang keymap
+ interface.
+
+
+
+ 3.3. Intrinsic Functions
+
+
+
+ An intrinsic function is simply a function that is written in C and is
+ made available to the interpreter as a built-in function. For this
+ reason, the words `intrinsic' and `built-in' are often used
+ interchangeably.
+
+ Applications are expected to add application specific functions to the
+ interpreter. For example, jed adds nearly 300 editor-specific
+ intrinsic functions. The application designer should think carefully
+ about what intrinsic functions to add to the interpreter.
+
+
+ 3.3.1. Restrictions on Intrinsic Functions
+
+
+
+ Intrinsic functions are required to follow a few rules to cooperate
+ with the interpreter.
+
+ Intrinsic function must take only pointer arguments. This is because
+ when the interpreter calls an intrinsic function, it passes value to
+ the function by reference and not by value. For example, intrinsic
+ with the declarations:
+
+
+ int intrinsic_0 (void);
+ int intrinsic_1 (char *s);
+ void intrinsic_2 (char *s, int *i);
+ void intrinsic_3 (int *i, double *d, double *e);
+
+
+
+
+ are all valid. However,
+
+
+ int invalid_1 (char *s, int len);
+
+
+
+
+ is not valid since the len parameter is not a pointer.
+
+ Intrinsic functions can only return void, int, double, or char *. A
+ function such as
+
+
+ int *invalid (void);
+
+
+
+
+ is not permitted since it does not return one of these types. The
+ current implementation limits the number of arguments to 7.
+
+ Another restriction is that the intrinsic should regard all its
+ parameters as pointers to constant objects and make no attempt to
+ modify the value to which they point. For example,
+
+
+ void truncate (char *s)
+ {
+ s[0] = 0;
+ }
+
+
+
+
+ is illegal since the function modifies the string s.
+ 3.3.2. Adding a New Intrinsic
+
+
+
+ There are two mechanisms for adding an intrinsic function to the
+ interpreter: SLadd_intrinsic_function and SLadd_intrin_fun_table.
+
+ As an specific example, consider a function that will cause the
+ program to exit via the exit C library function. It is not possible
+ to make this function an intrinsic because it does not meet the
+ specifications for an intrinsic function that were described earlier.
+ However, one can call exit from a function that is suitable, e.g.,
+
+
+ void intrin_exit (int *code)
+ {
+ exit (*code);
+ }
+
+
+
+
+ This function may be made available to the interpreter as as an
+ intrinsic via the SLadd_intrinsic_function routine:
+
+
+ if (-1 == SLadd_intrinsic_function ("exit", (FVOID_STAR) intrin_exit,
+ SLANG_VOID_TYPE, 1,
+ SLANG_INT_TYPE))
+ exit (EXIT_FAILURE);
+
+
+
+
+ This statement basically tells the interpreter that intrin_exit is a
+ function that returns nothing and takes a single argument: a pointer
+ to an integer (SLANG_INT_TYPE). A user can call this function from
+ within the interpreter via
+
+
+ message ("Calling the exit function");
+ exit (0);
+
+
+
+
+ After printing a message, this will cause the intrin_exit function to
+ execute, which in turn calls exit.
+
+ The most convenient mechanism for adding new intrinsic functions is to
+ create a table of SLang_Intrin_Fun_Type objects and add the table via
+ the SLadd_intrin_fun_table function. The table will look like:
+
+
+ SLang_Intrin_Fun_Type My_Intrinsics [] =
+ {
+ /* table entries */
+ MAKE_INTRINSIC_N(...),
+ MAKE_INTRINSIC_N(...),
+ .
+ .
+ MAKE_INTRINSIC_N(...),
+ SLANG_END_TABLE
+ };
+
+
+ Construction of the table entries may be facilitated using a set of
+ MAKE_INTRINSIC macros defined in slang.h. The main macro is called
+ MAKE_INTRINSIC_N and takes ?? arguments:
+
+
+ MAKE_INTRINSIC_N(name, funct-ptr, return-type, num-args,
+ arg-1-type, arg-2-type, ... arg-7-type)
+
+
+
+
+ Here name is the name of the intrinsic function that the interpreter
+ is to give to the function. func-ptr is a pointer to the intrinsic
+ function taking num-args and returning ret-type. The final 7 argu-
+ ments specifiy the argument types. For example, the intrin_exit
+ intrinsic described above may be added to the table using
+
+
+ MAKE_INTRINSIC_N("exit", intrin_exit, SLANG_VOID_TYPE, 1,
+ SLANG_INT_TYPE, 0,0,0,0,0,0)
+
+
+
+
+ While MAKE_INTRINSIC_N is the main macro for constructing table
+ entries, slang.h defines other macros that may prove useful. In
+ particular, an entry for the intrin_exit function may also be created
+ using any of the following forms:
+
+
+ MAKE_INTRINSIC_1("exit", intrin_exit, SLANG_VOID_TYPE, SLANG_INT_TYPE)
+ MAKE_INTRINSIC_I("exit", intrin_exit, SLANG_VOID_TYPE)
+
+
+
+
+ See slang.h for related macros. You are also encouraged to look at,
+ e.g., slang/src/slstd.c for a more extensive examples.
+
+ The table may be added via the SLadd_intrin_fun_table function, e.g.,
+
+
+ if (-1 == SLadd_intrin_fun_table (My_Intrinsics, NULL))
+ {
+ /* an error occurred */
+ }
+
+
+
+
+ Please note that there is no need to load a given table more than
+ once, and it is considered to be an error on the part of the applica-
+ tion it adds the same table multiple times. For performance reasons,
+ no checking is performed by the library to see if a table has already
+ been added.
+
+
+
+ 3.3.3. More Complicated Intrinsics
+
+
+ The intrinsic functions described in the previous example were
+ functions that took a fixed number of arguments. In this section we
+ explore more complex intrinsics such as those that take a variable
+ number of arguments.
+
+ Consider a function that takes two double precision numbers and
+ returns the lesser:
+
+
+ double intrin_min (double *a, double *b)
+ {
+ if (*a < *b) return *a;
+ return *b;
+ }
+
+
+
+
+ This function may be added to a table of intrinsics using
+
+
+ MAKE_INTRINSIC_2("min", intrin_min, SLANG_DOUBLE_TYPE,
+ SLANG_DOUBLE_TYPE, SLANG_DOUBLE_TYPE)
+
+
+
+
+ It is useful to extend this function to take an arbitray number of
+ arguments and return the lesser. Consider the following variant:
+
+
+ double intrin_min_n (int *num_ptr)
+ {
+ double min_value, x;
+ unsigned int num = (unsigned int) *num_ptr;
+
+ if (-1 == SLang_pop_double (&min_value, NULL, NULL))
+ return 0.0;
+ num--;
+
+ while (num > 0)
+ {
+ num--;
+ if (-1 == SLang_pop_double (&x, NULL, NULL))
+ return 0.0;
+ if (x < min_value) min_value = x;
+ }
+ return min_value;
+ }
+
+
+
+
+ Here the number to compare is passed to the function and the actual
+ numbers are removed from the stack via the SLang_pop_double function.
+ A suitable table entry for it is
+
+
+ MAKE_INTRINSIC_I("min", intrin_min_n, SLANG_DOUBLE_TYPE)
+
+
+
+
+ This function would be used in an interpreter script via a statement
+ such as
+
+
+ variable xmin = min (x0, x1, x2, x3, x4, 5);
+
+
+
+ which computes the smallest of 5 values.
+
+ The problem with this intrinsic function is that the user must
+ explicitly specify how many numbers to compare. It would be more
+ convenient to simply use
+
+
+ variable xmin = min (x0, x1, x2, x3, x4);
+
+
+
+
+ An intrinsic function can query the value of the variable
+ SLang_Num_Function_Args to obtain the necessary information:
+
+
+ double intrin_min (void)
+ {
+ double min_value, x;
+
+ unsigned int num = SLang_Num_Function_Args;
+
+ if (-1 == SLang_pop_double (&min_value, NULL, NULL))
+ return 0.0;
+ num--;
+
+ while (num > 0)
+ {
+ num--;
+ if (-1 == SLang_pop_double (&x, NULL, NULL))
+ return 0.0;
+ if (x < min_value) min_value = x;
+ }
+ return min_value;
+ }
+
+
+
+
+ This may be declared as an intrinsic using:
+
+
+ MAKE_INTRINSIC_0("min", intrin_min, SLANG_DOUBLE_TYPE)
+
+
+
+
+
+
+
+
+ 3.4. Intrinsic Variables
+
+
+
+ It is possible to access an application's global variables from within
+ the interpreter. The current implementation supports the access of
+ variables of type int, char *, and double.
+
+ There are two methods of making an intrinsic variable available to the
+ interpreter. The most straight forward method is to use the function
+ SLadd_intrinsic_variable:
+
+
+
+
+ int SLadd_intrinsic_variable (char *name, VOID_STAR addr,
+ unsigned char data_type,
+ int read_only);
+
+
+
+
+ For example, suppose that I is an integer variable, e.g.,
+
+
+ int I;
+
+
+
+
+ One can make it known to the interpreter as I_Variable via a statement
+ such as
+
+
+ if (-1 == SLadd_intrinsic_variable ("I_Variable", &I,
+ SLANG_INT_TYPE, 0))
+ exit (EXIT_FAILURE);
+
+
+
+
+ Similarly, if S is declared as
+
+
+ char *S;
+
+
+
+
+ then
+
+
+ if (-1 == SLadd_intrinsic_variable ("S_Variable", &S,
+ SLANG_STRING_TYPE, 1))
+ exit (EXIT_FAILURE);
+
+
+
+
+ makes S available as a read-only variable with the name S_Variable.
+ Note that if a pointer variable is made available to the interpreter,
+ its value is managed by the interpreter and not the application. For
+ this reason, it is recommended that such variables be declared as
+ read-only.
+
+ It is important to note that if S were declared as an array of
+ characters, e.g.,
+
+
+ char S[256];
+
+
+
+
+ then it would not be possible to make it directly available to the
+ interpreter. However, one could create a pointer to it, i.e.,
+
+
+ char *S_Ptr = S;
+
+
+ and make S_Ptr available as a read-only variable.
+
+ One should not make the mistake of trying to use the same address for
+ different variables as the following example illustrates:
+
+
+ int do_not_try_this (void)
+ {
+ static char *names[3] = {"larry", "curly", "moe"};
+ unsigned int i;
+
+ for (i = 0; i < 3; i++)
+ {
+ int value;
+ if (-1 == SLadd_intrinsic_variable (names[i], (VOID_STAR) &value,
+ SLANG_INT_TYPE, 1))
+ return -1;
+ }
+ return 0;
+ }
+
+
+
+
+ Not only does this piece of code create intrinsic variables that use
+ the same address, it also uses the address of a local variable that
+ will go out of scope.
+
+ The most convenient method for adding many intrinsic variables to the
+ interpreter is to create an array of SLang_Intrin_Var_Type objects and
+ then add the array via SLadd_intrin_var_table. For example, the array
+
+
+ static SLang_Intrin_Var_Type Intrin_Vars [] =
+ {
+ MAKE_VARIABLE("I_Variable", &I, SLANG_INT_TYPE, 0),
+ MAKE_VARIABLE("S_Variable", &S_Ptr, SLANG_STRING_TYPE, 1),
+ SLANG_END_TABLE
+ };
+
+
+
+
+ may be added via
+
+
+ if (-1 == SLadd_intrin_var_table (Intrin_Vars, NULL))
+ exit (EXIT_FAILURE);
+
+
+
+
+ It should be rather obvious that the arguments to the MAKE_VARIABLE
+ macro correspond to the parameters of the SLadd_intrinsic_variable
+ function.
+
+
+
+
+ 3.5. Aggregate Data Objects
+
+
+ An aggregate data object is an object that can contain more than one
+ data value. The S-Lang interpreter supports several such objects:
+ arrays, structure, and associative arrays. In the following sections,
+ information about interacting with these objects is given.
+ 3.5.1. Arrays
+
+
+ An intrinsic function may interact with an array in several different
+ ways. For example, an intrinsic may create an array and return it.
+ The basic functions for manipulating arrays include:
+
+
+ SLang_create_array
+ SLang_pop_array_of_type
+ SLang_push_array
+ SLang_free_array
+ SLang_get_array_element
+ SLang_set_array_element
+
+
+
+
+ The use of these functions will be illustrated via a few simple exam-
+ ples.
+
+ The first example shows how to create an return an array of strings to
+ the interpreter. In particular, the names of the four seasons of the
+ year will be returned:
+
+
+ void months_of_the_year (void)
+ {
+ static char *seasons[4] =
+ {
+ "Spring", "Summer", "Autumn", "Winter"
+ };
+ SLang_Array_Type *at;
+ int i, four;
+
+ four = 4;
+ at = SLang_create_array (SLANG_STRING_TYPE, 0, NULL, &four, 1);
+ if (at == NULL)
+ return;
+
+ /* Now set the elements of the array */
+ for (i = 0; i < 4; i++)
+ {
+ if (-1 == SLang_set_array_element (at, &i, &seasons[i]))
+ {
+ SLang_free_array (at);
+ return;
+ }
+ }
+
+ (void) SLang_push_array (at, 0);
+ SLang_free_array (at);
+ }
+
+
+
+
+ This example illustrates several points. First of all, the SLang_cre-
+ ate_array function was used to create a 1 dimensional array of 4
+ strings. Since this function could fail, its return value was
+ checked. Then the SLang_set_array_element function was used to set
+ the elements of the newly created array. Note that the address con-
+ taining the value of the array element was passed and not the value of
+ the array element itself. That is,
+
+
+ SLang_set_array_element (at, &i, seasons[i])
+
+
+
+
+ was not used. The return value from this function was also checked
+ because it too could also fail. Finally, the array was pushed onto
+ the interpreter's stack and then it was freed. It is important to
+ understand why it was freed. This is because arrays are reference-
+ counted. When the array was created, it was returned with a reference
+ count of 1. When it was pushed, the reference count was bumped up to
+ 2. Then since it was nolonger needed by the function,
+ SLang_free_array was called to decrement the reference count back to
+ 1. For convenience, the second argument to SLang_push_array deter-
+ mines whether or not it is to also free the array. So, instead of the
+ two function calls:
+
+
+ (void) SLang_push_array (at, 0);
+ SLang_free_array (at);
+
+
+
+
+ it is preferable to combine them as
+
+
+ (void) SLang_push_array (at, 1);
+
+
+
+
+ The second example returns a diagonal array of a specified size to the
+ stack. A diagonal array is a 2-d array with all elements zero except
+ for those along the diagonal, which have a value of one:
+
+
+ void make_diagonal_array (int n)
+ {
+ SLang_Array_Type *at;
+ int dims[2];
+ int i, one;
+
+ dims[0] = dims[1] = n;
+ at = SLang_create_array (SLANG_INT_TYPE, 0, NULL, dims, 2);
+ if (at == NULL)
+ return;
+
+ one = 1;
+ for (i = 0; i < n; i++)
+ {
+ dims[0] = dims[1] = i;
+ if (-1 == SLang_set_array_element (at, dims, &one))
+ {
+ SLang_free_array (at);
+ return;
+ }
+ }
+
+ (void) SLang_push_array (at, 1);
+ }
+
+
+
+
+ In this example, only the diagonal elements of the array were set.
+ This is bacause when the array was created, all its elements were set
+ to zero.
+
+ Now consider an example that acts upon an existing array. In
+ particular, consider one that computes the trace of a 2-d matrix,
+ i.e., the sum of the diagonal elements:
+
+
+ double compute_trace (void)
+ {
+ SLang_Array_Type *at;
+ double trace;
+ int dims[2];
+
+ if (-1 == SLang_pop_array_of_type (&at, SLANG_DOUBLE_TYPE))
+ return 0.0;
+
+ /* We want a 2-d square matrix. If the matrix is 1-d and has only one
+ element, then return that element. */
+ trace = 0.0;
+ if (((at->num_dims == 1) && (at->dims[0] == 1))
+ || ((at->num_dims == 2) && (at->dims[0] == at->dims[1])))
+ {
+ double dtrace;
+ int n = at->dims[0];
+
+ for (i = 0; i < n; i++)
+ {
+ dims[0] = dims[1] = i;
+ (void) SLang_get_array_element (at, &dims, &dtrace);
+ trace += dtrace;
+ }
+ }
+ else SLang_verror (SL_TYPE_MISMATCH, "Expecting a square matrix");
+
+ SLang_free_array (at);
+ return trace;
+ }
+
+
+
+
+ In this example, SLang_pop_array_of_type was used to pop an array of
+ doubles from the stack. This function will make implicit typecasts in
+ order to return an array of the requested type.
+
+
+
+ 3.5.2. Structures
+
+
+
+ For the purposes of this section, we shall differentiate structures
+ according to whether or not they correspond to an application defined
+ C structure. Those that do are called intrinsic structures, and those
+ do not are called S-Lang interpreter structures.
+
+
+ 3.5.2.1. Interpreter Structures
+
+
+ The following simple example shows how to create and return a
+ structure to the stack with a string an integer field:
+
+
+
+ int push_struct_example (char *string_value, int int_value)
+ {
+ char *field_names[2];
+ unsigned char field_types[2];
+ VOID_STAR field_values[2];
+
+ field_names[0] = "string_field";
+ field_types[0] = SLANG_STRING_TYPE;
+ field_values[0] = &string_value;
+
+ field_names[1] = "int_field";
+ field_types[1] = SLANG_INT_TYPE;
+ field_values[1] = &int_value;
+
+ if (-1 == SLstruct_create_struct (2, field_names,
+ field_types, field_values))
+ return -1;
+ return 0;
+ }
+
+
+
+
+ Here, SLstruct_create_struct was used to push a structure with the
+ specified field names and values onto the interpreter's stack.
+
+
+ 3.5.2.2. Intrinsic Structures
+
+
+ Here we show how to make intrinsic structures available to the
+ interpreter. The simplest interface is to structure pointers and not
+ to the actual structures themselves. The latter would require the
+ interpreter to be involved with the creation and destruction of the
+ structures. Dealing with the pointers themselves is far simpler.
+
+ As an example, consider an object such as
+
+
+ typedef struct _Window_Type
+ {
+ char *title;
+ int row;
+ int col;
+ int width;
+ int height;
+ } Window_Type;
+
+
+
+
+ which defines a window object with a title, size (width, height), and
+ location (row, col).
+
+ We can make variables of type Window_Type available to the interpreter
+ via a table as follows:
+
+
+
+
+
+
+
+
+
+
+ static SLang_IStruct_Field_Type Window_Type_Field_Table [] =
+ {
+ MAKE_ISTRUCT_FIELD(Window_Type, title, "title", SLANG_STRING_TYPE, 1),
+ MAKE_ISTRUCT_FIELD(Window_Type, row, "row", SLANG_INT_TYPE, 0),
+ MAKE_ISTRUCT_FIELD(Window_Type, col, "col", SLANG_INT_TYPE, 0),
+ MAKE_ISTRUCT_FIELD(Window_Type, width, "width", SLANG_INT_TYPE, 0),
+ MAKE_ISTRUCT_FIELD(Window_Type, height, "height", SLANG_INT_TYPE, 0),
+ SLANG_END_TABLE
+ };
+
+
+
+
+ More precisely, this defines the layout of the Window_Type structure.
+ Here, the title has been declared as a read-only field. Using
+
+
+ MAKE_ISTRUCT_FIELD(Window_Type, title, "title", SLANG_STRING_TYPE, 0),
+
+
+
+
+ would allow read-write access.
+
+ Now suppose that My_Window is a pointer to a Window_Type object, i.e.,
+
+
+ Window_Type *My_Window;
+
+
+
+
+ We can make this variable available to the interpreter via the
+ SLadd_istruct_table function:
+
+
+ if (-1 == SLadd_istruct_table (Window_Type_Field_Table,
+ (VOID_STAR) &My_Window,
+ "My_Window"))
+ exit (1);
+
+
+
+
+ This creates a S-Lang interpreter variable called My_Win whose value
+ corresponds to to the My_Win structure. This would permit one to
+ access the fields of My_Window via S-Lang statements such as
+
+
+ define set_width_and_height (w,h)
+ {
+ My_Win.width = w;
+ My_Win.height = h;
+ }
+
+
+
+
+ It is extremely important to understand that the interface described
+ in this section does not allow the interpreter to create new instances
+ of Window_Type objects. The interface merely defines an association
+ or correspondence between an intrinsic structure pointer and a S-Lang
+ variable. For example, if the value of My_Window is NULL, then My_Win
+ would also be NULL.
+
+
+ One should be careful in allowing read/write access to character
+ string fields. If read/write access is allowed, then the application
+ should always use the SLang_create_slstring and SLang_free_slstring
+ functions to set the character string field of the structure.
+ Finally, note that access to character array fields is not permitted
+ via this interface. That is, a structure such as
+
+
+ typedef struct
+ {
+ char name[32];
+ }
+ Name_Type;
+
+
+
+
+ is not permitted since char name[32] is not a SLANG_STRING_TYPE
+ object.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4. Keyboard Interface
+
+
+
+
+
+ S-Lang's keyboard interface has been designed to allow an application
+ to read keyboard input from the user in a system-independent manner.
+ The interface consists of a set of low routines for reading single
+ character data as well as a higher level interface (SLkp) which
+ utilize S-Lang's keymap facility for reading multi-character
+ sequences.
+
+ To initialize the interface, one must first call the function
+ SLang_init_tty. Before exiting the program, the function
+ SLang_reset_tty must be called to restore the keyboard interface to
+ its original state. Once initialized, the low-level SLang_getkey
+ function may be used to read simgle keyboard characters from the
+ terminal. An application using the the higher-level SLkp interface
+ will read charcters using the SLkp_getkey function.
+
+ In addition to these basic functions, there are also functions to
+ ``unget'' keyboard characters, flush the input, detect pending-input
+ with a timeout, etc. These functions are defined below.
+
+
+
+ 4.1. Initializing the Keyboard Interface
+
+
+
+ The function SLang_init_tty must be called to initialize the terminal
+ for single character input. This puts the terminal in a mode usually
+ referred to as ``raw'' mode.
+
+ The prototype for the function is:
+
+
+ int SLang_init_tty (int abort_char, int flow_ctrl, int opost);
+
+
+
+
+ It takes three parameters that are used to specify how the terminal is
+ to be initialized. %Although the S-Lang keyboard interface has been
+ %designed to be as system independent as possible, there are semantic
+ % differences.
+
+ The first parameter, abort_char, is used to specify the interrupt
+ character (SIGINT). Under MSDOS, this value corresponds to the scan
+ code of the character that will be used to generate the interrupt.
+ For example, under MSDOS, 34 should be used to make Ctrl-G generate an
+ interrupt signal since 34 is the scan code for G. On other systems,
+ the value of abort_char will simply be the ascii value of the control
+ character that will be used to generate the interrupt signal, e.g., 7
+ for Ctrl-G. If -1 is passed, the interrupt character will not be
+ changed.
+
+ Pressing the interrupt character specified by the first argument will
+ generate a signal (SIGINT) that may or not be caught by the
+ application. It is up to the application to catch this signal. S-
+ Lang provides the function Slang_set_abort_signal to make it easy to
+ facilitate this task.
+
+ The second parameter is used to specify whether or not flow control
+ should be used. If this parameter is zero, flow control is enabled
+ otherwise it is disabled. Disabling flow control is necessary to pass
+ certain characters to the application (e.g., Ctrl-S and Ctrl-Q). For
+ some systems such as MSDOS, this parameter is meaningless.
+
+ The third parameter, opost, is used to turn output processing on or
+ off. If opost is zero, output processing is not turned on otherwise,
+ output processing is turned on.
+
+ The SLang_init_tty function returns -1 upon failure. In addition,
+ after it returns, the S-Lang global variable SLang_TT_Baud_Rate will
+ be set to the baud rate of the terminal if this value can be
+ determined.
+
+ Example:
+
+
+ if (-1 == SLang_init_tty (7, 0, 0)) /* For MSDOS, use 34 as scan code */
+ {
+ fprintf (stderr, "Unable to initialize the terminal.\n");
+ exit (1);
+ }
+ SLang_set_abort_signal (NULL);
+
+
+
+
+ Here the terminal is initialized such that flow control and output
+ processing are turned off. In addition, the character Ctrl-G (-- For
+ MSDOS systems, use the scan code 34 instead of 7 for Ctrl-G--) has
+ been specified to be the interrupt character. The function
+ SLang_set_abort_signal is used to install the default S-Lang interrupt
+ signal handler.
+
+
+
+ 4.2. Resetting the Keyboard Interface
+
+
+
+ The function SLang_reset_tty must be called to reset the terminal to
+ the state it was in before the call to SLang_init_tty. The prototype
+ for this function is:
+
+
+ void SLang_reset_tty (void);
+
+
+
+
+ Usually this function is only called before the program exits. How-
+ ever, if the program is suspended it should also be called just before
+ suspension.
+
+
+
+ 4.3. Initializing the SLkp Routines
+
+
+
+ Extra initialization of the higher-level SLkp functions are required
+ because they are layered on top of the lower level routines. Since
+ the SLkp_getkey function is able to process function and arrow keys in
+ a terminal independent manner, it is necessary to call the
+ SLtt_get_terminfo function to get information about the escape
+ character sequences that the terminal's function keys send. Once that
+ information is available, the SLkp_init function can construct the
+ proper keymaps to process the escape sequences.
+
+ This part of the initialization process for an application using this
+ interface will look something like:
+
+
+
+ SLtt_get_terminfo ();
+ if (-1 == SLkp_init ())
+ {
+ SLang_doerror ("SLkp_init failed.");
+ exit (1);
+ }
+ if (-1 == SLang_init_tty (-1, 0, 1))
+ {
+ SLang_doerror ("SLang_init_tty failed.");
+ exit (1);
+ }
+
+
+
+
+ It is important to check the return status of the SLkp_init function
+ which can failed if it cannot allocate enough memory for the keymap.
+
+
+
+ 4.4. Setting the Interrupt Handler
+
+
+
+ The function SLang_set_abort_signal may be used to associate an
+ interrupt handler with the interrupt character that was previously
+ specified by the SLang_init_tty function call. The prototype for this
+ function is:
+
+
+ void SLang_set_abort_signal (void (*)(int));
+
+
+
+
+ This function returns nothing and takes a single parameter which is a
+ pointer to a function taking an integer value and returning void. If
+ a NULL pointer is passed, the default S-Lang interrupt handler will be
+ used. The S-Lang default interrupt handler under Unix looks like:
+
+
+ static void default_sigint (int sig)
+ {
+ SLsignal_intr (SIGINT, default_sigint);
+ SLKeyBoard_Quit = 1;
+ if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK;
+ }
+
+
+
+
+ It simply sets the global variable SLKeyBoard_Quit to one and if the
+ variable SLang_Ignore_User_Abort is non-zero, SLang_Error is set to
+ indicate a user break condition. (The function SLsignal_intr is simi-
+ lar to the standard C signal function except that it will interrupt
+ system calls. Some may not like this behavior and may wish to call
+ this SLang_set_abort_signal with a different handler.)
+
+
+ Although the function expressed above is specific to Unix, the
+ analogous routines for other operating systems are equivalent in
+ functionality even though the details of the implementation may vary
+ drastically (e.g., under MSDOS, the hardware keyboard interrupt int 9h
+ is hooked).
+
+
+
+ 4.5. Reading Keyboard Input with SLang_getkey
+
+
+
+ After initializing the keyboard via SLang_init_tty, the S-Lang
+ function SLang_getkey may be used to read characters from the terminal
+ interface. In addition, the function SLang_input_pending may be used
+ to determine whether or not keyboard input is available to be read.
+
+ These functions have prototypes:
+
+
+ unsigned int SLang_getkey (void);
+ int SLang_input_pending (int tsecs);
+
+
+
+
+ The SLang_getkey function returns a single character from the termi-
+ nal. Upon failure, it returns 0xFFFF. If the interrupt character
+ specified by the SLang_init_tty function is pressed while this func-
+ tion is called, the function will return the value of the interrupt
+ character and set the S-Lang global variable SLKeyBoard_Quit to a non-
+ zero value. In addition, if the default S-Lang interrupt handler has
+ been specified by a NULL argument to the SLang_set_abort_signal func-
+ tion, the global variable SLang_Error will be set to USER_BREAK unless
+ the variable SLang_Ignore_User_Abort is non-zero.
+
+ The SLang_getkey function waits until input is available to be read.
+ The SLang_input_pending function may be used to determine whether or
+ not input is ready. It takes a single parameter that indicates the
+ amount of time to wait for input before returning with information
+ regarding the availability of input. This parameter has units of one
+ tenth (1/10) of a second, i.e., to wait one second, the value of the
+ parameter should be 10. Passing a value of zero causes the function
+ to return right away. SLang_input_pending returns a positive integer
+ if input is available or zero if input is not available. It will
+ return -1 if an error occurs.
+
+ Here is a simple example that reads keys from the terminal until one
+ presses Ctrl-G or until 5 seconds have gone by with no input:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #include <stdio.h>
+ #include "slang.h"
+ int main ()
+ {
+ int abort_char = 7; /* For MSDOS, use 34 as scan code */
+ unsigned int ch;
+
+ if (-1 == SLang_init_tty (abort_char, 0, 1))
+ {
+ fprintf (stderr, "Unable to initialize the terminal.\n");
+ exit (-1);
+ }
+ SLang_set_abort_signal (NULL);
+ while (1)
+ {
+ fputs ("\nPress any key. To quit, press Ctrl-G: ", stdout);
+ fflush (stdout);
+ if (SLang_input_pending (50) == 0) /* 50/10 seconds */
+ {
+ fputs ("Waited too long! Bye\n", stdout);
+ break;
+ }
+
+ ch = SLang_getkey ();
+ if (SLang_Error == USER_BREAK)
+ {
+ fputs ("Ctrl-G pressed! Bye\n", stdout);
+ break;
+ }
+ putc ((int) ch, stdout);
+ }
+ SLang_reset_tty ();
+ return 0;
+ }
+
+
+
+
+
+
+
+ 4.6. Reading Keyboard Input with SLkp_getkey
+
+
+
+ Unlike the low-level function SLang_getkey, the SLkp_getkey function
+ can read a multi-character sequence associated with function keys.
+ The SLkp_getkey function uses SLang_getkey and S-Lang's keymap
+ facility to process escape sequences. It returns a single integer
+ which describes the key that was pressed:
+
+
+ int SLkp_getkey (void);
+
+
+
+
+ That is, the SLkp_getkey function simple provides a mapping between
+ keys and integers. In this context the integers are called keysyms.
+
+ For single character input such as generated by the a key on the
+ keyboard, the function returns the character that was generated, e.g.,
+ 'a'. For single characters, SLkp_getkey will always return an keysym
+ whose value ranges from 0 to 256. For keys that generate multiple
+ character sequences, e.g., a function or arrow key, the function
+ returns an keysym whose value is greater that 256. The actual values
+ of these keysyms are represented as macros defined in the slang.h
+ include file. For example, the up arrow key corresponds to the keysym
+ whose value is SL_KEY_UP.
+
+ Since it is possible for the user to enter a character sequence that
+ does not correspond to any key. If this happens, the special keysym
+ SL_KEY_ERR will be returned.
+
+ Here is an example of how SLkp_getkey may be used by a file viewer:
+
+
+ switch (SLkp_getkey ())
+ {
+ case ' ':
+ case SL_KEY_NPAGE:
+ next_page ();
+ break;
+ case 'b':
+ case SL_KEY_PPAGE:
+ previous_page ();
+ break;
+ case '\r':
+ case SL_KEY_DOWN:
+ next_line ();
+ break;
+ .
+ .
+ case SL_KEY_ERR:
+ default:
+ SLtt_beep ();
+ }
+
+
+
+
+ Unlike its lower-level counterpart, SLang_getkey, there do not yet
+ exist any functions in the library that are capable of ``ungetting''
+ keysyms. In particular, the SLang_ungetkey function will not work.
+
+
+
+ 4.7. Buffering Input
+
+
+
+ S-Lang has several functions pushing characters back onto the input
+ stream to be read again later by SLang_getkey. It should be noted
+ that none of the above functions are designed to push back keysyms
+ read by the SLkp_getkey function. These functions are declared as
+ follows:
+
+
+ void SLang_ungetkey (unsigned char ch);
+ void SLang_ungetkey_string (unsigned char *buf, int buflen);
+ void SLang_buffer_keystring (unsigned char *buf, int buflen);
+
+
+
+
+ SLang_ungetkey is the most simple of the three functions. It takes a
+ single character a pushes it back on to the input stream. The next
+ call to SLang_getkey will return this character. This function may be
+ used to peek at the character to be read by first reading it and then
+ putting it back.
+
+
+ SLang_ungetkey_string has the same function as SLang_ungetkey except
+ that it is able to push more than one character back onto the input
+ stream. Since this function can push back null (ascii 0) characters,
+ the number of characters to push is required as one of the parameters.
+
+ The last of these three functions, SLang_buffer_keystring can handle
+ more than one charater but unlike the other two, it places the
+ characters at the end of the keyboard buffer instead of at the
+ beginning.
+
+ Note that the use of each of these three functions will cause
+ SLang_input_pending to return right away with a non-zero value.
+
+ Finally, the S-Lang keyboard interface includes the function
+ SLang_flush_input with prototype
+
+
+ void SLang_flush_input (void);
+
+
+
+
+ It may be used to discard all input.
+
+ Here is a simple example that looks to see what the next key to be
+ read is if one is available:
+
+
+ int peek_key ()
+ {
+ int ch;
+ if (SLang_input_pending (0) == 0) return -1;
+ ch = SLang_getkey ();
+ SLang_ungetkey (ch);
+ return ch;
+ }
+
+
+
+
+
+
+
+ 4.8. Global Variables
+
+
+ Although the following S-Lang global variables have already been
+ mentioned earlier, they are gathered together here for completeness.
+
+ int SLang_Ignore_User_Abort; If non-zero, pressing the interrupt
+ character will not result in SLang_Error being set to USER_BREAK.
+
+ volatile int SLKeyBoard_Quit; This variable is set to a non-zero value
+ when the interrupt character is pressed. If the interrupt character is
+ pressed when SLang_getkey is called, the interrupt character will be
+ returned from SLang_getkey.
+
+ int SLang_TT_Baud_Rate; On systems which support it, this variable is
+ set to the value of the terminal's baud rate after the call to
+ SLang_init_tty.
+
+
+
+
+
+
+ 5. Screen Management
+
+
+
+ The S-Lang library provides two interfaces to terminal independent
+ routines for manipulating the display on a terminal. The highest
+ level interface, known as the SLsmg interface is discussed in this
+ section. It provides high level screen management functions more
+ manipulating the display in an optimal manner and is similar in spirit
+ to the curses library. The lowest level interface, or the SLtt
+ interface, is used by the SLsmg routines to actually perform the task
+ of writing to the display. This interface is discussed in another
+ section. Like the keyboard routines, the SLsmg routines are platform
+ independent and work the same on MSDOS, OS/2, Unix, and VMS.
+
+ The screen management, or SLsmg, routines are initialized by function
+ SLsmg_init_smg. Once initialized, the application uses various SLsmg
+ functions to write to a virtual display. This does not cause the
+ physical terminal display to be updated immediately. The physical
+ display is updated to look like the virtual display only after a call
+ to the function SLsmg_refresh. Before exiting, the application using
+ these routines is required to call SLsmg_reset_smg to reset the
+ display system.
+
+ The following subsections explore S-Lang's screen management system in
+ greater detail.
+
+
+ 5.1. Initialization
+
+
+ The function SLsmg_init_smg must be called before any other SLsmg
+ function can be used. It has the simple prototype:
+
+
+ int SLsmg_init_smg (void);
+
+
+
+
+ It returns zero if successful or -1 if it cannot allocate space for
+ the virtual display.
+
+ For this routine to properly initialize the virtual display, the
+ capabilities of the terminal must be known as well as the size of the
+ physical display. For these reasons, the lower level SLtt routines
+ come into play. In particular, before the first call to
+ SLsmg_init_smg, the application is required to call the function
+ SLtt_get_terminfo before calling SLsmg_init_smg.
+
+ The SLtt_get_terminfo function sets the global variables
+ SLtt_Screen_Rows and SLtt_Screen_Cols to the values appropriate for
+ the terminal. It does this by calling the SLtt_get_screen_size
+ function to query the terminal driver for the appropriate values for
+ these variables. From this point on, it is up to the application to
+ maintain the correct values for these variables by calling the
+ SLtt_get_screen_size function whenever the display size changes, e.g.,
+ in response to a SIGWINCH signal. Finally, if the application is going
+ to read characters from the keyboard, it is also a good idea to
+ initialize the keyboard routines at this point as well.
+
+
+ 5.2. Resetting SLsmg
+
+
+
+ Before the program exits or suspends, the function SLsmg_reset_tty
+ should be called to shutdown the display system. This function has
+ the prototype
+
+
+ void SLsmg_reset_smg (void);
+
+
+
+
+ This will deallocate any memory allocated for the virtual screen and
+ reset the terminal's display.
+
+ Basically, a program that uses the SLsmg screen management functions
+ and S-Lang's keyboard interface will look something like:
+
+
+ #include "slang.h"
+ int main ()
+ {
+ SLtt_get_terminfo ();
+ SLang_init_tty (-1, 0, 0);
+ SLsmg_init_smg ();
+
+ /* do stuff .... */
+
+ SLsmg_reset_smg ();
+ SLang_reset_tty ();
+ return 0;
+ }
+
+
+
+
+ If this program is compiled and run, all it will do is clear the
+ screen and position the cursor at the bottom of the display. In the
+ following sections, other SLsmg functions will be introduced which may
+ be used to make this simple program do much more.
+
+
+ 5.3. Handling Screen Resize Events
+
+ The function SLsmg_reinit_smg is designed to be used in conjunction
+ with resize events.
+
+ Under Unix-like operating systems, when the size of the display
+ changes, the application will be sent a SIGWINCH signal. To properly
+ handle this signal, the SLsmg routines must be reinitialized to use
+ the new display size. This may be accomplished by calling
+ SLtt_get_screen_size to get the new size, followed by SLsmg_reinit_smg
+ to reinitialize the SLsmg interface to use the new size. Keep in mind
+ that these routines should not be called from within the signal
+ handler. The following code illustrates the main ideas involved in
+ handling such events:
+
+
+
+
+
+
+
+
+
+
+
+
+ static volatile int Screen_Size_Changed;
+ static sigwinch_handler (int sig)
+ {
+ Screen_Size_Changed = 1;
+ SLsignal (SIGWINCH, sigwinch_handler);
+ }
+
+ int main (int argc, char **argv)
+ {
+ SLsignal (SIGWINCH, sigwinch_handler);
+ SLsmg_init_smg ();
+ .
+ .
+ /* Now enter main loop */
+ while (not_done)
+ {
+ if (Screen_Size_Changed)
+ {
+ SLtt_get_screen_size ();
+ SLsmg_reinit_smg ();
+ redraw_display ();
+ }
+ .
+ .
+ }
+ return 0;
+ }
+
+
+
+
+
+
+ 5.4. SLsmg Functions
+
+
+
+ In the previous sections, functions for initializing and shutting down
+ the SLsmg routines were discussed. In this section, the rest of the
+ SLsmg functions are presented. These functions act only on the
+ virtual display. The physical display is updated when the
+ SLsmg_refresh function is called and not until that time. This
+ function has the simple prototype:
+
+
+ void SLsmg_refresh (void);
+
+
+
+
+
+ 5.4.1. Positioning the cursor
+
+
+ The SLsmg_gotorc function is used to position the cursor at a given
+ row and column. The prototype for this function is:
+
+
+ void SLsmg_gotorc (int row, int col);
+
+
+
+
+ The origin of the screen is at the top left corner and is given the
+ coordinate (0, 0), i.e., the top row of the screen corresponds to row
+ = 0 and the first column corresponds to col = 0. The last row of the
+ screen is given by row = SLtt_Screen_Rows - 1.
+
+ It is possible to change the origin of the coordinate system by using
+ the function SLsmg_set_screen_start with prototype:
+
+
+ void SLsmg_set_screen_start (int *r, int *c);
+
+
+
+
+ This function takes pointers to the new values of the first row and
+ first column. It returns the previous values by modifying the values
+ of the integers at the addresses specified by the parameter list. A
+ NULL pointer may be passed to indicate that the origin is to be set to
+ its initial value of 0. For example,
+
+
+ int r = 10;
+ SLsmg_set_screen_start (&r, NULL);
+
+
+
+
+ sets the origin to (10, 0) and after the function returns, the vari-
+ able r will have the value of the previous row origin.
+
+
+ 5.4.2. Writing to the Display
+
+
+ SLsmg has several routines for outputting text to the virtual display.
+ The following points should be understood:
+
+ o The text is output at the position of the cursor of the virtual
+ display and the cursor is advanced to the position that corresponds
+ to the end of the text.
+
+
+ o Text does not wrap at the boundary of the display--- it is
+ trucated. This behavior seems to be more useful in practice since
+ most programs that would use screen management tend to be line
+ oriented.
+
+
+ o Control characters are displayed in a two character sequence
+ representation with ^ as the first character. That is, Ctrl-X is
+ output as ^X.
+
+
+ o The newline character does not cause the cursor to advance to the
+ next row. Instead, when a newline character is encountered when
+ outputting text, the output routine will return. That is,
+ outputting a string containing a newline character will only
+ display the contents of the string up to the newline character.
+
+
+ Although the some of the above items might appear to be too
+ restrictive, in practice this is not seem to be the case. In fact,
+ the design of the output routines was influenced by their actual use
+ and modified to simplify the code of the application utilizing them.
+
+ void SLsmg_write_char (char ch); Write a single character to the
+ virtual display.
+
+
+ void SLsmg_write_nchars (char *str, int len); Write len characters
+ pointed to by str to the virtual display.
+
+ void SLsmg_write_string (char *str); Write the null terminated string
+ given by pointer str to the virtual display. This function is a
+ wrapper around SLsmg_write_nchars.
+
+ void SLsmg_write_nstring (char *str, int n); Write the null terminated
+ string given by pointer str to the virtual display. At most, only n
+ characters are written. If the length of the string is less than n,
+ then the string will be padded with blanks. This function is a
+ wrapper around SLsmg_write_nchars.
+
+ void SLsmg_printf (char *fmt, ...); This function is similar to printf
+ except that it writes to the SLsmg virtual display.
+
+ void SLsmg_vprintf (char *, va_list); Like SLsmg_printf but uses a
+ variable argument list.
+
+
+ 5.4.3. Erasing the Display
+
+
+ The following functions may be used to fill portions of the display
+ with blank characters. The attributes of blank character are the
+ current attributes. (See below for a discussion of character
+ attributes)
+
+ void SLsmg_erase_eol (void); Erase line from current position to the
+ end of the line.
+
+ void SLsmg_erase_eos (void); Erase from the current position to the
+ end of the screen.
+
+ void SLsmg_cls (void); Clear the entire virtual display.
+
+
+ 5.4.4. Setting Character Attributes
+
+
+ Character attributes define the visual characteristics the character
+ possesses when it is displayed. Visual characteristics include the
+ foreground and background colors as well as other attributes such as
+ blinking, bold, and so on. Since SLsmg takes a different approach to
+ this problem than other screen management libraries an explanation of
+ this approach is given here. This approach has been motivated by
+ experience with programs that require some sort of screen management.
+
+ Most programs that use SLsmg are composed of specific textual objects
+ or objects made up of line drawing characters. For example, consider
+ an application with a menu bar with drop down menus. The menus might
+ be enclosed by some sort of frame or perhaps a shadow. The basic idea
+ is to associate an integer to each of the objects (e.g., menu bar,
+ shadow, current menu item, etc.) and create a mapping from the integer
+ to the set of attributes. In the terminology of SLsmg, the integer is
+ simply called an object.
+
+ For example, the menu bar might be associated with the object 1, the
+ drop down menu could be object 2, the shadow could be object 3, and so
+ on.
+
+ The range of values for the object integer is restricted from 0 up to
+ and including 255 on all systems except MSDOS where the maximum
+ allowed integer is 15 (-- This difference is due to memory constraints
+ imposed by MSDOS. This restriction might be removed in a future
+ version of the library.--) . The object numbered zero should not be
+ regarding as an object at all. Rather it should be regarded as all
+ other objects that have not explicitly been given an object number.
+ SLsmg, or more precisely SLtt, refers to the attributes of this
+ special object as the default or normal attributes.
+
+ The SLsmg routines know nothing about the mapping of the color to the
+ attributes associated with the color. The actual mapping takes place
+ at a lower level in the SLtt routines. Hence, to map an object to the
+ actual set of attributes requires a call to any of the following SLtt
+ routines:
+
+
+ void SLtt_set_color (int obj, char *name, char *fg, char *bg);
+ void SLtt_set_color_object (int obj, SLtt_Char_Type attr);
+ void SLtt_set_mono (int obj, char *, SLtt_Char_Type attr);
+
+
+
+
+ Only the first of these routines will be discussed briefly here. The
+ latter two functions allow more fine control over the object to
+ attribute mapping (such as assigning a ``blink'' attribute to the
+ object). For a more full explanation on all of these routines see the
+ section about the SLtt interface.
+
+ The SLtt_set_color function takes four parameters. The first
+ parameter, obj, is simply the integer of the object for which
+ attributes are to be assigned. The second parameter is currently
+ unused by these routines. The third and forth parameters, fg and bg,
+ are the names of the foreground and background color to be used
+ associated with the object. The strings that one can use for the
+ third and fourth parameters can be any one of the 16 colors:
+
+
+ "black" "gray"
+ "red" "brightred"
+ "green" "brightgreen"
+ "brown" "yellow"
+ "blue" "brightblue"
+ "magenta" "brightmagenta"
+ "cyan" "brightcyan"
+ "lightgray" "white"
+
+
+
+
+ The value of the foreground parameter fg can be anyone of these six-
+ teen colors. However, on most terminals, the background color will
+ can only be one of the colors listed in the first column (-- This is
+ also true on the Linux console. However, it need not be the case and
+ hopefully the designers of Linux will someday remove this restric-
+ tion.--) .
+
+ Of course not all terminals are color terminals. If the S-Lang global
+ variable SLtt_Use_Ansi_Colors is non-zero, the terminal is assumed to
+ be a color terminal. The SLtt_get_terminfo will try to determine
+ whether or not the terminal supports colors and set this variable
+ accordingly. It does this by looking for the capability in the
+ terminfo/termcap database. Unfortunately many Unix databases lack
+ this information and so the SLtt_get_terminfo routine will check
+ whether or not the environment variable COLORTERM exists. If it
+ exists, the terminal will be assumed to support ANSI colors and
+ SLtt_Use_Ansi_Colors will be set to one. Nevertheless, the
+ application should provide some other mechanism to set this variable,
+ e.g., via a command line parameter.
+
+ When the SLtt_Use_Ansi_Colors variable is zero, all objects with
+ numbers greater than one will be displayed in inverse video (-- This
+ behavior can be modified by using the SLtt_set_mono function call.--)
+ .
+
+ With this background, the SLsmg functions for setting the character
+ attributes can now be defined. These functions simply set the object
+ attributes that are to be assigned to subsequent characters written to
+ the virtual display. For this reason, the new attribute is called the
+ current attribute.
+
+ void SLsmg_set_color (int obj); Set the current attribute to those of
+ object obj.
+
+ void SLsmg_normal_video (void); This function is equivalent to
+ SLsmg_set_color (0).
+
+ void SLsmg_reverse_video (void); This function is equivalent to
+ SLsmg_set_color (1). On monochrome terminals, it is equivalent to
+ setting the subsequent character attributes to inverse video.
+
+ Unfortunately there does not seem to be a standard way for the
+ application or, in particular, the library to determine which color
+ will be used by the terminal for the default background. Such
+ information would be useful in initializing the foreground and
+ background colors associated with the default color object (0). FOr
+ this reason, it is up to the application to provide some means for the
+ user to indicate what these colors are for the particular terminal
+ setup. To facilitate this, the SLtt_get_terminfo function checks for
+ the existence of the COLORFGBG environment variable. If this variable
+ exists, its value will be used to initialize the colors associated
+ with the default color object. Specifically, the value is assumed to
+ consist of a foreground color name and a background color name
+ separated by a semicolon. For example, if the value of COLORTERM is
+ lightgray;blue, the default color object will be initialized to
+ represent a lightgray foreground upon a blue background.
+
+
+ 5.4.5. Lines and Alternate Character Sets
+
+ The S-Lang screen management library also includes routines for
+ turning on and turning off alternate character sets. This is
+ especially useful for drawing horizontal and vertical lines.
+
+ void SLsmg_set_char_set (int flag); If flag is non-zero, subsequent
+ write functions will use characters from the alternate character set.
+ If flag is zero, the default, or, ordinary character set will be used.
+
+ void SLsmg_draw_hline (int len); Draw a horizontal line from the
+ current position to the column that is len characters to the right.
+
+ void SLsmg_draw_vline (int len); Draw a horizontal line from the
+ current position to the row that is len rows below.
+
+ void SLsmg_draw_box (int r, int c, int dr, int dc); Draw a box whose
+ upper right corner is at row r and column c. The box spans dr rows
+ and dc columns. The current position will be left at row r and column
+ c.
+
+
+ 5.4.6. Miscellaneous Functions
+
+
+ void SLsmg_touch_lines (int r, int n); Mark screen rows numbered r, r
+ + 1, ... r + (n - 1) as modified. When SLsmg_refresh is called, these
+ rows will be completely redrawn.
+ unsigned short SLsmg_char_at(void); Returns the character and its
+ attributes object number at the current cursor position. The
+ character itself occupies the lower byte and the object attributes
+ number forms the upper byte. The object returned by this function
+ call should not be written back out via any of the functions that
+ write characters or character strings.
+
+
+
+
+ 5.5. Variables
+
+
+
+ The following S-Lang global variables are used by the SLsmg interface.
+ Some of these have been previously discussed.
+
+ int SLtt_Screen_Rows; int SLtt_Screen_Cols; The number of rows and
+ columns of the physical display. If either of these numbers changes,
+ the functions SLsmg_reset_smg and SLsmg_init_smg should be called
+ again so that the SLsmg routines can re-adjust to the new size.
+
+ int SLsmg_Tab_Width; Set this variable to the tab width that will be
+ used when expanding tab characters. The default is 8.
+
+ int SLsmg_Display_Eight_Bit This variable determines how characters
+ with the high bit set are to be output. Specifically, a character
+ with the high bit set with a value greater than or equal to this value
+ is output as is; otherwise, it will be output in a 7-bit
+ representation. The default value for this variable is 128 for MSDOS
+ and 160 for other systems (ISO-Latin).
+
+ int SLtt_Use_Ansi_Colors; If this value is non-zero, the terminal is
+ assumed to support ANSI colors otherwise it is assumed to be
+ monochrome. The default is 0.
+
+ int SLtt_Term_Cannot_Scroll; If this value is zero, the SLsmg will
+ attempt to scroll the physical display to optimize the update. If it
+ is non-zero, the screen management routines will not perform this
+ optimization. For some applications, this variable should be set to
+ zero. The default value is set by the SLtt_get_terminfo function.
+
+
+
+ 5.6. Hints for using SLsmg
+
+
+ This section discusses some general design issues that one must face
+ when writing an application that requires some sort of screen
+ management.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 6. Signal Functions
+
+
+
+ Almost all non-trivial programs must worry about signals. This is
+ especially true for programs that use the S-Lang terminal input/output
+ and screen management routines. Unfortunately, there is no fixed way
+ to handle signals; otherwise, the Unix kernel would take care of all
+ issues regarding signals and the application programmer would never
+ have to worry about them. For this reason, none of the routines in
+ the S-Lang library catch signals; however, some of the routines block
+ the delivery of signals during crucial moments. It is up to the
+ application programmer to install handlers for the various signals of
+ interest.
+
+ For the interpreter, the most important signal to worry about is
+ SIGINT. This signal is usually generated when the user presses Ctrl-C
+ at the keyboard. The interpreter checks the value of the SLang_Error
+ variable to determine whether or not it should abort the interpreting
+ process and return control back to the application. This means that
+ if SIGINT is to be used to abort the interpreter, a signal handler for
+ SIGINT should be installed. The handler should set the value of
+ SLang_Error to SL_USER_BREAK.
+
+ Applications that use the tty getkey routines or the screen management
+ routines must worry about about signals such as:
+
+
+ SIGINT interrupt
+ SIGTSTP stop
+ SIGQUIT quit
+ SIGTTOU background write
+ SIGTTIN background read
+ SIGWINCH window resize
+
+
+
+
+ It is important that handlers be established for these signals while
+ the either the SLsmg routines or the getkey routines are initialized.
+ The SLang_init_tty, SLang_reset_tty, SLsmg_init_smg, and
+ SLsmg_reset_smg functions block these signals from occuring while they
+ are being called.
+
+ Since a signal can be delivered at any time, it is important for the
+ signal handler to call only functions that can be called from a signal
+ handler. This usually means that such function must be re-entrant. In
+ particular, the SLsmg routines are not re-entrant; hence, they should
+ not be called when a signal is being processed unless the application
+ can ensure that the signal was not delivered while an SLsmg function
+ was called. This statement applies to many other functions such as
+ malloc, or, more generally, any function that calls malloc. The
+ upshot is that the signal handler should not attempt to do too much
+ except set a global variable for the application to look at while not
+ in a signal handler.
+
+ The S-Lang library provides two functions for blocking and unblocking
+ the above signals:
+
+
+ int SLsig_block_signals (void);
+ int SLsig_unblock_signals (void);
+
+
+
+
+ It should be noted that for every call to SLsig_block_signals, a cor-
+ responding call should be made to SLsig_unblock_signals, e.g.,
+
+
+ void update_screen ()
+ {
+ SLsig_block_signals ();
+
+ /* Call SLsmg functions */
+ .
+ .
+ SLsig_unblock_signals ();
+ }
+
+
+
+
+ See demo/pager.c for examples.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 7. Searching Functions
+
+
+
+ The S-Lang library incorporates two types of searches: Regular
+ expression pattern matching and ordinary searching.
+
+
+ 7.1. Regular Expressions
+
+
+
+ !!! No documentation available yet !!!
+
+
+
+ 7.2. Simple Searches
+
+
+ The routines for ordinary searching are defined in the slsearch.c
+ file. To use these routines, simply include "slang.h" in your program
+ and simply call the appropriate routines.
+
+ The searches can go in either a forward or backward direction and can
+ either be case or case insensitive. The region that is searched may
+ contain null characters (ASCII 0) however, the search string cannot in
+ the current implementation. In addition the length of the string to
+ be found is currently limited to 256 characters.
+
+ Before searching, the function SLsearch_init must first be called to
+ `preprocess' the search string.
+
+
+
+ 7.3. Initialization
+
+
+ The function SLsearch_init must be called before a search can take
+ place. Its prototype is:
+
+
+ int SLsearch_init (char *key, int dir, int case_sens, SLsearch_Type *st);
+
+
+
+
+ Here key is the string to be searched for. dir specifies the direc-
+ tion of the search: a value greater than zero is used for searching
+ forward and a value less than zero is used for searching backward.
+ The parameter case_sens specifies whether the search is case sensitive
+ or not. A non-zero value indicates that case is important. st is a
+ pointer to a structure of type SLsearch_Type defined in "slang.h".
+ This structure is initialized by this routine and must be passed to
+ SLsearch when the search is actually performed.
+
+ This routine returns the length of the string to be searched for.
+
+
+
+ 7.4. SLsearch
+
+
+
+
+
+
+ Prototype: unsigned char *SLsearch (unsigned char *pmin,
+ unsigned char *pmax,
+ SLsearch_Type *st);
+
+
+
+
+ This function performs the search defined by a previous call to
+ SLsearch_init over a region specified by the pointers pmin and pmax.
+
+ It returns a pointer to the start of the match if successful or it
+ will return NULL if a match was not found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ H. Copyright
+
+ The S-Lang library is distributed under two copyrights: the GNU Genral
+ Public License, and the Artistic License. Any program that uses the
+ interpreter must adhere to rules of one of these licenses.
+
+
+ H.1. The GNU Public License
+
+
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+
+
+
+ The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License
+ is intended to guarantee your freedom to share and change free soft-
+ ware--to make sure the software is free for all its users. This Gen-
+ eral Public License applies to most of the Free Software Foundation's
+ software and to any other program whose authors commit to using it.
+ (Some other Free Software Foundation software is covered by the GNU
+ Library General Public License instead.) You can apply it to your
+ programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it
+ in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if
+ you distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+ (2) offer you this license which gives you legal permission to copy,
+ distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on,
+ we want its recipients to know that what they have is not the
+ original, so that any problems introduced by others will not reflect
+ on the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary. To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at
+ all.
+
+ The precise terms and conditions for copying, distribution and
+ modification follow.
+
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+
+
+
+ 0. This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The "Program", below,
+ refers to any such program or work, and a "work based on the Program"
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term "modification".) Each licensee is addressed as "you".
+
+ Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of
+ running the Program is not restricted, and the output from the Program
+ is covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether
+ that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+
+ You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a
+ fee.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above,
+ provided that you also meet all of these conditions:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+
+
+
+ These requirements apply to the modified work as a whole. If identi-
+ fiable sections of that work are not derived from the Program, and can
+ be reasonably considered independent and separate works in themselves,
+ then this License, and its terms, do not apply to those sections when
+ you distribute them as separate works. But when you distribute the
+ same sections as part of a whole which is a work based on the Program,
+ the distribution of the whole must be on the terms of this License,
+ whose permissions for other licensees extend to the entire whole, and
+ thus to each and every part regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.
+
+ In addition, mere aggregation of another work not based on the Program
+ with the Program (or with a work based on the Program) on a volume of
+ a storage or distribution medium does not bring the other work under
+ the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+
+
+ The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to con-
+ trol compilation and installation of the executable. However, as a
+ special exception, the source code distributed need not include any-
+ thing that is normally distributed (in either source or binary form)
+ with the major components (compiler, kernel, and so on) of the operat-
+ ing system on which the executable runs, unless that component itself
+ accompanies the executable.
+
+ If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+ void, and will automatically terminate your rights under this License.
+ However, parties who have received copies, or rights, from you under
+ this License will not have their licenses terminated so long as such
+ parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying
+ the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions. You may not impose any further
+ restrictions on the recipients' exercise of the rights granted herein.
+ You are not responsible for enforcing compliance by third parties to
+ this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent
+ license would not permit royalty-free redistribution of the Program by
+ all those who receive copies directly or indirectly through you, then
+ the only way you could satisfy both it and this License would be to
+ refrain entirely from distribution of the Program.
+
+ If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made
+ generous contributions to the wide range of software distributed
+ through that system in reliance on consistent application of that
+ system; it is up to the author/donor to decide if he or she is willing
+ to distribute software through any other system and a licensee cannot
+ impose that choice.
+
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License
+ may add an explicit geographical distribution limitation excluding
+ those countries, so that distribution is permitted only in or among
+ countries not thus excluded. In such case, this License incorporates
+ the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new
+ versions of the General Public License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and
+ "any later version", you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a
+ version number of this License, you may choose any version ever
+ published by the Free Software Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by
+ the Free Software Foundation, write to the Free Software Foundation;
+ we sometimes make exceptions for this. Our decision will be guided by
+ the two goals of preserving the free status of all derivatives of our
+ free software and of promoting the sharing and reuse of software
+ generally.
+
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+ REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these
+ terms.
+
+ To do so, attach the following notices to the program. It is safest
+ to attach them to the start of each source file to most effectively
+ convey the exclusion of warranty; and each file should have at least
+ the "copyright" line and a pointer to where the full notice is found.
+
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+
+ Also add information on how to contact you by electronic and paper
+ mail.
+
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+
+
+
+ The hypothetical commands `show w' and `show c' should show the appro-
+ priate parts of the General Public License. Of course, the commands
+ you use may be called something other than `show w' and `show c'; they
+ could even be mouse-clicks or menu items--whatever suits your program.
+
+ You should also get your employer (if you work as a programmer) or
+ your school, if any, to sign a "copyright disclaimer" for the program,
+ if necessary. Here is a sample; alter the names:
+
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+
+
+ This General Public License does not permit incorporating your program
+ into proprietary programs. If your program is a subroutine library,
+ you may consider it more useful to permit linking proprietary applica-
+ tions with the library. If this is what you want to do, use the GNU
+ Library General Public License instead of this License.
+
+
+ H.2. The Artistic License
+
+
+
+ The "Artistic License"
+
+ Preamble
+
+
+
+
+ The intent of this document is to state the conditions under which a
+ Package may be copied, such that the Copyright Holder maintains some
+ semblance of artistic control over the development of the package,
+ while giving the users of the package the right to use and distribute
+ the Package in a more-or-less customary fashion, plus the right to
+ make reasonable modifications.
+
+ Definitions:
+
+
+ "Package" refers to the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection of files
+ created through textual modification.
+
+ "Standard Version" refers to such a Package if it has not been
+ modified, or has been modified in accordance with the wishes
+ of the Copyright Holder as specified below.
+
+ "Copyright Holder" is whoever is named in the copyright or
+ copyrights for the package.
+
+ "You" is you, if you're thinking about copying or distributing
+ this Package.
+
+ "Reasonable copying fee" is whatever you can justify on the
+ basis of media cost, duplication charges, time of people involved,
+ and so on. (You will not be required to justify it to the
+ Copyright Holder, but only to the computing community at large
+ as a market that must bear the fee.)
+
+ "Freely Available" means that no fee is charged for the item
+ itself, though there may be fees involved in handling the item.
+ It also means that recipients of the item may redistribute it
+ under the same conditions they received it.
+
+
+
+
+ 1. You may make and give away verbatim copies of the source form of
+ the Standard Version of this Package without restriction, provided
+ that you duplicate all of the original copyright notices and associ-
+ ated disclaimers.
+
+ 2. You may apply bug fixes, portability fixes and other modifications
+ derived from the Public Domain or from the Copyright Holder. A
+ Package modified in such a way shall still be considered the Standard
+ Version.
+
+ 3. You may otherwise modify your copy of this Package in any way,
+ provided that you insert a prominent notice in each changed file
+ stating how and when you changed that file, and provided that you do
+ at least ONE of the following:
+
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or
+ an equivalent medium, or placing the modifications on a major archive
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
+ your modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided, and provide
+ a separate manual page for each non-standard executable that clearly
+ documents how it differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+
+
+
+ 4. You may distribute the programs of this Package in object code or
+ executable form, provided that you do at least ONE of the following:
+
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where
+ to get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of
+ the Package with your modifications.
+
+ c) give non-standard executables non-standard names, and clearly
+ document the differences in manual pages (or equivalent), together
+ with instructions on where to get the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+
+
+
+ 5. You may charge a reasonable copying fee for any distribution of
+ this Package. You may charge any fee you choose for support of this
+ Package. You may not charge a fee for this Package itself. However,
+ you may distribute this Package in aggregate with other (possibly com-
+ mercial) programs as part of a larger (possibly commercial) software
+ distribution provided that you do not advertise this Package as a
+ product of your own. You may embed this Package's interpreter within
+ an executable of yours (by linking); this shall be construed as a mere
+ form of aggregation, provided that the complete Standard Version of
+ the interpreter is so embedded.
+
+ 6. The scripts and library files supplied as input to or produced as
+ output from the programs of this Package do not automatically fall
+ under the copyright of this Package, but belong to whomever generated
+ them, and may be sold commercially, and may be aggregated with this
+ Package. If such scripts or library files are aggregated with this
+ Package via the so-called "undump" or "unexec" methods of producing a
+ binary executable image, then distribution of such an image shall
+ neither be construed as a distribution of this Package nor shall it
+ fall under the restrictions of Paragraphs 3 and 4, provided that you
+ do not represent such an executable image as a Standard Version of
+ this Package.
+ 7. C subroutines (or comparably compiled subroutines in other
+ languages) supplied by you and linked into this Package in order to
+ emulate subroutines and variables of the language defined by this
+ Package shall not be considered part of this Package, but are the
+ equivalent of input as in Paragraph 6, provided these subroutines do
+ not change the language in any way that would cause it to fail the
+ regression tests for the language.
+
+ 8. Aggregation of this Package with a commercial distribution is
+ always permitted provided that the use of this Package is embedded;
+ that is, when no overt attempt is made to make this Package's
+ interfaces visible to the end user of the commercial distribution.
+ Such use shall not be construed as a distribution of this Package.
+
+ 9. The name of the Copyright Holder may not be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+ 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Table of Contents
+
+
+ 1. Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
+ 1.1. A Brief History of S-Lang . . . . . . . . . . . . . . . . . . 4
+ 1.2. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 4
+ 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 6
+ 3. Interpreter Interface . . . . . . . . . . . . . . . . . . . . . 7
+ 3.1. Embedding the Interpreter . . . . . . . . . . . . . . . . . . 7
+ 3.2. Calling the Interpreter . . . . . . . . . . . . . . . . . . . 8
+ 3.3. Intrinsic Functions . . . . . . . . . . . . . . . . . . . . . 8
+ 3.3.1. Restrictions on Intrinsic Functions . . . . . . . . . . . . 9
+ 3.3.2. Adding a New Intrinsic . . . . . . . . . . . . . . . . . . 10
+ 3.3.3. More Complicated Intrinsics . . . . . . . . . . . . . . . . 11
+ 3.4. Intrinsic Variables . . . . . . . . . . . . . . . . . . . . . 13
+ 3.5. Aggregate Data Objects . . . . . . . . . . . . . . . . . . . 15
+ 3.5.1. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 16
+ 3.5.2. Structures . . . . . . . . . . . . . . . . . . . . . . . . 18
+ 3.5.2.1. Interpreter Structures . . . . . . . . . . . . . . . . . 18
+ 3.5.2.2. Intrinsic Structures . . . . . . . . . . . . . . . . . . 19
+ 4. Keyboard Interface . . . . . . . . . . . . . . . . . . . . . . 22
+ 4.1. Initializing the Keyboard Interface . . . . . . . . . . . . . 22
+ 4.2. Resetting the Keyboard Interface . . . . . . . . . . . . . . 23
+ 4.3. Initializing the SLkp Routines . . . . . . . . . . . . . . . 23
+ 4.4. Setting the Interrupt Handler . . . . . . . . . . . . . . . . 24
+ 4.5. Reading Keyboard Input with SLang_getkey . . . . . . . . . . 25
+ 4.6. Reading Keyboard Input with SLkp_getkey . . . . . . . . . . . 26
+ 4.7. Buffering Input . . . . . . . . . . . . . . . . . . . . . . . 27
+ 4.8. Global Variables . . . . . . . . . . . . . . . . . . . . . . 28
+ 5. Screen Management . . . . . . . . . . . . . . . . . . . . . . . 29
+ 5.1. Initialization . . . . . . . . . . . . . . . . . . . . . . . 29
+ 5.2. Resetting SLsmg . . . . . . . . . . . . . . . . . . . . . . . 29
+ 5.3. Handling Screen Resize Events . . . . . . . . . . . . . . . . 30
+ 5.4. SLsmg Functions . . . . . . . . . . . . . . . . . . . . . . . 31
+ 5.4.1. Positioning the cursor . . . . . . . . . . . . . . . . . . 31
+ 5.4.2. Writing to the Display . . . . . . . . . . . . . . . . . . 32
+ 5.4.3. Erasing the Display . . . . . . . . . . . . . . . . . . . . 33
+ 5.4.4. Setting Character Attributes . . . . . . . . . . . . . . . 33
+ 5.4.5. Lines and Alternate Character Sets . . . . . . . . . . . . 35
+ 5.4.6. Miscellaneous Functions . . . . . . . . . . . . . . . . . . 35
+ 5.5. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . 36
+ 5.6. Hints for using SLsmg . . . . . . . . . . . . . . . . . . . . 36
+ 6. Signal Functions . . . . . . . . . . . . . . . . . . . . . . . 37
+ 7. Searching Functions . . . . . . . . . . . . . . . . . . . . . . 39
+ 7.1. Regular Expressions . . . . . . . . . . . . . . . . . . . . . 39
+ 7.2. Simple Searches . . . . . . . . . . . . . . . . . . . . . . . 39
+ 7.3. Initialization . . . . . . . . . . . . . . . . . . . . . . . 39
+ 7.4. SLsearch . . . . . . . . . . . . . . . . . . . . . . . . . . 39
+ H. Copyright . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
+ H.1. The GNU Public License . . . . . . . . . . . . . . . . . . . 41
+ H.2. The Artistic License . . . . . . . . . . . . . . . . . . . . 47
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/erlslang.txt b/doc/erlslang.txt
new file mode 100644
index 0000000..b647c96
--- /dev/null
+++ b/doc/erlslang.txt
@@ -0,0 +1,2143 @@
+ slang Library erlang Programmer's Guide, V1.0
+ Claes Wikstrom, klacke@bluetail.com
+ Adopted to erlang from the original
+ document by John E. Davis, davis@space.mit.edu
+
+ Thu Dec 14 00:05:42 CET 2000
+ ____________________________________________________________
+
+ Table of Contents
+
+ Preface
+
+ 1. A Brief History of
+
+ 2. Acknowledgements
+
+ 2. Introduction
+
+ 2. Interpreter Interface
+
+ 3. Embedding the Interpreter
+
+ 4. Calling the Interpreter
+
+ 5. Intrinsic Functions
+
+ 5.1 Restrictions on Intrinsic Functions
+ 5.2 Adding a New Intrinsic
+ 5.3 More Complicated Intrinsics
+
+ 6. Intrinsic Variables
+
+ 7. Aggregate Data Objects
+
+ 7.1 Arrays
+ 7.2 Structures
+ 7.2.1 Interpreter Structures
+ 7.2.2 Intrinsic Structures
+ 7.2.2 Keyboard Interface
+
+ 8. Initializing the Keyboard Interface
+
+ 9. Resetting the Keyboard Interface
+
+ 10. Initializing the
+
+ 11. Setting the Interrupt Handler
+
+ 12. Reading Keyboard Input with SLang[lowbar]getkey
+
+ 13. Reading Keyboard Input with SLkp[lowbar]getkey
+
+ 14. Buffering Input
+
+ 15. Global Variables
+
+ 15. Screen Management
+
+ 16. Initialization
+
+ 17. Resetting SLsmg
+
+ 18. Handling Screen Resize Events
+
+ 19. SLsmg Functions
+
+ 19.1 Positioning the cursor
+ 19.2 Writing to the Display
+ 19.3 Erasing the Display
+ 19.4 Setting Character Attributes
+ 19.5 Lines and Alternate Character Sets
+ 19.6 Miscellaneous Functions
+
+ 20. Variables
+
+ 21. Hints for using SLsmg
+ 21. Signal Functions
+
+ 21. Searching Functions
+
+ 22. Regular Expressions
+
+ 23. Simple Searches
+
+ 24. Initialization
+
+ 25. SLsearch
+
+ 25. Copyright
+
+ 26. The GNU Public License
+
+ 27. The Artistic License
+
+
+
+ ______________________________________________________________________
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1. Preface
+
+
+
+ S-Lang is an interpreted language that was designed from the start to
+ be easily embedded into a program to provide it with a powerful
+ extension language. Examples of programs that use S-Lang as an
+ extension language include the jed text editor, the slrn newsreader,
+ and sldxe (unreleased), a numerical computation program. For this
+ reason, S-Lang does not exist as a separate application and many of
+ the examples in this document are presented in the context of one of
+ the above applications.
+
+ S-Lang is also a programmer's library that permits a programmer to
+ develop sophisticated platform-independent software. In addition to
+ providing the S-Lang extension language, the library provides
+ facilities for screen management, keymaps, low-level terminal I/O,
+ etc.
+
+ This document describes the slang API for erlang programmers.
+ Slang itself is a progaming language in its own right and
+ it is an interpreter which is ment to be integerated into
+ applications. The erlang API does not include the S-Lang language,
+ only the actual functions which manipulate the terminal.
+
+
+ 1.2. Acknowledgements
+
+ (This is the Acknowledgements from the original author)
+
+ Since I first released S-Lang, I have received a lot feedback about
+ the library and the language from many people. This has given me the
+ opportunity and pleasure to interact with several people to make the
+ library portable and easy to use. In particular, I would like to
+ thank the following individuals:
+
+ Luchesar Ionkov <lionkov@sf.cit.bg> for his comments and criticisms of
+ the syntax of the language. He was the person who made me realize
+ that the low-level byte-code engine should be totally type-
+ independent. He also improved the tokenizer and preparser and
+ impressed upon me that the language needed a grammar.
+
+ Mark Olesen <olesen@weber.me.queensu.ca> for his many patches to
+ various aspects of the library and his support on AIX. He also
+ contributed a lot to the pre-processing (SLprep) routines.
+
+
+ John Burnell <j.burnell@irl.cri.nz> for the OS/2 port of the video and
+ keyboard routines. He also made value suggestions regarding the
+ interpreter interface.
+
+ Darrel Hankerson <hankedr@mail.auburn.edu> for cleaning up and
+ unifying some of the code and the makefiles.
+
+ Dominik Wujastyk <ucgadkw@ucl.ac.uk> who was always willing to test
+ new releases of the library.
+
+ Michael Elkins <me@muddcs.cs.hmc.edu> for his work on the curses
+ emulation.
+
+ Ulli Horlacher <framstag@belwue.de> and Oezguer Kesim <kesim@math.fu-
+ berlin.de> for the S-Lang newsgroup and mailing list.
+
+ Hunter Goatley, Andy Harper <Andy.Harper@kcl.ac.uk>, and Martin P.J.
+ Zinser <zinser@decus.decus.de> for their VMS support.
+
+ Dave Sims <sims@usa.acsys.com> and Chin Huang <cthuang@vex.net> for
+ Windows 95 and Windows NT support.
+
+ Lloyd Zusman <ljz@asfast.com> and Rich Roth <rich@on-the-net.com> for
+ creating and maintaining www.s-lang.org.
+
+ I am also grateful to many other people who send in bug-reports and
+ bug-fixes, for without such community involvement, S-Lang would not be
+ as well-tested and stable as it is. Finally, I would like to thank my
+ wife for her support and understanding while I spent long weekend
+ hours developing the library.
+
+
+
+
+ 2. Introduction
+
+
+
+ Slang is an Erlang programmer's library that includes routines for the
+ rapid development of sophisticated, user friendly, multi-platform
+ applications. The slang library includes the following:
+
+
+ o Low level tty input routines for reading single characters at a
+ time.
+
+ o Keymap routines for defining keys and manipulating multiple
+ keymaps.
+
+ o A high-level keyprocessing interface (SLkp) for handling function
+ and arrow keys.
+
+ o High level screen management routines for manipulating both
+ monochrome and color terminals. These routines are very efficient.
+ (SLsmg)
+
+ o Low level terminal-independent routines for manipulating the
+ display of a terminal. (SLtt)
+
+ o Routines for reading single line input with line editing and recall
+ capabilities. (SLrline)
+
+ o Searching functions: both ordinary searches and regular expression
+ searches. (SLsearch)
+
+
+ The library is currently available for OS/2, MSDOS, Unix, and VMS
+ systems. For the most part, the interface to library routines has
+ been implemented in such a way that it appears to be platform
+ independent from the point of view of the application. In addition,
+ care has been taken to ensure that the routines are ``independent'' of
+ one another as much as possible. For example, although the keymap
+ routines require keyboard input, they are not tied to S-Lang's
+ keyboard input routines--- one can use a different keyboard getkey
+ routine if one desires. This also means that linking to only part of
+ the S-Lang library does not pull the whole library into the
+ application. Thus, S-Lang applications tend to be relatively small in
+ comparison to programs that use libraries with similar capabilities.
+
+
+
+
+ 4. Keyboard Interface
+
+
+
+ S-Lang's keyboard interface has been designed to allow an application
+ to read keyboard input from the user in a system-independent manner.
+ The interface consists of a set of low routines for reading single
+ character data as well as a higher level interface (SLkp) which
+ utilize S-Lang's keymap facility for reading multi-character
+ sequences.
+
+ To initialize the interface, one must first call the function
+ SLang_init_tty. Before exiting the program, the function
+ SLang_reset_tty must be called to restore the keyboard interface to
+ its original state. Once initialized, the low-level SLang_getkey
+ function may be used to read simgle keyboard characters from the
+ terminal. An application using the the higher-level SLkp interface
+ will read charcters using the SLkp_getkey function.
+
+ In addition to these basic functions, there are also functions to
+ ``unget'' keyboard characters, flush the input, detect pending-input
+ with a timeout, etc. These functions are defined below.
+
+
+
+ 4.1. Initializing the Keyboard Interface
+
+
+
+ The function SLang_init_tty must be called to initialize the terminal
+ for single character input. This puts the terminal in a mode usually
+ referred to as ``raw'' mode.
+
+ The type for the function is:
+
+ slang:init_tty(Int AbortChar, Int FlowCtrl, Int Opost) -> Int
+
+
+ It takes three parameters that are used to specify how the terminal is
+ to be initialized. %Although the S-Lang keyboard interface has been
+ %designed to be as system independent as possible, there are semantic
+ % differences.
+
+ The first parameter, AbortChar, is used to specify the interrupt
+ character (SIGINT). Under MSDOS, this value corresponds to the scan
+ code of the character that will be used to generate the interrupt.
+ For example, under MSDOS, 34 should be used to make Ctrl-G generate an
+ interrupt signal since 34 is the scan code for G. On other systems,
+ the value of AbortChar will simply be the ascii value of the control
+ character that will be used to generate the interrupt signal, e.g., 7
+ for Ctrl-G. If -1 is passed, the interrupt character will not be
+ changed.
+
+ Pressing the interrupt character specified by the first argument will
+ generate a signal (SIGINT) that may or not be caught by the
+ application. It is up to the application to catch this signal. S-
+ Lang provides the function slang:set_abort_signal/1 to make it easy to
+ facilitate this task.
+
+ The second parameter is used to specify whether or not flow control
+ should be used. If this parameter is zero, flow control is enabled
+ otherwise it is disabled. Disabling flow control is necessary to pass
+ certain characters to the application (e.g., Ctrl-S and Ctrl-Q). For
+ some systems such as MSDOS, this parameter is meaningless.
+
+ The third parameter, Opost, is used to turn output processing on or
+ off. If opost is zero, output processing is not turned on otherwise,
+ output processing is turned on.
+
+ The slang:init_tty function/3 returns -1 upon failure. In addition,
+ after it returns, the S-Lang global variable 'baudrate' will
+ be set to the baud rate of the terminal if this value can be
+ determined.
+
+ Example:
+
+ %% For MSDOS, use 34 as scan code
+ case slang:init_tty(7,0,0) of
+ -1 ->
+ io:format("Failed to initialize tty ~n",[]),
+ halt();
+ 0 ->
+ slang:set_abort_signal(null)
+ end.
+
+
+ Here the terminal is initialized such that flow control and output
+ processing are turned off. In addition, the character Ctrl-G (-- For
+ MSDOS systems, use the scan code 34 instead of 7 for Ctrl-G--) has
+ been specified to be the interrupt character. The function
+ slang:set_abort_signal/1 is used to install the default slang interrupt
+ signal handler.
+
+
+ 4.2. Resetting the Keyboard Interface
+
+ The function slang:reset_tty/0 must be called to reset the terminal to
+ the state it was in before the call to slang:init_tty/3. The type
+ for this function is:
+
+ slang:reset_tty() -> void
+
+
+ Usually this function is only called before the program exits. How-
+ ever, if the program is suspended it should also be called just before
+ suspension.
+
+ 4.3. Initializing the kp Routines
+
+ Extra initialization of the higher-level kp functions are required
+ because they are layered on top of the lower level routines. Since
+ the kp_getkey function is able to process function and arrow keys in
+ a terminal independent manner, it is necessary to call the
+ SLtt_get_terminfo function to get information about the escape
+ character sequences that the terminal's function keys send. Once that
+ information is available, the kp_init function can construct the
+ proper keymaps to process the escape sequences.
+
+ This part of the initialization process for an application using this
+ interface will look something like:
+
+ slang:tt_get_terminfo(),
+ case slang:kp_init() of
+ -1 ->
+ io:format("kp_init failed."),
+ halt();
+ 0 ->
+ case slang:init_tty(-1,0,1) of
+ -1 ->
+ io:format("init tty failed ~n",[]),
+ halt();
+ 0 ->
+ ok
+ end
+ end
+
+
+ It is important to check the return status of the kp_init function
+ which can failed if it cannot allocate enough memory for the keymap.
+
+
+ 4.4. Setting the Interrupt Handler
+
+
+
+ The function slang:set_abort_signal/1 may be used to associate an
+ interrupt handler with the interrupt character that was previously
+ specified by the slang:init_tty/3 function call. The type for this
+ function is:
+
+ slang:set_abort_signal(null | Fun/1) -> void
+
+
+ This function returns nothing and takes a single parameter which is a
+ pointer to a function taking an integer value and returning void. If
+ a null atom is passed, the default slang interrupt handler will be
+ used. The slang default interrupt handler under Unix looks like:
+
+ static void default_sigint (int sig)
+ {
+ SLsignal_intr (SIGINT, default_sigint);
+ SLKeyBoard_Quit = 1;
+ if (SLang_Ignore_User_Abort == 0) SLang_Error = USER_BREAK;
+ }
+
+
+
+ It simply sets the global variable SLKeyBoard_Quit to one and if the
+ variable SLang_Ignore_User_Abort is non-zero, SLang_Error is set to
+ indicate a user break condition. (The function SLsignal_intr is simi-
+ lar to the standard C signal function except that it will interrupt
+ system calls. Some may not like this behavior and may wish to call
+ this SLang_set_abort_signal with a different handler.)
+
+
+ Although the function expressed above is specific to Unix, the
+ analogous routines for other operating systems are equivalent in
+ functionality even though the details of the implementation may vary
+ drastically (e.g., under MSDOS, the hardware keyboard interrupt int 9h
+ is hooked).
+
+
+ 4.5. Reading Keyboard Input with slang:getkey/0
+
+
+ After initializing the keyboard via slang:init_tty/3, the S-Lang
+ function slang:getkey/0 may be used to read characters from the terminal
+ interface. In addition, the function slang:input_pending/1 may be used
+ to determine whether or not keyboard input is available to be read.
+
+ These functions have types:
+
+
+ slang:getkey () -> Int
+ slang:input_pending (Int Tsecs) -> Int
+
+
+ The getkey/0 function returns a single character from the termi-
+ nal. Upon failure, it returns 16#FFFF. If the interrupt character
+ specified by the slang:init_tty/3 function is pressed while this func-
+ tion is called, the function will return the value of the interrupt
+ character and set the S-Lang global variable SLKeyBoard_Quit to a non- XX
+ zero value. In addition, if the default S-Lang interrupt handler has
+ been specified by a 'null' argument to the set_abort_signal func-
+ tion, the global variable SLang_Error will be set to USER_BREAK unless XX
+ the variable SLang_Ignore_User_Abort is non-zero. XX
+
+ The getkey/0 function waits until input is available to be read.
+ The input_pending/1 function may be used to determine whether or
+ not input is ready. It takes a single parameter that indicates the
+ amount of time to wait for input before returning with information
+ regarding the availability of input. This parameter has units of one
+ tenth (1/10) of a second, i.e., to wait one second, the value of the
+ parameter should be 10. Passing a value of zero causes the function
+ to return right away. SLang_input_pending returns a positive integer
+ if input is available or zero if input is not available. It will
+ return -1 if an error occurs.
+
+ Here is a simple example that reads keys from the terminal until one
+ presses Ctrl-G or until 5 seconds have gone by with no input:
+ This code can be found in demo/ex1.erl
+
+ -include_lib("slang.hrl")
+
+ start() ->
+ slang:init_tty(7,0,1),
+ slang:set_abort_signal(null),
+ loop().
+
+ loop() ->
+ io:format("\nPress any key. To quit, press Ctrl-G: ", []),
+ case slang:input_pending (50) of %% 5secs
+ 0 ->
+ io:format("waited toooo long ~n",[]),
+ ok;
+ _ ->
+ Ch = slang:getkey(),
+ case slang:getvar(error) of
+ ?USER_BREAK ->
+ io:format("Ctrl-G pressed ~n",[]),
+
+
+ {
+ fputs ("Waited too long! Bye\n", stdout);
+ break;
+ }
+
+ ch = SLang_getkey ();
+ if (SLang_Error == USER_BREAK)
+ {
+ fputs ("Ctrl-G pressed! Bye\n", stdout);
+ break;
+ }
+ putc ((int) ch, stdout);
+ }
+ SLang_reset_tty ();
+ return 0;
+ }
+
+
+
+
+
+
+
+ 4.6. Reading Keyboard Input with SLkp_getkey
+
+
+
+ Unlike the low-level function SLang_getkey, the SLkp_getkey function
+ can read a multi-character sequence associated with function keys.
+ The SLkp_getkey function uses SLang_getkey and S-Lang's keymap
+ facility to process escape sequences. It returns a single integer
+ which describes the key that was pressed:
+
+
+ int SLkp_getkey (void);
+
+
+
+
+ That is, the SLkp_getkey function simple provides a mapping between
+ keys and integers. In this context the integers are called keysyms.
+
+ For single character input such as generated by the a key on the
+ keyboard, the function returns the character that was generated, e.g.,
+ 'a'. For single characters, SLkp_getkey will always return an keysym
+ whose value ranges from 0 to 256. For keys that generate multiple
+ character sequences, e.g., a function or arrow key, the function
+ returns an keysym whose value is greater that 256. The actual values
+ of these keysyms are represented as macros defined in the slang.h
+ include file. For example, the up arrow key corresponds to the keysym
+ whose value is SL_KEY_UP.
+
+ Since it is possible for the user to enter a character sequence that
+ does not correspond to any key. If this happens, the special keysym
+ SL_KEY_ERR will be returned.
+
+ Here is an example of how SLkp_getkey may be used by a file viewer:
+
+
+ switch (SLkp_getkey ())
+ {
+ case ' ':
+ case SL_KEY_NPAGE:
+ next_page ();
+ break;
+ case 'b':
+ case SL_KEY_PPAGE:
+ previous_page ();
+ break;
+ case '\r':
+ case SL_KEY_DOWN:
+ next_line ();
+ break;
+ .
+ .
+ case SL_KEY_ERR:
+ default:
+ SLtt_beep ();
+ }
+
+
+
+
+ Unlike its lower-level counterpart, SLang_getkey, there do not yet
+ exist any functions in the library that are capable of ``ungetting''
+ keysyms. In particular, the SLang_ungetkey function will not work.
+
+
+
+ 4.7. Buffering Input
+
+
+
+ S-Lang has several functions pushing characters back onto the input
+ stream to be read again later by SLang_getkey. It should be noted
+ that none of the above functions are designed to push back keysyms
+ read by the SLkp_getkey function. These functions are declared as
+ follows:
+
+
+ void SLang_ungetkey (unsigned char ch);
+ void SLang_ungetkey_string (unsigned char *buf, int buflen);
+ void SLang_buffer_keystring (unsigned char *buf, int buflen);
+
+
+
+
+ SLang_ungetkey is the most simple of the three functions. It takes a
+ single character a pushes it back on to the input stream. The next
+ call to SLang_getkey will return this character. This function may be
+ used to peek at the character to be read by first reading it and then
+ putting it back.
+
+
+ SLang_ungetkey_string has the same function as SLang_ungetkey except
+ that it is able to push more than one character back onto the input
+ stream. Since this function can push back null (ascii 0) characters,
+ the number of characters to push is required as one of the parameters.
+
+ The last of these three functions, SLang_buffer_keystring can handle
+ more than one charater but unlike the other two, it places the
+ characters at the end of the keyboard buffer instead of at the
+ beginning.
+
+ Note that the use of each of these three functions will cause
+ SLang_input_pending to return right away with a non-zero value.
+
+ Finally, the S-Lang keyboard interface includes the function
+ SLang_flush_input with prototype
+
+
+ void SLang_flush_input (void);
+
+
+
+
+ It may be used to discard all input.
+
+ Here is a simple example that looks to see what the next key to be
+ read is if one is available:
+
+
+ int peek_key ()
+ {
+ int ch;
+ if (SLang_input_pending (0) == 0) return -1;
+ ch = SLang_getkey ();
+ SLang_ungetkey (ch);
+ return ch;
+ }
+
+
+
+
+
+
+
+ 4.8. Global Variables
+
+
+ Although the following S-Lang global variables have already been
+ mentioned earlier, they are gathered together here for completeness.
+
+ int SLang_Ignore_User_Abort; If non-zero, pressing the interrupt
+ character will not result in SLang_Error being set to USER_BREAK.
+
+ volatile int SLKeyBoard_Quit; This variable is set to a non-zero value
+ when the interrupt character is pressed. If the interrupt character is
+ pressed when SLang_getkey is called, the interrupt character will be
+ returned from SLang_getkey.
+
+ int SLang_TT_Baud_Rate; On systems which support it, this variable is
+ set to the value of the terminal's baud rate after the call to
+ SLang_init_tty.
+
+
+
+
+
+
+ 5. Screen Management
+
+
+
+ The S-Lang library provides two interfaces to terminal independent
+ routines for manipulating the display on a terminal. The highest
+ level interface, known as the SLsmg interface is discussed in this
+ section. It provides high level screen management functions more
+ manipulating the display in an optimal manner and is similar in spirit
+ to the curses library. The lowest level interface, or the SLtt
+ interface, is used by the SLsmg routines to actually perform the task
+ of writing to the display. This interface is discussed in another
+ section. Like the keyboard routines, the SLsmg routines are platform
+ independent and work the same on MSDOS, OS/2, Unix, and VMS.
+
+ The screen management, or SLsmg, routines are initialized by function
+ SLsmg_init_smg. Once initialized, the application uses various SLsmg
+ functions to write to a virtual display. This does not cause the
+ physical terminal display to be updated immediately. The physical
+ display is updated to look like the virtual display only after a call
+ to the function SLsmg_refresh. Before exiting, the application using
+ these routines is required to call SLsmg_reset_smg to reset the
+ display system.
+
+ The following subsections explore S-Lang's screen management system in
+ greater detail.
+
+
+ 5.1. Initialization
+
+
+ The function SLsmg_init_smg must be called before any other SLsmg
+ function can be used. It has the simple prototype:
+
+
+ int SLsmg_init_smg (void);
+
+
+
+
+ It returns zero if successful or -1 if it cannot allocate space for
+ the virtual display.
+
+ For this routine to properly initialize the virtual display, the
+ capabilities of the terminal must be known as well as the size of the
+ physical display. For these reasons, the lower level SLtt routines
+ come into play. In particular, before the first call to
+ SLsmg_init_smg, the application is required to call the function
+ SLtt_get_terminfo before calling SLsmg_init_smg.
+
+ The SLtt_get_terminfo function sets the global variables
+ SLtt_Screen_Rows and SLtt_Screen_Cols to the values appropriate for
+ the terminal. It does this by calling the SLtt_get_screen_size
+ function to query the terminal driver for the appropriate values for
+ these variables. From this point on, it is up to the application to
+ maintain the correct values for these variables by calling the
+ SLtt_get_screen_size function whenever the display size changes, e.g.,
+ in response to a SIGWINCH signal. Finally, if the application is going
+ to read characters from the keyboard, it is also a good idea to
+ initialize the keyboard routines at this point as well.
+
+
+ 5.2. Resetting SLsmg
+
+
+
+ Before the program exits or suspends, the function SLsmg_reset_tty
+ should be called to shutdown the display system. This function has
+ the prototype
+
+
+ void SLsmg_reset_smg (void);
+
+
+
+
+ This will deallocate any memory allocated for the virtual screen and
+ reset the terminal's display.
+
+ Basically, a program that uses the SLsmg screen management functions
+ and S-Lang's keyboard interface will look something like:
+
+
+ #include "slang.h"
+ int main ()
+ {
+ SLtt_get_terminfo ();
+ SLang_init_tty (-1, 0, 0);
+ SLsmg_init_smg ();
+
+ /* do stuff .... */
+
+ SLsmg_reset_smg ();
+ SLang_reset_tty ();
+ return 0;
+ }
+
+
+
+
+ If this program is compiled and run, all it will do is clear the
+ screen and position the cursor at the bottom of the display. In the
+ following sections, other SLsmg functions will be introduced which may
+ be used to make this simple program do much more.
+
+
+ 5.3. Handling Screen Resize Events
+
+ The function SLsmg_reinit_smg is designed to be used in conjunction
+ with resize events.
+
+ Under Unix-like operating systems, when the size of the display
+ changes, the application will be sent a SIGWINCH signal. To properly
+ handle this signal, the SLsmg routines must be reinitialized to use
+ the new display size. This may be accomplished by calling
+ SLtt_get_screen_size to get the new size, followed by SLsmg_reinit_smg
+ to reinitialize the SLsmg interface to use the new size. Keep in mind
+ that these routines should not be called from within the signal
+ handler. The following code illustrates the main ideas involved in
+ handling such events:
+
+
+
+
+
+
+
+
+
+
+
+
+ static volatile int Screen_Size_Changed;
+ static sigwinch_handler (int sig)
+ {
+ Screen_Size_Changed = 1;
+ SLsignal (SIGWINCH, sigwinch_handler);
+ }
+
+ int main (int argc, char **argv)
+ {
+ SLsignal (SIGWINCH, sigwinch_handler);
+ SLsmg_init_smg ();
+ .
+ .
+ /* Now enter main loop */
+ while (not_done)
+ {
+ if (Screen_Size_Changed)
+ {
+ SLtt_get_screen_size ();
+ SLsmg_reinit_smg ();
+ redraw_display ();
+ }
+ .
+ .
+ }
+ return 0;
+ }
+
+
+
+
+
+
+ 5.4. SLsmg Functions
+
+
+
+ In the previous sections, functions for initializing and shutting down
+ the SLsmg routines were discussed. In this section, the rest of the
+ SLsmg functions are presented. These functions act only on the
+ virtual display. The physical display is updated when the
+ SLsmg_refresh function is called and not until that time. This
+ function has the simple prototype:
+
+
+ void SLsmg_refresh (void);
+
+
+
+
+
+ 5.4.1. Positioning the cursor
+
+
+ The SLsmg_gotorc function is used to position the cursor at a given
+ row and column. The prototype for this function is:
+
+
+ void SLsmg_gotorc (int row, int col);
+
+
+
+
+ The origin of the screen is at the top left corner and is given the
+ coordinate (0, 0), i.e., the top row of the screen corresponds to row
+ = 0 and the first column corresponds to col = 0. The last row of the
+ screen is given by row = SLtt_Screen_Rows - 1.
+
+ It is possible to change the origin of the coordinate system by using
+ the function SLsmg_set_screen_start with prototype:
+
+
+ void SLsmg_set_screen_start (int *r, int *c);
+
+
+
+
+ This function takes pointers to the new values of the first row and
+ first column. It returns the previous values by modifying the values
+ of the integers at the addresses specified by the parameter list. A
+ NULL pointer may be passed to indicate that the origin is to be set to
+ its initial value of 0. For example,
+
+
+ int r = 10;
+ SLsmg_set_screen_start (&r, NULL);
+
+
+
+
+ sets the origin to (10, 0) and after the function returns, the vari-
+ able r will have the value of the previous row origin.
+
+
+ 5.4.2. Writing to the Display
+
+
+ SLsmg has several routines for outputting text to the virtual display.
+ The following points should be understood:
+
+ o The text is output at the position of the cursor of the virtual
+ display and the cursor is advanced to the position that corresponds
+ to the end of the text.
+
+
+ o Text does not wrap at the boundary of the display--- it is
+ trucated. This behavior seems to be more useful in practice since
+ most programs that would use screen management tend to be line
+ oriented.
+
+
+ o Control characters are displayed in a two character sequence
+ representation with ^ as the first character. That is, Ctrl-X is
+ output as ^X.
+
+
+ o The newline character does not cause the cursor to advance to the
+ next row. Instead, when a newline character is encountered when
+ outputting text, the output routine will return. That is,
+ outputting a string containing a newline character will only
+ display the contents of the string up to the newline character.
+
+
+ Although the some of the above items might appear to be too
+ restrictive, in practice this is not seem to be the case. In fact,
+ the design of the output routines was influenced by their actual use
+ and modified to simplify the code of the application utilizing them.
+
+ void SLsmg_write_char (char ch); Write a single character to the
+ virtual display.
+
+
+ void SLsmg_write_nchars (char *str, int len); Write len characters
+ pointed to by str to the virtual display.
+
+ void SLsmg_write_string (char *str); Write the null terminated string
+ given by pointer str to the virtual display. This function is a
+ wrapper around SLsmg_write_nchars.
+
+ void SLsmg_write_nstring (char *str, int n); Write the null terminated
+ string given by pointer str to the virtual display. At most, only n
+ characters are written. If the length of the string is less than n,
+ then the string will be padded with blanks. This function is a
+ wrapper around SLsmg_write_nchars.
+
+ void SLsmg_printf (char *fmt, ...); This function is similar to printf
+ except that it writes to the SLsmg virtual display.
+
+ void SLsmg_vprintf (char *, va_list); Like SLsmg_printf but uses a
+ variable argument list.
+
+
+ 5.4.3. Erasing the Display
+
+
+ The following functions may be used to fill portions of the display
+ with blank characters. The attributes of blank character are the
+ current attributes. (See below for a discussion of character
+ attributes)
+
+ void SLsmg_erase_eol (void); Erase line from current position to the
+ end of the line.
+
+ void SLsmg_erase_eos (void); Erase from the current position to the
+ end of the screen.
+
+ void SLsmg_cls (void); Clear the entire virtual display.
+
+
+ 5.4.4. Setting Character Attributes
+
+
+ Character attributes define the visual characteristics the character
+ possesses when it is displayed. Visual characteristics include the
+ foreground and background colors as well as other attributes such as
+ blinking, bold, and so on. Since SLsmg takes a different approach to
+ this problem than other screen management libraries an explanation of
+ this approach is given here. This approach has been motivated by
+ experience with programs that require some sort of screen management.
+
+ Most programs that use SLsmg are composed of specific textual objects
+ or objects made up of line drawing characters. For example, consider
+ an application with a menu bar with drop down menus. The menus might
+ be enclosed by some sort of frame or perhaps a shadow. The basic idea
+ is to associate an integer to each of the objects (e.g., menu bar,
+ shadow, current menu item, etc.) and create a mapping from the integer
+ to the set of attributes. In the terminology of SLsmg, the integer is
+ simply called an object.
+
+ For example, the menu bar might be associated with the object 1, the
+ drop down menu could be object 2, the shadow could be object 3, and so
+ on.
+
+ The range of values for the object integer is restricted from 0 up to
+ and including 255 on all systems except MSDOS where the maximum
+ allowed integer is 15 (-- This difference is due to memory constraints
+ imposed by MSDOS. This restriction might be removed in a future
+ version of the library.--) . The object numbered zero should not be
+ regarding as an object at all. Rather it should be regarded as all
+ other objects that have not explicitly been given an object number.
+ SLsmg, or more precisely SLtt, refers to the attributes of this
+ special object as the default or normal attributes.
+
+ The SLsmg routines know nothing about the mapping of the color to the
+ attributes associated with the color. The actual mapping takes place
+ at a lower level in the SLtt routines. Hence, to map an object to the
+ actual set of attributes requires a call to any of the following SLtt
+ routines:
+
+
+ void SLtt_set_color (int obj, char *name, char *fg, char *bg);
+ void SLtt_set_color_object (int obj, SLtt_Char_Type attr);
+ void SLtt_set_mono (int obj, char *, SLtt_Char_Type attr);
+
+
+
+
+ Only the first of these routines will be discussed briefly here. The
+ latter two functions allow more fine control over the object to
+ attribute mapping (such as assigning a ``blink'' attribute to the
+ object). For a more full explanation on all of these routines see the
+ section about the SLtt interface.
+
+ The SLtt_set_color function takes four parameters. The first
+ parameter, obj, is simply the integer of the object for which
+ attributes are to be assigned. The second parameter is currently
+ unused by these routines. The third and forth parameters, fg and bg,
+ are the names of the foreground and background color to be used
+ associated with the object. The strings that one can use for the
+ third and fourth parameters can be any one of the 16 colors:
+
+
+ "black" "gray"
+ "red" "brightred"
+ "green" "brightgreen"
+ "brown" "yellow"
+ "blue" "brightblue"
+ "magenta" "brightmagenta"
+ "cyan" "brightcyan"
+ "lightgray" "white"
+
+
+
+
+ The value of the foreground parameter fg can be anyone of these six-
+ teen colors. However, on most terminals, the background color will
+ can only be one of the colors listed in the first column (-- This is
+ also true on the Linux console. However, it need not be the case and
+ hopefully the designers of Linux will someday remove this restric-
+ tion.--) .
+
+ Of course not all terminals are color terminals. If the S-Lang global
+ variable SLtt_Use_Ansi_Colors is non-zero, the terminal is assumed to
+ be a color terminal. The SLtt_get_terminfo will try to determine
+ whether or not the terminal supports colors and set this variable
+ accordingly. It does this by looking for the capability in the
+ terminfo/termcap database. Unfortunately many Unix databases lack
+ this information and so the SLtt_get_terminfo routine will check
+ whether or not the environment variable COLORTERM exists. If it
+ exists, the terminal will be assumed to support ANSI colors and
+ SLtt_Use_Ansi_Colors will be set to one. Nevertheless, the
+ application should provide some other mechanism to set this variable,
+ e.g., via a command line parameter.
+
+ When the SLtt_Use_Ansi_Colors variable is zero, all objects with
+ numbers greater than one will be displayed in inverse video (-- This
+ behavior can be modified by using the SLtt_set_mono function call.--)
+ .
+
+ With this background, the SLsmg functions for setting the character
+ attributes can now be defined. These functions simply set the object
+ attributes that are to be assigned to subsequent characters written to
+ the virtual display. For this reason, the new attribute is called the
+ current attribute.
+
+ void SLsmg_set_color (int obj); Set the current attribute to those of
+ object obj.
+
+ void SLsmg_normal_video (void); This function is equivalent to
+ SLsmg_set_color (0).
+
+ void SLsmg_reverse_video (void); This function is equivalent to
+ SLsmg_set_color (1). On monochrome terminals, it is equivalent to
+ setting the subsequent character attributes to inverse video.
+
+ Unfortunately there does not seem to be a standard way for the
+ application or, in particular, the library to determine which color
+ will be used by the terminal for the default background. Such
+ information would be useful in initializing the foreground and
+ background colors associated with the default color object (0). FOr
+ this reason, it is up to the application to provide some means for the
+ user to indicate what these colors are for the particular terminal
+ setup. To facilitate this, the SLtt_get_terminfo function checks for
+ the existence of the COLORFGBG environment variable. If this variable
+ exists, its value will be used to initialize the colors associated
+ with the default color object. Specifically, the value is assumed to
+ consist of a foreground color name and a background color name
+ separated by a semicolon. For example, if the value of COLORTERM is
+ lightgray;blue, the default color object will be initialized to
+ represent a lightgray foreground upon a blue background.
+
+
+ 5.4.5. Lines and Alternate Character Sets
+
+ The S-Lang screen management library also includes routines for
+ turning on and turning off alternate character sets. This is
+ especially useful for drawing horizontal and vertical lines.
+
+ void SLsmg_set_char_set (int flag); If flag is non-zero, subsequent
+ write functions will use characters from the alternate character set.
+ If flag is zero, the default, or, ordinary character set will be used.
+
+ void SLsmg_draw_hline (int len); Draw a horizontal line from the
+ current position to the column that is len characters to the right.
+
+ void SLsmg_draw_vline (int len); Draw a horizontal line from the
+ current position to the row that is len rows below.
+
+ void SLsmg_draw_box (int r, int c, int dr, int dc); Draw a box whose
+ upper right corner is at row r and column c. The box spans dr rows
+ and dc columns. The current position will be left at row r and column
+ c.
+
+
+ 5.4.6. Miscellaneous Functions
+
+
+ void SLsmg_touch_lines (int r, int n); Mark screen rows numbered r, r
+ + 1, ... r + (n - 1) as modified. When SLsmg_refresh is called, these
+ rows will be completely redrawn.
+ unsigned short SLsmg_char_at(void); Returns the character and its
+ attributes object number at the current cursor position. The
+ character itself occupies the lower byte and the object attributes
+ number forms the upper byte. The object returned by this function
+ call should not be written back out via any of the functions that
+ write characters or character strings.
+
+
+
+
+ 5.5. Variables
+
+
+
+ The following S-Lang global variables are used by the SLsmg interface.
+ Some of these have been previously discussed.
+
+ int SLtt_Screen_Rows; int SLtt_Screen_Cols; The number of rows and
+ columns of the physical display. If either of these numbers changes,
+ the functions SLsmg_reset_smg and SLsmg_init_smg should be called
+ again so that the SLsmg routines can re-adjust to the new size.
+
+ int SLsmg_Tab_Width; Set this variable to the tab width that will be
+ used when expanding tab characters. The default is 8.
+
+ int SLsmg_Display_Eight_Bit This variable determines how characters
+ with the high bit set are to be output. Specifically, a character
+ with the high bit set with a value greater than or equal to this value
+ is output as is; otherwise, it will be output in a 7-bit
+ representation. The default value for this variable is 128 for MSDOS
+ and 160 for other systems (ISO-Latin).
+
+ int SLtt_Use_Ansi_Colors; If this value is non-zero, the terminal is
+ assumed to support ANSI colors otherwise it is assumed to be
+ monochrome. The default is 0.
+
+ int SLtt_Term_Cannot_Scroll; If this value is zero, the SLsmg will
+ attempt to scroll the physical display to optimize the update. If it
+ is non-zero, the screen management routines will not perform this
+ optimization. For some applications, this variable should be set to
+ zero. The default value is set by the SLtt_get_terminfo function.
+
+
+
+ 5.6. Hints for using SLsmg
+
+
+ This section discusses some general design issues that one must face
+ when writing an application that requires some sort of screen
+ management.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 6. Signal Functions
+
+
+
+ Almost all non-trivial programs must worry about signals. This is
+ especially true for programs that use the S-Lang terminal input/output
+ and screen management routines. Unfortunately, there is no fixed way
+ to handle signals; otherwise, the Unix kernel would take care of all
+ issues regarding signals and the application programmer would never
+ have to worry about them. For this reason, none of the routines in
+ the S-Lang library catch signals; however, some of the routines block
+ the delivery of signals during crucial moments. It is up to the
+ application programmer to install handlers for the various signals of
+ interest.
+
+ For the interpreter, the most important signal to worry about is
+ SIGINT. This signal is usually generated when the user presses Ctrl-C
+ at the keyboard. The interpreter checks the value of the SLang_Error
+ variable to determine whether or not it should abort the interpreting
+ process and return control back to the application. This means that
+ if SIGINT is to be used to abort the interpreter, a signal handler for
+ SIGINT should be installed. The handler should set the value of
+ SLang_Error to SL_USER_BREAK.
+
+ Applications that use the tty getkey routines or the screen management
+ routines must worry about about signals such as:
+
+
+ SIGINT interrupt
+ SIGTSTP stop
+ SIGQUIT quit
+ SIGTTOU background write
+ SIGTTIN background read
+ SIGWINCH window resize
+
+
+
+
+ It is important that handlers be established for these signals while
+ the either the SLsmg routines or the getkey routines are initialized.
+ The SLang_init_tty, SLang_reset_tty, SLsmg_init_smg, and
+ SLsmg_reset_smg functions block these signals from occuring while they
+ are being called.
+
+ Since a signal can be delivered at any time, it is important for the
+ signal handler to call only functions that can be called from a signal
+ handler. This usually means that such function must be re-entrant. In
+ particular, the SLsmg routines are not re-entrant; hence, they should
+ not be called when a signal is being processed unless the application
+ can ensure that the signal was not delivered while an SLsmg function
+ was called. This statement applies to many other functions such as
+ malloc, or, more generally, any function that calls malloc. The
+ upshot is that the signal handler should not attempt to do too much
+ except set a global variable for the application to look at while not
+ in a signal handler.
+
+ The S-Lang library provides two functions for blocking and unblocking
+ the above signals:
+
+
+ int SLsig_block_signals (void);
+ int SLsig_unblock_signals (void);
+
+
+
+
+ It should be noted that for every call to SLsig_block_signals, a cor-
+ responding call should be made to SLsig_unblock_signals, e.g.,
+
+
+ void update_screen ()
+ {
+ SLsig_block_signals ();
+
+ /* Call SLsmg functions */
+ .
+ .
+ SLsig_unblock_signals ();
+ }
+
+
+
+
+ See demo/pager.c for examples.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 7. Searching Functions
+
+
+
+ The S-Lang library incorporates two types of searches: Regular
+ expression pattern matching and ordinary searching.
+
+
+ 7.1. Regular Expressions
+
+
+
+ !!! No documentation available yet !!!
+
+
+
+ 7.2. Simple Searches
+
+
+ The routines for ordinary searching are defined in the slsearch.c
+ file. To use these routines, simply include "slang.h" in your program
+ and simply call the appropriate routines.
+
+ The searches can go in either a forward or backward direction and can
+ either be case or case insensitive. The region that is searched may
+ contain null characters (ASCII 0) however, the search string cannot in
+ the current implementation. In addition the length of the string to
+ be found is currently limited to 256 characters.
+
+ Before searching, the function SLsearch_init must first be called to
+ `preprocess' the search string.
+
+
+
+ 7.3. Initialization
+
+
+ The function SLsearch_init must be called before a search can take
+ place. Its prototype is:
+
+
+ int SLsearch_init (char *key, int dir, int case_sens, SLsearch_Type *st);
+
+
+
+
+ Here key is the string to be searched for. dir specifies the direc-
+ tion of the search: a value greater than zero is used for searching
+ forward and a value less than zero is used for searching backward.
+ The parameter case_sens specifies whether the search is case sensitive
+ or not. A non-zero value indicates that case is important. st is a
+ pointer to a structure of type SLsearch_Type defined in "slang.h".
+ This structure is initialized by this routine and must be passed to
+ SLsearch when the search is actually performed.
+
+ This routine returns the length of the string to be searched for.
+
+
+
+ 7.4. SLsearch
+
+
+
+
+
+
+ Prototype: unsigned char *SLsearch (unsigned char *pmin,
+ unsigned char *pmax,
+ SLsearch_Type *st);
+
+
+
+
+ This function performs the search defined by a previous call to
+ SLsearch_init over a region specified by the pointers pmin and pmax.
+
+ It returns a pointer to the start of the match if successful or it
+ will return NULL if a match was not found.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ H. Copyright
+
+ The S-Lang library is distributed under two copyrights: the GNU Genral
+ Public License, and the Artistic License. Any program that uses the
+ interpreter must adhere to rules of one of these licenses.
+
+
+ H.1. The GNU Public License
+
+
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+
+
+
+ The licenses for most software are designed to take away your freedom
+ to share and change it. By contrast, the GNU General Public License
+ is intended to guarantee your freedom to share and change free soft-
+ ware--to make sure the software is free for all its users. This Gen-
+ eral Public License applies to most of the Free Software Foundation's
+ software and to any other program whose authors commit to using it.
+ (Some other Free Software Foundation software is covered by the GNU
+ Library General Public License instead.) You can apply it to your
+ programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+ price. Our General Public Licenses are designed to make sure that you
+ have the freedom to distribute copies of free software (and charge for
+ this service if you wish), that you receive source code or can get it
+ if you want it, that you can change the software or use pieces of it
+ in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+ anyone to deny you these rights or to ask you to surrender the rights.
+ These restrictions translate to certain responsibilities for you if
+ you distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+ gratis or for a fee, you must give the recipients all the rights that
+ you have. You must make sure that they, too, receive or can get the
+ source code. And you must show them these terms so they know their
+ rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+ (2) offer you this license which gives you legal permission to copy,
+ distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+ that everyone understands that there is no warranty for this free
+ software. If the software is modified by someone else and passed on,
+ we want its recipients to know that what they have is not the
+ original, so that any problems introduced by others will not reflect
+ on the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+ patents. We wish to avoid the danger that redistributors of a free
+ program will individually obtain patent licenses, in effect making the
+ program proprietary. To prevent this, we have made it clear that any
+ patent must be licensed for everyone's free use or not licensed at
+ all.
+
+ The precise terms and conditions for copying, distribution and
+ modification follow.
+
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+
+
+
+ 0. This License applies to any program or other work which contains a
+ notice placed by the copyright holder saying it may be distributed
+ under the terms of this General Public License. The "Program", below,
+ refers to any such program or work, and a "work based on the Program"
+ means either the Program or any derivative work under copyright law:
+ that is to say, a work containing the Program or a portion of it,
+ either verbatim or with modifications and/or translated into another
+ language. (Hereinafter, translation is included without limitation in
+ the term "modification".) Each licensee is addressed as "you".
+
+ Activities other than copying, distribution and modification are not
+ covered by this License; they are outside its scope. The act of
+ running the Program is not restricted, and the output from the Program
+ is covered only if its contents constitute a work based on the Program
+ (independent of having been made by running the Program). Whether
+ that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's source
+ code as you receive it, in any medium, provided that you conspicuously
+ and appropriately publish on each copy an appropriate copyright notice
+ and disclaimer of warranty; keep intact all the notices that refer to
+ this License and to the absence of any warranty; and give any other
+ recipients of the Program a copy of this License along with the
+ Program.
+
+ You may charge a fee for the physical act of transferring a copy, and
+ you may at your option offer warranty protection in exchange for a
+ fee.
+
+ 2. You may modify your copy or copies of the Program or any portion of
+ it, thus forming a work based on the Program, and copy and distribute
+ such modifications or work under the terms of Section 1 above,
+ provided that you also meet all of these conditions:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+
+
+
+ These requirements apply to the modified work as a whole. If identi-
+ fiable sections of that work are not derived from the Program, and can
+ be reasonably considered independent and separate works in themselves,
+ then this License, and its terms, do not apply to those sections when
+ you distribute them as separate works. But when you distribute the
+ same sections as part of a whole which is a work based on the Program,
+ the distribution of the whole must be on the terms of this License,
+ whose permissions for other licensees extend to the entire whole, and
+ thus to each and every part regardless of who wrote it.
+
+ Thus, it is not the intent of this section to claim rights or contest
+ your rights to work written entirely by you; rather, the intent is to
+ exercise the right to control the distribution of derivative or
+ collective works based on the Program.
+
+ In addition, mere aggregation of another work not based on the Program
+ with the Program (or with a work based on the Program) on a volume of
+ a storage or distribution medium does not bring the other work under
+ the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+ under Section 2) in object code or executable form under the terms of
+ Sections 1 and 2 above provided that you also do one of the following:
+
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+
+
+ The source code for a work means the preferred form of the work for
+ making modifications to it. For an executable work, complete source
+ code means all the source code for all modules it contains, plus any
+ associated interface definition files, plus the scripts used to con-
+ trol compilation and installation of the executable. However, as a
+ special exception, the source code distributed need not include any-
+ thing that is normally distributed (in either source or binary form)
+ with the major components (compiler, kernel, and so on) of the operat-
+ ing system on which the executable runs, unless that component itself
+ accompanies the executable.
+
+ If distribution of executable or object code is made by offering
+ access to copy from a designated place, then offering equivalent
+ access to copy the source code from the same place counts as
+ distribution of the source code, even though third parties are not
+ compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+ except as expressly provided under this License. Any attempt
+ otherwise to copy, modify, sublicense or distribute the Program is
+ void, and will automatically terminate your rights under this License.
+ However, parties who have received copies, or rights, from you under
+ this License will not have their licenses terminated so long as such
+ parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+ signed it. However, nothing else grants you permission to modify or
+ distribute the Program or its derivative works. These actions are
+ prohibited by law if you do not accept this License. Therefore, by
+ modifying or distributing the Program (or any work based on the
+ Program), you indicate your acceptance of this License to do so, and
+ all its terms and conditions for copying, distributing or modifying
+ the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+ Program), the recipient automatically receives a license from the
+ original licensor to copy, distribute or modify the Program subject to
+ these terms and conditions. You may not impose any further
+ restrictions on the recipients' exercise of the rights granted herein.
+ You are not responsible for enforcing compliance by third parties to
+ this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+ infringement or for any other reason (not limited to patent issues),
+ conditions are imposed on you (whether by court order, agreement or
+ otherwise) that contradict the conditions of this License, they do not
+ excuse you from the conditions of this License. If you cannot
+ distribute so as to satisfy simultaneously your obligations under this
+ License and any other pertinent obligations, then as a consequence you
+ may not distribute the Program at all. For example, if a patent
+ license would not permit royalty-free redistribution of the Program by
+ all those who receive copies directly or indirectly through you, then
+ the only way you could satisfy both it and this License would be to
+ refrain entirely from distribution of the Program.
+
+ If any portion of this section is held invalid or unenforceable under
+ any particular circumstance, the balance of the section is intended to
+ apply and the section as a whole is intended to apply in other
+ circumstances.
+
+ It is not the purpose of this section to induce you to infringe any
+ patents or other property right claims or to contest validity of any
+ such claims; this section has the sole purpose of protecting the
+ integrity of the free software distribution system, which is
+ implemented by public license practices. Many people have made
+ generous contributions to the wide range of software distributed
+ through that system in reliance on consistent application of that
+ system; it is up to the author/donor to decide if he or she is willing
+ to distribute software through any other system and a licensee cannot
+ impose that choice.
+
+ This section is intended to make thoroughly clear what is believed to
+ be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+ certain countries either by patents or by copyrighted interfaces, the
+ original copyright holder who places the Program under this License
+ may add an explicit geographical distribution limitation excluding
+ those countries, so that distribution is permitted only in or among
+ countries not thus excluded. In such case, this License incorporates
+ the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new
+ versions of the General Public License from time to time. Such new
+ versions will be similar in spirit to the present version, but may
+ differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the Program
+ specifies a version number of this License which applies to it and
+ "any later version", you have the option of following the terms and
+ conditions either of that version or of any later version published by
+ the Free Software Foundation. If the Program does not specify a
+ version number of this License, you may choose any version ever
+ published by the Free Software Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+ programs whose distribution conditions are different, write to the
+ author to ask for permission. For software which is copyrighted by
+ the Free Software Foundation, write to the Free Software Foundation;
+ we sometimes make exceptions for this. Our decision will be guided by
+ the two goals of preserving the free status of all derivatives of our
+ free software and of promoting the sharing and reuse of software
+ generally.
+
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+ FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+ OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+ PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+ OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+ PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+ REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+ REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+ INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+ OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+ TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+ PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+
+
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+ possible use to the public, the best way to achieve this is to make it
+ free software which everyone can redistribute and change under these
+ terms.
+
+ To do so, attach the following notices to the program. It is safest
+ to attach them to the start of each source file to most effectively
+ convey the exclusion of warranty; and each file should have at least
+ the "copyright" line and a pointer to where the full notice is found.
+
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+
+
+ Also add information on how to contact you by electronic and paper
+ mail.
+
+ If the program is interactive, make it output a short notice like this
+ when it starts in an interactive mode:
+
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+
+
+
+ The hypothetical commands `show w' and `show c' should show the appro-
+ priate parts of the General Public License. Of course, the commands
+ you use may be called something other than `show w' and `show c'; they
+ could even be mouse-clicks or menu items--whatever suits your program.
+
+ You should also get your employer (if you work as a programmer) or
+ your school, if any, to sign a "copyright disclaimer" for the program,
+ if necessary. Here is a sample; alter the names:
+
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+
+
+ This General Public License does not permit incorporating your program
+ into proprietary programs. If your program is a subroutine library,
+ you may consider it more useful to permit linking proprietary applica-
+ tions with the library. If this is what you want to do, use the GNU
+ Library General Public License instead of this License.
+
+
+ H.2. The Artistic License
+
+
+
+ The "Artistic License"
+
+ Preamble
+
+
+
+
+ The intent of this document is to state the conditions under which a
+ Package may be copied, such that the Copyright Holder maintains some
+ semblance of artistic control over the development of the package,
+ while giving the users of the package the right to use and distribute
+ the Package in a more-or-less customary fashion, plus the right to
+ make reasonable modifications.
+
+ Definitions:
+
+
+ "Package" refers to the collection of files distributed by the
+ Copyright Holder, and derivatives of that collection of files
+ created through textual modification.
+
+ "Standard Version" refers to such a Package if it has not been
+ modified, or has been modified in accordance with the wishes
+ of the Copyright Holder as specified below.
+
+ "Copyright Holder" is whoever is named in the copyright or
+ copyrights for the package.
+
+ "You" is you, if you're thinking about copying or distributing
+ this Package.
+
+ "Reasonable copying fee" is whatever you can justify on the
+ basis of media cost, duplication charges, time of people involved,
+ and so on. (You will not be required to justify it to the
+ Copyright Holder, but only to the computing community at large
+ as a market that must bear the fee.)
+
+ "Freely Available" means that no fee is charged for the item
+ itself, though there may be fees involved in handling the item.
+ It also means that recipients of the item may redistribute it
+ under the same conditions they received it.
+
+
+
+
+ 1. You may make and give away verbatim copies of the source form of
+ the Standard Version of this Package without restriction, provided
+ that you duplicate all of the original copyright notices and associ-
+ ated disclaimers.
+
+ 2. You may apply bug fixes, portability fixes and other modifications
+ derived from the Public Domain or from the Copyright Holder. A
+ Package modified in such a way shall still be considered the Standard
+ Version.
+
+ 3. You may otherwise modify your copy of this Package in any way,
+ provided that you insert a prominent notice in each changed file
+ stating how and when you changed that file, and provided that you do
+ at least ONE of the following:
+
+
+ a) place your modifications in the Public Domain or otherwise make them
+ Freely Available, such as by posting said modifications to Usenet or
+ an equivalent medium, or placing the modifications on a major archive
+ site such as uunet.uu.net, or by allowing the Copyright Holder to include
+ your modifications in the Standard Version of the Package.
+
+ b) use the modified Package only within your corporation or organization.
+
+ c) rename any non-standard executables so the names do not conflict
+ with standard executables, which must also be provided, and provide
+ a separate manual page for each non-standard executable that clearly
+ documents how it differs from the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+
+
+
+ 4. You may distribute the programs of this Package in object code or
+ executable form, provided that you do at least ONE of the following:
+
+
+ a) distribute a Standard Version of the executables and library files,
+ together with instructions (in the manual page or equivalent) on where
+ to get the Standard Version.
+
+ b) accompany the distribution with the machine-readable source of
+ the Package with your modifications.
+
+ c) give non-standard executables non-standard names, and clearly
+ document the differences in manual pages (or equivalent), together
+ with instructions on where to get the Standard Version.
+
+ d) make other distribution arrangements with the Copyright Holder.
+
+
+
+
+ 5. You may charge a reasonable copying fee for any distribution of
+ this Package. You may charge any fee you choose for support of this
+ Package. You may not charge a fee for this Package itself. However,
+ you may distribute this Package in aggregate with other (possibly com-
+ mercial) programs as part of a larger (possibly commercial) software
+ distribution provided that you do not advertise this Package as a
+ product of your own. You may embed this Package's interpreter within
+ an executable of yours (by linking); this shall be construed as a mere
+ form of aggregation, provided that the complete Standard Version of
+ the interpreter is so embedded.
+
+ 6. The scripts and library files supplied as input to or produced as
+ output from the programs of this Package do not automatically fall
+ under the copyright of this Package, but belong to whomever generated
+ them, and may be sold commercially, and may be aggregated with this
+ Package. If such scripts or library files are aggregated with this
+ Package via the so-called "undump" or "unexec" methods of producing a
+ binary executable image, then distribution of such an image shall
+ neither be construed as a distribution of this Package nor shall it
+ fall under the restrictions of Paragraphs 3 and 4, provided that you
+ do not represent such an executable image as a Standard Version of
+ this Package.
+ 7. C subroutines (or comparably compiled subroutines in other
+ languages) supplied by you and linked into this Package in order to
+ emulate subroutines and variables of the language defined by this
+ Package shall not be considered part of this Package, but are the
+ equivalent of input as in Paragraph 6, provided these subroutines do
+ not change the language in any way that would cause it to fail the
+ regression tests for the language.
+
+ 8. Aggregation of this Package with a commercial distribution is
+ always permitted provided that the use of this Package is embedded;
+ that is, when no overt attempt is made to make this Package's
+ interfaces visible to the end user of the commercial distribution.
+ Such use shall not be construed as a distribution of this Package.
+
+ 9. The name of the Copyright Holder may not be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+ 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Table of Contents
+
+
+ 1. Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
+ 1.1. A Brief History of S-Lang . . . . . . . . . . . . . . . . . . 4
+ 1.2. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 4
+ 2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 6
+ 3. Interpreter Interface . . . . . . . . . . . . . . . . . . . . . 7
+ 3.1. Embedding the Interpreter . . . . . . . . . . . . . . . . . . 7
+ 3.2. Calling the Interpreter . . . . . . . . . . . . . . . . . . . 8
+ 3.3. Intrinsic Functions . . . . . . . . . . . . . . . . . . . . . 8
+ 3.3.1. Restrictions on Intrinsic Functions . . . . . . . . . . . . 9
+ 3.3.2. Adding a New Intrinsic . . . . . . . . . . . . . . . . . . 10
+ 3.3.3. More Complicated Intrinsics . . . . . . . . . . . . . . . . 11
+ 3.4. Intrinsic Variables . . . . . . . . . . . . . . . . . . . . . 13
+ 3.5. Aggregate Data Objects . . . . . . . . . . . . . . . . . . . 15
+ 3.5.1. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 16
+ 3.5.2. Structures . . . . . . . . . . . . . . . . . . . . . . . . 18
+ 3.5.2.1. Interpreter Structures . . . . . . . . . . . . . . . . . 18
+ 3.5.2.2. Intrinsic Structures . . . . . . . . . . . . . . . . . . 19
+ 4. Keyboard Interface . . . . . . . . . . . . . . . . . . . . . . 22
+ 4.1. Initializing the Keyboard Interface . . . . . . . . . . . . . 22
+ 4.2. Resetting the Keyboard Interface . . . . . . . . . . . . . . 23
+ 4.3. Initializing the SLkp Routines . . . . . . . . . . . . . . . 23
+ 4.4. Setting the Interrupt Handler . . . . . . . . . . . . . . . . 24
+ 4.5. Reading Keyboard Input with SLang_getkey . . . . . . . . . . 25
+ 4.6. Reading Keyboard Input with SLkp_getkey . . . . . . . . . . . 26
+ 4.7. Buffering Input . . . . . . . . . . . . . . . . . . . . . . . 27
+ 4.8. Global Variables . . . . . . . . . . . . . . . . . . . . . . 28
+ 5. Screen Management . . . . . . . . . . . . . . . . . . . . . . . 29
+ 5.1. Initialization . . . . . . . . . . . . . . . . . . . . . . . 29
+ 5.2. Resetting SLsmg . . . . . . . . . . . . . . . . . . . . . . . 29
+ 5.3. Handling Screen Resize Events . . . . . . . . . . . . . . . . 30
+ 5.4. SLsmg Functions . . . . . . . . . . . . . . . . . . . . . . . 31
+ 5.4.1. Positioning the cursor . . . . . . . . . . . . . . . . . . 31
+ 5.4.2. Writing to the Display . . . . . . . . . . . . . . . . . . 32
+ 5.4.3. Erasing the Display . . . . . . . . . . . . . . . . . . . . 33
+ 5.4.4. Setting Character Attributes . . . . . . . . . . . . . . . 33
+ 5.4.5. Lines and Alternate Character Sets . . . . . . . . . . . . 35
+ 5.4.6. Miscellaneous Functions . . . . . . . . . . . . . . . . . . 35
+ 5.5. Variables . . . . . . . . . . . . . . . . . . . . . . . . . . 36
+ 5.6. Hints for using SLsmg . . . . . . . . . . . . . . . . . . . . 36
+ 6. Signal Functions . . . . . . . . . . . . . . . . . . . . . . . 37
+ 7. Searching Functions . . . . . . . . . . . . . . . . . . . . . . 39
+ 7.1. Regular Expressions . . . . . . . . . . . . . . . . . . . . . 39
+ 7.2. Simple Searches . . . . . . . . . . . . . . . . . . . . . . . 39
+ 7.3. Initialization . . . . . . . . . . . . . . . . . . . . . . . 39
+ 7.4. SLsearch . . . . . . . . . . . . . . . . . . . . . . . . . . 39
+ H. Copyright . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
+ H.1. The GNU Public License . . . . . . . . . . . . . . . . . . . 41
+ H.2. The Artistic License . . . . . . . . . . . . . . . . . . . . 47
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ebin/.gitignore b/ebin/.gitignore
new file mode 100644
index 0000000..17278c0
--- /dev/null
+++ b/ebin/.gitignore
@@ -0,0 +1 @@
+*.beam
diff --git a/include.mk b/include.mk
new file mode 100644
index 0000000..9905e80
--- /dev/null
+++ b/include.mk
@@ -0,0 +1,15 @@
+
+CC=gcc
+ERLDIR=/usr/local/lib/erlang
+SLANG_INCLUDE=/usr/include/slang
+LD_SHARED=ld -shared
+
+ERLC = erlc
+ERLC_FLAGS+=-W $(DEBUG_FLAGS)
+
+../ebin/%.beam: %.erl
+ $(ERLC) -b beam $(ERLC_FLAGS) -o ../ebin $<
+
+%.beam: %.erl
+ $(ERLC) -b beam $(ERLC_FLAGS) $<
+
diff --git a/include.mk.in b/include.mk.in
new file mode 100644
index 0000000..6d08a9d
--- /dev/null
+++ b/include.mk.in
@@ -0,0 +1,15 @@
+
+CC=gcc
+ERLDIR=@ERLDIR@
+SLANG_INCLUDE=@SLANG_INCLUDE@
+LD_SHARED=@LD_SHARED@
+
+ERLC = erlc
+ERLC_FLAGS+=-W $(DEBUG_FLAGS)
+
+../ebin/%.beam: %.erl
+ $(ERLC) -b beam $(ERLC_FLAGS) -o ../ebin $<
+
+%.beam: %.erl
+ $(ERLC) -b beam $(ERLC_FLAGS) $<
+
diff --git a/include/slang.hrl b/include/slang.hrl
new file mode 100644
index 0000000..9d70d6c
--- /dev/null
+++ b/include/slang.hrl
@@ -0,0 +1,84 @@
+%%%----------------------------------------------------------------------
+%%% File : slang.hrl
+%%% Author : Claes Wikstrom <klacke@kaja.hemma.net>
+%%% Purpose :
+%%% Created : 22 Nov 2000 by Claes Wikstrom <klacke@kaja.hemma.net>
+%%%----------------------------------------------------------------------
+
+-author('klacke@kaja.hemma.net').
+
+
+%% Keypad constants
+-define (SL_KEY_ERR, 16#FFFF).
+-define (SL_KEY_UP, 16#101).
+-define (SL_KEY_DOWN, 16#102).
+-define (SL_KEY_LEFT, 16#103).
+-define (SL_KEY_RIGHT, 16#104).
+-define (SL_KEY_PPAGE, 16#105).
+-define (SL_KEY_NPAGE, 16#106).
+-define (SL_KEY_HOME, 16#107).
+-define (SL_KEY_END, 16#108).
+-define (SL_KEY_A1, 16#109).
+-define (SL_KEY_A3, 16#10A).
+-define (SL_KEY_B2, 16#10B).
+-define (SL_KEY_C1, 16#10C).
+-define (SL_KEY_C3, 16#10D).
+-define (SL_KEY_REDO, 16#10E).
+-define (SL_KEY_UNDO, 16#10F).
+-define (SL_KEY_BACKSPACE, 16#110).
+-define (SL_KEY_ENTER, 16#111).
+-define (SL_KEY_IC, 16#112).
+-define (SL_KEY_DELETE, 16#113).
+-define (SL_KEY_F0, 16#200).
+-define (SL_KEY_F(X), (?SL_KEY_F0 + X)).
+
+
+
+%% define some common signal numbers
+-define(SIGINT, 1).
+-define(SIGTSTP, 2).
+-define(SIGQUIT, 3).
+-define(SIGTTOU, 4).
+-define(SIGTTIN, 5).
+-define(SIGWINCH,6).
+
+
+
+%% variable defines
+-define(baud_rate, 1).
+-define(read_fd, 2).
+-define(abort_char, 3).
+-define(ignore_user_abort, 4).
+-define(input_buffer_len, 5).
+-define(keyboard_quit, 6).
+-define(last_key_char, 7).
+-define(rl_eof_char, 8).
+-define(rline_quit, 9).
+-define(screen_rows, 10).
+-define(screen_cols, 11).
+-define(tab_width, 12).
+-define(newline_behaviour, 13).
+-define(error, 14).
+-define(version, 15).
+-define(backspace_moves, 16).
+-define(display_eight_bit, 17).
+
+
+-define('NEWLINE_IGNORED', 0). %% default
+-define('NEWLINE_MOVES', 1). %% moves to next line, column 0
+-define('NEWLINE_SCROLLS', 2). %% moves but scrolls at bottom of screen
+-define('NEWLINE_PRINTABLE', 3). %% prints as ^J
+
+
+
+
+
+-ifdef (debug).
+-define(Debug(F, A),
+ slang:debug(?FILE,?LINE, F, A)).
+-else.
+-define(Debug(F, A),debug_disabled).
+-endif.
+
+
+
diff --git a/mk.include b/mk.include
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/mk.include
diff --git a/priv/.gitignore b/priv/.gitignore
new file mode 100644
index 0000000..140f8cf
--- /dev/null
+++ b/priv/.gitignore
@@ -0,0 +1 @@
+*.so
diff --git a/slang.pub b/slang.pub
new file mode 100644
index 0000000..2d3d4bd
--- /dev/null
+++ b/slang.pub
@@ -0,0 +1,11 @@
+{name, "slang"}.
+{vsn, {1,0}}.
+{summary, "terminal library for Erlang"}.
+{author, "Claes Wikstrom", "klacke@bluetail.com", "981123"}.
+{keywords, ["quack"]}.
+{needs, []}.
+{abstract,"This is a library which makes it possible to write terminal based aplications al'a vi/emacs/mutt/slrn in erlang."}.
+
+
+
+
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..b383c01
--- /dev/null
+++ b/src/Makefile
@@ -0,0 +1,23 @@
+
+
+
+ifeq ($(TYPE),debug)
+DEBUG_FLAGS = -Ddebug
+else
+DEBUG_FLAGS =
+endif
+
+include ../include.mk
+include ../vsn.mk
+
+ERLC_FLAGS+=-W $(DEBUG_FLAGS)
+MODULES = slang
+
+TARGETS = $(MODULES:%=../ebin/%.beam) ../ebin/slang.app
+
+
+all debug: $(TARGETS)
+clean:
+ rm -f $(TARGETS)
+../ebin/slang.app: slang.app.src
+ cat slang.app.src | sed 's/%VSN%/${SLANG_VSN}/' > ../ebin/slang.app
diff --git a/src/slang.app.src b/src/slang.app.src
new file mode 100644
index 0000000..c602303
--- /dev/null
+++ b/src/slang.app.src
@@ -0,0 +1,8 @@
+{application,slang,
+ [{description,"tty interface"},
+ {vsn,"%VSN%"},
+ {modules,[slang]},
+ {registered,[]},
+ {env,[]},
+ {applications,[kernel,stdlib]}]}.
+
diff --git a/src/slang.erl b/src/slang.erl
new file mode 100644
index 0000000..eca5507
--- /dev/null
+++ b/src/slang.erl
@@ -0,0 +1,644 @@
+%%% FILE : slang.erl
+%%% Author : Claes Wikstrom <klacke@kaja.hemma.net>
+%%% Purpose : interface to the cool multi platform tty slang lib
+%%% Created : 22 Nov 2000 by Claes Wikstrom <klacke@kaja.hemma.net>
+%%%----------------------------------------------------------------------
+
+-module(slang).
+-author('klacke@kaja.hemma.net').
+
+-include("../include/slang.hrl").
+-include("slang_int.hrl").
+
+-compile(export_all).
+
+
+stop_user() ->
+ Flag=process_flag(trap_exit, true),
+ {links, Lks0} = process_info(whereis(user),links),
+ Lks = lists:delete(whereis(error_logger), Lks0),
+
+ Hs = gen_event:which_handlers(error_logger),
+
+ case lists:member(error_logger_tty_h, Hs) of
+ true ->
+ error_logger:delete_report_handler(error_logger_tty_h),
+
+
+ supervisor:terminate_child(kernel_sup, user),
+ lists:foreach(fun(Pid) ->
+ exit(Pid, kill)
+ end, Lks),
+ {stopdata, true};
+ false ->
+ {stopdata, false}
+ end.
+
+
+restart_user({stopdata, TTY_H}) ->
+ case TTY_H of
+ true ->
+ supervisor:restart_child(kernel_sup, user),
+ wait_user(whereis(user)),
+ error_logger:add_report_handler(error_logger_tty_h);
+ false ->
+ supervisor:restart_child(kernel_sup, user)
+ end.
+
+
+%% restart chaild ain't synced
+wait_user(undefined) ->
+ timer:sleep(200),
+ wait_user(whereis(user));
+wait_user(_) ->
+ ok.
+
+
+init_tty(AbortChar, FlowControl, Opost) ->
+ P = gp(),
+ p_cmd(P, ?INIT_TTY, [{int, AbortChar},
+ {int, FlowControl},
+ {int, Opost}], int32).
+
+set_abort_signal(null) ->
+ P = gp(),
+ p_cmd(P, ?SET_ABORT_SIGNAL, [{int, 0}], int32).
+
+getkey() ->
+ P = gp(),
+ p_cmd(P, ?GETKEY, [], int32).
+
+kp_getkey() ->
+ P = gp(),
+ p_cmd(P, ?KP_GETKEY, [], int32).
+
+
+kp_init() ->
+ P = gp(),
+ p_cmd(P, ?KP_INIT, [], int32).
+
+reset_tty() ->
+ P = gp(),
+ p_cmd(P, ?RESET_TTY, [], void).
+
+
+ungetkey(Char) ->
+ P = gp(),
+ p_cmd(P, ?GETKEY, [{char, Char}], void).
+
+
+%% read slang lib global variables
+getvar(Var) when atom(Var) ->
+ P = gp(),
+ p_cmd(P, ?GETVAR, [{int, encode_var(Var)}], int).
+
+%% set slang lib global variables
+setvar(Var, IntegerValue) when atom(Var) ->
+ P = gp(),
+ p_cmd(P, ?SETVAR, [{int, encode_var(Var)}, {int, IntegerValue}], void).
+
+
+isatty(Fd) ->
+ P = gp(),
+ p_cmd(P, ?ISATTY, [{int, Fd}], int).
+
+eformat(Fmt, Args) ->
+ P = gp(),
+ p_cmd(P,?EFORMAT, [{string, lists:flatten(io_lib:format(Fmt,Args))}],void).
+
+
+%% install Fun/0 as a Fun to be invoked
+%% on signal Sig
+
+signal(Sig, Fun) ->
+ P = gp(),
+ put({signal_handler, Sig}, Fun),
+ p_cmd(P,?SIGNAL, [{int, Sig}], void).
+
+
+%%% screen management
+
+
+smg_fill_region (R, C, Nr, Nc, Ch) ->
+ P = gp(),
+ p_cmd(P,?SMG_FILL_REGION, [{int,R}, {int, C},
+ {int, Nr}, {int, Nc},
+ {char, Ch}], void).
+
+smg_set_char_set (A) ->
+ P = gp(),
+ p_cmd(P, ?SMG_SET_CHAR_SET, [{int, A}], void).
+
+smg_suspend_smg () ->
+ P = gp(),
+ p_cmd(P, ?SMG_SUSPEND_SMG, [], int).
+
+smg_resume_smg () ->
+ P = gp(),
+ p_cmd(P, ?SMG_RESUME_SMG, [], int).
+
+smg_erase_eol () ->
+ P = gp(),
+ p_cmd(P, ?SMG_ERASE_EOL, [], void).
+
+smg_gotorc (R, C) ->
+ P = gp(),
+ p_cmd(P, ?SMG_GOTORC, [{int, R}, {int, C}], void).
+
+smg_erase_eos () ->
+ P = gp(),
+ p_cmd(P, ?SMG_ERASE_EOS, [], void).
+
+smg_reverse_video () ->
+ P = gp(),
+ p_cmd(P, ?SMG_REVERSE_VIDEO, [], void).
+
+smg_set_color (C) ->
+ P = gp(),
+ p_cmd(P, ?SMG_SET_COLOR, [{int, C}], void).
+
+smg_normal_video () ->
+ P = gp(),
+ p_cmd(P, ?SMG_NORMAL_VIDEO, [], void).
+
+smg_printf (Format, Args) ->
+ P = gp(),
+ Str = io_lib:format(Format, Args),
+ p_cmd(P, ?SMG_WRITE_STRING, [{string, lists:flatten(Str)}], void).
+
+smg_vprintf () ->
+ exit(nyi).
+
+smg_write_string (Str) ->
+ P = gp(),
+ p_cmd(P, ?SMG_WRITE_STRING, [{string, Str}], void).
+
+smg_write_nstring (S, N) ->
+ L = lists:flatten(N),
+ Len = length(L),
+ if
+ Len < N ->
+ smg_write_string(L ++ lists:duplicate(N - Len, 32));
+ true ->
+ smg_write_string(L)
+ end.
+
+smg_write_char (Ch) ->
+ P = gp(),
+ p_cmd(P, ?SMG_WRITE_CHAR, [{char, Ch}], void).
+
+smg_write_nchars (S, N) ->
+ L = lists:sublist(lists:flatten(S), N),
+ smg_write_string(L).
+
+smg_write_wrapped_string (S, R, C, Nr, Nc, Fill) ->
+ P = gp(),
+ p_cmd(P, ?SMG_WRITE_WRAPPED_STRING, [{string, S},{int, R}, {int, C},
+ {int, Nr}, {int, Nc}, {int, Fill}],
+ void).
+
+smg_cls () ->
+ P = gp(),
+ p_cmd(P, ?SMG_CLS, [], void).
+
+smg_refresh () ->
+ P = gp(),
+ p_cmd(P, ?SMG_REFRESH, [], void).
+
+smg_touch_lines (R, Nr) ->
+ P = gp(),
+ p_cmd(P, ?SMG_TOUCH_LINES, [{int, R}, {int, Nr}], void).
+
+smg_touch_screen () ->
+ P = gp(),
+ p_cmd(P, ?SMG_TOUCH_SCREEN, [], void).
+
+smg_init_smg () ->
+ P = gp(),
+ p_cmd(P, ?SMG_INIT_SMG, [], int).
+
+smg_reinit_smg () ->
+ P = gp(),
+ p_cmd(P, ?SMG_REINIT_SMG, [], void).
+
+smg_reset_smg () ->
+ P = gp(),
+ p_cmd(P, ?SMG_RESET_SMG, [], void).
+
+smg_char_at () ->
+ P = gp(),
+ p_cmd(P, ?SMG_CHAR_AT, [], int).
+
+%% 0 == NULL
+smg_set_screen_start (R, C) ->
+ P = gp(),
+ p_cmd(P, ?SMG_SET_SCREEN_START, [{int, R}, {int, C}], int_int).
+
+smg_draw_hline (Len) ->
+ P = gp(),
+ p_cmd(P, ?SMG_DRAW_HLINE, [{int, Len}], void).
+
+smg_draw_vline (Len) ->
+ P = gp(),
+ p_cmd(P, ?SMG_DRAW_VLINE, [{int, Len}], void).
+
+smg_draw_object (R, C, Obj) ->
+ P = gp(),
+ p_cmd(P, ?SMG_DRAW_OBJECT, [{int, R}, {int, C}, {int, Obj}], void).
+
+smg_draw_box (R, C, Dr, Dc) ->
+ P = gp(),
+ p_cmd(P, ?SMG_DRAW_BOX, [], void).
+
+smg_get_column () ->
+ P = gp(),
+ p_cmd(P, ?SMG_GET_COLUMN, [], int).
+
+smg_get_row () ->
+ P = gp(),
+ p_cmd(P, ?SMG_GET_RO, [], int).
+
+smg_forward (N) ->
+ P = gp(),
+ p_cmd(P, ?SMG_FORWARD, [{int, N}], void).
+
+smg_write_color_chars (S, Len) ->
+ P = gp(),
+ p_cmd(P, ?SMG_WRITE_COLOR_CHARS, [{smg_char_type, S}, {int, Len}], void).
+
+smg_read_raw (Len) ->
+ P = gp(),
+ p_cmd(P, ?SMG_READ_RAW, [{int, Len}], smg_char_type).
+
+smg_write_raw (Str, Len) ->
+ P = gp(),
+ p_cmd(P, ?SMG_WRITE_RAW, [{smg_char_type, Str}, {int, Len}], int).
+
+smg_set_color_in_region (Color, R, C, Dr, Dc) ->
+ P = gp(),
+ p_cmd(P, ?SMG_SET_COLOR_IN_REGION, [{int, Color}, {int, R}, {int, C},
+ {int, Dr}, {int, Dc}], void).
+
+
+
+
+
+%%%%%%% auxilliary functions %%%%%%%%%%%%%%%%%
+
+
+encode_var(baud_rate) -> 1;
+encode_var(read_fd) -> 2;
+encode_var(abort_char) -> 3;
+encode_var(ignore_user_abort) -> 4;
+encode_var(input_buffer_len) -> 5;
+encode_var(keyboard_quit) -> 6;
+encode_var(last_key_char) -> 7;
+encode_var(rl_eof_char) -> 8;
+encode_var(rline_quit) -> 9;
+encode_var(screen_rows) -> 10;
+encode_var(screen_cols) -> 11;
+encode_var(tab_width) -> 12;
+encode_var(newline_behaviour) -> 13;
+encode_var(error) -> 14;
+encode_var(version) -> 15;
+encode_var(backspace_moves) -> 16;
+encode_var(display_eight_bit) -> 17.
+
+
+
+p_cmd(P, Op, ArgList, void) ->
+ Cmd = [Op | mk_args(ArgList)],
+ %?Debug("CMD ~p~n", [Cmd]),
+ P ! {self(), {command, Cmd}};
+
+
+p_cmd(P, Op, ArgList, Expect) ->
+ Cmd = [Op | mk_args(ArgList)],
+ P ! {self(), {command, Cmd}},
+ case rec_loop(P, Expect, nosig) of
+ {Reply, nosig} ->
+ Reply;
+ {Reply, SignalFun} ->
+ SignalFun(),
+ Reply
+ end.
+
+rec_loop(P, Expect, Sig) ->
+ receive
+ {P, {data, [1 |What]}} ->
+ {expect(What, Expect), Sig};
+ {P, {data, [0 , X1, X2, X3, X4]}} ->
+ SigNo = ?i32(X1,X2, X3, X4),
+ case get({signal_handler, SigNo}) of
+ undefined ->
+ rec_loop(P, Expect, Sig);
+ Fun ->
+ rec_loop(P, Expect, Fun)
+ end;
+ {'EXIT', P, Reason} ->
+ exit(Reason)
+ after 200 ->
+ P ! {self(), {command, [255]}}, % tick
+ rec_loop(P, Expect, Sig)
+ end.
+
+
+expect(List, smg_char_type) ->
+ upack_smg_char_type(List);
+expect([X1,X2, X3, X4], int32) ->
+ ?i32(X1,X2, X3, X4);
+expect([X1,X2, X3, X4], int) ->
+ ?i32(X1,X2, X3, X4);
+expect([X1,X2, X3, X4, Y1, Y2, Y3, Y4], int_int) ->
+ {?i32(X1,X2, X3, X4), ?i32(Y1, Y2, Y3, Y4)};
+
+expect(List, string) ->
+ List.
+
+
+upack_smg_char_type([X1, X2 |Tail]) ->
+ [?u16(X1, X2) | upack_smg_char_type(Tail)];
+upack_smg_char_type([]) ->
+ [];
+upack_smg_char_type([X]) ->
+ [X].
+
+
+mk_args([]) ->
+ [];
+mk_args([{int, Int} |Tail]) when integer(Int) ->
+ [?int32(Int) | mk_args(Tail)];
+mk_args([{char, Char} |Tail]) when integer(Char) ->
+ [Char| mk_args(Tail)];
+mk_args([{string, Str} |Tail]) when list(Str) ->
+ [Str, 0 | mk_args(Tail)];
+mk_args([{string, Str} |Tail]) when atom(Str) ->
+ [atom_to_list(Str), 0 | mk_args(Tail)];
+mk_args([{smg_char_type, Str} |Tail]) when list(Str) ->
+ Len = 2 * length(Str),
+ List = [?int32(Len) | lists:map(fun(I) -> ?int16(I) end, Str)] ,
+ [List| mk_args(Tail)].
+
+
+open_slang_driver() ->
+ erl_ddll:start(),
+ Path=case code:priv_dir(slang) of
+ {error, _} ->
+ {ok, Dir, _} = regexp:sub(code:which(slang),
+ "ebin/slang.beam",[]),
+ Dir ++ "/priv";
+ Dir ->
+ Dir
+ end,
+ case erl_ddll:load_driver(Path, "slang_drv") of
+ ok ->
+ ok;
+ {error,{already_started, _}} ->
+ ok;
+ {error, What} ->
+ error_logger:format("Failed to open driver ~p~n", [What]),
+ exit(nodriver)
+ end,
+ P = open_port({spawn, slang_drv}, []),
+ P.
+
+
+gp() ->
+ case get(slang_port) of
+ undefined ->
+ Port = open_slang_driver(),
+ put(slang_port, Port),
+ Port;
+ Port ->
+ Port
+ end.
+
+
+%% all the not so necessary tt_ functions
+%% int
+tt_flush_output() ->
+ P = gp(),
+ p_cmd(P, ?TT_FLUSH_OUTPUT, [], int).
+
+%% void
+tt_set_scroll_region(X,Y) ->
+ P = gp(),
+ p_cmd(P, ?TT_SET_SCROLL_REGION, [{int, X}, {int, Y}], void).
+
+% void
+tt_reset_scroll_region() ->
+ P = gp(),
+ p_cmd(P, ?TT_RESET_SCROLL_REGION,[],void).
+
+tt_reverse_video(Int) ->
+ P = gp(),
+ p_cmd(P, ?TT_REVERSE_VIDEO,[{int, Int}],void).
+
+tt_bold_video() ->
+ P = gp(),
+ p_cmd(P, ?TT_BOLD_VIDEO,[],void).
+
+tt_begin_insert() ->
+ P = gp(),
+ p_cmd(P, ?TT_BEGIN_INSERT,[],void).
+
+tt_end_insert() ->
+ P = gp(),
+ p_cmd(P, ?TT_END_INSERT,[],void).
+
+tt_del_eol() ->
+ P = gp(),
+ p_cmd(P, ?TT_DEL_EOL,[],void).
+
+tt_goto_rc() ->
+ P = gp(),
+ p_cmd(P, ?TT_GOTO_RC,[],void).
+
+tt_delete_nlines(Int) ->
+ P = gp(),
+ p_cmd(P, ?TT_DELETE_NLINES,[{int, Int}],void).
+
+tt_delete_char() ->
+ P = gp(),
+ p_cmd(P, ?TT_DELETE_CHAR,[],void).
+
+tt_erase_line() ->
+ P = gp(),
+ p_cmd(P, ?TT_ERASE_LINE,[],void).
+
+tt_normal_video() ->
+ P = gp(),
+ p_cmd(P, ?TT_NORMAL_VIDEO,[],void).
+
+tt_cls() ->
+ P = gp(),
+ p_cmd(P, ?TT_CLS,[],void).
+
+tt_beep() ->
+ P = gp(),
+ p_cmd(P, ?TT_BEEP,[],void).
+
+tt_reverse_index(Int) ->
+ P = gp(),
+ p_cmd(P, ?TT_REVERSE_INDEX,[{int, Int}],void).
+
+tt_smart_puts(S1, S2, X, Y) ->
+ P = gp(),
+ p_cmd(P, ?TT_SMART_PUTS,[{smg_char_type, S1}, {smg_char_type, S2},
+ {int, X}, {int, Y}],void).
+
+tt_write_string(Str) ->
+ P = gp(),
+ p_cmd(P, ?TT_WRITE_STRING,[{string, Str}],void).
+
+tt_putchar(Char) ->
+ P = gp(),
+ p_cmd(P, ?TT_PUTCHAR,[{int, Char}],void).
+
+tt_init_video() ->
+ P = gp(),
+ p_cmd(P, ?TT_INIT_VIDEO,[],int).
+
+tt_reset_video() ->
+ P = gp(),
+ p_cmd(P, ?TT_RESET_VIDEO,[],void).
+
+tt_get_terminfo() ->
+ P = gp(),
+ p_cmd(P, ?TT_GET_TERMINFO,[],void).
+
+tt_get_screen_size() ->
+ P = gp(),
+ p_cmd(P, ?TT_GET_SCREEN_SIZE,[],void).
+
+tt_set_cursor_visibility(Int) ->
+ P = gp(),
+ p_cmd(P, ?TT_SET_CURSOR_VISIBILITY,[{int, Int}],int).
+
+tt_set_mouse_mode(X, Y) ->
+ P = gp(),
+ p_cmd(P, ?TT_SET_MOUSE_MODE,[{int, X}, {int, Y}],int).
+
+tt_initialize(Str) ->
+ P = gp(),
+ p_cmd(P, ?TT_INITIALIZE,[{string, Str}],int).
+
+
+tt_enable_cursor_keys() ->
+ P = gp(),
+ p_cmd(P, ?TT_ENABLE_CURSOR_KEYS,[],void).
+
+tt_set_term_vtxxx() ->
+ exit(nyi),
+ P = gp(),
+ p_cmd(P, ?TT_SET_TERM_VTXXX,[],void).
+
+tt_set_color_esc(Int, Str) ->
+ P = gp(),
+ p_cmd(P, ?TT_SET_COLOR_ESC,[{int, Int}, {string, Str}],void).
+
+tt_wide_width() ->
+ P = gp(),
+ p_cmd(P, ?TT_WIDE_WIDTH,[],void).
+
+tt_narrow_width() ->
+ P = gp(),
+ p_cmd(P, ?TT_NARROW_WIDTH,[],void).
+
+tt_set_alt_char_set() ->
+ P = gp(),
+ p_cmd(P, ?TT_SET_ALT_CHAR_SET,[],void).
+
+tt_write_to_status_line(Int, Str) ->
+ P = gp(),
+ p_cmd(P, ?TT_WRITE_TO_STATUS_LINE,[{int, Int}, {string, Str}],void).
+
+tt_disable_status_line() ->
+ P = gp(),
+ p_cmd(P, ?TT_DISABLE_STATUS_LINE,[],void).
+
+tt_tgetstr(Str) ->
+ P = gp(),
+ p_cmd(P, ?TT_TGETSTR,[{string, Str}],string).
+
+tt_tgetnum(Str) ->
+ P = gp(),
+ p_cmd(P, ?TT_TGETNUM,[{string, Str}],int).
+
+tt_tgetflag(Str) ->
+ P = gp(),
+ p_cmd(P, ?TT_TGETFLAG,[{string, Str}],int).
+
+tt_tigetent(Str) ->
+ P = gp(),
+ p_cmd(P, ?TT_TIGETENT,[{string, Str}],string).
+
+
+tt_tigetstr() ->
+ exit(nyi),
+ P = gp(),
+ p_cmd(P, ?TT_TIGETSTR,[],void).
+
+tt_tigetnum() ->
+ exit(nyi),
+ P = gp(),
+ p_cmd(P, ?TT_TIGETNUM,[],void).
+
+sltt_get_color_object(Int) ->
+ P = gp(),
+ p_cmd(P, ?SLTT_GET_COLOR_OBJECT,[{int, Int}], int).
+
+tt_set_color_object(Int, CType) ->
+ P = gp(),
+ p_cmd(P, ?TT_SET_COLOR_OBJECT,[{int, Int}, {int, CType}],void).
+
+tt_set_color(Obj, Name, Fg, Bg) ->
+ P = gp(),
+ p_cmd(P, ?TT_SET_COLOR,[{int, Obj}, {string, Name},
+ {string, Fg}, {string, Bg}],void).
+
+tt_set_mono(Int, Str, Attr) ->
+ P = gp(),
+ p_cmd(P, ?TT_SET_MONO,[{int, Int}, {string, Str},
+ {int, Attr}],void).
+
+tt_add_color_attribute(Int, Ctype) ->
+ P = gp(),
+ p_cmd(P, ?TT_ADD_COLOR_ATTRIBUTE,[{int, Int}, {int, Ctype}],void).
+
+tt_set_color_fgbg(Int, CT1, CT2) ->
+ P = gp(),
+ p_cmd(P, ?TT_SET_COLOR_FGBG,[{int, Int}, {int, CT1}, {int, CT2}],void).
+
+
+
+%% debug slang apps by tail -f 'ing /tmp/slang.debug
+%% use ?DEBUG(F, A) or slang:debug/2,
+
+debug(File, Line, Fmt, Args) ->
+ DFD = case get(slang_debug_fd) of
+ undefined ->
+ case file:open("/tmp/slang.debug", [append]) of
+ {ok, Fd} ->
+ put(slang_debug_fd, Fd),
+ Fd;
+ Err ->
+ exit({nodebugfd, Err})
+ end;
+ Fd ->
+ Fd
+ end,
+
+ Str = lists:flatten(
+ io_lib:format("DEBUG ~s:~p, pid ~w: ~n",
+ [filename:basename(File),
+ Line, self()])),
+
+ case io:format(DFD, Str ++ Fmt ++ "~n", Args) of
+ ok -> ok;
+ _ -> io:format(DFD, "ERROR ~p:~p: Pid ~w: (bad format)~n~p,~p~n",
+ [File, Line, self(), Fmt, Args]),
+
+ ok
+ end.
+
diff --git a/src/slang_int.hrl b/src/slang_int.hrl
new file mode 100644
index 0000000..0d47f7f
--- /dev/null
+++ b/src/slang_int.hrl
@@ -0,0 +1,180 @@
+%%%----------------------------------------------------------------------
+%%% File : slang_int.hrl
+%%% Author : Claes Wikstrom <klacke@kaja.hemma.net>
+%%% Purpose :
+%%% Created : 5 Dec 2000 by Claes Wikstrom <klacke@kaja.hemma.net>
+%%%----------------------------------------------------------------------
+
+
+-author('klacke@kaja.hemma.net').
+
+
+
+
+
+%% ops list
+
+
+-define(INIT_TTY, 1).
+-define(SET_ABORT_SIGNAL,2).
+-define(GETKEY, 3).
+-define(RESET_TTY, 4).
+-define(KP_GETKEY, 5).
+-define(UNGETKEY, 6).
+-define(SETVAR, 7).
+-define(GETVAR, 8).
+-define(KP_INIT, 9).
+
+%% screen mgm
+
+-define(SMG_FILL_REGION, 10).
+-define(SMG_SET_CHAR_SET, 11).
+-define(SMG_SUSPEND_SMG, 12).
+-define(SMG_RESUME_SMG, 13).
+-define(SMG_ERASE_EOL, 14).
+-define(SMG_GOTORC, 15).
+-define(SMG_ERASE_EOS, 16).
+-define(SMG_REVERSE_VIDEO, 17).
+-define(SMG_SET_COLOR, 18).
+-define(SMG_NORMAL_VIDEO, 19).
+-define(SMG_PRINTF, 20).
+-define(SMG_VPRINTF, 21).
+-define(SMG_WRITE_STRING, 22).
+-define(SMG_WRITE_NSTRING, 23).
+-define(SMG_WRITE_CHAR, 24).
+-define(SMG_WRITE_NCHARS, 25).
+-define(SMG_WRITE_WRAPPED_STRING, 26).
+-define(SMG_CLS, 27).
+-define(SMG_REFRESH, 28).
+-define(SMG_TOUCH_LINES, 29).
+-define(SMG_TOUCH_SCREEN, 30).
+-define(SMG_INIT_SMG, 31).
+-define(SMG_REINIT_SMG, 32).
+-define(SMG_RESET_SMG, 33).
+-define(SMG_CHAR_AT, 34).
+-define(SMG_SET_SCREEN_START, 35).
+-define(SMG_DRAW_HLINE, 36).
+-define(SMG_DRAW_VLINE, 37).
+-define(SMG_DRAW_OBJECT, 38).
+-define(SMG_DRAW_BOX, 39).
+-define(SMG_GET_COLUMN, 40).
+-define(SMG_GET_RO, 41).
+-define(SMG_FORWARD, 42).
+-define(SMG_WRITE_COLOR_CHARS, 43).
+-define(SMG_READ_RAW, 44).
+-define(SMG_WRITE_RAW, 45).
+-define(SMG_SET_COLOR_IN_REGION, 46).
+
+
+
+
+
+%% a whole loong list of tt_ function ops
+
+-define (TT_FLUSH_OUTPUT, 50).
+-define (TT_SET_SCROLL_REGION, 51).
+-define (TT_RESET_SCROLL_REGION, 52).
+-define (TT_REVERSE_VIDEO, 53).
+-define (TT_BOLD_VIDEO, 54).
+-define (TT_BEGIN_INSERT, 55).
+-define (TT_END_INSERT, 56).
+-define (TT_DEL_EOL, 57).
+-define (TT_GOTO_RC, 58).
+-define (TT_DELETE_NLINES, 59).
+-define (TT_DELETE_CHAR, 60).
+-define (TT_ERASE_LINE, 61).
+-define (TT_NORMAL_VIDEO, 62).
+-define (TT_CLS, 63).
+-define (TT_BEEP, 64).
+-define (TT_REVERSE_INDEX, 65).
+-define (TT_SMART_PUTS, 66).
+-define (TT_WRITE_STRING, 67).
+-define (TT_PUTCHAR, 68).
+-define (TT_INIT_VIDEO, 69).
+-define (TT_RESET_VIDEO, 70).
+-define (TT_GET_TERMINFO, 71).
+-define (TT_GET_SCREEN_SIZE, 72).
+-define (TT_SET_CURSOR_VISIBILITY, 73).
+-define (TT_SET_MOUSE_MODE, 74).
+-define (TT_INITIALIZE, 75).
+-define (TT_ENABLE_CURSOR_KEYS, 76).
+-define (TT_SET_TERM_VTXXX, 77).
+-define (TT_SET_COLOR_ESC, 78).
+-define (TT_WIDE_WIDTH, 79).
+-define (TT_NARROW_WIDTH, 80).
+-define (TT_SET_ALT_CHAR_SET, 81).
+-define (TT_WRITE_TO_STATUS_LINE, 82).
+-define (TT_DISABLE_STATUS_LINE, 83).
+-define (TT_TGETSTR, 84).
+-define (TT_TGETNUM, 85).
+-define (TT_TGETFLAG, 86).
+-define (TT_TIGETENT, 87).
+-define (TT_TIGETSTR, 88).
+-define (TT_TIGETNUM, 89).
+-define (SLTT_GET_COLOR_OBJECT, 90).
+-define (TT_SET_COLOR_OBJECT, 91).
+-define (TT_SET_COLOR, 92).
+-define (TT_SET_MONO, 93).
+-define (TT_ADD_COLOR_ATTRIBUTE, 94).
+-define (TT_SET_COLOR_FGBG, 95).
+
+
+%% aux functions
+-define(ISATTY, 100).
+-define(EFORMAT, 101).
+-define(SIGNAL, 102).
+-define(SIGNAL_CHECK, 103).
+
+
+%% int macros
+
+%%
+%% Int to bytes
+%%
+-define(int8(X), [(X) band 16#ff]).
+
+-define(int16(X), [((X) bsr 8) band 16#ff, (X) band 16#ff]).
+
+-define(int24(X), [((X) bsr 16) band 16#ff,
+ ((X) bsr 8) band 16#ff, (X) band 16#ff]).
+
+-define(int32(X),
+ [((X) bsr 24) band 16#ff, ((X) bsr 16) band 16#ff,
+ ((X) bsr 8) band 16#ff, (X) band 16#ff]).
+
+%% Bytes to unsigned
+-define(u64(X7,X6,X5,X4,X3,X2,X1,X0),
+ ( ((X7) bsl 56) bor ((X6) bsl 48) bor ((X5) bsl 40) bor
+ ((X4) bsl 32) bor ((X3) bsl 24) bor ((X2) bsl 16) bor
+ ((X1) bsl 8) bor (X0) )).
+
+-define(u32(X3,X2,X1,X0),
+ (((X3) bsl 24) bor ((X2) bsl 16) bor ((X1) bsl 8) bor (X0))).
+
+-define(u24(X2,X1,X0),
+ (((X2) bsl 16) bor ((X1) bsl 8) bor (X0))).
+
+-define(u16(X1,X0),
+ (((X1) bsl 8) bor (X0))).
+
+-define(u8(X0), (X0)).
+
+%% Bytes to signed
+-define(i32(X3,X2,X1,X0),
+ (?u32(X3,X2,X1,X0) -
+ (if (X3) > 127 -> 16#100000000; true -> 0 end))).
+
+-define(i24(X2,X1,X0),
+ (?u24(X2,X1,X0) -
+ (if (X2) > 127 -> 16#1000000; true -> 0 end))).
+
+-define(i16(X1,X0),
+ (?u16(X1,X0) -
+ (if (X1) > 127 -> 16#10000; true -> 0 end))).
+
+-define(i8(X0),
+ (?u8(X0) -
+ (if (X0) > 127 -> 16#100; true -> 0 end))).
+
+
+
diff --git a/src/slang_lib.erl b/src/slang_lib.erl
new file mode 100644
index 0000000..76f5550
--- /dev/null
+++ b/src/slang_lib.erl
@@ -0,0 +1,15 @@
+%%%----------------------------------------------------------------------
+%%% File : slang_lib.erl
+%%% Author : Claes Wikstrom <klacke@kaja.hemma.net>
+%%% Purpose :
+%%% Created : 4 Dec 2000 by Claes Wikstrom <klacke@kaja.hemma.net>
+%%%----------------------------------------------------------------------
+
+-module(slang_lib).
+-author('klacke@kaja.hemma.net').
+
+-include("slang.hrl").
+-compile(export_all).
+
+
+%% higher level functions for slang
diff --git a/vsn.mk b/vsn.mk
new file mode 100644
index 0000000..3094e64
--- /dev/null
+++ b/vsn.mk
@@ -0,0 +1 @@
+SLANG_VSN=1.0$(SERIALNO)