This is interp.c in view mode; [Download] [Up]
#include "config.h" #include "features.h" #include <stdio.h> /* rest of file inside this #if statement */ #if SLRN_HAS_SLANG #if HAVE_STDLIB_H # include <stdlib.h> #endif #include <string.h> #include <slang.h> #include "jdmacros.h" #include "slrn.h" #include "group.h" #include "art.h" #include "misc.h" #include "startup.h" #include "server.h" #include "menu.h" #include "interp.h" int Slrn_Use_Slang = 0; static void error (char *msg) { slrn_error (msg); } static void make_home_filename (char *name) { char file [SLRN_MAX_PATH_LEN]; slrn_make_home_filename (name, file); SLang_push_string (file); } int slrn_eval_slang_file (char *name) { char file [SLRN_MAX_PATH_LEN]; slrn_make_home_filename (name, file); if (0 == SLang_load_file (file)) return -1; return 0; } /* Global variables that can be set from the interpreter. */ static void set_string_variable (void) { int df1, df2; char *s1 = NULL, *s2 = NULL; if ((0 == SLang_pop_string (&s2, &df2)) && (0 == SLang_pop_string (&s1, &df1))) { if (-1 == slrn_set_string_variable (s1, s2)) slrn_error ("%s is not a valid variable name.", s1); } if (df1 && (s1 != NULL)) SLFREE (s1); if (df2 && (s2 != NULL)) SLFREE (s2); } static void set_integer_variable (void) { int df1; char *s1 = NULL; int val; if (SLang_pop_integer (&val)) return; if (SLang_pop_string (&s1, &df1)) return; if (-1 == slrn_set_integer_variable (s1, val)) slrn_error ("%s is not a valid variable name.", s1); if (df1 && (s1 != NULL)) SLFREE (s1); } static void get_variable_value (void) { char *name; char **s; int *ip; int type, df; if (SLang_pop_string (&name, &df)) return; if (-1 == slrn_get_variable_value (name, &type, &s, &ip)) { slrn_error ("%s is not a valid variable name.", name); return; } if (type == STRING_TYPE) { char *str; if ((s == NULL) || (*s == NULL)) str = ""; else str = *s; SLang_push_string (str); } else if (type == INT_TYPE) { int i; if (ip == NULL) i = 0; else i = *ip; SLang_push_integer (i); } if (df && (name != NULL)) SLFREE (name); } static char *get_server_name (void) { if ((NULL == Slrn_Server_Obj) || (NULL == Slrn_Server_Obj->sv_name)) return ""; return Slrn_Server_Obj->sv_name; } static void quit (int *code) { slrn_quit (*code); } static void message (char *msg) { slrn_message (msg); } static void call_command (char *cmd) { SLKeymap_Function_Type *list; if ((Slrn_Current_Mode == NULL) || (Slrn_Current_Mode->keymap == NULL)) list = NULL; else list = Slrn_Current_Mode->keymap->functions; while ((list != NULL) && (list->name != NULL)) { if (0 == strcmp (cmd, list->name)) { (void) (*list->f) (); return; } list++; } slrn_error ("call: %s not in current keymap.", cmd); } static void definekey (char *fun, char *key, char *map) { SLKeyMap_List_Type *kmap; if (NULL == (kmap = SLang_find_keymap (map))) { error ("definekey: no such keymap."); return; } if (0 != SLang_define_key (key, fun, kmap)) { } } static void undefinekey (char *key, char *map) { SLKeyMap_List_Type *kmap; if (NULL == (kmap = SLang_find_keymap (map))) { error ("undefinekey: no such keymap."); return; } SLang_undefine_key (key, kmap); } static void read_mini (char *prompt, char *init) { char str[256]; strncpy (str, init, sizeof (str)); str[sizeof (str) - 1] = 0; if (-1 == slrn_read_input (prompt, str, 0)) { error ("Quit!"); } SLang_push_string (str); } static void set_prefix_arg (int *arg) { slrn_set_prefix_argument (*arg); } static int check_article_mode (void) { if ((Slrn_Current_Mode == NULL) || (Slrn_Current_Mode->mode != SLRN_ARTICLE_MODE)) { error ("Not in article mode."); return -1; } return 0; } static void pipe_article_cmd (char *cmd) { if (-1 == check_article_mode ()) return; (void) slrn_pipe_article_to_cmd (cmd); } static int generic_search_article (char *str, int is_regexp) { Slrn_Article_Line_Type *l; char *ptr; if (-1 == check_article_mode ()) return 0; l = slrn_search_article (str, &ptr, is_regexp, 1); if (l == NULL) return 0; SLang_push_string (l->buf); return 1; } static int search_article (char *s) { return generic_search_article (s, 0); } static int re_search_article (char *s) { return generic_search_article (s, 1); } static void uncollapse_threads (void) { if (0 == check_article_mode ()) slrn_uncollapse_threads (1); } static void collapse_threads (void) { if (0 == check_article_mode ()) slrn_collapse_threads (1); } static int header_down (int *num) { if ((-1 == check_article_mode ()) || (*num <= 0)) return 0; return slrn_header_down_n (*num, 0); } static int header_up (int *num) { if ((-1 == check_article_mode ()) || (*num <= 0)) return 0; return slrn_header_up_n (*num, 0); } static int get_header_flags (void) { if ((-1 == check_article_mode ()) || (Slrn_Current_Header == NULL)) return 0; return (int) (Slrn_Current_Header->flags & HEADER_HARMLESS_FLAGS_MASK); } static void set_header_flags (int *flagsp) { unsigned int flags; if ((-1 == check_article_mode ()) || (Slrn_Current_Header == NULL)) return; Slrn_Current_Header->flags &= ~HEADER_HARMLESS_FLAGS_MASK; flags = ((unsigned int) *flagsp) & HEADER_HARMLESS_FLAGS_MASK; Slrn_Current_Header->flags |= flags; } static void update (void) { if ((Slrn_Current_Mode != NULL) && (Slrn_Current_Mode->redraw_fun != NULL)) { (*Slrn_Current_Mode->redraw_fun) (); slrn_smg_refresh (); } } static int re_header_search (char *pat, unsigned int offset, int dir) { SLRegexp_Type *re; Slrn_Header_Type *h = Slrn_Current_Header; if ((-1 == check_article_mode ()) || (h == NULL) || (NULL == (re = slrn_compile_regexp_pattern (pat)))) return 0; while (h != NULL) { if (NULL != slrn_regexp_match (re, *(char **) ((char *)h + offset))) { slrn_goto_header (h, 0); return 1; } if (dir > 0) h = h->next; else h = h->prev; } return 0; } static int re_subject_search_forward (char *pat) { Slrn_Header_Type h; return re_header_search (pat, (char *) &h.subject - (char *)&h, 1); } static int re_subject_search_backward (char *pat) { Slrn_Header_Type h; return re_header_search (pat, (char *) &h.subject - (char *)&h, -1); } static int re_author_search_forward (char *pat) { Slrn_Header_Type h; return re_header_search (pat, (char *) &h.from - (char *)&h, 1); } static int re_author_search_backward (char *pat) { Slrn_Header_Type h; return re_header_search (pat, (char *) &h.from - (char *)&h, -1); } static int interp_select_box (int *np) { int ret = 0; int n, i; char **selections; int *do_free; Slrn_Select_Box_Type box; n = *np; if (n <= 0) return ret; n++; /* for title */ selections = (char **) SLMALLOC (sizeof (char *) * (n + 1)); do_free = (int *) SLMALLOC (sizeof (int) * n); if ((selections == NULL) || (do_free == NULL)) { if (selections != NULL) SLFREE (selections); if (do_free != NULL) SLFREE (do_free); SLang_Error = SL_MALLOC_ERROR; return ret; } selections [n] = NULL; i = n; while (i != 0) { i--; if (SLang_pop_string (selections + i, do_free + i)) { i++; goto return_error; } } box.title = selections[0];; box.lines = selections + 1; /* +1 to skip title */ ret = slrn_select_box (&box); i = 0; /* drop */ return_error: while (i < n) { if (do_free [i]) SLFREE (selections[i]); i++; } return ret; } static int Interp_Header_Read = HEADER_READ; static int Interp_Header_Tagged = HEADER_TAGGED; static int Interp_Header_High_Score = HEADER_HIGH_SCORE; static int Interp_Header_Low_Score = HEADER_LOW_SCORE; static SLang_Name_Type Slrn_Intrinsics [] = { MAKE_VARIABLE(".HEADER_READ", &Interp_Header_Read, INT_TYPE, 1), MAKE_VARIABLE(".HEADER_TAGGED", &Interp_Header_Tagged, INT_TYPE, 1), MAKE_VARIABLE(".HEADER_HIGH_SCORE", &Interp_Header_High_Score, INT_TYPE, 1), MAKE_VARIABLE(".HEADER_LOW_SCORE", &Interp_Header_Low_Score, INT_TYPE, 1), MAKE_INTRINSIC(".call", call_command, VOID_TYPE, 1), MAKE_INTRINSIC(".collapse_threads", collapse_threads, VOID_TYPE, 0), MAKE_INTRINSIC(".current_newsgroup", slrn_current_group, STRING_TYPE, 0), MAKE_INTRINSIC(".definekey", definekey, VOID_TYPE, 3), MAKE_INTRINSIC(".error", error, VOID_TYPE, 1), MAKE_INTRINSIC(".get_header_flags", get_header_flags, INT_TYPE, 0), MAKE_INTRINSIC(".get_select_box_response", interp_select_box, INT_TYPE, 1), MAKE_INTRINSIC(".get_variable_value", get_variable_value, VOID_TYPE, 0), MAKE_INTRINSIC(".goto_num_tagged_header", slrn_goto_num_tagged_header, VOID_TYPE, 1), MAKE_INTRINSIC(".header_down", header_down, INT_TYPE, 1), MAKE_INTRINSIC(".header_up", header_up, INT_TYPE, 1), MAKE_INTRINSIC(".make_home_filename", make_home_filename, VOID_TYPE, 1), MAKE_INTRINSIC(".message", message, VOID_TYPE, 1), MAKE_INTRINSIC(".next_tagged_header", slrn_next_tagged_header, INT_TYPE, 0), MAKE_INTRINSIC(".pipe_article", pipe_article_cmd, VOID_TYPE, 1), MAKE_INTRINSIC(".prev_tagged_header", slrn_prev_tagged_header, INT_TYPE, 0), MAKE_INTRINSIC(".quit", quit, VOID_TYPE, 1), MAKE_INTRINSIC(".re_bsearch_author", re_author_search_backward, INT_TYPE, 1), MAKE_INTRINSIC(".re_bsearch_subject", re_subject_search_backward, INT_TYPE, 1), MAKE_INTRINSIC(".re_fsearch_author", re_author_search_forward, INT_TYPE, 1), MAKE_INTRINSIC(".re_fsearch_subject", re_subject_search_forward, INT_TYPE, 1), MAKE_INTRINSIC(".re_search_article", re_search_article, INT_TYPE, 1), MAKE_INTRINSIC(".read_mini", read_mini, VOID_TYPE, 2), MAKE_INTRINSIC(".search_article", search_article, INT_TYPE, 1), MAKE_INTRINSIC(".server_name", get_server_name, STRING_TYPE, 0), MAKE_INTRINSIC(".set_header_flags", set_header_flags, VOID_TYPE, 1), MAKE_INTRINSIC(".set_integer_variable", set_integer_variable, VOID_TYPE, 0), MAKE_INTRINSIC(".set_prefix_argument", set_prefix_arg, VOID_TYPE, 1), MAKE_INTRINSIC(".set_string_variable", set_string_variable, VOID_TYPE, 0), MAKE_INTRINSIC(".uncollapse_threads", uncollapse_threads, VOID_TYPE, 0), MAKE_INTRINSIC(".undefinekey", undefinekey, VOID_TYPE, 2), MAKE_INTRINSIC(".update", update, VOID_TYPE, 0), SLANG_END_TABLE }; static int interp_system (char *s) { return slrn_posix_system (s, 1); } int slrn_init_slang (void) { Slrn_Use_Slang = 0; if (!init_SLang() /* basic interpreter functions */ || !init_SLmath() /* sin, cos, etc... */ #ifdef unix || !init_SLunix() /* unix system calls */ #endif || !init_SLfiles() /* file i/o */ /* Now add intrinsics for this application */ || !SLang_add_table(Slrn_Intrinsics, "slrn")) return -1; SLadd_name ("system", (long) interp_system, SLANG_INTRINSIC, SLANG_MAKE_ARGS(INT_TYPE, 1)); SLang_Error_Routine = error; Slrn_Use_Slang = 1; return 0; } #endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.