1 /*
2 * QUOTE.C
3 *
4 * Written on 10-Jul-94 by John Dennis and released to the public domain.
5 *
6 * Contains routines relevant to detection of quotes and quoting.
7 */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <time.h>
13 #include <ctype.h>
14 #include "addr.h"
15 #include "nedit.h"
16 #include "memextra.h"
17 #include "strextra.h"
18 #include "mctype.h"
19 #include "msged.h"
20 #include "wrap.h"
21 #include "quote.h"
22
23 #define TEXTLEN 128
24 #define INPLEN 60
25
26 /* is the passed line a quote? */
27
is_quote(char * text)28 int is_quote(char *text)
29 {
30 char *s = text, *c = text;
31
32 while (*s && s && s - text < 12)
33 {
34 if (*s == '>')
35 {
36 break;
37 }
38 s++;
39 }
40
41 if (*s != '>')
42 {
43 return FALSE;
44 }
45
46 while (c && *c && c < s)
47 {
48 switch (*c)
49 {
50 case '<':
51 return FALSE;
52
53 case ' ':
54 case ':':
55 case '-':
56 case '@':
57 c++;
58 continue;
59
60 default:
61 if (!m_isalnum(*c))
62 {
63 return FALSE;
64 }
65 c++;
66 break;
67 }
68 }
69
70 return TRUE;
71 }
72
is_same_quote(LINE * l,LINE * o)73 int is_same_quote(LINE * l, LINE * o)
74 {
75 char *s, *c;
76 int lenl, leno;
77
78 lenl = strlen(l->text);
79 leno = strlen(o->text);
80
81 if (l->quote && o->quote)
82 {
83 if (lenl >= 12)
84 {
85 s = l->text + 11;
86 }
87 else
88 {
89 s = l->text + lenl - 1;
90 }
91
92 if (leno >= 12)
93 {
94 c = o->text + 11;
95 }
96 else
97 {
98 c = o->text + leno - 1;
99 }
100
101 while (*s && *s != '>')
102 {
103 s--;
104 }
105
106 while (*c && *c != '>')
107 {
108 c--;
109 }
110
111 if (*s == '>' && *(s + 1))
112 {
113 s++;
114 }
115
116 if (*c == '>' && *(c + 1))
117 {
118 c++;
119 }
120
121 if (!strncmpi(l->text, o->text, (size_t) max((s - l->text),
122 c - o->text)))
123 {
124 return TRUE;
125 }
126
127 return FALSE;
128 }
129
130 return FALSE;
131 }
132
is_blank(LINE * l)133 int is_blank(LINE * l)
134 {
135 char *s;
136 int len;
137
138 if (!l || !l->text || *l->text == '\n' || *l->text == '\0')
139 {
140 return TRUE;
141 }
142
143 len = strlen(l->text);
144 if (l->quote)
145 {
146 if (len >= 12)
147 {
148 s = l->text + 11;
149 }
150 else
151 {
152 s = l->text + len - 1;
153 }
154
155 while (*s && *s != '>')
156 {
157 s--;
158 }
159
160 if (*s == '>' && *(s + 1))
161 {
162 s++;
163 }
164
165 while (*s && m_isspace(*s))
166 {
167 s++;
168 }
169
170 if (*s == '\0')
171 {
172 return TRUE;
173 }
174 else
175 {
176 return FALSE;
177 }
178 }
179 else
180 {
181 s = l->text;
182 while (*s && m_isspace(*s))
183 {
184 s++;
185 }
186
187 if (*s == '\0')
188 {
189 return TRUE;
190 }
191 else
192 {
193 return FALSE;
194 }
195 }
196 }
197
replace_noise(char * text)198 char *replace_noise(char *text)
199 {
200 char *s = text;
201 char *c;
202
203 /* replace nasty bits */
204
205 if (*text == '\01')
206 {
207 *text = '@';
208 }
209
210 if (!SW->soteot)
211 {
212 if (!strncmp(text, " * Ori", 6))
213 {
214 *(text + 1) = '+';
215 }
216
217 if (!strncmp(text, "---", 3) && strncmp(text, "----", 4))
218 {
219 *(text + 1) = '+';
220 }
221
222 if (!strncmp(text, "SEEN-BY:", 8))
223 {
224 *(text + 4) = '+';
225 }
226 }
227
228 /* strip leading spaces unless hard-quoting */
229
230 if (!SW->hardquote)
231 {
232 while (*s && m_isspace(*s))
233 {
234 s++;
235 }
236 }
237
238 if (!*s)
239 {
240 return text;
241 }
242
243 c = xstrdup(s);
244 release(text);
245
246 return c;
247 }
248
249
makequote(LINE * l,char * isfrom)250 LINE *makequote(LINE * l, char *isfrom)
251 {
252 int i;
253 char *qs;
254 char *s, c;
255 LINE *t, *o;
256 char initial[10];
257 char line2[256];
258
259 if (l == NULL)
260 {
261 return l;
262 }
263
264 i = 0;
265 s = isfrom;
266
267 while (s && *s && i < 10)
268 {
269 while (*s && m_isspace(*s))
270 {
271 s++;
272 }
273 if (!m_isalnum(*s)) s++; /* mtt */
274 initial[i++] = *s;
275 while (*s && !m_isspace(*s))
276 {
277 s++;
278 }
279 }
280
281 initial[i] = '\0';
282
283 s = strchr(ST->quotestr, '&');
284 if (s == NULL)
285 {
286 qs = xstrdup(ST->quotestr);
287 }
288 else
289 {
290 qs = xmalloc(strlen(ST->quotestr) + strlen(initial) + 1);
291 *s = '\0';
292 strcpy(qs, ST->quotestr);
293 strcat(qs, initial);
294 strcat(qs, s + 1);
295 *s = '&';
296 }
297
298 s = qs;
299 s = strchr(s, '^');
300 while (s != NULL)
301 {
302 if (initial[0])
303 {
304 *s = initial[0];
305 }
306 else
307 {
308 strdel(s, 1);
309 }
310 s = strchr(s, '^');
311 }
312
313 s = qs;
314 s = strchr(s, '*');
315 while (s != NULL)
316 {
317 if (initial[1])
318 {
319 *s = initial[1];
320 }
321 else
322 {
323 strdel(s, 1);
324 }
325 s = strchr(s, '*');
326 }
327
328 t = l;
329
330 while (t)
331 {
332 t->hide = t->block = 0;
333 if (!t->text || strlen(t->text) == 0)
334 {
335 release(t->text);
336 t->text = xstrdup("\n");
337 t = t->next;
338 continue;
339 }
340 if (!t->quote)
341 {
342 if (SW->hardquote)
343 {
344 wrap(t, 1, maxy, SW->qm - strlen(qs));
345 }
346 if (strchr(t->text, '\n') != NULL)
347 {
348 /* don't quote a blank line */
349 if (*t->text == ' ')
350 {
351 char *p;
352
353 p = t->text;
354 while (*p == ' ')
355 {
356 p++;
357 }
358 if (*p == '\n' && *(p + 1) == '\0')
359 {
360 strcpy(t->text, "\n");
361 }
362 }
363 if (*t->text != '\n' && *t->text)
364 {
365 t->hide = t->block = 0;
366 t->text = replace_noise(t->text);
367 sprintf(line2, "%s%s", qs, t->text);
368 release(t->text);
369 t->text = xstrdup(line2);
370 t->quote = 1;
371 }
372 }
373 else
374 {
375 if (!SW->hardquote)
376 {
377 wrap(t, 1, maxy, SW->qm - strlen(qs));
378 }
379 while (t != NULL && strchr(t->text, '\n') == NULL)
380 {
381 t->hide = t->block = 0;
382 t->text = replace_noise(t->text);
383 sprintf(line2, "%s%s\n", qs, t->text);
384 release(t->text);
385 t->text = xstrdup(line2);
386 t->quote = 1;
387 t = t->next;
388 }
389 continue;
390 }
391 }
392 else
393 {
394 if (SW->qquote)
395 {
396 s = strchr(t->text, '>');
397 if (s)
398 {
399 if (s - t->text <= 11)
400 {
401 c = *s;
402 *s = '\0';
403 strcpy(line2, t->text);
404 strcat(line2, ">");
405 *s = c;
406 strcat(line2, s);
407 }
408 else
409 {
410 strcpy(line2, t->text);
411 }
412 }
413 else
414 {
415 strcpy(line2, t->text);
416 }
417 }
418 else
419 {
420 if (t->text)
421 {
422 strcpy(line2, t->text);
423 }
424 else
425 {
426 strcpy(line2, "");
427 }
428 }
429 release(t->text);
430
431 if (!strchr(line2, '\n'))
432 {
433 strcat(line2, "\n");
434 }
435
436 if (*line2 == ' ')
437 {
438 t->text = xstrdup(line2 + 1);
439 }
440 else
441 {
442 t->text = xstrdup(line2);
443 }
444 }
445 t = t->next;
446 }
447
448 xfree(qs);
449
450 t = l; /* returns the last line of the msg */
451 while (t->next != NULL)
452 {
453 if (strlen(t->text) > SW->qm)
454 {
455 wrap(t, 1, maxy, SW->qm);
456 t = t->next;
457 }
458 else
459 {
460 t = t->next;
461 }
462 }
463
464 t = l;
465
466 while (t)
467 {
468 if (strchr(t->text, '\n') && t->prev && !strchr(t->prev->text, '\n'))
469 {
470 if (t->next && !is_blank(t->next) && is_same_quote(t, t->next))
471 {
472 *((char *)strchr(t->text, '\n')) = '\0';
473 }
474
475 wrap(t, 1, maxy, SW->qm);
476 o = t;
477
478 while (t && !strchr(t->text, '\n'))
479 {
480 t = t->next;
481 }
482
483 if (t == o)
484 {
485 t = t->next;
486 }
487 }
488 else
489 {
490 t = t->next;
491 }
492 }
493
494 t = l;
495
496 /* make sure the quotes are all terminated with '\n' */
497
498 while (t->next)
499 {
500 if (t->text && strlen(t->text) > 1 && *ST->quotestr == ' ' && *(t->text) != ' ')
501 {
502 strcpy(line2, " ");
503 strcat(line2, t->text);
504 xfree(t->text);
505 t->text = xstrdup(line2);
506 }
507 if (t->text && !strchr(t->text, '\n') && t->quote)
508 {
509 strcpy(line2, t->text);
510 strcat(line2, "\n");
511 xfree(t->text);
512 t->text = xstrdup(line2);
513 }
514 t = t->next;
515 }
516
517 return t; /* last line of message */
518 }
519