home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume22
/
nn6.4
/
part12
/
variable.c
< prev
Wrap
C/C++ Source or Header
|
1990-06-07
|
21KB
|
863 lines
/*
* (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
*
* Variabel setting and display
*/
#include "config.h"
#include "keymap.h"
import in_init;
import char /* string variables */
*bak_suffix,
*bug_address,
*decode_header_file,
*default_distribution,
*default_save_file,
*editor_program,
*extra_mail_headers,
*extra_news_headers,
*header_lines,
*folder_directory,
included_mark[],
*mail_box,
*mail_record,
*mail_script,
*mailer_program,
attributes[],
*newsrc_file,
*news_record,
*news_script,
*pager,
patch_command[],
printer[],
*response_dflt_answer,
*save_counter_format,
*spell_checker,
unshar_command[],
*unshar_header_file,
*user_shell;
import int /* boolean variables */
also_cross_postings,
also_subgroups,
append_sig_mail,
append_sig_post,
auto_junk_seen,
auto_preview_mode,
case_fold_search,
compress_mode,
conf_append,
conf_auto_quit,
conf_create,
conf_dont_sleep,
conf_group_entry,
conf_junk_seen,
delay_redraw,
do_kill_handling,
dont_sort_articles,
dont_sort_folders,
dont_split_digests,
edit_patch_command,
edit_print_command,
edit_unshar_command,
empty_answer_check,
flow_control,
flush_typeahead,
fmt_rptsubj,
include_art_id,
include_full_header,
keep_rc_backup,
keep_unsubscribed,
keep_unsub_long,
long_menu,
macro_debug,
mailer_pipe_input,
mark_overlap,
match_parts_equal,
monitor_mode,
novice,
preview_mark_read,
query_signature,
quick_save,
quick_unread_count,
repeat_group_query,
report_cost_on_exit,
retain_seen_status,
save_report,
scroll_clear_page,
select_leave_next,
select_on_sender,
seq_cross_filtering,
shell_restrictions,
show_article_date,
show_current_time,
silent,
slow_mode,
suggest_save_file,
tidy_newsrc,
use_mail_folders,
use_mmdf_folders,
use_selections,
use_visible_bell;
import int /* integer variables */
also_read_articles,
article_limit,
conf_entry_limit,
collapse_subject,
Columns,
data_bits,
Debug,
decode_skip_prefix,
entry_message_limit,
expired_msg_delay,
first_page_lines,
fmt_linenum,
Lines,
match_skip_prefix,
min_pv_window,
new_group_action,
newsrc_update_freq,
orig_to_include_mask,
overlap,
preview_continuation,
preview_window,
re_layout,
response_check_pause,
retry_on_error,
save_counter_offset,
slow_speed,
sort_mode,
subject_match_limit,
wrap_headers;
#ifdef NNTP
import char *nntp_cache_dir;
import int nntp_cache_size, nntp_debug;
#endif
import key_type /* key strokes */
comp1_key,
comp2_key,
help_key,
erase_key,
delword_key,
kill_key;
#undef STR
#undef BOOL
#undef INT
#undef KEY
#undef SPEC
#undef SAFE
#undef INIT
#define V_STRING 0x1000
#define V_BOOLEAN 0x2000
#define V_INTEGER 0x3000
#define V_KEY 0x4000
#define V_SPECIAL 0x5000
#define V_SAFE 0x0100
#define V_INIT 0x0200
#define V_MODIFIED 0x8000
#define STR V_STRING |
#define BOOL V_BOOLEAN |
#define INT V_INTEGER |
#define KEY V_KEY |
#define SPEC V_SPECIAL |
#define SAFE V_SAFE |
#define INIT V_INIT |
struct variable_defs {
char *var_name;
int var_flags;
char **var_addr;
} variables[] = {
"also-subgroups", BOOL INIT 0, (char **)&also_subgroups,
"append-signature-mail", BOOL 0, (char **)&append_sig_mail,
"append-signature-post", BOOL 0, (char **)&append_sig_post,
"attributes", STR 1, (char **)attributes,
"auto-junk-seen", BOOL 0, (char **)&auto_junk_seen,
"auto-preview-mode", BOOL 0, (char **)&auto_preview_mode,
"backup", BOOL 0, (char **)&keep_rc_backup,
"backup-suffix", STR 0, (char **)&bak_suffix,
"bug-report-address", STR 0, (char **)&bug_address,
"case-fold-search", BOOL 0, (char **)&case_fold_search,
"collapse-subject", INT 3, (char **)&collapse_subject,
"columns", INT 1, (char **)&Columns,
"comp1-key", KEY 0, (char **)&comp1_key,
"comp2-key", KEY 0, (char **)&comp2_key,
"compress", BOOL 0, (char **)&compress_mode,
"confirm-append", BOOL 0, (char **)&conf_append,
"confirm-auto-quit", BOOL 0, (char **)&conf_auto_quit,
"confirm-create", BOOL 0, (char **)&conf_create,
"confirm-entry", BOOL 0, (char **)&conf_group_entry,
"confirm-entry-limit", INT 0, (char **)&conf_entry_limit,
"confirm-junk-seen", BOOL 0, (char **)&conf_junk_seen,
"confirm-messages", BOOL 0, (char **)&conf_dont_sleep,
"cross-filter-seq", BOOL 0, (char **)&seq_cross_filtering,
"cross-post", BOOL 0, (char **)&also_cross_postings,
"data-bits", INT 0, (char **)&data_bits,
"date", BOOL 0, (char **)&show_article_date,
"debug", INT 0, (char **)&Debug,
"decode-header-file", STR 0, (char **)&decode_header_file,
"decode-skip-prefix", INT 0, (char **)&decode_skip_prefix,
"default-distribution", STR 0, (char **)&default_distribution,
"default-save-file", STR 3, (char **)&default_save_file,
"delay-redraw", BOOL 0, (char **)&delay_redraw,
"edit-patch-command", BOOL 0, (char **)&edit_patch_command,
"edit-print-command", BOOL 0, (char **)&edit_print_command,
"edit-response-check", BOOL 0, (char **)&empty_answer_check,
"edit-unshar-command", BOOL 0, (char **)&edit_unshar_command,
"editor", STR 0, (char **)&editor_program,
"entry-report-limit", INT 0, (char **)&entry_message_limit,
"erase-key", KEY 0, (char **)&erase_key,
"expert", BOOL 4, (char **)&novice,
"expired-message-delay", INT 0, (char **)&expired_msg_delay,
"flow-control", BOOL 0, (char **)&flow_control,
"flush-typeahead", BOOL 0, (char **)&flush_typeahead,
"folder", STR 2, (char **)&folder_directory,
"fsort", BOOL 2, (char **)&dont_sort_folders,
"header-lines", STR 0, (char **)&header_lines,
"help-key", KEY 0, (char **)&help_key,
"include-art-id", BOOL 0, (char **)&include_art_id,
"include-full-header", BOOL 0, (char **)&include_full_header,
"included-mark", STR 1, (char **)included_mark,
"keep-unsubscribed", BOOL 0, (char **)&keep_unsubscribed,
"kill", BOOL 0, (char **)&do_kill_handling,
"kill-key", KEY 0, (char **)&kill_key,
"layout", INT 1, (char **)&fmt_linenum,
"limit", INT 2, (char **)&article_limit,
"lines", INT 1, (char **)&Lines,
"long-menu", BOOL 1, (char **)&long_menu,
"macro-debug", BOOL 0, (char **)¯o_debug,
"mail", STR 2, (char **)&mail_box,
"mail-format", BOOL 0, (char **)&use_mail_folders,
"mail-header", STR 0, (char **)&extra_mail_headers,
"mail-record", STR 2, (char **)&mail_record,
"mail-script", STR SAFE 2, (char **)&mail_script,
"mailer", STR 0, (char **)&mailer_program,
"mailer-pipe-input", BOOL 0, (char **)&mailer_pipe_input,
"mark-overlap", BOOL 0, (char **)&mark_overlap,
"min-window", INT 1, (char **)&min_pv_window,
"mmdf-format", BOOL 0, (char **)&use_mmdf_folders,
"monitor", BOOL 0, (char **)&monitor_mode,
"new-group-action", INT 0, (char **)&new_group_action,
"news-header", STR 0, (char **)&extra_news_headers,
"news-record", STR 2, (char **)&news_record,
"news-script", STR SAFE 2, (char **)&news_script,
"newsrc", STR 2, (char **)&newsrc_file,
#ifdef NNTP
"nntp-cache-dir", STR INIT 0, (char **)&nntp_cache_dir,
"nntp-cache-size", INT INIT 0, (char **)&nntp_cache_size,
"nntp-debug", BOOL 0, (char **)&nntp_debug,
#endif
/* "no....." -- cannot have variable names starting with "no" */
"old", SPEC 2, (char **)NULL,
"orig-to-include-mask", INT 0, (char **)&orig_to_include_mask,
"overlap", INT 0, (char **)&overlap,
"pager", STR SAFE 3, (char **)&pager,
"patch-command", STR SAFE 1, (char **)patch_command,
"preview-continuation", INT 0, (char **)&preview_continuation,
"preview-mark-read", BOOL 0, (char **)&preview_mark_read,
"printer", STR SAFE 1, (char **)printer,
"query-signature", BOOL 0, (char **)&query_signature,
"quick-count", BOOL 0, (char **)&quick_unread_count,
"quick-save", BOOL 0, (char **)&quick_save,
"re-layout", INT 0, (char **)&re_layout,
"record", SPEC 1, (char **)NULL,
"repeat", BOOL 0, (char **)&fmt_rptsubj,
"repeat-group-query", BOOL 0, (char **)&repeat_group_query,
"report-cost", BOOL 0, (char **)&report_cost_on_exit,
"response-check-pause", INT 0, (char **)&response_check_pause,
"response-default-answer", STR 0, (char **)&response_dflt_answer,
"retain-seen-status", BOOL 0, (char **)&retain_seen_status,
"retry-on-error", INT 0, (char **)&retry_on_error,
"save-counter", STR 3, (char **)&save_counter_format,
"save-counter-offset", INT 0, (char **)&save_counter_offset,
"save-report", BOOL 0, (char **)&save_report,
"scroll-clear-page", BOOL 0, (char **)&scroll_clear_page,
"select-leave-next", BOOL 0, (char **)&select_leave_next,
"select-on-sender", BOOL 0, (char **)&select_on_sender,
"shell", STR SAFE 0, (char **)&user_shell,
"shell-restrictions", BOOL INIT 0, (char **)&shell_restrictions,
"silent", BOOL 0, (char **)&silent,
"slow-mode", BOOL 0, (char **)&slow_mode,
"slow-speed", INT 0, (char **)&slow_speed,
"sort", BOOL 2, (char **)&dont_sort_articles,
"sort-mode", INT 0, (char **)&sort_mode,
"spell-checker", STR 0, (char **)&spell_checker,
"split", BOOL 4, (char **)&dont_split_digests,
"stop", INT 0, (char **)&first_page_lines,
"subject-match-limit", INT 0, (char **)&subject_match_limit,
"subject-match-offset", INT 0, (char **)&match_skip_prefix,
"subject-match-parts", BOOL 0, (char **)&match_parts_equal,
"suggest-default-save", BOOL 0, (char **)&suggest_save_file,
"tidy-newsrc", BOOL 0, (char **)&tidy_newsrc,
"time", BOOL 0, (char **)&show_current_time,
"unshar-command", STR SAFE 1, (char **)unshar_command,
"unshar-header-file", STR 0, (char **)&unshar_header_file,
"unsubscribe-mark-read", BOOL 4, (char **)&keep_unsub_long,
"update-frequency", INT 0, (char **)&newsrc_update_freq,
"use-selections", BOOL 0, (char **)&use_selections,
"visible-bell", BOOL 0, (char **)&use_visible_bell,
"window", INT 1, (char **)&preview_window,
"word-key", KEY 0, (char **)&delword_key,
"wrap-header-margin", INT 2, (char **)&wrap_headers
};
#define TABLE_SIZE (sizeof(variables)/sizeof(struct variable_defs))
#define INT_VAR (*((int *)(var->var_addr)))
#define BOOL_VAR (*((int *)(var->var_addr)))
#define STR_VAR (*(var->var_addr))
#define CBUF_VAR ((char *)(var->var_addr))
#define KEY_VAR (*((key_type *)(var->var_addr)))
#define VAR_TYPE (var->var_flags & 0x7000)
#define VAR_OP (var->var_flags & 0x000f)
static struct variable_defs *lookup_variable(variable)
char *variable;
{
register struct variable_defs *var;
register i, j, k, t;
i = 0; j = TABLE_SIZE - 1;
while (i <= j) {
k = (i + j) / 2;
var = &variables[k];
if ( (t=strcmp(variable, var->var_name)) > 0)
i = k+1;
else
if (t < 0)
j = k-1;
else
return var;
}
init_message("unknown variable: %s", variable);
return NULL;
}
static adjust(str)
register char *str;
{
if (str == NULL) return;
while (*str && !isspace(*str) && *str != '#') str++;
*str = NUL;
}
set_variable(variable, on, val_string)
char *variable;
int on;
char *val_string;
{
int value;
register struct variable_defs *var;
if (strncmp(variable, "no", 2) == 0) {
on = !on;
variable += 2;
if (variable[0] == '-') variable++;
}
if ((var = lookup_variable(variable)) == NULL)
return 0;
if (!in_init && (var->var_flags & (V_INIT | V_SAFE))) {
if (var->var_flags & V_INIT) {
msg("'%s' can only be set in the init file", variable);
return 0;
}
if (shell_restrictions) {
msg("Restricted operation - cannot change");
return 0;
}
}
if (!on || val_string == NULL)
value = 0;
else
value = atoi(val_string);
var->var_flags |= V_MODIFIED;
switch (VAR_TYPE) {
case V_STRING:
switch (VAR_OP) {
case 0:
STR_VAR = (on && val_string) ? copy_str(val_string) : (char *)NULL;
break;
case 1:
strcpy(CBUF_VAR, (on && val_string) ? val_string : "");
break;
case 2:
if (on) {
char exp_buf[FILENAME];
adjust(val_string);
if (val_string) {
if (expand_file_name(exp_buf, val_string, 1))
STR_VAR = home_relative(exp_buf);
}
} else
STR_VAR = (char *)NULL;
break;
case 3:
if (!on || val_string == NULL) {
msg("Cannot unset string `%s'", variable);
break;
}
STR_VAR = copy_str(val_string);
break;
}
break;
case V_BOOLEAN:
if (val_string)
if (val_string[0] == 'o')
on = val_string[1] == 'n'; /* on */
else
on = val_string[0] == 't'; /* true */
switch (VAR_OP) {
case 0:
BOOL_VAR = on;
break;
case 1:
BOOL_VAR = on;
return 1;
case 2:
if (BOOL_VAR == on) {
BOOL_VAR = !on;
if (!in_init) {
sort_articles(BOOL_VAR ? 0 : -1);
return 1;
}
}
break;
case 4:
BOOL_VAR = !on;
break;
}
break;
case V_INTEGER:
switch (VAR_OP) {
case 0:
case 1:
INT_VAR = value;
break;
case 2:
case 3:
if (!on) value = -1;
INT_VAR = value;
break;
}
return (VAR_OP & 1);
case V_KEY:
switch (VAR_OP) {
case 0:
if (val_string) {
if (*val_string) adjust(val_string + 1); /* #N is valid */
KEY_VAR = parse_key(val_string);
}
break;
}
break;
case V_SPECIAL:
switch (VAR_OP) {
case 1:
if (val_string) {
adjust(val_string);
news_record = home_relative(val_string);
mail_record = news_record;
}
break;
case 2:
also_read_articles = on;
article_limit = (on && value > 0) ? value : -1;
break;
}
break;
}
return 0;
}
toggle_variable(variable)
char *variable;
{
register struct variable_defs *var;
if ((var = lookup_variable(variable)) == NULL) return;
if (VAR_TYPE != V_BOOLEAN) {
init_message("variable %s is not boolean", variable);
return;
}
BOOL_VAR = !BOOL_VAR;
}
test_variable(expr)
char *expr;
{
char *variable;
register struct variable_defs *var;
int res = -1;
variable = expr;
if ((expr = strchr(variable, '=')) == NULL)
goto err;
*expr++ = NUL;
if ((var = lookup_variable(variable)) == NULL) {
msg("testing unknown variable %s=%s", variable, expr);
goto out;
}
switch (VAR_TYPE) {
case V_BOOLEAN:
res = BOOL_VAR;
if (strcmp(expr, "on") == 0 || strcmp(expr, "true") == 0) break;
if (strcmp(expr, "off") == 0 || strcmp(expr, "false") == 0) {
res = !res;
break;
}
msg("boolean variables must be tested =on or =off");
break;
case V_INTEGER:
res = (INT_VAR == atoi(expr)) ? 1 : 0;
break;
default:
msg("%s: cannot only test boolean and integer variables", variable);
break;
}
out:
*--expr = '=';
err:
return res;
}
var_completion(path, index)
char *path;
int index;
{
static char *head, *tail = NULL;
static int len;
static struct variable_defs *var, *help_var;
if (index < 0) return 0;
if (path) {
head = path;
tail = path + index;
while (*head && isspace(*head)) head++;
if (strncmp(head, "no", 2) == 0) {
head += 2;
if (*head == '-') head++;
}
help_var = var = variables;
len = tail - head;
return 1;
}
if (index) {
list_completion((char *)NULL);
for (;; help_var++) {
if (help_var >= &variables[TABLE_SIZE]) {
help_var = variables;
break;
}
index = strncmp(help_var->var_name, head, len);
if (index < 0) continue;
if (index > 0) {
help_var = variables;
break;
}
if (list_completion(help_var->var_name) == 0) break;
}
fl;
return 1;
}
for (; var < &variables[TABLE_SIZE]; var++) {
if (len == 0)
index = 0;
else
index = strncmp(var->var_name, head, len);
if (index < 0) continue;
if (index > 0) break;
sprintf(tail, "%s ", var->var_name + len);
var++;
return 1;
}
return 0;
}
static struct var_stack {
struct var_stack *next;
struct variable_defs *v;
int mod_flag;
union {
int ivar;
int bool;
char key;
char *str;
} value;
} *var_stack = NULL, *vs_pool = NULL;
mark_var_stack()
{
register struct var_stack *vs;
if (vs_pool) {
vs = vs_pool;
vs_pool = vs->next;
} else
vs = newobj(struct var_stack, 1);
vs->next = var_stack;
var_stack = vs;
vs->v = NULL;
}
push_variable(variable)
char *variable;
{
register struct variable_defs *var;
register struct var_stack *vs;
if (strncmp(variable, "no", 2) == 0) {
variable += 2;
if (variable[0] == '-') variable++;
}
if ((var = lookup_variable(variable)) == NULL) {
msg("pushing unknown variable %s", variable);
return 0;
}
mark_var_stack();
vs = var_stack;
vs->v = var;
vs->mod_flag = var->var_flags & V_MODIFIED;
switch (VAR_TYPE) {
case V_STRING:
switch (VAR_OP) {
case 0: /* if we update one of these variables, */
case 2: /* new storage will be allocated for it */
case 3: /* so it is ok just to save the pointer */
vs->value.str = STR_VAR;
break;
case 1: /* we free this memory when restored */
vs->value.str = copy_str(CBUF_VAR);
break;
}
break;
case V_BOOLEAN:
vs->value.bool = BOOL_VAR;
break;
case V_INTEGER:
vs->value.ivar = INT_VAR;
break;
case V_KEY:
vs->value.key = KEY_VAR;
break;
case V_SPECIAL:
msg("Cannot push pseudo variable %s", var->var_name);
break;
}
return 1;
}
restore_variables()
{
register struct variable_defs *var;
register struct var_stack *vs, *vs1;
vs = var_stack;
while (vs != NULL) {
if ((var = vs->v) == NULL) {
var_stack = vs->next;
vs->next = vs_pool;
vs_pool = vs;
return;
}
var->var_flags &= ~V_MODIFIED;
var->var_flags |= vs->mod_flag;
switch (VAR_TYPE) {
case V_STRING:
switch (VAR_OP) {
case 0: /* only restore the string if changed; then we */
case 2: /* can also free the memory occupied by the */
case 3: /* 'new' value (if not NULL) */
if (STR_VAR != vs->value.str) {
if (STR_VAR != NULL) freeobj(STR_VAR);
STR_VAR = vs->value.str;
}
break;
case 1: /* it fitted before, so it will fit againg */
strcpy(CBUF_VAR, vs->value.str);
freeobj(vs->value.str);
break;
}
break;
case V_BOOLEAN:
BOOL_VAR = vs->value.bool;
break;
case V_INTEGER:
INT_VAR = vs->value.ivar;
break;
case V_KEY:
KEY_VAR = vs->value.key;
break;
case V_SPECIAL: /* these are not saved, so... */
break;
}
vs1 = vs->next;
vs->next = vs_pool;
vs_pool = vs;
vs = vs1;
}
var_stack = NULL;
}
static var_on_stack(var)
register struct variable_defs *var;
{
register struct var_stack *vs;
for (vs = var_stack; vs; vs = vs->next)
if (vs->v == var) return 1;
return 0;
}
disp_variables(all)
int all;
{
char *str, pushed;
int b;
register struct variable_defs *var;
if (in_init) return;
pg_init(0, 1);
clrdisp();
if (novice && !all) {
msg("Use `:set all' to see all variable settings");
home();
}
pg_next();
so_printf("\1Variable settings:\1");
for (var = variables; var < &variables[TABLE_SIZE]; var++) {
pushed =
var_on_stack(var) ? '>' :
(var->var_flags & V_MODIFIED) ? '*' : ' ';
if (!all && pushed == ' ') continue;
switch (VAR_TYPE) {
case V_STRING:
if (pg_next() < 0) goto out;
str = (VAR_OP == 1) ? CBUF_VAR : STR_VAR;
if (str == NULL) str = "";
printf("%c %-20.20s = \"%s\"\n", pushed, var->var_name, str);
break;
case V_BOOLEAN:
if (pg_next() < 0) goto out;
b = BOOL_VAR;
if (VAR_OP == 2 || VAR_OP == 4) b = !b;
printf("%c %-20.20s = %s\n",
pushed, var->var_name, b ? "on" : "off");
break;
case V_INTEGER:
if (pg_next() < 0) goto out;
printf("%c %-20.20s = %d\n", pushed, var->var_name, INT_VAR);
break;
case V_KEY:
if (pg_next() < 0) goto out;
printf("%c %-20.20s = %s\n",
pushed, var->var_name, key_name(KEY_VAR));
break;
case V_SPECIAL:
switch (VAR_OP) {
case 1:
break;
case 2:
if (also_read_articles) {
if (pg_next() < 0) goto out;
printf("%c %-20.20s = %d\n",
pushed, var->var_name, article_limit);
}
break;
}
break;
}
}
out:
pg_end();
}