aboutsummaryrefslogtreecommitdiffhomepage
path: root/libslang/doc/OLD/help/slhelp.c
diff options
context:
space:
mode:
Diffstat (limited to 'libslang/doc/OLD/help/slhelp.c')
-rw-r--r--libslang/doc/OLD/help/slhelp.c587
1 files changed, 587 insertions, 0 deletions
diff --git a/libslang/doc/OLD/help/slhelp.c b/libslang/doc/OLD/help/slhelp.c
new file mode 100644
index 0000000..be7638f
--- /dev/null
+++ b/libslang/doc/OLD/help/slhelp.c
@@ -0,0 +1,587 @@
+#include "config.h"
+
+#include <stdio.h>
+
+#ifdef unix
+# include <signal.h>
+#endif
+
+#include "slang.h"
+#include "jdmacros.h"
+
+#ifndef HELP_DIR
+#define HELP_DIR ""
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+
+typedef struct SLhlp_Node_Type
+{
+ char *name;
+ struct SLhlp_Node_Type *child;
+ struct SLhlp_Node_Type *sister;
+ unsigned long pos;
+} SLhlp_Node_Type;
+
+typedef struct
+{
+ FILE *fp;
+ SLhlp_Node_Type *root;
+ SLhlp_Node_Type *sub; /* current subtopic node */
+ SLhlp_Node_Type *now; /* Node we are currently reading from */
+ SLhlp_Node_Type *path[10]; /* path to current node */
+ int level;
+} SLhlp_File_Type;
+
+#define MAX_HELP_FILES 10
+
+SLhlp_File_Type Help_Files[MAX_HELP_FILES];
+
+
+static int add_level (int level, int fd, char *name, unsigned long pos)
+{
+ SLhlp_Node_Type *node, *parent, *new_node;
+ int len;
+
+ while (*name == ' ') name++;
+ len = strlen(name);
+
+ if (len) while (name[len - 1] == ' ') len--;
+ if (len == 0) return -1;
+ name[len] = 0;
+
+ parent = node = Help_Files[fd].root;
+ while (level-- > 0)
+ {
+ if (node == NULL)
+ {
+ return -1;
+ }
+ while (node->sister != NULL) node = node->sister;
+ parent = node;
+ node = node->child;
+ }
+
+
+ if ((NULL == (new_node = (SLhlp_Node_Type *) SLMALLOC (sizeof (SLhlp_Node_Type))))
+ || (NULL == (new_node->name = (char *) SLMALLOC (len + 1))))
+ {
+ SLang_Error = SL_MALLOC_ERROR;
+ return -1;
+ }
+
+ new_node->sister = NULL;
+ new_node->child = NULL;
+ new_node->pos = pos;
+ strcpy (new_node->name, name);
+
+ if (node == NULL)
+ {
+ if (parent == NULL)
+ {
+ Help_Files[fd].root = new_node;
+ }
+ else parent->child = new_node;
+ }
+ else
+ {
+ while (node->sister != NULL) node = node->sister;
+ node->sister = new_node;
+ }
+ return 0;
+}
+
+
+static void free_nodes (SLhlp_Node_Type *node)
+{
+ if (node->child != NULL) free_nodes (node->child);
+ if (node->sister != NULL) free_nodes (node->sister);
+ if (node->name != NULL) SLFREE (node->name);
+ SLFREE (node);
+}
+
+
+
+static int check_fd (int fd)
+{
+ if (((fd >= MAX_HELP_FILES) || (fd < 0)) || (Help_Files[fd].fp == NULL))
+ {
+ if (SLang_Error == 0) SLang_Error = INTRINSIC_ERROR;
+ return 0;
+ }
+ return 1;
+}
+
+
+static void SLhlp_close_help (int fd)
+{
+ if (!check_fd (fd)) return;
+ fclose (Help_Files[fd].fp); Help_Files[fd].fp = NULL;
+ if (Help_Files[fd].root != NULL) free_nodes (Help_Files[fd].root);
+}
+
+
+static int SLhlp_open_help (char *file)
+{
+ int fd = 0, ch;
+ FILE *fp;
+ int level;
+ char topic[256], *b;
+ unsigned long pos;
+
+ while ((fd < MAX_HELP_FILES) && (Help_Files[fd].fp != NULL))
+ fd++;
+
+ if (fd == MAX_HELP_FILES) return -1;
+ if (NULL == (Help_Files[fd].fp = fp = fopen (file, "r"))) return -1;
+
+
+ while (1)
+ {
+ ch = getc (fp);
+
+ bypass_getc:
+
+ if ((ch > '9') || (ch == ' ')) continue;
+ if (ch == '\n')
+ {
+ ch = getc (fp);
+ if ((ch == ' ') || (ch > '9')) continue;
+ if (ch >= '1')
+ {
+ level = ch - '1';
+ pos = ftell (fp);
+ b = topic;
+ while (('\n' != (ch = getc (fp))) && (ch != EOF))
+ {
+ *b++ = ch;
+ }
+ *b = 0;
+ if (add_level (level, fd, topic, pos)) goto error;
+ }
+ goto bypass_getc;
+ }
+ if (ch == EOF) break;
+ }
+
+ Help_Files[fd].now = NULL;
+ Help_Files[fd].sub = Help_Files[fd].root;
+ Help_Files[fd].path[0] = NULL;
+
+ return fd;
+
+
+ error:
+ SLhlp_close_help (fd);
+ return -1;
+}
+
+static char *SLhlp_get_subtopic (int fd)
+{
+ SLhlp_Node_Type *node;
+
+ if (!check_fd(fd)) return NULL;
+ if ((node = Help_Files[fd].sub) == NULL) return NULL;
+
+ Help_Files[fd].sub = node->sister;
+ return node->name;
+}
+
+
+static char *SLhlp_gets (int fd, char *buf)
+{
+ SLhlp_Node_Type *node;
+ char ch;
+
+
+ if (!check_fd(fd)) return NULL;
+
+ node = Help_Files[fd].now;
+ if (node == NULL) return NULL;
+
+ if ((NULL == fgets(buf, 255, Help_Files[fd].fp))
+ || ((*buf <= '9') && (*buf >= '0')))
+ {
+ if ((node->child == NULL) && Help_Files[fd].level)
+ {
+ Help_Files[fd].level--;
+ }
+ Help_Files[fd].now = NULL;
+ return NULL;
+ }
+
+ /* First character is reserved. */
+ if (*buf > ' ')
+ {
+ ch = *buf | 0x20;
+ if ((ch < 'a') || (ch > 'z'))
+ {
+ *buf = '\n';
+ *(buf + 1) = 0;
+ }
+ }
+
+ return buf;
+}
+
+static int my_strncasecmp (char *a, char *b, int n)
+{
+ register char cha, chb;
+
+ while (n--)
+ {
+ cha = *a++;
+ chb = *b++;
+ if (cha != 0)
+ {
+ if ((cha == chb)
+ || ((cha | 0x20) == (chb | 0x20))) continue;
+ }
+ return cha - chb;
+ }
+ return 0;
+}
+
+
+
+static int SLhlp_select_topic (int fd, char *topic)
+{
+ char topic_buf[256];
+ char *t, ch;
+ int level = 0;
+ int len;
+
+ SLhlp_Node_Type *node, *parent;
+
+ if (!check_fd (fd)) return -1;
+
+ parent = node = Help_Files[fd].root;
+
+ ch = 0;
+ if (topic != NULL)
+ while (((ch = *topic) <= ' ') && ch) topic++;
+
+ if (ch != 0) while (node != NULL)
+ {
+ parent = node;
+ t = topic_buf;
+
+ while ((ch = *topic) > ' ')
+ {
+ *t++ = ch;
+ topic++;
+ }
+ while (((ch = *topic) <= ' ') && ch) topic++;
+ *t = 0;
+
+ len = strlen (topic_buf);
+
+
+ if (len) while (my_strncasecmp (node->name, topic_buf, len))
+ {
+ node = node->sister;
+ if (node == NULL) break;
+ }
+
+ if (node == NULL) break;
+ Help_Files[fd].path[level++] = node;
+ if ((ch == 0) || (ch == '\n')) break;
+ node = node -> child;
+ }
+
+ /* level comes out at 1 greater than last valid one */
+ Help_Files[fd].level = level;
+
+ if (node != NULL) /* success */
+ {
+ Help_Files[fd].sub = node->child;
+ Help_Files[fd].now = node;
+ fseek (Help_Files[fd].fp, node->pos, SEEK_SET);
+ return 0;
+ }
+ else /* failure */
+ {
+ Help_Files[fd].now = NULL;
+ Help_Files[fd].sub = parent;
+ return -1;
+ }
+}
+
+static int SLhlp_what_topic (int fd, char *buf)
+{
+ int level, i;
+ char *b;
+ if (!check_fd(fd)) return -1;
+
+ level = Help_Files[fd].level;
+ *buf = 0;
+ if (level == 0) return 0;
+
+ b = buf;
+ for (i = 0; i < level; i++)
+ {
+ strcpy (b, Help_Files[fd].path[i]->name);
+ b = b + strlen (b);
+ *b++ = ' ';
+ }
+ *(b - 1) = 0;
+ return level;
+}
+
+static int SLhlp_up_topic (int fd)
+{
+ if (!check_fd(fd)) return -1;
+
+ if (Help_Files[fd].level) Help_Files[fd].level--;
+ return 0;
+}
+
+
+
+
+/* --------------------------------------------------------------------- */
+
+static void cls (void)
+{
+ SLtt_cls ();
+ SLtt_flush_output ();
+}
+
+
+static void newline (int nl, int reset, int cls_flag)
+{
+ static int n;
+
+ if (nl) putc('\n', stdout);
+ n++;
+
+ if (n == SLtt_Screen_Rows - 1)
+ {
+ SLtt_reverse_video (1);
+ SLtt_write_string ("---Press RETURN to continue.---");
+ SLtt_normal_video ();
+ SLtt_flush_output ();
+
+ SLang_getkey ();
+ if (cls_flag) cls ();
+ else
+ fputs("\r \r", stdout);
+
+ cls_flag = 0;
+ n = 0;
+ }
+
+ if (reset)
+ {
+ n = 0;
+ if (cls_flag) cls ();
+ return;
+ }
+}
+
+SLang_RLine_Info_Type *Help_Rli;
+
+static SLang_RLine_Info_Type *init_readline (void)
+{
+ unsigned char *buf = NULL;
+ SLang_RLine_Info_Type *rli;
+
+ if ((NULL == (rli = (SLang_RLine_Info_Type *) SLMALLOC (sizeof(SLang_RLine_Info_Type))))
+ || (NULL == (buf = (unsigned char *) SLMALLOC (256))))
+ {
+ fprintf(stderr, "malloc error.\n");
+ exit(-1);
+ }
+
+ SLMEMSET ((char *) rli, 0, sizeof (SLang_RLine_Info_Type));
+ rli->buf = buf;
+ rli->buf_len = 255;
+ rli->tab = 8;
+ rli->dhscroll = 20;
+ rli->getkey = SLang_getkey;
+ rli->tt_goto_column = NULL;
+ rli->update_hook = NULL;
+
+ if (SLang_init_readline (rli) < 0)
+ {
+ fprintf(stderr, "Unable to initialize readline library.\n");
+ exit (-1);
+ }
+
+ return rli;
+}
+
+static char *hlp_get_input (char *prompt)
+{
+ int i;
+
+ if (Help_Rli == NULL)
+ {
+ Help_Rli = init_readline ();
+ Help_Rli->update_hook = NULL;
+ }
+
+ Help_Rli->edit_width = SLtt_Screen_Cols - 1;
+ Help_Rli->prompt = prompt;
+ *Help_Rli->buf = 0;
+
+
+ i = SLang_read_line (Help_Rli);
+
+ if ((i >= 0) && !SLang_Error && !SLKeyBoard_Quit)
+ {
+ SLang_rline_save_line (Help_Rli);
+ }
+ else return NULL;
+
+ return (char *) Help_Rli->buf;
+}
+
+
+static void do_subtopics (int fd)
+{
+ char *s;
+ int len, dlen;
+
+ if ((s = SLhlp_get_subtopic (fd)) != NULL)
+ {
+ len = 0;
+ newline (1, 0, 0);
+ fprintf(stdout, "Available Topics/Subtopics:");
+ newline (1, 0, 0);
+ newline (1, 0, 0);
+ do
+ {
+ dlen = strlen (s);
+ len += dlen;
+
+ if (len >= 80)
+ {
+ len = dlen;
+ newline (1, 0, 0);
+ }
+ fputs(s, stdout);
+ dlen = 21 - len % 20;
+ len += dlen;
+ if (len < 80)
+ {
+ while (dlen--) putc(' ', stdout);
+ }
+ }
+ while (NULL != (s = SLhlp_get_subtopic(fd)));
+ newline (1, 0, 0);
+ }
+}
+
+static void get_screen_size (int sig)
+{
+ SLtt_get_screen_size ();
+#ifdef SIGWINCH
+ signal (SIGWINCH, get_screen_size);
+#endif
+}
+
+
+
+int main (int argc, char **argv)
+{
+ char *buf, *file;
+ char buffer[256];
+ static int fd = -1;
+ int len;
+
+ if (argc != 2)
+ {
+ fprintf(stderr, "Usage: slhelp HELP-FILE\n");
+ exit (-1);
+ }
+
+ file = argv[1];
+ if (fd < 0) fd = SLhlp_open_help (file);
+ if (fd < 0)
+ {
+ fprintf (stderr, "Unable to open help file %s\n", file);
+ exit (-1);
+ }
+
+ SLang_init_tty (7, 1, 1);
+ SLtt_get_terminfo ();
+ SLtt_init_video ();
+ SLtt_Use_Ansi_Colors = 0;
+
+#ifdef SIGWINCH
+ signal (SIGWINCH, get_screen_size);
+#endif
+
+ get_screen_size (0);
+ cls ();
+
+ fputs ("\n\nSimply press RETURN at the 'Topic>' prompt to quit help.\n\n",
+ stdout);
+
+ if (SLhlp_what_topic (fd, buffer) > 0)
+ {
+ SLhlp_select_topic (fd, buffer);
+ }
+
+ while (1)
+ {
+ while (1)
+ {
+ if (SLhlp_what_topic (fd, buffer) <= 0)
+ {
+ SLhlp_select_topic (fd, "?");
+ *buffer = 0;
+ }
+ do_subtopics (fd);
+
+ len = strlen (buffer);
+ if (len) strcat (buffer, " Subtopic> ");
+ else strcpy (buffer, "Topic> ");
+ newline (1, 1, 0);
+
+ if (NULL == (buf = hlp_get_input (buffer)))
+ {
+ SLang_Error = 0;
+ if (SLKeyBoard_Quit)
+ {
+ SLKeyBoard_Quit = 0;
+ continue;
+ }
+ goto the_return;
+ }
+
+ if ((*buf == '\n') || (*buf == 0))
+ {
+ if (len == 0) goto the_return;
+ SLhlp_up_topic (fd);
+ continue;
+ }
+
+ buffer[len] = ' '; /* kill prompt */
+ strcpy (buffer + (len + 1), buf);
+ break;
+ }
+
+ newline (1, 1, 1);
+ if (-1 == SLhlp_select_topic (fd, buffer))
+ {
+ fprintf(stdout, "No help available on: %s", buf);
+ newline (1, 0, 0);
+ }
+ else while (NULL != SLhlp_gets (fd, buffer))
+ {
+ fputs(buffer, stdout);
+ newline (0, 0, 1);
+ }
+ }
+
+ the_return:
+
+ SLtt_reset_video ();
+ SLang_reset_tty ();
+ return 0;
+}