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.