implemented
Showing
2 changed files
with
290 additions
and
6 deletions
... | @@ -17,8 +17,62 @@ | ... | @@ -17,8 +17,62 @@ |
17 | 17 | ||
18 | #include "mail.h" | 18 | #include "mail.h" |
19 | 19 | ||
20 | static int is_terminal; | ||
21 | |||
22 | #define COND_STK_SIZE 64 | ||
23 | #define COND_STK_INCR 16 | ||
24 | static int *_cond_stack; /* Stack of conditions */ | ||
25 | static int _cond_stack_size; /* Number of elements allocated this far */ | ||
26 | static int _cond_level; /* Number of nested `if' blocks */ | ||
27 | |||
28 | static void _cond_push(int val); | ||
29 | static int _cond_pop(void); | ||
30 | |||
31 | int | ||
32 | if_cond() | ||
33 | { | ||
34 | if (_cond_level == 0) | ||
35 | return 1; | ||
36 | return _cond_stack[_cond_level-1]; | ||
37 | } | ||
38 | |||
39 | void | ||
40 | _cond_push(int val) | ||
41 | { | ||
42 | if (!_cond_stack) | ||
43 | { | ||
44 | _cond_stack = calloc(COND_STK_SIZE, sizeof(_cond_stack[0])); | ||
45 | _cond_stack_size = COND_STK_SIZE; | ||
46 | _cond_level = 0; | ||
47 | } | ||
48 | else if (_cond_level >= _cond_stack_size) | ||
49 | { | ||
50 | _cond_stack_size += COND_STK_INCR; | ||
51 | _cond_stack = realloc(_cond_stack, | ||
52 | sizeof(_cond_stack[0])*_cond_stack_size); | ||
53 | } | ||
54 | |||
55 | if (!_cond_stack) | ||
56 | { | ||
57 | fprintf(ofile, "not enough memeory"); | ||
58 | exit (EXIT_FAILURE); | ||
59 | } | ||
60 | _cond_stack[_cond_level++] = val; | ||
61 | } | ||
62 | |||
63 | int | ||
64 | _cond_pop() | ||
65 | { | ||
66 | if (_cond_level == 0) | ||
67 | { | ||
68 | fprintf(ofile, "internal error: condition stack underflow\n"); | ||
69 | abort(); | ||
70 | } | ||
71 | return _cond_stack[--_cond_level]; | ||
72 | } | ||
73 | |||
20 | /* | 74 | /* |
21 | * i[f] s|r | 75 | * i[f] s|r|t |
22 | * mail-commands | 76 | * mail-commands |
23 | * el[se] | 77 | * el[se] |
24 | * mail-commands | 78 | * mail-commands |
... | @@ -30,7 +84,89 @@ | ... | @@ -30,7 +84,89 @@ |
30 | int | 84 | int |
31 | mail_if (int argc, char **argv) | 85 | mail_if (int argc, char **argv) |
32 | { | 86 | { |
33 | fprintf (ofile, "Function not implemented in %s line %d\n", | 87 | struct mail_env_entry *mode; |
34 | __FILE__, __LINE__); | 88 | int cond; |
89 | |||
90 | if (argc != 2) | ||
91 | { | ||
92 | fprintf(ofile, "if requires an argument: s | r | t\n"); | ||
93 | return 1; | ||
94 | } | ||
95 | |||
96 | if (argv[1][1] != 0) | ||
97 | { | ||
98 | fprintf(ofile, "valid if arguments are: s | r | t\n"); | ||
35 | return 1; | 99 | return 1; |
100 | } | ||
101 | |||
102 | mode = util_find_env("mode"); | ||
103 | if (!mode) | ||
104 | { | ||
105 | exit (EXIT_FAILURE); | ||
106 | } | ||
107 | |||
108 | if (if_cond() == 0) | ||
109 | /* Propagate negative condition */ | ||
110 | cond = 0; | ||
111 | else | ||
112 | { | ||
113 | switch (argv[1][0]) | ||
114 | { | ||
115 | case 's': /* Send mode */ | ||
116 | cond = strcmp(mode->value, "send") == 0; | ||
117 | break; | ||
118 | case 'r': /* Read mode */ | ||
119 | cond = strcmp(mode->value, "send") != 0; | ||
120 | break; | ||
121 | case 't': /* Reading from a terminal */ | ||
122 | cond = is_terminal; | ||
123 | break; | ||
124 | default: | ||
125 | fprintf(ofile, "valid if arguments are: s | r | t\n"); | ||
126 | return 1; | ||
127 | } | ||
128 | } | ||
129 | _cond_push(cond); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | |||
134 | int | ||
135 | mail_else (int argc, char **argv) | ||
136 | { | ||
137 | int cond; | ||
138 | if (_cond_level == 0) | ||
139 | { | ||
140 | fprintf(ofile, "else without matching if\n"); | ||
141 | return 1; | ||
142 | } | ||
143 | cond = _cond_pop(); | ||
144 | if (_cond_level == 0) | ||
145 | cond = !cond; | ||
146 | _cond_push(cond); | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | int | ||
151 | mail_endif (int argc, char **argv) | ||
152 | { | ||
153 | if (_cond_level == 0) | ||
154 | { | ||
155 | fprintf(ofile, "endif without matching if\n"); | ||
156 | return 1; | ||
157 | } | ||
158 | _cond_pop(); | ||
159 | return 1; | ||
160 | } | ||
161 | |||
162 | void | ||
163 | mail_set_is_terminal(int val) | ||
164 | { | ||
165 | is_terminal = val; | ||
166 | } | ||
167 | |||
168 | int | ||
169 | mail_is_terminal(void) | ||
170 | { | ||
171 | return is_terminal; | ||
36 | } | 172 | } | ... | ... |
... | @@ -17,14 +17,162 @@ | ... | @@ -17,14 +17,162 @@ |
17 | 17 | ||
18 | #include "mail.h" | 18 | #include "mail.h" |
19 | 19 | ||
20 | static unsigned int | ||
21 | z_lines() | ||
22 | { | ||
23 | struct mail_env_entry *ep = util_find_env("screen"); | ||
24 | size_t n; | ||
25 | |||
26 | if (ep && ep->value && (n = atoi(ep->value)) != 0) | ||
27 | return n; | ||
28 | return util_getlines(); | ||
29 | } | ||
30 | |||
31 | /* Scroll directions */ | ||
32 | #define D_BWD -1 /* z- */ | ||
33 | #define D_NONE 0 /* z. */ | ||
34 | #define D_FWD 1 /* z+ */ | ||
35 | |||
20 | /* | 36 | /* |
21 | * z [+|-] | 37 | * z [+|-|. [count]] |
38 | * Optional [count] specifies number of pages to skip before | ||
39 | * displaying from lines. Default is 1. | ||
40 | * . modifier causes command to redisplay the current page, i.e. | ||
41 | * starting from the current message. | ||
22 | */ | 42 | */ |
23 | 43 | ||
44 | static int | ||
45 | z_parse_args(int argc, char **argv, int *return_count, int *return_dir) | ||
46 | { | ||
47 | int count = 1; | ||
48 | int mul = 1; | ||
49 | int dir = D_FWD; | ||
50 | int an = 0; | ||
51 | char *argp = NULL; | ||
52 | |||
53 | argp = &argv[an][1]; | ||
54 | if (*argp == 0) | ||
55 | { | ||
56 | an++; | ||
57 | if (an < argc) | ||
58 | argp = argv[an]; | ||
59 | } | ||
60 | |||
61 | if (*argp) | ||
62 | { | ||
63 | switch (*argp++) | ||
64 | { | ||
65 | case '+': | ||
66 | break; | ||
67 | case '-': | ||
68 | dir = D_BWD; | ||
69 | break; | ||
70 | case '.': | ||
71 | dir = D_NONE; | ||
72 | break; | ||
73 | default: | ||
74 | fprintf(ofile, "Bad arguments for the scrolling command\n"); | ||
75 | return 1; | ||
76 | } | ||
77 | |||
78 | if (*argp == 0) | ||
79 | { | ||
80 | an++; | ||
81 | if (an < argc) | ||
82 | argp = argv[an]; | ||
83 | } | ||
84 | |||
85 | argc -= an; | ||
86 | |||
87 | if (argc > 1) | ||
88 | { | ||
89 | fprintf(ofile, "Too many arguments for the scrolling command\n"); | ||
90 | return 1; | ||
91 | } | ||
92 | |||
93 | if (argp && *argp) | ||
94 | { | ||
95 | if (dir == D_NONE) | ||
96 | { | ||
97 | fprintf(ofile, "argument no applicable for z.\n"); | ||
98 | return 1; | ||
99 | } | ||
100 | |||
101 | if ((mul = atoi(argp)) == 0) | ||
102 | { | ||
103 | fprintf(ofile, "Bad number of pages\n"); | ||
104 | return 1; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | } | ||
109 | |||
110 | *return_count = mul * count; | ||
111 | *return_dir = dir; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
24 | int | 116 | int |
25 | mail_z (int argc, char **argv) | 117 | mail_z (int argc, char **argv) |
26 | { | 118 | { |
27 | fprintf (ofile, "Function not implemented in %s line %d\n", | 119 | unsigned int i, nlines; |
28 | __FILE__, __LINE__); | 120 | unsigned int pagelines = z_lines(); |
121 | int count; | ||
122 | int dir; | ||
123 | |||
124 | if (z_parse_args(argc, argv, &count, &dir)) | ||
125 | return 1; | ||
126 | |||
127 | nlines = pagelines; | ||
128 | |||
129 | count *= pagelines; | ||
130 | switch (dir) | ||
131 | { | ||
132 | case D_BWD: | ||
133 | if (cursor < nlines) | ||
134 | { | ||
135 | fprintf(stdout, "On first screenful of messages\n"); | ||
136 | return 0; | ||
137 | } | ||
138 | if (cursor < count) | ||
139 | cursor = 1; | ||
140 | else | ||
141 | cursor -= count; | ||
142 | break; | ||
143 | |||
144 | case D_FWD: | ||
145 | if (cursor + pagelines > total) | ||
146 | { | ||
147 | fprintf(stdout, "On last screenful of messages\n"); | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | cursor += count; | ||
152 | |||
153 | if (cursor + nlines > total) | ||
154 | nlines = total - cursor; | ||
155 | |||
156 | if (nlines <= 0) | ||
157 | { | ||
158 | fprintf(stdout, "On last screenful of messages\n"); | ||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | case D_NONE: | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | realcursor = cursor; | ||
167 | |||
168 | for (i = 0; i < nlines; i++) | ||
169 | { | ||
170 | if (mail_from(0, NULL)) | ||
171 | break; | ||
172 | cursor++; | ||
173 | } | ||
174 | |||
175 | cursor = realcursor; | ||
176 | |||
29 | return 1; | 177 | return 1; |
30 | } | 178 | } | ... | ... |
-
Please register or sign in to post a comment