comparison src/fns.c @ 414:da8ed4261e83 r21-2-15

Import from CVS: tag r21-2-15
author cvs
date Mon, 13 Aug 2007 11:21:38 +0200
parents 697ef44129c6
children ebe98a74bd68
comparison
equal deleted inserted replaced
413:901169e5ca31 414:da8ed4261e83
879 Relevant parts of the string-extent-data are copied in the new string. 879 Relevant parts of the string-extent-data are copied in the new string.
880 */ 880 */
881 (string, from, to)) 881 (string, from, to))
882 { 882 {
883 Charcount ccfr, ccto; 883 Charcount ccfr, ccto;
884 Bytecount bfr, bto; 884 Bytecount bfr, blen;
885 Lisp_Object val; 885 Lisp_Object val;
886 886
887 CHECK_STRING (string); 887 CHECK_STRING (string);
888 CHECK_INT (from); 888 CHECK_INT (from);
889 get_string_range_char (string, from, to, &ccfr, &ccto, 889 get_string_range_char (string, from, to, &ccfr, &ccto,
890 GB_HISTORICAL_STRING_BEHAVIOR); 890 GB_HISTORICAL_STRING_BEHAVIOR);
891 bfr = charcount_to_bytecount (XSTRING_DATA (string), ccfr); 891 bfr = charcount_to_bytecount (XSTRING_DATA (string), ccfr);
892 bto = charcount_to_bytecount (XSTRING_DATA (string), ccto); 892 blen = charcount_to_bytecount (XSTRING_DATA (string) + bfr, ccto - ccfr);
893 val = make_string (XSTRING_DATA (string) + bfr, bto - bfr); 893 val = make_string (XSTRING_DATA (string) + bfr, blen);
894 /* Copy any applicable extent information into the new string: */ 894 /* Copy any applicable extent information into the new string: */
895 copy_string_extents (val, string, 0, bfr, bto - bfr); 895 copy_string_extents (val, string, 0, bfr, blen);
896 return val; 896 return val;
897 } 897 }
898 898
899 DEFUN ("subseq", Fsubseq, 2, 3, 0, /* 899 DEFUN ("subseq", Fsubseq, 2, 3, 0, /*
900 Return a subsequence of SEQ, starting at index FROM and ending before TO. 900 Return a subsequence of SEQ, starting at index FROM and ending before TO.
3438 3438
3439 The octets are divided into 6 bit chunks, which are then encoded into 3439 The octets are divided into 6 bit chunks, which are then encoded into
3440 base64 characters. */ 3440 base64 characters. */
3441 3441
3442 #define ADVANCE_INPUT(c, stream) \ 3442 #define ADVANCE_INPUT(c, stream) \
3443 (ec = Lstream_get_emchar (stream), \ 3443 ((ec = Lstream_get_emchar (stream)) == -1 ? 0 : \
3444 ec == -1 ? 0 : \
3445 ((ec > 255) ? \ 3444 ((ec > 255) ? \
3446 (error ("Non-ascii character detected in base64 input"), 0) \ 3445 (signal_simple_error ("Non-ascii character in base64 input", \
3447 : (c = (Bufbyte)ec, 1))) 3446 make_char (ec)), 0) \
3447 : (c = (Bufbyte)ec), 1))
3448 3448
3449 static Bytind 3449 static Bytind
3450 base64_encode_1 (Lstream *istream, Bufbyte *to, int line_break) 3450 base64_encode_1 (Lstream *istream, Bufbyte *to, int line_break)
3451 { 3451 {
3452 EMACS_INT counter = 0; 3452 EMACS_INT counter = 0;
3502 3502
3503 return e - to; 3503 return e - to;
3504 } 3504 }
3505 #undef ADVANCE_INPUT 3505 #undef ADVANCE_INPUT
3506 3506
3507 /* Semantically identical to ADVANCE_INPUT above, only no >255
3508 checking is needed for decoding -- checking is covered by IS_BASE64
3509 below. */
3507 #define ADVANCE_INPUT(c, stream) \ 3510 #define ADVANCE_INPUT(c, stream) \
3508 (ec = Lstream_get_emchar (stream), \ 3511 (ec = Lstream_get_emchar (stream), \
3509 ec == -1 ? 0 : (c = (Bufbyte)ec, 1)) 3512 ec == -1 ? 0 : (c = (Bufbyte)ec, 1))
3513
3514 /* Get next character from the stream, but ignore it if it's
3515 whitespace. ENDP is set to 1 if EOF is hit. */
3516 #define ADVANCE_INPUT_IGNORE_WHITESPACE(c, endp, stream) do { \
3517 endp = 0; \
3518 do { \
3519 if (!ADVANCE_INPUT (c, stream)) \
3520 endp = 1; \
3521 } while (!endp && (c == ' ' || c == '\t' || c == '\r' || c == '\n' \
3522 || c == '\f' || c == '\v')); \
3523 } while (0)
3510 3524
3511 #define STORE_BYTE(pos, val) do { \ 3525 #define STORE_BYTE(pos, val) do { \
3512 pos += set_charptr_emchar (pos, (Emchar)((unsigned char)(val))); \ 3526 pos += set_charptr_emchar (pos, (Emchar)((unsigned char)(val))); \
3513 ++*ccptr; \ 3527 ++*ccptr; \
3514 } while (0) 3528 } while (0)
3515 3529
3516 static Bytind 3530 static Bytind
3517 base64_decode_1 (Lstream *istream, Bufbyte *to, Charcount *ccptr) 3531 base64_decode_1 (Lstream *istream, Bufbyte *to, Charcount *ccptr)
3518 { 3532 {
3519 Emchar ec;
3520 Bufbyte *e = to; 3533 Bufbyte *e = to;
3521 unsigned long value; 3534 unsigned long value;
3522 3535
3523 *ccptr = 0; 3536 *ccptr = 0;
3524 while (1) 3537 while (1)
3525 { 3538 {
3526 Bufbyte c; 3539 Bufbyte c;
3527 3540 Emchar ec;
3528 if (!ADVANCE_INPUT (c, istream)) 3541 int endp;
3542
3543 ADVANCE_INPUT_IGNORE_WHITESPACE (c, endp, istream);
3544 if (endp)
3529 break; 3545 break;
3530
3531 /* Accept wrapping lines. */
3532 if (c == '\r')
3533 {
3534 if (!ADVANCE_INPUT (c, istream)
3535 || c != '\n')
3536 return -1;
3537 }
3538 if (c == '\n')
3539 {
3540 if (!ADVANCE_INPUT (c, istream))
3541 break;
3542 /* FSF checks for end of text here, but that's wrong. */
3543 /* FSF checks for correct line length here; that's also
3544 wrong; some MIME encoders use different line lengths. */
3545 }
3546 3546
3547 /* Process first byte of a quadruplet. */ 3547 /* Process first byte of a quadruplet. */
3548 if (!IS_BASE64 (c)) 3548 if (!IS_BASE64 (c))
3549 return -1; 3549 return -1;
3550 value = base64_char_to_value[c] << 18; 3550 value = base64_char_to_value[c] << 18;
3551 3551
3552 /* Process second byte of a quadruplet. */ 3552 /* Process second byte of a quadruplet. */
3553 if (!ADVANCE_INPUT (c, istream)) 3553 ADVANCE_INPUT_IGNORE_WHITESPACE (c, endp, istream);
3554 if (endp)
3554 return -1; 3555 return -1;
3555 3556
3556 if (!IS_BASE64 (c)) 3557 if (!IS_BASE64 (c))
3557 return -1; 3558 return -1;
3558 value |= base64_char_to_value[c] << 12; 3559 value |= base64_char_to_value[c] << 12;
3559 3560
3560 STORE_BYTE (e, value >> 16); 3561 STORE_BYTE (e, value >> 16);
3561 3562
3562 /* Process third byte of a quadruplet. */ 3563 /* Process third byte of a quadruplet. */
3563 if (!ADVANCE_INPUT (c, istream)) 3564 ADVANCE_INPUT_IGNORE_WHITESPACE (c, endp, istream);
3565 if (endp)
3564 return -1; 3566 return -1;
3565 3567
3566 if (c == '=') 3568 if (c == '=')
3567 { 3569 {
3568 if (!ADVANCE_INPUT (c, istream)) 3570 ADVANCE_INPUT_IGNORE_WHITESPACE (c, endp, istream);
3571 if (endp)
3569 return -1; 3572 return -1;
3570 if (c != '=') 3573 if (c != '=')
3571 return -1; 3574 return -1;
3572 continue; 3575 continue;
3573 } 3576 }
3577 value |= base64_char_to_value[c] << 6; 3580 value |= base64_char_to_value[c] << 6;
3578 3581
3579 STORE_BYTE (e, 0xff & value >> 8); 3582 STORE_BYTE (e, 0xff & value >> 8);
3580 3583
3581 /* Process fourth byte of a quadruplet. */ 3584 /* Process fourth byte of a quadruplet. */
3582 if (!ADVANCE_INPUT (c, istream)) 3585 ADVANCE_INPUT_IGNORE_WHITESPACE (c, endp, istream);
3586 if (endp)
3583 return -1; 3587 return -1;
3584 3588
3585 if (c == '=') 3589 if (c == '=')
3586 continue; 3590 continue;
3587 3591
3593 } 3597 }
3594 3598
3595 return e - to; 3599 return e - to;
3596 } 3600 }
3597 #undef ADVANCE_INPUT 3601 #undef ADVANCE_INPUT
3598 #undef INPUT_EOF_P 3602 #undef ADVANCE_INPUT_IGNORE_WHITESPACE
3603 #undef STORE_BYTE
3599 3604
3600 static Lisp_Object 3605 static Lisp_Object
3601 free_malloced_ptr (Lisp_Object unwind_obj) 3606 free_malloced_ptr (Lisp_Object unwind_obj)
3602 { 3607 {
3603 void *ptr = (void *)get_opaque_ptr (unwind_obj); 3608 void *ptr = (void *)get_opaque_ptr (unwind_obj);