ftp.nice.ch/pub/next/unix/network/news/slrn0.9.0.0.s.tar.gz#/slrn/src/interp.c

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.