diff options
| author | Richard M. Stallman | 1994-12-26 23:48:27 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1994-12-26 23:48:27 +0000 |
| commit | 3d23b9853efa648232f2d704092c3c15e4516bd7 (patch) | |
| tree | d9ca35073b28d617685aa17f169024db000447ff /lib-src | |
| parent | c3724dc278be6e9402acba37b8deb13ebc18f7e4 (diff) | |
| download | emacs-3d23b9853efa648232f2d704092c3c15e4516bd7.tar.gz emacs-3d23b9853efa648232f2d704092c3c15e4516bd7.zip | |
(xmalloc, xrealloc): Add casts.
(add_field): Handle <...> and "..." syntax.
(setup_files, get_keyword): Clean up parens and line breaks.
(args_size): Likewise.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/fakemail.c | 121 |
1 files changed, 96 insertions, 25 deletions
diff --git a/lib-src/fakemail.c b/lib-src/fakemail.c index 118cfced7b6..da3911b4b49 100644 --- a/lib-src/fakemail.c +++ b/lib-src/fakemail.c | |||
| @@ -170,7 +170,7 @@ static char * | |||
| 170 | xmalloc (size) | 170 | xmalloc (size) |
| 171 | int size; | 171 | int size; |
| 172 | { | 172 | { |
| 173 | char *result = malloc (((unsigned) size)); | 173 | char *result = (char *) malloc (((unsigned) size)); |
| 174 | if (result == ((char *) NULL)) | 174 | if (result == ((char *) NULL)) |
| 175 | fatal ("virtual memory exhausted", 0); | 175 | fatal ("virtual memory exhausted", 0); |
| 176 | return result; | 176 | return result; |
| @@ -181,7 +181,7 @@ xrealloc (ptr, size) | |||
| 181 | char *ptr; | 181 | char *ptr; |
| 182 | int size; | 182 | int size; |
| 183 | { | 183 | { |
| 184 | char *result = realloc (ptr, ((unsigned) size)); | 184 | char *result = (char *) realloc (ptr, ((unsigned) size)); |
| 185 | if (result == ((char *) NULL)) | 185 | if (result == ((char *) NULL)) |
| 186 | fatal ("virtual memory exhausted"); | 186 | fatal ("virtual memory exhausted"); |
| 187 | return result; | 187 | return result; |
| @@ -232,6 +232,12 @@ readline (linebuffer, stream) | |||
| 232 | return p - buffer; | 232 | return p - buffer; |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | /* Extract a colon-terminated keyword from the string FIELD. | ||
| 236 | Return that keyword as a string stored in a static buffer. | ||
| 237 | Store the address of the rest of the string into *REST. | ||
| 238 | |||
| 239 | If there is no keyword, return NULL and don't alter *REST. */ | ||
| 240 | |||
| 235 | char * | 241 | char * |
| 236 | get_keyword (field, rest) | 242 | get_keyword (field, rest) |
| 237 | register char *field; | 243 | register char *field; |
| @@ -243,18 +249,22 @@ get_keyword (field, rest) | |||
| 243 | 249 | ||
| 244 | ptr = &keyword[0]; | 250 | ptr = &keyword[0]; |
| 245 | c = *field++; | 251 | c = *field++; |
| 246 | if ((isspace (c)) || (c == ':')) | 252 | if (isspace (c) || c == ':') |
| 247 | return ((char *) NULL); | 253 | return ((char *) NULL); |
| 248 | *ptr++ = ((islower (c)) ? (toupper (c)) : c); | 254 | *ptr++ = (islower (c) ? toupper (c) : c); |
| 249 | while (((c = *field++) != ':') && (!(isspace (c)))) | 255 | while (((c = *field++) != ':') && ! isspace (c)) |
| 250 | *ptr++ = ((islower (c)) ? (toupper (c)) : c); | 256 | *ptr++ = (islower (c) ? toupper (c) : c); |
| 251 | *ptr++ = '\0'; | 257 | *ptr++ = '\0'; |
| 252 | while (isspace (c)) c = *field++; | 258 | while (isspace (c)) |
| 253 | if (c != ':') return ((char *) NULL); | 259 | c = *field++; |
| 260 | if (c != ':') | ||
| 261 | return ((char *) NULL); | ||
| 254 | *rest = field; | 262 | *rest = field; |
| 255 | return &keyword[0]; | 263 | return &keyword[0]; |
| 256 | } | 264 | } |
| 257 | 265 | ||
| 266 | /* Nonzero if the string FIELD starts with a colon-terminated keyword. */ | ||
| 267 | |||
| 258 | boolean | 268 | boolean |
| 259 | has_keyword (field) | 269 | has_keyword (field) |
| 260 | char *field; | 270 | char *field; |
| @@ -263,6 +273,16 @@ has_keyword (field) | |||
| 263 | return (get_keyword (field, &ignored) != ((char *) NULL)); | 273 | return (get_keyword (field, &ignored) != ((char *) NULL)); |
| 264 | } | 274 | } |
| 265 | 275 | ||
| 276 | /* Store the string FIELD, followed by any lines in THE_LIST, | ||
| 277 | into the buffer WHERE. | ||
| 278 | Concatenate lines, putting just a space between them. | ||
| 279 | Delete everything contained in parentheses. | ||
| 280 | When a recipient name contains <...>, we discard | ||
| 281 | everything except what is inside the <...>. | ||
| 282 | |||
| 283 | We don't pay attention to overflowing WHERE; | ||
| 284 | the caller has to make it big enough. */ | ||
| 285 | |||
| 266 | char * | 286 | char * |
| 267 | add_field (the_list, field, where) | 287 | add_field (the_list, field, where) |
| 268 | line_list the_list; | 288 | line_list the_list; |
| @@ -271,17 +291,48 @@ add_field (the_list, field, where) | |||
| 271 | register char c; | 291 | register char c; |
| 272 | while (true) | 292 | while (true) |
| 273 | { | 293 | { |
| 294 | char *this_recipient_where; | ||
| 295 | int in_quotes = 0; | ||
| 296 | |||
| 274 | *where++ = ' '; | 297 | *where++ = ' '; |
| 298 | this_recipient_where = where; | ||
| 299 | |||
| 275 | while ((c = *field++) != '\0') | 300 | while ((c = *field++) != '\0') |
| 276 | { | 301 | { |
| 277 | if (c == '(') | 302 | if (c == '\\') |
| 303 | *where++ = c; | ||
| 304 | else if (c == '"') | ||
| 305 | { | ||
| 306 | in_quotes = ! in_quotes; | ||
| 307 | *where++ = c; | ||
| 308 | } | ||
| 309 | else if (in_quotes) | ||
| 310 | *where++ = c; | ||
| 311 | else if (c == '(') | ||
| 278 | { | 312 | { |
| 279 | while (*field && *field != ')') ++field; | 313 | while (*field && *field != ')') ++field; |
| 280 | if (! (*field++)) break; /* no closer */ | 314 | if (! (*field++)) break; /* no close */ |
| 281 | if (! (*field)) break; /* closerNULL */ | 315 | continue; |
| 282 | c = *field; | ||
| 283 | } | 316 | } |
| 284 | *where++ = ((c == ','||c=='>'||c=='<') ? ' ' : c); | 317 | else if (c == ',') |
| 318 | { | ||
| 319 | *where++ = ' '; | ||
| 320 | /* When we get to the end of one recipient, | ||
| 321 | don't discard it if the next one has <...>. */ | ||
| 322 | this_recipient_where = where; | ||
| 323 | } | ||
| 324 | else if (c == '<') | ||
| 325 | /* Discard everything we got before the `<'. */ | ||
| 326 | where = this_recipient_where; | ||
| 327 | else if (c == '>') | ||
| 328 | /* Discard the rest of this name that follows the `>'. */ | ||
| 329 | { | ||
| 330 | while (*field && *field != ',') ++field; | ||
| 331 | if (! (*field++)) break; /* no comma */ | ||
| 332 | continue; | ||
| 333 | } | ||
| 334 | else | ||
| 335 | *where++ = c; | ||
| 285 | } | 336 | } |
| 286 | if (the_list == NIL) break; | 337 | if (the_list == NIL) break; |
| 287 | field = the_list->string; | 338 | field = the_list->string; |
| @@ -462,6 +513,10 @@ put_line (string) | |||
| 462 | 513 | ||
| 463 | #define mail_error error | 514 | #define mail_error error |
| 464 | 515 | ||
| 516 | /* Handle an FCC field. FIELD is the text of the first line (after | ||
| 517 | the header name), and THE_LIST holds the continuation lines if any. | ||
| 518 | Call open_a_file for each file. */ | ||
| 519 | |||
| 465 | void | 520 | void |
| 466 | setup_files (the_list, field) | 521 | setup_files (the_list, field) |
| 467 | register line_list the_list; | 522 | register line_list the_list; |
| @@ -471,18 +526,18 @@ setup_files (the_list, field) | |||
| 471 | register char c; | 526 | register char c; |
| 472 | while (true) | 527 | while (true) |
| 473 | { | 528 | { |
| 474 | while (((c = *field) != '\0') && | 529 | while (((c = *field) != '\0') |
| 475 | ((c == ' ') || | 530 | && (c == ' ' |
| 476 | (c == '\t') || | 531 | || c == '\t' |
| 477 | (c == ','))) | 532 | || c == ',')) |
| 478 | field += 1; | 533 | field += 1; |
| 479 | if (c != '\0') | 534 | if (c != '\0') |
| 480 | { | 535 | { |
| 481 | start = field; | 536 | start = field; |
| 482 | while (((c = *field) != '\0') && | 537 | while (((c = *field) != '\0') |
| 483 | (c != ' ') && | 538 | && c != ' ' |
| 484 | (c != '\t') && | 539 | && c != '\t' |
| 485 | (c != ',')) | 540 | && c != ',') |
| 486 | field += 1; | 541 | field += 1; |
| 487 | *field = '\0'; | 542 | *field = '\0'; |
| 488 | if (!open_a_file (start)) | 543 | if (!open_a_file (start)) |
| @@ -490,12 +545,16 @@ setup_files (the_list, field) | |||
| 490 | *field = c; | 545 | *field = c; |
| 491 | if (c != '\0') continue; | 546 | if (c != '\0') continue; |
| 492 | } | 547 | } |
| 493 | if (the_list == ((line_list) NULL)) return; | 548 | if (the_list == ((line_list) NULL)) |
| 549 | return; | ||
| 494 | field = the_list->string; | 550 | field = the_list->string; |
| 495 | the_list = the_list->continuation; | 551 | the_list = the_list->continuation; |
| 496 | } | 552 | } |
| 497 | } | 553 | } |
| 498 | 554 | ||
| 555 | /* Compute the total size of all recipient names stored in THE_HEADER. | ||
| 556 | The result says how big to make the buffer to pass to parse_header. */ | ||
| 557 | |||
| 499 | int | 558 | int |
| 500 | args_size (the_header) | 559 | args_size (the_header) |
| 501 | header the_header; | 560 | header the_header; |
| @@ -507,9 +566,9 @@ args_size (the_header) | |||
| 507 | { | 566 | { |
| 508 | char *field; | 567 | char *field; |
| 509 | register char *keyword = get_keyword (the_header->text->string, &field); | 568 | register char *keyword = get_keyword (the_header->text->string, &field); |
| 510 | if ((strcmp (keyword, "TO") == 0) || | 569 | if ((strcmp (keyword, "TO") == 0) |
| 511 | (strcmp (keyword, "CC") == 0) || | 570 | || (strcmp (keyword, "CC") == 0) |
| 512 | (strcmp (keyword, "BCC") == 0)) | 571 | || (strcmp (keyword, "BCC") == 0)) |
| 513 | { | 572 | { |
| 514 | size += 1 + strlen (field); | 573 | size += 1 + strlen (field); |
| 515 | for (rem = the_header->text->continuation; | 574 | for (rem = the_header->text->continuation; |
| @@ -522,6 +581,12 @@ args_size (the_header) | |||
| 522 | return size; | 581 | return size; |
| 523 | } | 582 | } |
| 524 | 583 | ||
| 584 | /* Scan the header described by the lists THE_HEADER, | ||
| 585 | and put all recipient names into the buffer WHERE. | ||
| 586 | Precede each recipient name with a space. | ||
| 587 | |||
| 588 | Also, if the header has any FCC fields, call setup_files for each one. */ | ||
| 589 | |||
| 525 | parse_header (the_header, where) | 590 | parse_header (the_header, where) |
| 526 | header the_header; | 591 | header the_header; |
| 527 | register char *where; | 592 | register char *where; |
| @@ -549,6 +614,12 @@ parse_header (the_header, where) | |||
| 549 | return; | 614 | return; |
| 550 | } | 615 | } |
| 551 | 616 | ||
| 617 | /* Read lines from the input until we get a blank line. | ||
| 618 | Create a list of `header' objects, one for each header field, | ||
| 619 | each of which points to a list of `line_list' objects, | ||
| 620 | one for each line in that field. | ||
| 621 | Continuation lines are grouped in the headers they continue. */ | ||
| 622 | |||
| 552 | header | 623 | header |
| 553 | read_header () | 624 | read_header () |
| 554 | { | 625 | { |