Commit 857a789e 857a789ec05684466dee277b2a41382f5a84c5e0 by Sergey Poznyakoff

implemented

1 parent 493ff8a9
......@@ -17,8 +17,62 @@
#include "mail.h"
static int is_terminal;
#define COND_STK_SIZE 64
#define COND_STK_INCR 16
static int *_cond_stack; /* Stack of conditions */
static int _cond_stack_size; /* Number of elements allocated this far */
static int _cond_level; /* Number of nested `if' blocks */
static void _cond_push(int val);
static int _cond_pop(void);
int
if_cond()
{
if (_cond_level == 0)
return 1;
return _cond_stack[_cond_level-1];
}
void
_cond_push(int val)
{
if (!_cond_stack)
{
_cond_stack = calloc(COND_STK_SIZE, sizeof(_cond_stack[0]));
_cond_stack_size = COND_STK_SIZE;
_cond_level = 0;
}
else if (_cond_level >= _cond_stack_size)
{
_cond_stack_size += COND_STK_INCR;
_cond_stack = realloc(_cond_stack,
sizeof(_cond_stack[0])*_cond_stack_size);
}
if (!_cond_stack)
{
fprintf(ofile, "not enough memeory");
exit (EXIT_FAILURE);
}
_cond_stack[_cond_level++] = val;
}
int
_cond_pop()
{
if (_cond_level == 0)
{
fprintf(ofile, "internal error: condition stack underflow\n");
abort();
}
return _cond_stack[--_cond_level];
}
/*
* i[f] s|r
* i[f] s|r|t
* mail-commands
* el[se]
* mail-commands
......@@ -30,7 +84,89 @@
int
mail_if (int argc, char **argv)
{
fprintf (ofile, "Function not implemented in %s line %d\n",
__FILE__, __LINE__);
struct mail_env_entry *mode;
int cond;
if (argc != 2)
{
fprintf(ofile, "if requires an argument: s | r | t\n");
return 1;
}
if (argv[1][1] != 0)
{
fprintf(ofile, "valid if arguments are: s | r | t\n");
return 1;
}
mode = util_find_env("mode");
if (!mode)
{
exit (EXIT_FAILURE);
}
if (if_cond() == 0)
/* Propagate negative condition */
cond = 0;
else
{
switch (argv[1][0])
{
case 's': /* Send mode */
cond = strcmp(mode->value, "send") == 0;
break;
case 'r': /* Read mode */
cond = strcmp(mode->value, "send") != 0;
break;
case 't': /* Reading from a terminal */
cond = is_terminal;
break;
default:
fprintf(ofile, "valid if arguments are: s | r | t\n");
return 1;
}
}
_cond_push(cond);
return 0;
}
int
mail_else (int argc, char **argv)
{
int cond;
if (_cond_level == 0)
{
fprintf(ofile, "else without matching if\n");
return 1;
}
cond = _cond_pop();
if (_cond_level == 0)
cond = !cond;
_cond_push(cond);
return 0;
}
int
mail_endif (int argc, char **argv)
{
if (_cond_level == 0)
{
fprintf(ofile, "endif without matching if\n");
return 1;
}
_cond_pop();
return 1;
}
void
mail_set_is_terminal(int val)
{
is_terminal = val;
}
int
mail_is_terminal(void)
{
return is_terminal;
}
......
......@@ -17,14 +17,162 @@
#include "mail.h"
static unsigned int
z_lines()
{
struct mail_env_entry *ep = util_find_env("screen");
size_t n;
if (ep && ep->value && (n = atoi(ep->value)) != 0)
return n;
return util_getlines();
}
/* Scroll directions */
#define D_BWD -1 /* z- */
#define D_NONE 0 /* z. */
#define D_FWD 1 /* z+ */
/*
* z [+|-]
* z [+|-|. [count]]
* Optional [count] specifies number of pages to skip before
* displaying from lines. Default is 1.
* . modifier causes command to redisplay the current page, i.e.
* starting from the current message.
*/
static int
z_parse_args(int argc, char **argv, int *return_count, int *return_dir)
{
int count = 1;
int mul = 1;
int dir = D_FWD;
int an = 0;
char *argp = NULL;
argp = &argv[an][1];
if (*argp == 0)
{
an++;
if (an < argc)
argp = argv[an];
}
if (*argp)
{
switch (*argp++)
{
case '+':
break;
case '-':
dir = D_BWD;
break;
case '.':
dir = D_NONE;
break;
default:
fprintf(ofile, "Bad arguments for the scrolling command\n");
return 1;
}
if (*argp == 0)
{
an++;
if (an < argc)
argp = argv[an];
}
argc -= an;
if (argc > 1)
{
fprintf(ofile, "Too many arguments for the scrolling command\n");
return 1;
}
if (argp && *argp)
{
if (dir == D_NONE)
{
fprintf(ofile, "argument no applicable for z.\n");
return 1;
}
if ((mul = atoi(argp)) == 0)
{
fprintf(ofile, "Bad number of pages\n");
return 1;
}
}
}
*return_count = mul * count;
*return_dir = dir;
return 0;
}
int
mail_z (int argc, char **argv)
{
fprintf (ofile, "Function not implemented in %s line %d\n",
__FILE__, __LINE__);
unsigned int i, nlines;
unsigned int pagelines = z_lines();
int count;
int dir;
if (z_parse_args(argc, argv, &count, &dir))
return 1;
nlines = pagelines;
count *= pagelines;
switch (dir)
{
case D_BWD:
if (cursor < nlines)
{
fprintf(stdout, "On first screenful of messages\n");
return 0;
}
if (cursor < count)
cursor = 1;
else
cursor -= count;
break;
case D_FWD:
if (cursor + pagelines > total)
{
fprintf(stdout, "On last screenful of messages\n");
return 0;
}
cursor += count;
if (cursor + nlines > total)
nlines = total - cursor;
if (nlines <= 0)
{
fprintf(stdout, "On last screenful of messages\n");
return 0;
}
case D_NONE:
break;
}
realcursor = cursor;
for (i = 0; i < nlines; i++)
{
if (mail_from(0, NULL))
break;
cursor++;
}
cursor = realcursor;
return 1;
}
......