~ubuntu-branches/ubuntu/raring/nano/raring

« back to all changes in this revision

Viewing changes to src/chars.c

  • Committer: Bazaar Package Importer
  • Author(s): Jordi Mallach
  • Date: 2008-08-25 17:27:55 UTC
  • mfrom: (13.1.6 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080825172755-f7nqabuhghz16a5u
Tags: 2.0.7-4
* The "Valencia, tenemos la fórmula" release.
* Add patch successful_write_no_free_space.patch to solve an issue
  with nano reporting successful writes on full devices, potentially
  causing files to be zeroed.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: chars.c,v 1.121 2006/11/10 02:49:07 dolorous Exp $ */
 
1
/* $Id: chars.c,v 1.122.2.13 2007/10/11 05:01:29 dolorous Exp $ */
2
2
/**************************************************************************
3
3
 *   chars.c                                                              *
4
4
 *                                                                        *
5
 
 *   Copyright (C) 2001, 2002, 2003, 2004 Chris Allegretta                *
6
 
 *   Copyright (C) 2005, 2006 David Lawrence Ramsey                       *
 
5
 *   Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007               *
 
6
 *   Free Software Foundation, Inc.                                       *
7
7
 *   This program is free software; you can redistribute it and/or modify *
8
8
 *   it under the terms of the GNU General Public License as published by *
9
 
 *   the Free Software Foundation; either version 2, or (at your option)  *
 
9
 *   the Free Software Foundation; either version 3, or (at your option)  *
10
10
 *   any later version.                                                   *
11
11
 *                                                                        *
12
12
 *   This program is distributed in the hope that it will be useful, but  *
38
38
        /* Whether we've enabled UTF-8 support. */
39
39
static const wchar_t bad_wchar = 0xFFFD;
40
40
        /* If we get an invalid multibyte sequence, we treat it as
41
 
         * Unicode FFFD (Replacement Character), unless we're
42
 
         * determining if it's a control character or searching for a
43
 
         * match to it. */
 
41
         * Unicode FFFD (Replacement Character), unless we're searching
 
42
         * for a match to it. */
44
43
static const char *const bad_mbchar = "\xEF\xBF\xBD";
45
44
static const int bad_mbchar_len = 3;
46
45
 
507
506
/* This function is equivalent to strncasecmp(). */
508
507
int nstrncasecmp(const char *s1, const char *s2, size_t n)
509
508
{
 
509
    if (s1 == s2)
 
510
        return 0;
 
511
 
510
512
    assert(s1 != NULL && s2 != NULL);
511
513
 
512
 
    for (; n > 0 && *s1 != '\0' && *s2 != '\0'; n--, s1++, s2++) {
 
514
    for (; *s1 != '\0' && *s2 != '\0' && n > 0; s1++, s2++, n--) {
513
515
        if (tolower(*s1) != tolower(*s2))
514
516
            break;
515
517
    }
527
529
        char *s1_mb, *s2_mb;
528
530
        wchar_t ws1, ws2;
529
531
 
 
532
        if (s1 == s2)
 
533
            return 0;
 
534
 
530
535
        assert(s1 != NULL && s2 != NULL);
531
536
 
532
537
        s1_mb = charalloc(MB_CUR_MAX);
533
538
        s2_mb = charalloc(MB_CUR_MAX);
534
539
 
535
 
        while (n > 0 && *s1 != '\0' && *s2 != '\0') {
 
540
        for (; *s1 != '\0' && *s2 != '\0' && n > 0; s1 +=
 
541
                move_mbright(s1, 0), s2 += move_mbright(s2, 0), n--) {
536
542
            bool bad_s1_mb = FALSE, bad_s2_mb = FALSE;
537
543
            int s1_mb_len, s2_mb_len;
538
544
 
552
558
                bad_s2_mb = TRUE;
553
559
            }
554
560
 
555
 
            if (n == 0 || bad_s1_mb != bad_s2_mb ||
556
 
                towlower(ws1) != towlower(ws2))
 
561
            if (bad_s1_mb != bad_s2_mb || towlower(ws1) !=
 
562
                towlower(ws2))
557
563
                break;
558
 
 
559
 
            s1 += s1_mb_len;
560
 
            s2 += s2_mb_len;
561
 
            n--;
562
564
        }
563
565
 
564
566
        free(s1_mb);
565
567
        free(s2_mb);
566
568
 
567
 
        return towlower(ws1) - towlower(ws2);
 
569
        return (n > 0) ? towlower(ws1) - towlower(ws2) : 0;
568
570
    } else
569
571
#endif
570
572
        return strncasecmp(s1, s2, n);
571
573
}
572
574
 
573
575
#ifndef HAVE_STRCASESTR
574
 
/* This function, nstrcasestr() (originally mutt_stristr()), was adapted
575
 
 * from mutt 1.2.4i (lib.c).  Here is the notice from that file, with
576
 
 * the Free Software Foundation's address updated:
577
 
 *
578
 
 * Copyright (C) 1996, 1997, 1998, 1999, 2000 Michael R. Elkins
579
 
 * <me@cs.hmc.edu>
580
 
 * Copyright (C) 1999, 2000 Thomas Roessler <roessler@guug.de>
581
 
 * 
582
 
 *     This program is free software; you can redistribute it
583
 
 *     and/or modify it under the terms of the GNU General Public
584
 
 *     License as published by the Free Software Foundation; either
585
 
 *     version 2 of the License, or (at your option) any later
586
 
 *     version.
587
 
 * 
588
 
 *     This program is distributed in the hope that it will be
589
 
 *     useful, but WITHOUT ANY WARRANTY; without even the implied
590
 
 *     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
591
 
 *     PURPOSE.  See the GNU General Public License for more
592
 
 *     details.
593
 
 * 
594
 
 *     You should have received a copy of the GNU General Public
595
 
 *     License along with this program; if not, write to the Free
596
 
 *     Software Foundation, Inc., 51 Franklin St, Fifth Floor,
597
 
 *     Boston, MA  02110-1301, USA. */
598
 
 
599
576
/* This function is equivalent to strcasestr(). */
600
 
const char *nstrcasestr(const char *haystack, const char *needle)
 
577
char *nstrcasestr(const char *haystack, const char *needle)
601
578
{
 
579
    size_t haystack_len, needle_len;
 
580
 
602
581
    assert(haystack != NULL && needle != NULL);
603
582
 
604
 
    for (; *haystack != '\0'; haystack++) {
605
 
        const char *r = haystack, *q = needle;
606
 
 
607
 
        for (; tolower(*r) == tolower(*q) && *q != '\0'; r++, q++)
608
 
            ;
609
 
 
610
 
        if (*q == '\0')
611
 
            return haystack;
 
583
    if (*needle == '\0')
 
584
        return (char *)haystack;
 
585
 
 
586
    haystack_len = strlen(haystack);
 
587
    needle_len = strlen(needle);
 
588
 
 
589
    for (; *haystack != '\0' && haystack_len >= needle_len; haystack++,
 
590
        haystack_len--) {
 
591
        if (strncasecmp(haystack, needle, needle_len) == 0)
 
592
            return (char *)haystack;
612
593
    }
613
594
 
614
595
    return NULL;
616
597
#endif
617
598
 
618
599
/* This function is equivalent to strcasestr() for multibyte strings. */
619
 
const char *mbstrcasestr(const char *haystack, const char *needle)
 
600
char *mbstrcasestr(const char *haystack, const char *needle)
620
601
{
621
602
#ifdef ENABLE_UTF8
622
603
    if (use_utf8) {
623
 
        char *r_mb, *q_mb;
624
 
        wchar_t wr, wq;
625
 
        bool found_needle = FALSE;
 
604
        size_t haystack_len, needle_len;
626
605
 
627
606
        assert(haystack != NULL && needle != NULL);
628
607
 
629
 
        r_mb = charalloc(MB_CUR_MAX);
630
 
        q_mb = charalloc(MB_CUR_MAX);
631
 
 
632
 
        while (*haystack != '\0') {
633
 
            const char *r = haystack, *q = needle;
634
 
            int r_mb_len, q_mb_len;
635
 
 
636
 
            while (*q != '\0') {
637
 
                bool bad_r_mb = FALSE, bad_q_mb = FALSE;
638
 
 
639
 
                r_mb_len = parse_mbchar(r, r_mb, NULL);
640
 
 
641
 
                if (mbtowc(&wr, r_mb, r_mb_len) < 0) {
642
 
                    mbtowc(NULL, NULL, 0);
643
 
                    wr = (unsigned char)*r;
644
 
                    bad_r_mb = TRUE;
645
 
                }
646
 
 
647
 
                q_mb_len = parse_mbchar(q, q_mb, NULL);
648
 
 
649
 
                if (mbtowc(&wq, q_mb, q_mb_len) < 0) {
650
 
                    mbtowc(NULL, NULL, 0);
651
 
                    wq = (unsigned char)*q;
652
 
                    bad_q_mb = TRUE;
653
 
                }
654
 
 
655
 
                if (bad_r_mb != bad_q_mb ||
656
 
                        towlower(wr) != towlower(wq))
657
 
                    break;
658
 
 
659
 
                r += r_mb_len;
660
 
                q += q_mb_len;
661
 
            }
662
 
 
663
 
            if (*q == '\0') {
664
 
                found_needle = TRUE;
665
 
                break;
666
 
            }
667
 
 
668
 
            haystack += move_mbright(haystack, 0);
 
608
        if (*needle == '\0')
 
609
            return (char *)haystack;
 
610
 
 
611
        haystack_len = mbstrlen(haystack);
 
612
        needle_len = mbstrlen(needle);
 
613
 
 
614
        for (; *haystack != '\0' && haystack_len >= needle_len;
 
615
                haystack += move_mbright(haystack, 0), haystack_len--) {
 
616
            if (mbstrncasecmp(haystack, needle, needle_len) == 0)
 
617
                return (char *)haystack;
669
618
        }
670
619
 
671
 
        free(r_mb);
672
 
        free(q_mb);
673
 
 
674
 
        return found_needle ? haystack : NULL;
 
620
        return NULL;
675
621
    } else
676
622
#endif
677
623
        return strcasestr(haystack, needle);
680
626
#if !defined(NANO_TINY) || !defined(DISABLE_TABCOMP)
681
627
/* This function is equivalent to strstr(), except in that it scans the
682
628
 * string in reverse, starting at rev_start. */
683
 
const char *revstrstr(const char *haystack, const char *needle, const
684
 
        char *rev_start)
 
629
char *revstrstr(const char *haystack, const char *needle, const char
 
630
        *rev_start)
685
631
{
 
632
    size_t rev_start_len, needle_len;
 
633
 
686
634
    assert(haystack != NULL && needle != NULL && rev_start != NULL);
687
635
 
688
 
    for (; rev_start >= haystack; rev_start--) {
689
 
        const char *r, *q;
690
 
 
691
 
        for (r = rev_start, q = needle; *r == *q && *q != '\0'; r++, q++)
692
 
            ;
693
 
 
694
 
        if (*q == '\0')
695
 
            return rev_start;
 
636
    if (*needle == '\0')
 
637
        return (char *)rev_start;
 
638
 
 
639
    needle_len = strlen(needle);
 
640
 
 
641
    if (strlen(haystack) < needle_len)
 
642
        return NULL;
 
643
 
 
644
    rev_start_len = strlen(rev_start);
 
645
 
 
646
    for (; rev_start >= haystack; rev_start--, rev_start_len++) {
 
647
        if (rev_start_len >= needle_len && strncmp(rev_start, needle,
 
648
                needle_len) == 0)
 
649
            return (char *)rev_start;
696
650
    }
697
651
 
698
652
    return NULL;
702
656
#ifndef NANO_TINY
703
657
/* This function is equivalent to strcasestr(), except in that it scans
704
658
 * the string in reverse, starting at rev_start. */
705
 
const char *revstrcasestr(const char *haystack, const char *needle,
706
 
        const char *rev_start)
 
659
char *revstrcasestr(const char *haystack, const char *needle, const char
 
660
        *rev_start)
707
661
{
 
662
    size_t rev_start_len, needle_len;
 
663
 
708
664
    assert(haystack != NULL && needle != NULL && rev_start != NULL);
709
665
 
710
 
    for (; rev_start >= haystack; rev_start--) {
711
 
        const char *r = rev_start, *q = needle;
712
 
 
713
 
        for (; tolower(*r) == tolower(*q) && *q != '\0'; r++, q++)
714
 
            ;
715
 
 
716
 
        if (*q == '\0')
717
 
            return rev_start;
 
666
    if (*needle == '\0')
 
667
        return (char *)rev_start;
 
668
 
 
669
    needle_len = strlen(needle);
 
670
 
 
671
    if (strlen(haystack) < needle_len)
 
672
        return NULL;
 
673
 
 
674
    rev_start_len = strlen(rev_start);
 
675
 
 
676
    for (; rev_start >= haystack; rev_start--, rev_start_len++) {
 
677
        if (rev_start_len >= needle_len && strncasecmp(rev_start,
 
678
                needle, needle_len) == 0)
 
679
            return (char *)rev_start;
718
680
    }
719
681
 
720
682
    return NULL;
723
685
/* This function is equivalent to strcasestr() for multibyte strings,
724
686
 * except in that it scans the string in reverse, starting at
725
687
 * rev_start. */
726
 
const char *mbrevstrcasestr(const char *haystack, const char *needle,
727
 
        const char *rev_start)
 
688
char *mbrevstrcasestr(const char *haystack, const char *needle, const
 
689
        char *rev_start)
728
690
{
729
691
#ifdef ENABLE_UTF8
730
692
    if (use_utf8) {
731
 
        char *r_mb, *q_mb;
732
 
        wchar_t wr, wq;
733
 
        bool begin_line = FALSE, found_needle = FALSE;
 
693
        bool begin_line = FALSE;
 
694
        size_t rev_start_len, needle_len;
734
695
 
735
696
        assert(haystack != NULL && needle != NULL && rev_start != NULL);
736
697
 
737
 
        r_mb = charalloc(MB_CUR_MAX);
738
 
        q_mb = charalloc(MB_CUR_MAX);
 
698
        if (*needle == '\0')
 
699
            return (char *)rev_start;
 
700
 
 
701
        needle_len = mbstrlen(needle);
 
702
 
 
703
        if (mbstrlen(haystack) < needle_len)
 
704
            return NULL;
 
705
 
 
706
        rev_start_len = mbstrlen(rev_start);
739
707
 
740
708
        while (!begin_line) {
741
 
            const char *r = rev_start, *q = needle;
742
 
            int r_mb_len, q_mb_len;
743
 
 
744
 
            while (*q != '\0') {
745
 
                bool bad_r_mb = FALSE, bad_q_mb = FALSE;
746
 
 
747
 
                r_mb_len = parse_mbchar(r, r_mb, NULL);
748
 
 
749
 
                if (mbtowc(&wr, r_mb, r_mb_len) < 0) {
750
 
                    mbtowc(NULL, NULL, 0);
751
 
                    wr = (unsigned char)*r;
752
 
                    bad_r_mb = TRUE;
753
 
                }
754
 
 
755
 
                q_mb_len = parse_mbchar(q, q_mb, NULL);
756
 
 
757
 
                if (mbtowc(&wq, q_mb, q_mb_len) < 0) {
758
 
                    mbtowc(NULL, NULL, 0);
759
 
                    wq = (unsigned char)*q;
760
 
                    bad_q_mb = TRUE;
761
 
                }
762
 
 
763
 
                if (bad_r_mb != bad_q_mb ||
764
 
                        towlower(wr) != towlower(wq))
765
 
                    break;
766
 
 
767
 
                r += r_mb_len;
768
 
                q += q_mb_len;
769
 
            }
770
 
 
771
 
            if (*q == '\0') {
772
 
                found_needle = TRUE;
773
 
                break;
774
 
            }
 
709
            if (rev_start_len >= needle_len && mbstrncasecmp(rev_start,
 
710
                needle, needle_len) == 0)
 
711
                return (char *)rev_start;
775
712
 
776
713
            if (rev_start == haystack)
777
714
                begin_line = TRUE;
778
 
            else
 
715
            else {
779
716
                rev_start = haystack + move_mbleft(haystack, rev_start -
780
717
                        haystack);
 
718
                rev_start_len++;
 
719
            }
781
720
        }
782
721
 
783
 
        free(r_mb);
784
 
        free(q_mb);
785
 
 
786
 
        return found_needle ? rev_start : NULL;
 
722
        return NULL;
787
723
    } else
788
724
#endif
789
725
        return revstrcasestr(haystack, needle, rev_start);
804
740
 
805
741
    assert(s != NULL);
806
742
 
807
 
    for (; maxlen > 0 && *s != '\0'; maxlen--, n++, s++)
 
743
    for (; *s != '\0' && maxlen > 0; s++, maxlen--, n++)
808
744
        ;
809
745
 
810
746
    return n;
819
755
#ifdef ENABLE_UTF8
820
756
    if (use_utf8) {
821
757
        size_t n = 0;
822
 
        int s_mb_len;
823
 
 
824
 
        while (*s != '\0') {
825
 
            s_mb_len = parse_mbchar(s, NULL, NULL);
826
 
 
827
 
            if (maxlen == 0)
828
 
                break;
829
 
 
830
 
            maxlen--;
831
 
            s += s_mb_len;
832
 
            n++;
833
 
        }
 
758
 
 
759
        for (; *s != '\0' && maxlen > 0; s += move_mbright(s, 0),
 
760
                maxlen--, n++)
 
761
            ;
834
762
 
835
763
        return n;
836
764
    } else
894
822
 
895
823
#ifdef ENABLE_UTF8
896
824
    if (use_utf8) {
897
 
        while (*s != '\0') {
 
825
        for (; *s != '\0'; s += move_mbright(s, 0)) {
898
826
            if (mbstrchr(accept, s) != NULL)
899
827
                return (char *)s;
900
 
 
901
 
            s += move_mbright(s, 0);
902
828
        }
903
829
 
904
830
        return NULL;
980
906
 
981
907
#ifdef ENABLE_UTF8
982
908
    if (use_utf8) {
 
909
        bool retval = FALSE;
983
910
        char *chr_mb = charalloc(MB_CUR_MAX);
984
 
        bool retval = FALSE;
985
 
 
986
 
        while (*s != '\0') {
987
 
            int chr_mb_len;
988
 
 
989
 
            chr_mb_len = parse_mbchar(s, chr_mb, NULL);
 
911
 
 
912
        for (; *s != '\0'; s += move_mbright(s, 0)) {
 
913
            parse_mbchar(s, chr_mb, NULL);
990
914
 
991
915
            if (is_blank_mbchar(chr_mb)) {
992
916
                retval = TRUE;
993
917
                break;
994
918
            }
995
 
 
996
 
            s += chr_mb_len;
997
919
        }
998
920
 
999
921
        free(chr_mb);
1022
944
{
1023
945
    assert(s != NULL);
1024
946
 
1025
 
    return 
 
947
    return
1026
948
#ifdef ENABLE_UTF8
1027
949
        use_utf8 ? (mbstowcs(NULL, s, 0) != (size_t)-1) :
1028
950
#endif