source:
patches/coreutils-6.12-i18n-1.patch@
c5c8ee8
Last change on this file since c5c8ee8 was d33f80c, checked in by , 16 years ago | |
---|---|
|
|
File size: 100.4 KB |
-
lib/linebuffer.h
Submitted By: Jim Gifford <jim at cross-lfs dot org> Date: 2009-01-08 Initial Package Version: 6.12 Upstream Status: Unkown Origin: Mandriva Description: i18n Updates diff -Naur coreutils-6.12.orig/lib/linebuffer.h coreutils-6.12/lib/linebuffer.h
old new 21 21 22 22 # include <stdio.h> 23 23 24 /* Get mbstate_t. */ 25 # if HAVE_WCHAR_H 26 # include <wchar.h> 27 # endif 28 24 29 /* A `struct linebuffer' holds a line of text. */ 25 30 26 31 struct linebuffer … … 28 33 size_t size; /* Allocated. */ 29 34 size_t length; /* Used. */ 30 35 char *buffer; 36 # if HAVE_WCHAR_H 37 mbstate_t state; 38 # endif 31 39 }; 32 40 33 41 /* Initialize linebuffer LINEBUFFER for use. */ -
coreutils-6.12
diff -Naur coreutils-6.12.orig/src/cut.c coreutils-6.12/src/cut.c
old new 28 28 #include <assert.h> 29 29 #include <getopt.h> 30 30 #include <sys/types.h> 31 32 /* Get mbstate_t, mbrtowc(). */ 33 #if HAVE_WCHAR_H 34 # include <wchar.h> 35 #endif 31 36 #include "system.h" 32 37 33 38 #include "error.h" … … 36 41 #include "quote.h" 37 42 #include "xstrndup.h" 38 43 44 /* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 45 installation; work around this configuration error. */ 46 #if !defined MB_LEN_MAX || MB_LEN_MAX < 2 47 # undef MB_LEN_MAX 48 # define MB_LEN_MAX 16 49 #endif 50 51 /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 52 #if HAVE_MBRTOWC && defined mbstate_t 53 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 54 #endif 55 39 56 /* The official name of this program (e.g., no `g' prefix). */ 40 57 #define PROGRAM_NAME "cut" 41 58 … … 71 88 } \ 72 89 while (0) 73 90 91 /* Refill the buffer BUF to get a multibyte character. */ 92 #define REFILL_BUFFER(BUF, BUFPOS, BUFLEN, STREAM) \ 93 do \ 94 { \ 95 if (BUFLEN < MB_LEN_MAX && !feof (STREAM) && !ferror (STREAM)) \ 96 { \ 97 memmove (BUF, BUFPOS, BUFLEN); \ 98 BUFLEN += fread (BUF + BUFLEN, sizeof(char), BUFSIZ, STREAM); \ 99 BUFPOS = BUF; \ 100 } \ 101 } \ 102 while (0) 103 104 /* Get wide character on BUFPOS. BUFPOS is not included after that. 105 If byte sequence is not valid as a character, CONVFAIL is 1. Otherwise 0. */ 106 #define GET_NEXT_WC_FROM_BUFFER(WC, BUFPOS, BUFLEN, MBLENGTH, STATE, CONVFAIL) \ 107 do \ 108 { \ 109 mbstate_t state_bak; \ 110 \ 111 if (BUFLEN < 1) \ 112 { \ 113 WC = WEOF; \ 114 break; \ 115 } \ 116 \ 117 /* Get a wide character. */ \ 118 CONVFAIL = 0; \ 119 state_bak = STATE; \ 120 MBLENGTH = mbrtowc ((wchar_t *)&WC, BUFPOS, BUFLEN, &STATE); \ 121 \ 122 switch (MBLENGTH) \ 123 { \ 124 case (size_t)-1: \ 125 case (size_t)-2: \ 126 CONVFAIL++; \ 127 STATE = state_bak; \ 128 /* Fall througn. */ \ 129 \ 130 case 0: \ 131 MBLENGTH = 1; \ 132 break; \ 133 } \ 134 } \ 135 while (0) 136 74 137 struct range_pair 75 138 { 76 139 size_t lo; … … 89 152 /* The number of bytes allocated for FIELD_1_BUFFER. */ 90 153 static size_t field_1_bufsize; 91 154 92 /* The largest field or byteindex used as an endpoint of a closed155 /* The largest byte, character or field index used as an endpoint of a closed 93 156 or degenerate range specification; this doesn't include the starting 94 157 index of right-open-ended ranges. For example, with either range spec 95 158 `2-5,9-', `2-3,5,9-' this variable would be set to 5. */ … … 101 164 102 165 /* This is a bit vector. 103 166 In byte mode, which bytes to output. 167 In character mode, which characters to output. 104 168 In field mode, which DELIM-separated fields to output. 105 B oth bytes and fields are numbered starting with 1,169 Bytes, characters and fields are numbered starting with 1, 106 170 so the zeroth bit of this array is unused. 107 A field or byteK has been selected if171 A byte, character or field K has been selected if 108 172 (K <= MAX_RANGE_ENDPOINT and is_printable_field(K)) 109 173 || (EOL_RANGE_START > 0 && K >= EOL_RANGE_START). */ 110 174 static unsigned char *printable_field; … … 113 177 { 114 178 undefined_mode, 115 179 116 /* Output characters that are in the given bytes. */180 /* Output bytes that are at the given positions. */ 117 181 byte_mode, 118 182 183 /* Output characters that are at the given positions. */ 184 character_mode, 185 119 186 /* Output the given delimeter-separated fields. */ 120 187 field_mode 121 188 }; … … 125 192 126 193 static enum operating_mode operating_mode; 127 194 195 /* If nonzero, when in byte mode, don't split multibyte characters. */ 196 static int byte_mode_character_aware; 197 198 /* If nonzero, the function for single byte locale is work 199 if this program runs on multibyte locale. */ 200 static int force_singlebyte_mode; 201 128 202 /* If true do not output lines containing no delimeter characters. 129 203 Otherwise, all such lines are printed. This option is valid only 130 204 with field mode. */ … … 136 210 137 211 /* The delimeter character for field mode. */ 138 212 static unsigned char delim; 213 #if HAVE_WCHAR_H 214 static wchar_t wcdelim; 215 #endif 139 216 140 217 /* True if the --output-delimiter=STRING option was specified. */ 141 218 static bool output_delimiter_specified; … … 209 286 -f, --fields=LIST select only these fields; also print any line\n\ 210 287 that contains no delimiter character, unless\n\ 211 288 the -s option is specified\n\ 212 -n (ignored)\n\289 -n with -b: don't split multibyte characters\n\ 213 290 "), stdout); 214 291 fputs (_("\ 215 292 --complement complement the set of selected bytes, characters\n\ … … 368 445 in_digits = false; 369 446 /* Starting a range. */ 370 447 if (dash_found) 371 FATAL_ERROR (_("invalid byte or field list"));448 FATAL_ERROR (_("invalid byte, character or field list")); 372 449 dash_found = true; 373 450 fieldstr++; 374 451 … … 392 469 if (!rhs_specified) 393 470 { 394 471 /* `n-'. From `initial' to end of line. */ 395 eol_range_start = initial; 472 if (eol_range_start == 0 || 473 (eol_range_start != 0 && eol_range_start > initial)) 474 eol_range_start = initial; 396 475 field_found = true; 397 476 } 398 477 else 399 478 { 400 479 /* `m-n' or `-n' (1-n). */ 401 480 if (value < initial) 402 FATAL_ERROR (_("invalid decreasing range"));481 FATAL_ERROR (_("invalid byte, character or field list")); 403 482 404 483 /* Is there already a range going to end of line? */ 405 484 if (eol_range_start != 0) … … 479 558 if (operating_mode == byte_mode) 480 559 error (0, 0, 481 560 _("byte offset %s is too large"), quote (bad_num)); 561 else if (operating_mode == character_mode) 562 error (0, 0, 563 _("character offset %s is too large"), quote (bad_num)); 482 564 else 483 565 error (0, 0, 484 566 _("field number %s is too large"), quote (bad_num)); … … 489 571 fieldstr++; 490 572 } 491 573 else 492 FATAL_ERROR (_("invalid byte or field list"));574 FATAL_ERROR (_("invalid byte, character or field list")); 493 575 } 494 576 495 577 max_range_endpoint = 0; … … 582 664 } 583 665 } 584 666 667 #if HAVE_MBRTOWC 668 /* This function is in use for the following case. 669 670 1. Read from the stream STREAM, printing to standard output any selected 671 characters. 672 673 2. Read from stream STREAM, printing to standard output any selected bytes, 674 without splitting multibyte characters. */ 675 676 static void 677 cut_characters_or_cut_bytes_no_split (FILE *stream) 678 { 679 int idx; /* number of bytes or characters in the line so far. */ 680 char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 681 char *bufpos; /* Next read position of BUF. */ 682 size_t buflen; /* The length of the byte sequence in buf. */ 683 wint_t wc; /* A gotten wide character. */ 684 size_t mblength; /* The byte size of a multibyte character which shows 685 as same character as WC. */ 686 mbstate_t state; /* State of the stream. */ 687 int convfail; /* 1, when conversion is failed. Otherwise 0. */ 688 689 idx = 0; 690 buflen = 0; 691 bufpos = buf; 692 memset (&state, '\0', sizeof(mbstate_t)); 693 694 while (1) 695 { 696 REFILL_BUFFER (buf, bufpos, buflen, stream); 697 698 GET_NEXT_WC_FROM_BUFFER (wc, bufpos, buflen, mblength, state, convfail); 699 700 if (wc == WEOF) 701 { 702 if (idx > 0) 703 putchar ('\n'); 704 break; 705 } 706 else if (wc == L'\n') 707 { 708 putchar ('\n'); 709 idx = 0; 710 } 711 else 712 { 713 idx += (operating_mode == byte_mode) ? mblength : 1; 714 if (print_kth (idx, NULL)) 715 fwrite (bufpos, mblength, sizeof(char), stdout); 716 } 717 718 buflen -= mblength; 719 bufpos += mblength; 720 } 721 } 722 #endif 723 585 724 /* Read from stream STREAM, printing to standard output any selected fields. */ 586 725 587 726 static void … … 704 843 } 705 844 } 706 845 846 #if HAVE_MBRTOWC 847 static void 848 cut_fields_mb (FILE *stream) 849 { 850 int c; 851 unsigned int field_idx; 852 int found_any_selected_field; 853 int buffer_first_field; 854 int empty_input; 855 char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 856 char *bufpos; /* Next read position of BUF. */ 857 size_t buflen; /* The length of the byte sequence in buf. */ 858 wint_t wc = 0; /* A gotten wide character. */ 859 size_t mblength; /* The byte size of a multibyte character which shows 860 as same character as WC. */ 861 mbstate_t state; /* State of the stream. */ 862 int convfail; /* 1, when conversion is failed. Otherwise 0. */ 863 864 found_any_selected_field = 0; 865 field_idx = 1; 866 bufpos = buf; 867 buflen = 0; 868 memset (&state, '\0', sizeof(mbstate_t)); 869 870 c = getc (stream); 871 empty_input = (c == EOF); 872 if (c != EOF) 873 ungetc (c, stream); 874 else 875 wc = WEOF; 876 877 /* To support the semantics of the -s flag, we may have to buffer 878 all of the first field to determine whether it is `delimited.' 879 But that is unnecessary if all non-delimited lines must be printed 880 and the first field has been selected, or if non-delimited lines 881 must be suppressed and the first field has *not* been selected. 882 That is because a non-delimited line has exactly one field. */ 883 buffer_first_field = (suppress_non_delimited ^ !print_kth (1, NULL)); 884 885 while (1) 886 { 887 if (field_idx == 1 && buffer_first_field) 888 { 889 int len = 0; 890 891 while (1) 892 { 893 REFILL_BUFFER (buf, bufpos, buflen, stream); 894 895 GET_NEXT_WC_FROM_BUFFER 896 (wc, bufpos, buflen, mblength, state, convfail); 897 898 if (wc == WEOF) 899 break; 900 901 field_1_buffer = xrealloc (field_1_buffer, len + mblength); 902 memcpy (field_1_buffer + len, bufpos, mblength); 903 len += mblength; 904 buflen -= mblength; 905 bufpos += mblength; 906 907 if (!convfail && (wc == L'\n' || wc == wcdelim)) 908 break; 909 } 910 911 if (wc == WEOF) 912 break; 913 914 /* If the first field extends to the end of line (it is not 915 delimited) and we are printing all non-delimited lines, 916 print this one. */ 917 if (convfail || (!convfail && wc != wcdelim)) 918 { 919 if (suppress_non_delimited) 920 { 921 /* Empty. */ 922 } 923 else 924 { 925 fwrite (field_1_buffer, sizeof (char), len, stdout); 926 /* Make sure the output line is newline terminated. */ 927 if (convfail || (!convfail && wc != L'\n')) 928 putchar ('\n'); 929 } 930 continue; 931 } 932 933 if (print_kth (1, NULL)) 934 { 935 /* Print the field, but not the trailing delimiter. */ 936 fwrite (field_1_buffer, sizeof (char), len - 1, stdout); 937 found_any_selected_field = 1; 938 } 939 ++field_idx; 940 } 941 942 if (wc != WEOF) 943 { 944 if (print_kth (field_idx, NULL)) 945 { 946 if (found_any_selected_field) 947 { 948 fwrite (output_delimiter_string, sizeof (char), 949 output_delimiter_length, stdout); 950 } 951 found_any_selected_field = 1; 952 } 953 954 while (1) 955 { 956 REFILL_BUFFER (buf, bufpos, buflen, stream); 957 958 GET_NEXT_WC_FROM_BUFFER 959 (wc, bufpos, buflen, mblength, state, convfail); 960 961 if (wc == WEOF) 962 break; 963 else if (!convfail && (wc == wcdelim || wc == L'\n')) 964 { 965 buflen -= mblength; 966 bufpos += mblength; 967 break; 968 } 969 970 if (print_kth (field_idx, NULL)) 971 fwrite (bufpos, mblength, sizeof(char), stdout); 972 973 buflen -= mblength; 974 bufpos += mblength; 975 } 976 } 977 978 if ((!convfail || wc == L'\n') && buflen < 1) 979 wc = WEOF; 980 981 if (!convfail && wc == wcdelim) 982 ++field_idx; 983 else if (wc == WEOF || (!convfail && wc == L'\n')) 984 { 985 if (found_any_selected_field 986 || (!empty_input && !(suppress_non_delimited && field_idx == 1))) 987 putchar ('\n'); 988 if (wc == WEOF) 989 break; 990 field_idx = 1; 991 found_any_selected_field = 0; 992 } 993 } 994 } 995 #endif 996 707 997 static void 708 998 cut_stream (FILE *stream) 709 999 { 710 if (operating_mode == byte_mode) 711 cut_bytes (stream); 1000 #if HAVE_MBRTOWC 1001 if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 1002 { 1003 switch (operating_mode) 1004 { 1005 case byte_mode: 1006 if (byte_mode_character_aware) 1007 cut_characters_or_cut_bytes_no_split (stream); 1008 else 1009 cut_bytes (stream); 1010 break; 1011 1012 case character_mode: 1013 cut_characters_or_cut_bytes_no_split (stream); 1014 break; 1015 1016 case field_mode: 1017 cut_fields_mb (stream); 1018 break; 1019 1020 default: 1021 abort (); 1022 } 1023 } 712 1024 else 713 cut_fields (stream); 1025 #endif 1026 { 1027 if (operating_mode == field_mode) 1028 cut_fields (stream); 1029 else 1030 cut_bytes (stream); 1031 } 714 1032 } 715 1033 716 1034 /* Process file FILE to standard output. … … 760 1078 bool ok; 761 1079 bool delim_specified = false; 762 1080 char *spec_list_string IF_LINT(= NULL); 1081 char mbdelim[MB_LEN_MAX + 1]; 1082 size_t delimlen = 0; 763 1083 764 1084 initialize_main (&argc, &argv); 765 1085 program_name = argv[0]; … … 782 1102 switch (optc) 783 1103 { 784 1104 case 'b': 785 case 'c':786 1105 /* Build the byte list. */ 787 1106 if (operating_mode != undefined_mode) 788 1107 FATAL_ERROR (_("only one type of list may be specified")); … … 790 1109 spec_list_string = optarg; 791 1110 break; 792 1111 1112 case 'c': 1113 /* Build the character list. */ 1114 if (operating_mode != undefined_mode) 1115 FATAL_ERROR (_("only one type of list may be specified")); 1116 operating_mode = character_mode; 1117 spec_list_string = optarg; 1118 break; 1119 793 1120 case 'f': 794 1121 /* Build the field list. */ 795 1122 if (operating_mode != undefined_mode) … … 801 1128 case 'd': 802 1129 /* New delimiter. */ 803 1130 /* Interpret -d '' to mean `use the NUL byte as the delimiter.' */ 804 if (optarg[0] != '\0' && optarg[1] != '\0') 805 FATAL_ERROR (_("the delimiter must be a single character")); 806 delim = optarg[0]; 807 delim_specified = true; 1131 { 1132 #if HAVE_MBRTOWC 1133 if(MB_CUR_MAX > 1) 1134 { 1135 mbstate_t state; 1136 1137 memset (&state, '\0', sizeof(mbstate_t)); 1138 delimlen = mbrtowc (&wcdelim, optarg, strnlen(optarg, MB_LEN_MAX), &state); 1139 1140 if (delimlen == (size_t)-1 || delimlen == (size_t)-2) 1141 ++force_singlebyte_mode; 1142 else 1143 { 1144 delimlen = (delimlen < 1) ? 1 : delimlen; 1145 if (wcdelim != L'\0' && *(optarg + delimlen) != '\0') 1146 FATAL_ERROR (_("the delimiter must be a single character")); 1147 memcpy (mbdelim, optarg, delimlen); 1148 } 1149 } 1150 1151 if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 1152 #endif 1153 { 1154 if (optarg[0] != '\0' && optarg[1] != '\0') 1155 FATAL_ERROR (_("the delimiter must be a single character")); 1156 delim = (unsigned char) optarg[0]; 1157 } 1158 delim_specified = true; 1159 } 808 1160 break; 809 1161 810 1162 case OUTPUT_DELIMITER_OPTION: … … 817 1169 break; 818 1170 819 1171 case 'n': 1172 byte_mode_character_aware = 1; 820 1173 break; 821 1174 822 1175 case 's': … … 839 1192 if (operating_mode == undefined_mode) 840 1193 FATAL_ERROR (_("you must specify a list of bytes, characters, or fields")); 841 1194 842 if (delim != '\0'&& operating_mode != field_mode)1195 if (delim_specified && operating_mode != field_mode) 843 1196 FATAL_ERROR (_("an input delimiter may be specified only\ 844 1197 when operating on fields")); 845 1198 … … 866 1219 } 867 1220 868 1221 if (!delim_specified) 869 delim = '\t'; 1222 { 1223 delim = '\t'; 1224 #ifdef HAVE_MBRTOWC 1225 wcdelim = L'\t'; 1226 mbdelim[0] = '\t'; 1227 mbdelim[1] = '\0'; 1228 delimlen = 1; 1229 #endif 1230 } 870 1231 871 1232 if (output_delimiter_string == NULL) 872 1233 { 873 static char dummy[2]; 874 dummy[0] = delim; 875 dummy[1] = '\0'; 876 output_delimiter_string = dummy; 877 output_delimiter_length = 1; 1234 #ifdef HAVE_MBRTOWC 1235 if (MB_CUR_MAX > 1 && !force_singlebyte_mode) 1236 { 1237 output_delimiter_string = xstrdup(mbdelim); 1238 output_delimiter_length = delimlen; 1239 } 1240 1241 if (MB_CUR_MAX <= 1 || force_singlebyte_mode) 1242 #endif 1243 { 1244 static char dummy[2]; 1245 dummy[0] = delim; 1246 dummy[1] = '\0'; 1247 output_delimiter_string = dummy; 1248 output_delimiter_length = 1; 1249 } 878 1250 } 879 1251 880 1252 if (optind == argc) -
coreutils-6.12
diff -Naur coreutils-6.12.orig/src/expand.c coreutils-6.12/src/expand.c
old new 37 37 #include <stdio.h> 38 38 #include <getopt.h> 39 39 #include <sys/types.h> 40 41 /* Get mbstate_t, mbrtowc(), wcwidth(). */ 42 #if HAVE_WCHAR_H 43 # include <wchar.h> 44 #endif 45 40 46 #include "system.h" 41 47 #include "error.h" 42 48 #include "quote.h" 43 49 #include "xstrndup.h" 44 50 51 /* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 52 installation; work around this configuration error. */ 53 #if !defined MB_LEN_MAX || MB_LEN_MAX < 2 54 # define MB_LEN_MAX 16 55 #endif 56 57 /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 58 #if HAVE_MBRTOWC && defined mbstate_t 59 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 60 #endif 61 45 62 /* The official name of this program (e.g., no `g' prefix). */ 46 63 #define PROGRAM_NAME "expand" 47 64 … … 182 199 stops = num_start + len - 1; 183 200 } 184 201 } 202 185 203 else 186 204 { 187 205 error (0, 0, _("tab size contains invalid character(s): %s"), … … 364 382 } 365 383 } 366 384 385 #if HAVE_MBRTOWC 386 static void 387 expand_multibyte (void) 388 { 389 FILE *fp; /* Input strem. */ 390 mbstate_t i_state; /* Current shift state of the input stream. */ 391 mbstate_t i_state_bak; /* Back up the I_STATE. */ 392 mbstate_t o_state; /* Current shift state of the output stream. */ 393 char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 394 char *bufpos; /* Next read position of BUF. */ 395 size_t buflen = 0; /* The length of the byte sequence in buf. */ 396 wchar_t wc; /* A gotten wide character. */ 397 size_t mblength; /* The byte size of a multibyte character 398 which shows as same character as WC. */ 399 int tab_index = 0; /* Index in `tab_list' of next tabstop. */ 400 int column = 0; /* Column on screen of the next char. */ 401 int next_tab_column; /* Column the next tab stop is on. */ 402 int convert = 1; /* If nonzero, perform translations. */ 403 404 fp = next_file ((FILE *) NULL); 405 if (fp == NULL) 406 return; 407 408 memset (&o_state, '\0', sizeof(mbstate_t)); 409 memset (&i_state, '\0', sizeof(mbstate_t)); 410 411 for (;;) 412 { 413 /* Refill the buffer BUF. */ 414 if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) 415 { 416 memmove (buf, bufpos, buflen); 417 buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); 418 bufpos = buf; 419 } 420 421 /* No character is left in BUF. */ 422 if (buflen < 1) 423 { 424 fp = next_file (fp); 425 426 if (fp == NULL) 427 break; /* No more files. */ 428 else 429 { 430 memset (&i_state, '\0', sizeof(mbstate_t)); 431 continue; 432 } 433 } 434 435 /* Get a wide character. */ 436 i_state_bak = i_state; 437 mblength = mbrtowc (&wc, bufpos, buflen, &i_state); 438 439 switch (mblength) 440 { 441 case (size_t)-1: /* illegal byte sequence. */ 442 case (size_t)-2: 443 mblength = 1; 444 i_state = i_state_bak; 445 if (convert) 446 { 447 ++column; 448 if (convert_entire_line == 0) 449 convert = 0; 450 } 451 putchar (*bufpos); 452 break; 453 454 case 0: /* null. */ 455 mblength = 1; 456 if (convert && convert_entire_line == 0) 457 convert = 0; 458 putchar ('\0'); 459 break; 460 461 default: 462 if (wc == L'\n') /* LF. */ 463 { 464 tab_index = 0; 465 column = 0; 466 convert = 1; 467 putchar ('\n'); 468 } 469 else if (wc == L'\t' && convert) /* Tab. */ 470 { 471 if (tab_size == 0) 472 { 473 /* Do not let tab_index == first_free_tab; 474 stop when it is 1 less. */ 475 while (tab_index < first_free_tab - 1 476 && column >= tab_list[tab_index]) 477 tab_index++; 478 next_tab_column = tab_list[tab_index]; 479 if (tab_index < first_free_tab - 1) 480 tab_index++; 481 if (column >= next_tab_column) 482 next_tab_column = column + 1; 483 } 484 else 485 next_tab_column = column + tab_size - column % tab_size; 486 487 while (column < next_tab_column) 488 { 489 putchar (' '); 490 ++column; 491 } 492 } 493 else /* Others. */ 494 { 495 if (convert) 496 { 497 if (wc == L'\b') 498 { 499 if (column > 0) 500 --column; 501 } 502 else 503 { 504 int width; /* The width of WC. */ 505 506 width = wcwidth (wc); 507 column += (width > 0) ? width : 0; 508 if (convert_entire_line == 0) 509 convert = 0; 510 } 511 } 512 fwrite (bufpos, sizeof(char), mblength, stdout); 513 } 514 } 515 buflen -= mblength; 516 bufpos += mblength; 517 } 518 } 519 #endif 520 367 521 int 368 522 main (int argc, char **argv) 369 523 { … … 428 582 429 583 file_list = (optind < argc ? &argv[optind] : stdin_argv); 430 584 431 expand (); 585 #if HAVE_MBRTOWC 586 if (MB_CUR_MAX > 1) 587 expand_multibyte (); 588 else 589 #endif 590 expand (); 432 591 433 592 if (have_read_stdin && fclose (stdin) != 0) 434 593 error (EXIT_FAILURE, errno, "-"); -
coreutils-6.12
diff -Naur coreutils-6.12.orig/src/fold.c coreutils-6.12/src/fold.c
old new 22 22 #include <getopt.h> 23 23 #include <sys/types.h> 24 24 25 /* Get mbstate_t, mbrtowc(), wcwidth(). */ 26 #if HAVE_WCHAR_H 27 # include <wchar.h> 28 #endif 29 30 /* Get iswprint(), iswblank(), wcwidth(). */ 31 #if HAVE_WCTYPE_H 32 # include <wctype.h> 33 #endif 34 25 35 #include "system.h" 26 36 #include "error.h" 27 37 #include "quote.h" 28 38 #include "xstrtol.h" 29 39 40 /* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 41 installation; work around this configuration error. */ 42 #if !defined MB_LEN_MAX || MB_LEN_MAX < 2 43 # undef MB_LEN_MAX 44 # define MB_LEN_MAX 16 45 #endif 46 47 /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 48 #if HAVE_MBRTOWC && defined mbstate_t 49 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 50 #endif 51 30 52 #define TAB_WIDTH 8 31 53 32 54 /* The official name of this program (e.g., no `g' prefix). */ … … 34 56 35 57 #define AUTHORS proper_name ("David MacKenzie") 36 58 59 #define FATAL_ERROR(Message) \ 60 do \ 61 { \ 62 error (0, 0, (Message)); \ 63 usage (2); \ 64 } \ 65 while (0) 66 67 enum operating_mode 68 { 69 /* Fold texts by columns that are at the given positions. */ 70 column_mode, 71 72 /* Fold texts by bytes that are at the given positions. */ 73 byte_mode, 74 75 /* Fold texts by characters that are at the given positions. */ 76 character_mode, 77 }; 78 37 79 /* The name this program was run with. */ 38 80 char *program_name; 39 81 82 /* The argument shows current mode. (Default: column_mode) */ 83 static enum operating_mode operating_mode; 84 40 85 /* If nonzero, try to break on whitespace. */ 41 86 static bool break_spaces; 42 87 43 /* If nonzero, count bytes, not column positions. */44 static bool count_bytes;45 46 88 /* If nonzero, at least one of the files we read was standard input. */ 47 89 static bool have_read_stdin; 48 90 49 static char const shortopts[] = "b sw:0::1::2::3::4::5::6::7::8::9::";91 static char const shortopts[] = "bcsw:0::1::2::3::4::5::6::7::8::9::"; 50 92 51 93 static struct option const longopts[] = 52 94 { 53 95 {"bytes", no_argument, NULL, 'b'}, 96 {"characters", no_argument, NULL, 'c'}, 54 97 {"spaces", no_argument, NULL, 's'}, 55 98 {"width", required_argument, NULL, 'w'}, 56 99 {GETOPT_HELP_OPTION_DECL}, … … 80 123 "), stdout); 81 124 fputs (_("\ 82 125 -b, --bytes count bytes rather than columns\n\ 126 -c, --characters count characters rather than columns\n\ 83 127 -s, --spaces break at spaces\n\ 84 128 -w, --width=WIDTH use WIDTH columns instead of 80\n\ 85 129 "), stdout); … … 97 141 static size_t 98 142 adjust_column (size_t column, char c) 99 143 { 100 if ( !count_bytes)144 if (operating_mode != byte_mode) 101 145 { 102 146 if (c == '\b') 103 147 { … … 120 164 to stdout, with maximum line length WIDTH. 121 165 Return true if successful. */ 122 166 123 static bool124 fold_ file (char const *filename, size_t width)167 static void 168 fold_text (FILE *istream, size_t width, int *saved_errno) 125 169 { 126 FILE *istream;127 170 int c; 128 171 size_t column = 0; /* Screen column where next char will go. */ 129 172 size_t offset_out = 0; /* Index in `line_out' for next char. */ 130 173 static char *line_out = NULL; 131 174 static size_t allocated_out = 0; 132 int saved_errno;133 134 if (STREQ (filename, "-"))135 {136 istream = stdin;137 have_read_stdin = true;138 }139 else140 istream = fopen (filename, "r");141 142 if (istream == NULL)143 {144 error (0, errno, "%s", filename);145 return false;146 }147 175 148 176 while ((c = getc (istream)) != EOF) 149 177 { … … 171 199 bool found_blank = false; 172 200 size_t logical_end = offset_out; 173 201 202 /* If LINE_OUT has no wide character, 203 put a new wide character in LINE_OUT 204 if column is bigger than width. */ 205 if (offset_out == 0) 206 { 207 line_out[offset_out++] = c; 208 continue; 209 } 210 174 211 /* Look for the last blank. */ 175 212 while (logical_end) 176 213 { … … 217 254 line_out[offset_out++] = c; 218 255 } 219 256 220 saved_errno = errno; 257 *saved_errno = errno; 258 259 if (offset_out) 260 fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 261 262 free(line_out); 263 } 264 265 #if HAVE_MBRTOWC 266 static void 267 fold_multibyte_text (FILE *istream, size_t width, int *saved_errno) 268 { 269 char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 270 size_t buflen = 0; /* The length of the byte sequence in buf. */ 271 char *bufpos; /* Next read position of BUF. */ 272 wint_t wc; /* A gotten wide character. */ 273 size_t mblength; /* The byte size of a multibyte character which shows 274 as same character as WC. */ 275 mbstate_t state, state_bak; /* State of the stream. */ 276 int convfail; /* 1, when conversion is failed. Otherwise 0. */ 277 278 char *line_out = NULL; 279 size_t offset_out = 0; /* Index in `line_out' for next char. */ 280 size_t allocated_out = 0; 281 282 int increment; 283 size_t column = 0; 284 285 size_t last_blank_pos; 286 size_t last_blank_column; 287 int is_blank_seen; 288 int last_blank_increment; 289 int is_bs_following_last_blank; 290 size_t bs_following_last_blank_num; 291 int is_cr_after_last_blank; 292 293 #define CLEAR_FLAGS \ 294 do \ 295 { \ 296 last_blank_pos = 0; \ 297 last_blank_column = 0; \ 298 is_blank_seen = 0; \ 299 is_bs_following_last_blank = 0; \ 300 bs_following_last_blank_num = 0; \ 301 is_cr_after_last_blank = 0; \ 302 } \ 303 while (0) 304 305 #define START_NEW_LINE \ 306 do \ 307 { \ 308 putchar ('\n'); \ 309 column = 0; \ 310 offset_out = 0; \ 311 CLEAR_FLAGS; \ 312 } \ 313 while (0) 314 315 CLEAR_FLAGS; 316 memset (&state, '\0', sizeof(mbstate_t)); 317 318 for (;; bufpos += mblength, buflen -= mblength) 319 { 320 if (buflen < MB_LEN_MAX && !feof (istream) && !ferror (istream)) 321 { 322 memmove (buf, bufpos, buflen); 323 buflen += fread (buf + buflen, sizeof(char), BUFSIZ, istream); 324 bufpos = buf; 325 } 326 327 if (buflen < 1) 328 break; 329 330 /* Get a wide character. */ 331 convfail = 0; 332 state_bak = state; 333 mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &state); 334 335 switch (mblength) 336 { 337 case (size_t)-1: 338 case (size_t)-2: 339 convfail++; 340 state = state_bak; 341 /* Fall through. */ 342 343 case 0: 344 mblength = 1; 345 break; 346 } 347 348 rescan: 349 if (operating_mode == byte_mode) /* byte mode */ 350 increment = mblength; 351 else if (operating_mode == character_mode) /* character mode */ 352 increment = 1; 353 else /* column mode */ 354 { 355 if (convfail) 356 increment = 1; 357 else 358 { 359 switch (wc) 360 { 361 case L'\n': 362 fwrite (line_out, sizeof(char), offset_out, stdout); 363 START_NEW_LINE; 364 continue; 365 366 case L'\b': 367 increment = (column > 0) ? -1 : 0; 368 break; 369 370 case L'\r': 371 increment = -1 * column; 372 break; 373 374 case L'\t': 375 increment = 8 - column % 8; 376 break; 377 378 default: 379 increment = wcwidth (wc); 380 increment = (increment < 0) ? 0 : increment; 381 } 382 } 383 } 384 385 if (column + increment > width && break_spaces && last_blank_pos) 386 { 387 fwrite (line_out, sizeof(char), last_blank_pos, stdout); 388 putchar ('\n'); 389 390 offset_out = offset_out - last_blank_pos; 391 column = column - last_blank_column + ((is_cr_after_last_blank) 392 ? last_blank_increment : bs_following_last_blank_num); 393 memmove (line_out, line_out + last_blank_pos, offset_out); 394 CLEAR_FLAGS; 395 goto rescan; 396 } 397 398 if (column + increment > width && column != 0) 399 { 400 fwrite (line_out, sizeof(char), offset_out, stdout); 401 START_NEW_LINE; 402 goto rescan; 403 } 404 405 if (allocated_out < offset_out + mblength) 406 { 407 allocated_out += 1024; 408 line_out = xrealloc (line_out, allocated_out); 409 } 410 411 memcpy (line_out + offset_out, bufpos, mblength); 412 offset_out += mblength; 413 column += increment; 414 415 if (is_blank_seen && !convfail && wc == L'\r') 416 is_cr_after_last_blank = 1; 417 418 if (is_bs_following_last_blank && !convfail && wc == L'\b') 419 ++bs_following_last_blank_num; 420 else 421 is_bs_following_last_blank = 0; 422 423 if (break_spaces && !convfail && iswblank (wc)) 424 { 425 last_blank_pos = offset_out; 426 last_blank_column = column; 427 is_blank_seen = 1; 428 last_blank_increment = increment; 429 is_bs_following_last_blank = 1; 430 bs_following_last_blank_num = 0; 431 is_cr_after_last_blank = 0; 432 } 433 } 434 435 *saved_errno = errno; 221 436 222 437 if (offset_out) 223 438 fwrite (line_out, sizeof (char), (size_t) offset_out, stdout); 224 439 440 free(line_out); 441 } 442 #endif 443 444 /* Fold file FILENAME, or standard input if FILENAME is "-", 445 to stdout, with maximum line length WIDTH. 446 Return 0 if successful, 1 if an error occurs. */ 447 448 static bool 449 fold_file (char *filename, size_t width) 450 { 451 FILE *istream; 452 int saved_errno; 453 454 if (STREQ (filename, "-")) 455 { 456 istream = stdin; 457 have_read_stdin = 1; 458 } 459 else 460 istream = fopen (filename, "r"); 461 462 if (istream == NULL) 463 { 464 error (0, errno, "%s", filename); 465 return 1; 466 } 467 468 /* Define how ISTREAM is being folded. */ 469 #if HAVE_MBRTOWC 470 if (MB_CUR_MAX > 1) 471 fold_multibyte_text (istream, width, &saved_errno); 472 else 473 #endif 474 fold_text (istream, width, &saved_errno); 475 225 476 if (ferror (istream)) 226 477 { 227 478 error (0, saved_errno, "%s", filename); … … 254 505 255 506 atexit (close_stdout); 256 507 257 break_spaces = count_bytes = have_read_stdin = false; 508 operating_mode = column_mode; 509 break_spaces = have_read_stdin = false; 258 510 259 511 while ((optc = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1) 260 512 { … … 263 515 switch (optc) 264 516 { 265 517 case 'b': /* Count bytes rather than columns. */ 266 count_bytes = true; 518 if (operating_mode != column_mode) 519 FATAL_ERROR (_("only one way of folding may be specified")); 520 operating_mode = byte_mode; 521 break; 522 523 case 'c': 524 if (operating_mode != column_mode) 525 FATAL_ERROR (_("only one way of folding may be specified")); 526 operating_mode = character_mode; 267 527 break; 268 528 269 529 case 's': /* Break at word boundaries. */ -
coreutils-6.12
diff -Naur coreutils-6.12.orig/src/join.c coreutils-6.12/src/join.c
old new 22 22 #include <sys/types.h> 23 23 #include <getopt.h> 24 24 25 /* Get mbstate_t, mbrtowc(), mbrtowc(), wcwidth(). */ 26 #if HAVE_WCHAR_H 27 # include <wchar.h> 28 #endif 29 30 /* Get iswblank(), towupper. */ 31 #if HAVE_WCTYPE_H 32 # include <wctype.h> 33 #endif 34 25 35 #include "system.h" 26 36 #include "error.h" 27 37 #include "hard-locale.h" 28 38 #include "linebuffer.h" 29 #include "memcasecmp.h"30 39 #include "quote.h" 31 40 #include "stdio--.h" 32 41 #include "xmemcoll.h" 33 42 #include "xstrtol.h" 34 43 #include "argmatch.h" 35 44 45 /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 46 #if HAVE_MBRTOWC && defined mbstate_t 47 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 48 #endif 49 36 50 /* The official name of this program (e.g., no `g' prefix). */ 37 51 #define PROGRAM_NAME "join" 38 52 … … 113 127 /* Last element in `outlist', where a new element can be added. */ 114 128 static struct outlist *outlist_end = &outlist_head; 115 129 116 /* Tab character separating fields. If negative, fields are separated 117 by any nonempty string of blanks, otherwise by exactly one 118 tab character whose value (when cast to unsigned char) equals TAB. */ 119 static int tab = -1; 130 /* Tab character separating fields. If NULL, fields are separated 131 by any nonempty string of blanks. */ 132 static char *tab = NULL; 133 134 /* The number of bytes used for tab. */ 135 static size_t tablen = 0; 120 136 121 137 /* If nonzero, check that the input is correctly ordered. */ 122 138 static enum … … 221 237 222 238 /* Fill in the `fields' structure in LINE. */ 223 239 240 /* Fill in the `fields' structure in LINE. */ 241 224 242 static void 225 243 xfields (struct line *line) 226 244 { … … 230 248 if (ptr == lim) 231 249 return; 232 250 233 if ( 0 <= tab)251 if (tab != NULL) 234 252 { 253 unsigned char t = tab[0]; 235 254 char *sep; 236 for (; (sep = memchr (ptr, t ab, lim - ptr)) != NULL; ptr = sep + 1)255 for (; (sep = memchr (ptr, t, lim - ptr)) != NULL; ptr = sep + 1) 237 256 extract_field (line, ptr, sep - ptr); 238 257 } 239 258 else … … 305 324 size_t jf_1, size_t jf_2) 306 325 { 307 326 /* Start of field to compare in each file. */ 308 char *beg1; 309 char *beg2; 310 311 size_t len1; 312 size_t len2; /* Length of fields to compare. */ 327 char *beg[2]; 328 char *copy[2]; 329 size_t len[2]; /* Length of fields to compare. */ 313 330 int diff; 331 int i, j; 314 332 315 333 if (jf_1 < line1->nfields) 316 334 { 317 beg 1= line1->fields[jf_1].beg;318 len 1= line1->fields[jf_1].len;335 beg[0] = line1->fields[jf_1].beg; 336 len[0] = line1->fields[jf_1].len; 319 337 } 320 338 else 321 339 { 322 beg 1= NULL;323 len 1= 0;340 beg[0] = NULL; 341 len[0] = 0; 324 342 } 325 343 326 344 if (jf_2 < line2->nfields) 327 345 { 328 beg 2= line2->fields[jf_2].beg;329 len 2= line2->fields[jf_2].len;346 beg[1] = line2->fields[jf_2].beg; 347 len[1] = line2->fields[jf_2].len; 330 348 } 331 349 else 332 350 { 333 beg 2= NULL;334 len 2= 0;351 beg[1] = NULL; 352 len[1] = 0; 335 353 } 336 354 337 if (len 1== 0)338 return len 2== 0 ? 0 : -1;339 if (len 2== 0)355 if (len[0] == 0) 356 return len[1] == 0 ? 0 : -1; 357 if (len[1] == 0) 340 358 return 1; 341 359 342 360 if (ignore_case) 343 361 { 344 /* FIXME: ignore_case does not work with NLS (in particular, 345 with multibyte chars). */ 346 diff = memcasecmp (beg1, beg2, MIN (len1, len2)); 362 #ifdef HAVE_MBRTOWC 363 if (MB_CUR_MAX > 1) 364 { 365 size_t mblength; 366 wchar_t wc, uwc; 367 mbstate_t state, state_bak; 368 369 memset (&state, '\0', sizeof (mbstate_t)); 370 371 for (i = 0; i < 2; i++) 372 { 373 copy[i] = alloca (len[i] + 1); 374 375 for (j = 0; j < MIN (len[0], len[1]);) 376 { 377 state_bak = state; 378 mblength = mbrtowc (&wc, beg[i] + j, len[i] - j, &state); 379 380 switch (mblength) 381 { 382 case (size_t) -1: 383 case (size_t) -2: 384 state = state_bak; 385 /* Fall through */ 386 case 0: 387 mblength = 1; 388 break; 389 390 default: 391 uwc = towupper (wc); 392 393 if (uwc != wc) 394 { 395 mbstate_t state_wc; 396 397 memset (&state_wc, '\0', sizeof (mbstate_t)); 398 wcrtomb (copy[i] + j, uwc, &state_wc); 399 } 400 else 401 memcpy (copy[i] + j, beg[i] + j, mblength); 402 } 403 j += mblength; 404 } 405 copy[i][j] = '\0'; 406 } 407 } 408 else 409 #endif 410 { 411 for (i = 0; i < 2; i++) 412 { 413 copy[i] = alloca (len[i] + 1); 414 415 for (j = 0; j < MIN (len[0], len[1]); j++) 416 copy[i][j] = toupper (beg[i][j]); 417 418 copy[i][j] = '\0'; 419 } 420 } 347 421 } 348 422 else 349 423 { 350 if (hard_LC_COLLATE) 351 return xmemcoll (beg1, len1, beg2, len2); 352 diff = memcmp (beg1, beg2, MIN (len1, len2)); 424 copy[0] = (unsigned char *) beg[0]; 425 copy[1] = (unsigned char *) beg[1]; 353 426 } 354 427 428 if (hard_LC_COLLATE) 429 return xmemcoll ((char *) copy[0], len[0], (char *) copy[1], len[1]); 430 diff = memcmp (copy[0], copy[1], MIN (len[0], len[1])); 431 432 355 433 if (diff) 356 434 return diff; 357 return len 1 < len2 ? -1 : len1 != len2;435 return len[0] - len[1]; 358 436 } 359 437 360 438 /* Check that successive input lines PREV and CURRENT from input file … … 393 471 } 394 472 } 395 473 474 #if HAVE_MBRTOWC 475 static void 476 xfields_multibyte (struct line *line) 477 { 478 char *ptr = line->buf.buffer; 479 char const *lim = ptr + line->buf.length - 1; 480 wchar_t wc = 0; 481 size_t mblength = 1; 482 mbstate_t state, state_bak; 483 484 memset (&state, 0, sizeof (mbstate_t)); 485 486 if (ptr == lim) 487 return; 488 489 if (tab != NULL) 490 { 491 unsigned char t = tab[0]; 492 char *sep = ptr; 493 for (; ptr < lim; ptr = sep + mblength) 494 { 495 sep = ptr; 496 while (sep < lim) 497 { 498 state_bak = state; 499 mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 500 501 if (mblength == (size_t)-1 || mblength == (size_t)-2) 502 { 503 mblength = 1; 504 state = state_bak; 505 } 506 mblength = (mblength < 1) ? 1 : mblength; 507 508 if (mblength == tablen && !memcmp (sep, tab, mblength)) 509 break; 510 else 511 { 512 sep += mblength; 513 continue; 514 } 515 } 516 517 if (sep == lim) 518 break; 519 520 extract_field (line, ptr, sep - ptr); 521 } 522 } 523 else 524 { 525 /* Skip leading blanks before the first field. */ 526 while(ptr < lim) 527 { 528 state_bak = state; 529 mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 530 531 if (mblength == (size_t)-1 || mblength == (size_t)-2) 532 { 533 mblength = 1; 534 state = state_bak; 535 break; 536 } 537 mblength = (mblength < 1) ? 1 : mblength; 538 539 if (!iswblank(wc)) 540 break; 541 ptr += mblength; 542 } 543 544 do 545 { 546 char *sep; 547 state_bak = state; 548 mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 549 if (mblength == (size_t)-1 || mblength == (size_t)-2) 550 { 551 mblength = 1; 552 state = state_bak; 553 break; 554 } 555 mblength = (mblength < 1) ? 1 : mblength; 556 557 sep = ptr + mblength; 558 while (sep != lim) 559 { 560 state_bak = state; 561 mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 562 if (mblength == (size_t)-1 || mblength == (size_t)-2) 563 { 564 mblength = 1; 565 state = state_bak; 566 break; 567 } 568 mblength = (mblength < 1) ? 1 : mblength; 569 570 if (iswblank (wc)) 571 break; 572 573 sep += mblength; 574 } 575 576 extract_field (line, ptr, sep - ptr); 577 if (sep == lim) 578 return; 579 580 state_bak = state; 581 mblength = mbrtowc (&wc, sep, lim - sep + 1, &state); 582 if (mblength == (size_t)-1 || mblength == (size_t)-2) 583 { 584 mblength = 1; 585 state = state_bak; 586 break; 587 } 588 mblength = (mblength < 1) ? 1 : mblength; 589 590 ptr = sep + mblength; 591 while (ptr != lim) 592 { 593 state_bak = state; 594 mblength = mbrtowc (&wc, ptr, lim - ptr + 1, &state); 595 if (mblength == (size_t)-1 || mblength == (size_t)-2) 596 { 597 mblength = 1; 598 state = state_bak; 599 break; 600 } 601 mblength = (mblength < 1) ? 1 : mblength; 602 603 if (!iswblank (wc)) 604 break; 605 606 ptr += mblength; 607 } 608 } 609 while (ptr != lim); 610 } 611 612 extract_field (line, ptr, lim - ptr); 613 } 614 #endif 615 396 616 /* Read a line from FP into LINE and split it into fields. 397 617 Return true if successful. */ 398 618 … … 413 633 line->nfields_allocated = 0; 414 634 line->nfields = 0; 415 635 line->fields = NULL; 636 #if HAVE_MBRTOWC 637 if (MB_CUR_MAX > 1) 638 xfields_multibyte (line); 639 else 640 #endif 416 641 xfields (line); 417 642 418 643 if (prevline[which - 1]) … … 509 734 510 735 /* Print the join of LINE1 and LINE2. */ 511 736 737 #define PUT_TAB_CHAR \ 738 do \ 739 { \ 740 (tab != NULL) ? \ 741 fwrite(tab, sizeof(char), tablen, stdout) : putchar (' '); \ 742 } \ 743 while (0) 744 512 745 static void 513 746 prjoin (struct line const *line1, struct line const *line2) 514 747 { 515 748 const struct outlist *outlist; 516 char output_separator = tab < 0 ? ' ' : tab;517 749 518 750 outlist = outlist_head.next; 519 751 if (outlist) … … 529 761 if (o->file == 0) 530 762 { 531 763 if (line1 == &uni_blank) 532 764 { 533 765 line = line2; 534 766 field = join_field_2; 535 767 } 536 768 else 537 769 { 538 770 line = line1; 539 771 field = join_field_1; 540 772 } … … 548 780 o = o->next; 549 781 if (o == NULL) 550 782 break; 551 putchar (output_separator);783 PUT_TAB_CHAR; 552 784 } 553 785 putchar ('\n'); 554 786 } … … 566 798 prfield (join_field_1, line1); 567 799 for (i = 0; i < join_field_1 && i < line1->nfields; ++i) 568 800 { 569 putchar (output_separator);801 PUT_TAB_CHAR; 570 802 prfield (i, line1); 571 803 } 572 804 for (i = join_field_1 + 1; i < line1->nfields; ++i) 573 805 { 574 putchar (output_separator);806 PUT_TAB_CHAR; 575 807 prfield (i, line1); 576 808 } 577 809 578 810 for (i = 0; i < join_field_2 && i < line2->nfields; ++i) 579 811 { 580 putchar (output_separator);812 PUT_TAB_CHAR; 581 813 prfield (i, line2); 582 814 } 583 815 for (i = join_field_2 + 1; i < line2->nfields; ++i) 584 816 { 585 putchar (output_separator);817 PUT_TAB_CHAR; 586 818 prfield (i, line2); 587 819 } 588 820 putchar ('\n'); … … 1016 1248 1017 1249 case 't': 1018 1250 { 1019 unsigned char newtab = optarg[0]; 1020 if (! newtab) 1251 char *newtab; 1252 size_t newtablen; 1253 if (! optarg[0]) 1021 1254 error (EXIT_FAILURE, 0, _("empty tab")); 1022 if (optarg[1]) 1255 newtab = xstrdup (optarg); 1256 #if HAVE_MBRTOWC 1257 if (MB_CUR_MAX > 1) 1258 { 1259 mbstate_t state; 1260 1261 memset (&state, 0, sizeof (mbstate_t)); 1262 newtablen = mbrtowc (NULL, newtab, 1263 strnlen (newtab, MB_LEN_MAX), 1264 &state); 1265 if (newtablen == (size_t) 0 1266 || newtablen == (size_t) -1 1267 || newtablen == (size_t) -2) 1268 newtablen = 1; 1269 } 1270 else 1271 #endif 1272 newtablen = 1; 1273 1274 if (newtablen == 1 && newtab[1]) 1275 { 1276 if (STREQ (newtab, "\\0")) 1277 newtab[0] = '\0'; 1278 } 1279 if (tab != NULL && strcmp (tab, newtab)) 1023 1280 { 1024 if (STREQ (optarg, "\\0")) 1025 newtab = '\0'; 1026 else 1027 error (EXIT_FAILURE, 0, _("multi-character tab %s"), 1028 quote (optarg)); 1281 free (newtab); 1282 error (EXIT_FAILURE, 0, _("incompatible tabs")); 1029 1283 } 1030 if (0 <= tab && tab != newtab)1031 error (EXIT_FAILURE, 0, _("incompatible tabs"));1032 1284 tab = newtab; 1285 tablen = newtablen; 1033 1286 } 1034 1287 break; 1035 1288 -
coreutils-6.12
diff -Naur coreutils-6.12.orig/src/pr.c coreutils-6.12/src/pr.c
old new 312 312 313 313 #include <getopt.h> 314 314 #include <sys/types.h> 315 316 /* Get MB_LEN_MAX. */ 317 #include <limits.h> 318 /* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 319 installation; work around this configuration error. */ 320 #if !defined MB_LEN_MAX || MB_LEN_MAX == 1 321 # define MB_LEN_MAX 16 322 #endif 323 324 /* Get MB_CUR_MAX. */ 325 #include <stdlib.h> 326 327 /* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */ 328 /* Get mbstate_t, mbrtowc(), wcwidth(). */ 329 #if HAVE_WCHAR_H 330 # include <wchar.h> 331 #endif 332 333 /* Get iswprint(). -- for wcwidth(). */ 334 #if HAVE_WCTYPE_H 335 # include <wctype.h> 336 #endif 337 #if !defined iswprint && !HAVE_ISWPRINT 338 # define iswprint(wc) 1 339 #endif 340 315 341 #include "system.h" 316 342 #include "error.h" 317 343 #include "hard-locale.h" … … 322 348 #include "strftime.h" 323 349 #include "xstrtol.h" 324 350 351 /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 352 #if HAVE_MBRTOWC && defined mbstate_t 353 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 354 #endif 355 356 #ifndef HAVE_DECL_WCWIDTH 357 "this configure-time declaration test was not run" 358 #endif 359 #if !HAVE_DECL_WCWIDTH 360 extern int wcwidth (); 361 #endif 362 325 363 /* The official name of this program (e.g., no `g' prefix). */ 326 364 #define PROGRAM_NAME "pr" 327 365 … … 416 454 417 455 #define NULLCOL (COLUMN *)0 418 456 419 static int char_to_clump (char c); 457 /* Funtion pointers to switch functions for single byte locale or for 458 multibyte locale. If multibyte functions do not exist in your sysytem, 459 these pointers always point the function for single byte locale. */ 460 static void (*print_char) (char c); 461 static int (*char_to_clump) (char c); 462 463 /* Functions for single byte locale. */ 464 static void print_char_single (char c); 465 static int char_to_clump_single (char c); 466 467 /* Functions for multibyte locale. */ 468 static void print_char_multi (char c); 469 static int char_to_clump_multi (char c); 470 420 471 static bool read_line (COLUMN *p); 421 472 static bool print_page (void); 422 473 static bool print_stored (COLUMN *p); … … 426 477 static void pad_across_to (int position); 427 478 static void add_line_number (COLUMN *p); 428 479 static void getoptarg (char *arg, char switch_char, char *character, 480 int *character_length, int *character_width, 429 481 int *number); 430 482 void usage (int status); 431 483 static void print_files (int number_of_files, char **av); … … 440 492 static void pad_down (int lines); 441 493 static void read_rest_of_line (COLUMN *p); 442 494 static void skip_read (COLUMN *p, int column_number); 443 static void print_char (char c);444 495 static void cleanup (void); 445 496 static void print_sep_string (void); 446 497 static void separator_string (const char *optarg_S); … … 455 506 we store the leftmost columns contiguously in buff. 456 507 To print a line from buff, get the index of the first character 457 508 from line_vector[i], and print up to line_vector[i + 1]. */ 458 static char *buff;509 static unsigned char *buff; 459 510 460 511 /* Index of the position in buff where the next character 461 512 will be stored. */ … … 559 610 static bool untabify_input = false; 560 611 561 612 /* (-e) The input tab character. */ 562 static char input_tab_char = '\t';613 static char input_tab_char[MB_LEN_MAX] = "\t"; 563 614 564 615 /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ... 565 616 where the leftmost column is 1. */ … … 569 620 static bool tabify_output = false; 570 621 571 622 /* (-i) The output tab character. */ 572 static char output_tab_char = '\t'; 623 static char output_tab_char[MB_LEN_MAX] = "\t"; 624 625 /* (-i) The byte length of output tab character. */ 626 static int output_tab_char_length = 1; 573 627 574 628 /* (-i) The width of the output tab. */ 575 629 static int chars_per_output_tab = 8; … … 643 697 static bool numbered_lines = false; 644 698 645 699 /* (-n) Character which follows each line number. */ 646 static char number_separator = '\t'; 700 static char number_separator[MB_LEN_MAX] = "\t"; 701 702 /* (-n) The byte length of the character which follows each line number. */ 703 static int number_separator_length = 1; 704 705 /* (-n) The character width of the character which follows each line number. */ 706 static int number_separator_width = 0; 647 707 648 708 /* (-n) line counting starts with 1st line of input file (not with 1st 649 709 line of 1st page printed). */ … … 696 756 -a|COLUMN|-m is a `space' and with the -J option a `tab'. */ 697 757 static char *col_sep_string = ""; 698 758 static int col_sep_length = 0; 759 static int col_sep_width = 0; 699 760 static char *column_separator = " "; 700 761 static char *line_separator = "\t"; 701 762 … … 852 913 col_sep_length = (int) strlen (optarg_S); 853 914 col_sep_string = xmalloc (col_sep_length + 1); 854 915 strcpy (col_sep_string, optarg_S); 916 917 #if HAVE_MBRTOWC 918 if (MB_CUR_MAX > 1) 919 col_sep_width = mbswidth (col_sep_string, 0); 920 else 921 #endif 922 col_sep_width = col_sep_length; 855 923 } 856 924 857 925 int … … 876 944 877 945 atexit (close_stdout); 878 946 947 /* Define which functions are used, the ones for single byte locale or the ones 948 for multibyte locale. */ 949 #if HAVE_MBRTOWC 950 if (MB_CUR_MAX > 1) 951 { 952 print_char = print_char_multi; 953 char_to_clump = char_to_clump_multi; 954 } 955 else 956 #endif 957 { 958 print_char = print_char_single; 959 char_to_clump = char_to_clump_single; 960 } 961 879 962 n_files = 0; 880 963 file_names = (argc > 1 881 964 ? xmalloc ((argc - 1) * sizeof (char *)) … … 952 1035 break; 953 1036 case 'e': 954 1037 if (optarg) 955 getoptarg (optarg, 'e', &input_tab_char, 956 &chars_per_input_tab); 1038 { 1039 int dummy_length, dummy_width; 1040 1041 getoptarg (optarg, 'e', input_tab_char, &dummy_length, 1042 &dummy_width, &chars_per_input_tab); 1043 } 957 1044 /* Could check tab width > 0. */ 958 1045 untabify_input = true; 959 1046 break; … … 966 1053 break; 967 1054 case 'i': 968 1055 if (optarg) 969 getoptarg (optarg, 'i', &output_tab_char, 970 &chars_per_output_tab); 1056 { 1057 int dummy_width; 1058 1059 getoptarg (optarg, 'i', output_tab_char, &output_tab_char_length, 1060 &dummy_width, &chars_per_output_tab); 1061 } 971 1062 /* Could check tab width > 0. */ 972 1063 tabify_output = true; 973 1064 break; … … 994 1085 case 'n': 995 1086 numbered_lines = true; 996 1087 if (optarg) 997 getoptarg (optarg, 'n', &number_separator,998 & chars_per_number);1088 getoptarg (optarg, 'n', number_separator, &number_separator_length, 1089 &number_separator_width, &chars_per_number); 999 1090 break; 1000 1091 case 'N': 1001 1092 skip_count = false; … … 1034 1125 old_s = false; 1035 1126 /* Reset an additional input of -s, -S dominates -s */ 1036 1127 col_sep_string = ""; 1037 col_sep_length = 0;1128 col_sep_length = col_sep_width = 0; 1038 1129 use_col_separator = true; 1039 1130 if (optarg) 1040 1131 separator_string (optarg); … … 1191 1282 a number. */ 1192 1283 1193 1284 static void 1194 getoptarg (char *arg, char switch_char, char *character, int *number) 1285 getoptarg (char *arg, char switch_char, char *character, int *character_length, 1286 int *character_width, int *number) 1195 1287 { 1196 1288 if (!ISDIGIT (*arg)) 1197 *character = *arg++; 1289 { 1290 #ifdef HAVE_MBRTOWC 1291 if (MB_CUR_MAX > 1) /* for multibyte locale. */ 1292 { 1293 wchar_t wc; 1294 size_t mblength; 1295 int width; 1296 mbstate_t state = {'\0'}; 1297 1298 mblength = mbrtowc (&wc, arg, strnlen(arg, MB_LEN_MAX), &state); 1299 1300 if (mblength == (size_t)-1 || mblength == (size_t)-2) 1301 { 1302 *character_length = 1; 1303 *character_width = 1; 1304 } 1305 else 1306 { 1307 *character_length = (mblength < 1) ? 1 : mblength; 1308 width = wcwidth (wc); 1309 *character_width = (width < 0) ? 0 : width; 1310 } 1311 1312 strncpy (character, arg, *character_length); 1313 arg += *character_length; 1314 } 1315 else /* for single byte locale. */ 1316 #endif 1317 { 1318 *character = *arg++; 1319 *character_length = 1; 1320 *character_width = 1; 1321 } 1322 } 1323 1198 1324 if (*arg) 1199 1325 { 1200 1326 long int tmp_long; … … 1253 1379 else 1254 1380 col_sep_string = column_separator; 1255 1381 1256 col_sep_length = 1;1382 col_sep_length = col_sep_width = 1; 1257 1383 use_col_separator = true; 1258 1384 } 1259 1385 /* It's rather pointless to define a TAB separator with column … … 1284 1410 TAB_WIDTH (chars_per_input_tab, chars_per_number); */ 1285 1411 1286 1412 /* Estimate chars_per_text without any margin and keep it constant. */ 1287 if (number_separator == '\t')1413 if (number_separator[0] == '\t') 1288 1414 number_width = chars_per_number + 1289 1415 TAB_WIDTH (chars_per_default_tab, chars_per_number); 1290 1416 else 1291 number_width = chars_per_number + 1;1417 number_width = chars_per_number + number_separator_width; 1292 1418 1293 1419 /* The number is part of the column width unless we are 1294 1420 printing files in parallel. */ … … 1303 1429 } 1304 1430 1305 1431 chars_per_column = (chars_per_line - chars_used_by_number - 1306 (columns - 1) * col_sep_ length) / columns;1432 (columns - 1) * col_sep_width) / columns; 1307 1433 1308 1434 if (chars_per_column < 1) 1309 1435 error (EXIT_FAILURE, 0, _("page width too narrow")); … … 1428 1554 1429 1555 /* Enlarge p->start_position of first column to use the same form of 1430 1556 padding_not_printed with all columns. */ 1431 h = h + col_sep_ length;1557 h = h + col_sep_width; 1432 1558 1433 1559 /* This loop takes care of all but the rightmost column. */ 1434 1560 … … 1462 1588 } 1463 1589 else 1464 1590 { 1465 h = h_next + col_sep_ length;1591 h = h_next + col_sep_width; 1466 1592 h_next = h + chars_per_column; 1467 1593 } 1468 1594 } … … 1752 1878 align_column (COLUMN *p) 1753 1879 { 1754 1880 padding_not_printed = p->start_position; 1755 if (padding_not_printed - col_sep_ length > 0)1881 if (padding_not_printed - col_sep_width > 0) 1756 1882 { 1757 pad_across_to (padding_not_printed - col_sep_ length);1883 pad_across_to (padding_not_printed - col_sep_width); 1758 1884 padding_not_printed = ANYWHERE; 1759 1885 } 1760 1886 … … 2025 2151 /* May be too generous. */ 2026 2152 buff = X2REALLOC (buff, &buff_allocated); 2027 2153 } 2028 buff[buff_current++] = c;2154 buff[buff_current++] = (unsigned char) c; 2029 2155 } 2030 2156 2031 2157 static void 2032 2158 add_line_number (COLUMN *p) 2033 2159 { 2034 int i ;2160 int i, j; 2035 2161 char *s; 2036 2162 int left_cut; 2037 2163 … … 2054 2180 /* Tabification is assumed for multiple columns, also for n-separators, 2055 2181 but `default n-separator = TAB' hasn't been given priority over 2056 2182 equal column_width also specified by POSIX. */ 2057 if (number_separator == '\t')2183 if (number_separator[0] == '\t') 2058 2184 { 2059 2185 i = number_width - chars_per_number; 2060 2186 while (i-- > 0) 2061 2187 (p->char_func) (' '); 2062 2188 } 2063 2189 else 2064 (p->char_func) (number_separator); 2190 for (j = 0; j < number_separator_length; j++) 2191 (p->char_func) (number_separator[j]); 2065 2192 } 2066 2193 else 2067 2194 /* To comply with POSIX, we avoid any expansion of default TAB 2068 2195 separator with a single column output. No column_width requirement 2069 2196 has to be considered. */ 2070 2197 { 2071 (p->char_func) (number_separator); 2072 if (number_separator == '\t') 2198 for (j = 0; j < number_separator_length; j++) 2199 (p->char_func) (number_separator[j]); 2200 if (number_separator[0] == '\t') 2073 2201 output_position = POS_AFTER_TAB (chars_per_output_tab, 2074 2202 output_position); 2075 2203 } … … 2230 2358 while (goal - h_old > 1 2231 2359 && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal) 2232 2360 { 2233 putchar (output_tab_char);2361 fwrite (output_tab_char, sizeof(char), output_tab_char_length, stdout); 2234 2362 h_old = h_new; 2235 2363 } 2236 2364 while (++h_old <= goal) … … 2250 2378 { 2251 2379 char *s; 2252 2380 int l = col_sep_length; 2381 int not_space_flag; 2253 2382 2254 2383 s = col_sep_string; 2255 2384 … … 2263 2392 { 2264 2393 for (; separators_not_printed > 0; --separators_not_printed) 2265 2394 { 2395 not_space_flag = 0; 2266 2396 while (l-- > 0) 2267 2397 { 2268 2398 /* 3 types of sep_strings: spaces only, spaces and chars, … … 2276 2406 } 2277 2407 else 2278 2408 { 2409 not_space_flag = 1; 2279 2410 if (spaces_not_printed > 0) 2280 2411 print_white_space (); 2281 2412 putchar (*s++); 2282 ++output_position;2283 2413 } 2284 2414 } 2415 if (not_space_flag) 2416 output_position += col_sep_width; 2417 2285 2418 /* sep_string ends with some spaces */ 2286 2419 if (spaces_not_printed > 0) 2287 2420 print_white_space (); … … 2309 2442 required number of tabs and spaces. */ 2310 2443 2311 2444 static void 2312 print_char (char c)2445 print_char_single (char c) 2313 2446 { 2314 2447 if (tabify_output) 2315 2448 { … … 2333 2466 putchar (c); 2334 2467 } 2335 2468 2469 #ifdef HAVE_MBRTOWC 2470 static void 2471 print_char_multi (char c) 2472 { 2473 static size_t mbc_pos = 0; 2474 static char mbc[MB_LEN_MAX] = {'\0'}; 2475 static mbstate_t state = {'\0'}; 2476 mbstate_t state_bak; 2477 wchar_t wc; 2478 size_t mblength; 2479 int width; 2480 2481 if (tabify_output) 2482 { 2483 state_bak = state; 2484 mbc[mbc_pos++] = c; 2485 mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 2486 2487 while (mbc_pos > 0) 2488 { 2489 switch (mblength) 2490 { 2491 case (size_t)-2: 2492 state = state_bak; 2493 return; 2494 2495 case (size_t)-1: 2496 state = state_bak; 2497 ++output_position; 2498 putchar (mbc[0]); 2499 memmove (mbc, mbc + 1, MB_CUR_MAX - 1); 2500 --mbc_pos; 2501 break; 2502 2503 case 0: 2504 mblength = 1; 2505 2506 default: 2507 if (wc == L' ') 2508 { 2509 memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 2510 --mbc_pos; 2511 ++spaces_not_printed; 2512 return; 2513 } 2514 else if (spaces_not_printed > 0) 2515 print_white_space (); 2516 2517 /* Nonprintables are assumed to have width 0, except L'\b'. */ 2518 if ((width = wcwidth (wc)) < 1) 2519 { 2520 if (wc == L'\b') 2521 --output_position; 2522 } 2523 else 2524 output_position += width; 2525 2526 fwrite (mbc, sizeof(char), mblength, stdout); 2527 memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 2528 mbc_pos -= mblength; 2529 } 2530 } 2531 return; 2532 } 2533 putchar (c); 2534 } 2535 #endif 2536 2336 2537 /* Skip to page PAGE before printing. 2337 2538 PAGE may be larger than total number of pages. */ 2338 2539 … … 2510 2711 align_empty_cols = false; 2511 2712 } 2512 2713 2513 if (padding_not_printed - col_sep_ length > 0)2714 if (padding_not_printed - col_sep_width > 0) 2514 2715 { 2515 pad_across_to (padding_not_printed - col_sep_ length);2716 pad_across_to (padding_not_printed - col_sep_width); 2516 2717 padding_not_printed = ANYWHERE; 2517 2718 } 2518 2719 … … 2613 2814 } 2614 2815 } 2615 2816 2616 if (padding_not_printed - col_sep_ length > 0)2817 if (padding_not_printed - col_sep_width > 0) 2617 2818 { 2618 pad_across_to (padding_not_printed - col_sep_ length);2819 pad_across_to (padding_not_printed - col_sep_width); 2619 2820 padding_not_printed = ANYWHERE; 2620 2821 } 2621 2822 … … 2628 2829 if (spaces_not_printed == 0) 2629 2830 { 2630 2831 output_position = p->start_position + end_vector[line]; 2631 if (p->start_position - col_sep_ length == chars_per_margin)2632 output_position -= col_sep_ length;2832 if (p->start_position - col_sep_width == chars_per_margin) 2833 output_position -= col_sep_width; 2633 2834 } 2634 2835 2635 2836 return true; … … 2648 2849 number of characters is 1.) */ 2649 2850 2650 2851 static int 2651 char_to_clump (char c)2852 char_to_clump_single (char c) 2652 2853 { 2653 2854 unsigned char uc = c; 2654 2855 char *s = clump_buff; … … 2658 2859 int chars; 2659 2860 int chars_per_c = 8; 2660 2861 2661 if (c == input_tab_char )2862 if (c == input_tab_char[0]) 2662 2863 chars_per_c = chars_per_input_tab; 2663 2864 2664 if (c == input_tab_char || c == '\t')2865 if (c == input_tab_char[0] || c == '\t') 2665 2866 { 2666 2867 width = TAB_WIDTH (chars_per_c, input_position); 2667 2868 … … 2742 2943 return chars; 2743 2944 } 2744 2945 2946 #ifdef HAVE_MBRTOWC 2947 static int 2948 char_to_clump_multi (char c) 2949 { 2950 static size_t mbc_pos = 0; 2951 static char mbc[MB_LEN_MAX] = {'\0'}; 2952 static mbstate_t state = {'\0'}; 2953 mbstate_t state_bak; 2954 wchar_t wc; 2955 size_t mblength; 2956 int wc_width; 2957 register char *s = clump_buff; 2958 register int i, j; 2959 char esc_buff[4]; 2960 int width; 2961 int chars; 2962 int chars_per_c = 8; 2963 2964 state_bak = state; 2965 mbc[mbc_pos++] = c; 2966 mblength = mbrtowc (&wc, mbc, mbc_pos, &state); 2967 2968 width = 0; 2969 chars = 0; 2970 while (mbc_pos > 0) 2971 { 2972 switch (mblength) 2973 { 2974 case (size_t)-2: 2975 state = state_bak; 2976 return 0; 2977 2978 case (size_t)-1: 2979 state = state_bak; 2980 mblength = 1; 2981 2982 if (use_esc_sequence || use_cntrl_prefix) 2983 { 2984 width = +4; 2985 chars = +4; 2986 *s++ = '\\'; 2987 sprintf (esc_buff, "%03o", mbc[0]); 2988 for (i = 0; i <= 2; ++i) 2989 *s++ = (int) esc_buff[i]; 2990 } 2991 else 2992 { 2993 width += 1; 2994 chars += 1; 2995 *s++ = mbc[0]; 2996 } 2997 break; 2998 2999 case 0: 3000 mblength = 1; 3001 /* Fall through */ 3002 3003 default: 3004 if (memcmp (mbc, input_tab_char, mblength) == 0) 3005 chars_per_c = chars_per_input_tab; 3006 3007 if (memcmp (mbc, input_tab_char, mblength) == 0 || c == '\t') 3008 { 3009 int width_inc; 3010 3011 width_inc = TAB_WIDTH (chars_per_c, input_position); 3012 width += width_inc; 3013 3014 if (untabify_input) 3015 { 3016 for (i = width_inc; i; --i) 3017 *s++ = ' '; 3018 chars += width_inc; 3019 } 3020 else 3021 { 3022 for (i = 0; i < mblength; i++) 3023 *s++ = mbc[i]; 3024 chars += mblength; 3025 } 3026 } 3027 else if ((wc_width = wcwidth (wc)) < 1) 3028 { 3029 if (use_esc_sequence) 3030 { 3031 for (i = 0; i < mblength; i++) 3032 { 3033 width += 4; 3034 chars += 4; 3035 *s++ = '\\'; 3036 sprintf (esc_buff, "%03o", c); 3037 for (j = 0; j <= 2; ++j) 3038 *s++ = (int) esc_buff[j]; 3039 } 3040 } 3041 else if (use_cntrl_prefix) 3042 { 3043 if (wc < 0200) 3044 { 3045 width += 2; 3046 chars += 2; 3047 *s++ = '^'; 3048 *s++ = wc ^ 0100; 3049 } 3050 else 3051 { 3052 for (i = 0; i < mblength; i++) 3053 { 3054 width += 4; 3055 chars += 4; 3056 *s++ = '\\'; 3057 sprintf (esc_buff, "%03o", c); 3058 for (j = 0; j <= 2; ++j) 3059 *s++ = (int) esc_buff[j]; 3060 } 3061 } 3062 } 3063 else if (wc == L'\b') 3064 { 3065 width += -1; 3066 chars += 1; 3067 *s++ = c; 3068 } 3069 else 3070 { 3071 width += 0; 3072 chars += mblength; 3073 for (i = 0; i < mblength; i++) 3074 *s++ = mbc[i]; 3075 } 3076 } 3077 else 3078 { 3079 width += wc_width; 3080 chars += mblength; 3081 for (i = 0; i < mblength; i++) 3082 *s++ = mbc[i]; 3083 } 3084 } 3085 memmove (mbc, mbc + mblength, MB_CUR_MAX - mblength); 3086 mbc_pos -= mblength; 3087 } 3088 3089 input_position += width; 3090 return chars; 3091 } 3092 #endif 3093 2745 3094 /* We've just printed some files and need to clean up things before 2746 3095 looking for more options and printing the next batch of files. 2747 3096 -
coreutils-6.12
diff -Naur coreutils-6.12.orig/src/sort.c coreutils-6.12/src/sort.c
old new 22 22 23 23 #include <config.h> 24 24 25 #include <assert.h> 25 26 #include <getopt.h> 26 27 #include <sys/types.h> 27 28 #include <sys/wait.h> 28 29 #include <signal.h> 30 #if HAVE_WCHAR_H 31 # include <wchar.h> 32 #endif 33 /* Get isw* functions. */ 34 #if HAVE_WCTYPE_H 35 # include <wctype.h> 36 #endif 37 29 38 #include "system.h" 30 39 #include "argmatch.h" 31 40 #include "error.h" … … 117 126 /* Thousands separator; if -1, then there isn't one. */ 118 127 static int thousands_sep; 119 128 129 static int force_general_numcompare = 0; 130 120 131 /* Nonzero if the corresponding locales are hard. */ 121 132 static bool hard_LC_COLLATE; 122 #if HAVE_ NL_LANGINFO133 #if HAVE_LANGINFO_CODESET 123 134 static bool hard_LC_TIME; 124 135 #endif 125 136 126 137 #define NONZERO(x) ((x) != 0) 127 138 139 /* get a multibyte character's byte length. */ 140 #define GET_BYTELEN_OF_CHAR(LIM, PTR, MBLENGTH, STATE) \ 141 do \ 142 { \ 143 wchar_t wc; \ 144 mbstate_t state_bak; \ 145 \ 146 state_bak = STATE; \ 147 mblength = mbrtowc (&wc, PTR, LIM - PTR, &STATE); \ 148 \ 149 switch (MBLENGTH) \ 150 { \ 151 case (size_t)-1: \ 152 case (size_t)-2: \ 153 STATE = state_bak; \ 154 /* Fall through. */ \ 155 case 0: \ 156 MBLENGTH = 1; \ 157 } \ 158 } \ 159 while (0) 160 128 161 /* The kind of blanks for '-b' to skip in various options. */ 129 162 enum blanktype { bl_start, bl_end, bl_both }; 130 163 … … 262 295 they were read if all keys compare equal. */ 263 296 static bool stable; 264 297 265 /* If TAB has this value, blanks separate fields. */ 266 enum { TAB_DEFAULT = CHAR_MAX + 1 }; 267 268 /* Tab character separating fields. If TAB_DEFAULT, then fields are 298 /* Tab character separating fields. If tab_length is 0, then fields are 269 299 separated by the empty string between a non-blank character and a blank 270 300 character. */ 271 static int tab = TAB_DEFAULT; 301 static char tab[MB_LEN_MAX + 1]; 302 static size_t tab_length = 0; 272 303 273 304 /* Flag to remove consecutive duplicate lines from the output. 274 305 Only the last of a sequence of equal lines will be output. */ … … 655 686 update_proc (pid); 656 687 } 657 688 689 /* Function pointers. */ 690 static void 691 (*inittables) (void); 692 static char * 693 (*begfield) (const struct line*, const struct keyfield *); 694 static char * 695 (*limfield) (const struct line*, const struct keyfield *); 696 static int 697 (*getmonth) (char const *, size_t); 698 static int 699 (*keycompare) (const struct line *, const struct line *); 700 static int 701 (*numcompare) (const char *, const char *); 702 703 /* Test for white space multibyte character. 704 Set LENGTH the byte length of investigated multibyte character. */ 705 #if HAVE_MBRTOWC 706 static int 707 ismbblank (const char *str, size_t len, size_t *length) 708 { 709 size_t mblength; 710 wchar_t wc; 711 mbstate_t state; 712 713 memset (&state, '\0', sizeof(mbstate_t)); 714 mblength = mbrtowc (&wc, str, len, &state); 715 716 if (mblength == (size_t)-1 || mblength == (size_t)-2) 717 { 718 *length = 1; 719 return 0; 720 } 721 722 *length = (mblength < 1) ? 1 : mblength; 723 return iswblank (wc); 724 } 725 #endif 726 658 727 /* Clean up any remaining temporary files. */ 659 728 660 729 static void … … 994 1063 free (node); 995 1064 } 996 1065 997 #if HAVE_ NL_LANGINFO1066 #if HAVE_LANGINFO_CODESET 998 1067 999 1068 static int 1000 1069 struct_month_cmp (const void *m1, const void *m2) … … 1009 1078 /* Initialize the character class tables. */ 1010 1079 1011 1080 static void 1012 inittables (void)1081 inittables_uni (void) 1013 1082 { 1014 1083 size_t i; 1015 1084 … … 1021 1090 fold_toupper[i] = toupper (i); 1022 1091 } 1023 1092 1024 #if HAVE_ NL_LANGINFO1093 #if HAVE_LANGINFO_CODESET 1025 1094 /* If we're not in the "C" locale, read different names for months. */ 1026 1095 if (hard_LC_TIME) 1027 1096 { … … 1047 1116 #endif 1048 1117 } 1049 1118 1119 #if HAVE_MBRTOWC 1120 static void 1121 inittables_mb (void) 1122 { 1123 int i, j, k, l; 1124 char *name, *s; 1125 size_t s_len, mblength; 1126 char mbc[MB_LEN_MAX]; 1127 wchar_t wc, pwc; 1128 mbstate_t state_mb, state_wc; 1129 1130 for (i = 0; i < MONTHS_PER_YEAR; i++) 1131 { 1132 s = (char *) nl_langinfo (ABMON_1 + i); 1133 s_len = strlen (s); 1134 monthtab[i].name = name = (char *) xmalloc (s_len + 1); 1135 monthtab[i].val = i + 1; 1136 1137 memset (&state_mb, '\0', sizeof (mbstate_t)); 1138 memset (&state_wc, '\0', sizeof (mbstate_t)); 1139 1140 for (j = 0; j < s_len;) 1141 { 1142 if (!ismbblank (s + j, s_len - j, &mblength)) 1143 break; 1144 j += mblength; 1145 } 1146 1147 for (k = 0; j < s_len;) 1148 { 1149 mblength = mbrtowc (&wc, (s + j), (s_len - j), &state_mb); 1150 assert (mblength != (size_t)-1 && mblength != (size_t)-2); 1151 if (mblength == 0) 1152 break; 1153 1154 pwc = towupper (wc); 1155 if (pwc == wc) 1156 { 1157 memcpy (mbc, s + j, mblength); 1158 j += mblength; 1159 } 1160 else 1161 { 1162 j += mblength; 1163 mblength = wcrtomb (mbc, pwc, &state_wc); 1164 assert (mblength != (size_t)0 && mblength != (size_t)-1); 1165 } 1166 1167 for (l = 0; l < mblength; l++) 1168 name[k++] = mbc[l]; 1169 } 1170 name[k] = '\0'; 1171 } 1172 qsort ((void *) monthtab, MONTHS_PER_YEAR, 1173 sizeof (struct month), struct_month_cmp); 1174 } 1175 #endif 1176 1050 1177 /* Specify the amount of main memory to use when sorting. */ 1051 1178 static void 1052 1179 specify_sort_size (int oi, char c, char const *s) … … 1257 1384 by KEY in LINE. */ 1258 1385 1259 1386 static char * 1260 begfield (const struct line *line, const struct keyfield *key)1387 begfield_uni (const struct line *line, const struct keyfield *key) 1261 1388 { 1262 1389 char *ptr = line->text, *lim = ptr + line->length - 1; 1263 1390 size_t sword = key->sword; … … 1267 1394 /* The leading field separator itself is included in a field when -t 1268 1395 is absent. */ 1269 1396 1270 if (tab != TAB_DEFAULT)1397 if (tab_length) 1271 1398 while (ptr < lim && sword--) 1272 1399 { 1273 while (ptr < lim && *ptr != tab )1400 while (ptr < lim && *ptr != tab[0]) 1274 1401 ++ptr; 1275 1402 if (ptr < lim) 1276 1403 ++ptr; … … 1298 1425 return ptr; 1299 1426 } 1300 1427 1428 #if HAVE_MBRTOWC 1429 static char * 1430 begfield_mb (const struct line *line, const struct keyfield *key) 1431 { 1432 int i; 1433 char *ptr = line->text, *lim = ptr + line->length - 1; 1434 size_t sword = key->sword; 1435 size_t schar = key->schar; 1436 size_t mblength; 1437 mbstate_t state; 1438 1439 memset (&state, '\0', sizeof(mbstate_t)); 1440 1441 if (tab_length) 1442 while (ptr < lim && sword--) 1443 { 1444 while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 1445 { 1446 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1447 ptr += mblength; 1448 } 1449 if (ptr < lim) 1450 { 1451 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1452 ptr += mblength; 1453 } 1454 } 1455 else 1456 while (ptr < lim && sword--) 1457 { 1458 while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 1459 ptr += mblength; 1460 if (ptr < lim) 1461 { 1462 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1463 ptr += mblength; 1464 } 1465 while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 1466 ptr += mblength; 1467 } 1468 1469 if (key->skipsblanks) 1470 while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 1471 ptr += mblength; 1472 1473 for (i = 0; i < schar; i++) 1474 { 1475 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1476 1477 if (ptr + mblength > lim) 1478 break; 1479 else 1480 ptr += mblength; 1481 } 1482 1483 return ptr; 1484 } 1485 #endif 1486 1301 1487 /* Return the limit of (a pointer to the first character after) the field 1302 1488 in LINE specified by KEY. */ 1303 1489 1304 1490 static char * 1305 limfield (const struct line *line, const struct keyfield *key)1491 limfield_uni (const struct line *line, const struct keyfield *key) 1306 1492 { 1307 1493 char *ptr = line->text, *lim = ptr + line->length - 1; 1308 1494 size_t eword = key->eword, echar = key->echar; … … 1315 1501 `beginning' is the first character following the delimiting TAB. 1316 1502 Otherwise, leave PTR pointing at the first `blank' character after 1317 1503 the preceding field. */ 1318 if (tab != TAB_DEFAULT)1504 if (tab_length) 1319 1505 while (ptr < lim && eword--) 1320 1506 { 1321 while (ptr < lim && *ptr != tab )1507 while (ptr < lim && *ptr != tab[0]) 1322 1508 ++ptr; 1323 1509 if (ptr < lim && (eword | echar)) 1324 1510 ++ptr; … … 1364 1550 */ 1365 1551 1366 1552 /* Make LIM point to the end of (one byte past) the current field. */ 1367 if (tab != TAB_DEFAULT)1553 if (tab_length) 1368 1554 { 1369 1555 char *newlim; 1370 newlim = memchr (ptr, tab , lim - ptr);1556 newlim = memchr (ptr, tab[0], lim - ptr); 1371 1557 if (newlim) 1372 1558 lim = newlim; 1373 1559 } … … 1400 1586 return ptr; 1401 1587 } 1402 1588 1589 #if HAVE_MBRTOWC 1590 static char * 1591 limfield_mb (const struct line *line, const struct keyfield *key) 1592 { 1593 char *ptr = line->text, *lim = ptr + line->length - 1; 1594 size_t eword = key->eword, echar = key->echar; 1595 int i; 1596 size_t mblength; 1597 mbstate_t state; 1598 1599 memset (&state, '\0', sizeof(mbstate_t)); 1600 1601 if (tab_length) 1602 while (ptr < lim && eword--) 1603 { 1604 while (ptr < lim && memcmp (ptr, tab, tab_length) != 0) 1605 { 1606 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1607 ptr += mblength; 1608 } 1609 if (ptr < lim && (eword | echar)) 1610 { 1611 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1612 ptr += mblength; 1613 } 1614 } 1615 else 1616 while (ptr < lim && eword--) 1617 { 1618 while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 1619 ptr += mblength; 1620 if (ptr < lim) 1621 { 1622 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1623 ptr += mblength; 1624 } 1625 while (ptr < lim && !ismbblank (ptr, lim - ptr, &mblength)) 1626 ptr += mblength; 1627 } 1628 1629 1630 # ifdef POSIX_UNSPECIFIED 1631 /* Make LIM point to the end of (one byte past) the current field. */ 1632 if (tab_length) 1633 { 1634 char *newlim, *p; 1635 1636 newlim = NULL; 1637 for (p = ptr; p < lim;) 1638 { 1639 if (memcmp (p, tab, tab_length) == 0) 1640 { 1641 newlim = p; 1642 break; 1643 } 1644 1645 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1646 p += mblength; 1647 } 1648 } 1649 else 1650 { 1651 char *newlim; 1652 newlim = ptr; 1653 1654 while (newlim < lim && ismbblank (newlim, lim - newlim, &mblength)) 1655 newlim += mblength; 1656 if (ptr < lim) 1657 { 1658 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1659 ptr += mblength; 1660 } 1661 while (newlim < lim && !ismbblank (newlim, lim - newlim, &mblength)) 1662 newlim += mblength; 1663 lim = newlim; 1664 } 1665 # endif 1666 1667 /* If we're skipping leading blanks, don't start counting characters 1668 * until after skipping past any leading blanks. */ 1669 if (key->skipsblanks) 1670 while (ptr < lim && ismbblank (ptr, lim - ptr, &mblength)) 1671 ptr += mblength; 1672 1673 memset (&state, '\0', sizeof(mbstate_t)); 1674 1675 /* Advance PTR by ECHAR (if possible), but no further than LIM. */ 1676 for (i = 0; i < echar; i++) 1677 { 1678 GET_BYTELEN_OF_CHAR (lim, ptr, mblength, state); 1679 1680 if (ptr + mblength > lim) 1681 break; 1682 else 1683 ptr += mblength; 1684 } 1685 1686 return ptr; 1687 } 1688 #endif 1689 1403 1690 /* Fill BUF reading from FP, moving buf->left bytes from the end 1404 1691 of buf->buf to the beginning first. If EOF is reached and the 1405 1692 file wasn't terminated by a newline, supply one. Set up BUF's line … … 1482 1769 else 1483 1770 { 1484 1771 if (key->skipsblanks) 1485 while (blanks[to_uchar (*line_start)]) 1486 line_start++; 1772 { 1773 #if HAVE_MBRTOWC 1774 if (MB_CUR_MAX > 1) 1775 { 1776 size_t mblength; 1777 mbstate_t state; 1778 memset (&state, '\0', sizeof(mbstate_t)); 1779 while (line_start < line->keylim && 1780 ismbblank (line_start, 1781 line->keylim - line_start, 1782 &mblength)) 1783 line_start += mblength; 1784 } 1785 else 1786 #endif 1787 while (blanks[to_uchar (*line_start)]) 1788 line_start++; 1789 } 1487 1790 line->keybeg = line_start; 1488 1791 } 1489 1792 } … … 1521 1824 hideously fast. */ 1522 1825 1523 1826 static int 1524 numcompare (const char *a, const char *b)1827 numcompare_uni (const char *a, const char *b) 1525 1828 { 1526 1829 while (blanks[to_uchar (*a)]) 1527 1830 a++; … … 1531 1834 return strnumcmp (a, b, decimal_point, thousands_sep); 1532 1835 } 1533 1836 1837 #if HAVE_MBRTOWC 1838 static int 1839 numcompare_mb (const char *a, const char *b) 1840 { 1841 size_t mblength, len; 1842 len = strlen (a); /* okay for UTF-8 */ 1843 while (*a && ismbblank (a, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 1844 { 1845 a += mblength; 1846 len -= mblength; 1847 } 1848 len = strlen (b); /* okay for UTF-8 */ 1849 while (*b && ismbblank (b, len > MB_CUR_MAX ? MB_CUR_MAX : len, &mblength)) 1850 b += mblength; 1851 1852 return strnumcmp (a, b, decimal_point, thousands_sep); 1853 } 1854 #endif /* HAV_EMBRTOWC */ 1855 1534 1856 static int 1535 1857 general_numcompare (const char *sa, const char *sb) 1536 1858 { … … 1564 1886 Return 0 if the name in S is not recognized. */ 1565 1887 1566 1888 static int 1567 getmonth (char const *month, size_t len)1889 getmonth_uni (char const *month, size_t len) 1568 1890 { 1569 1891 size_t lo = 0; 1570 1892 size_t hi = MONTHS_PER_YEAR; … … 1719 2041 return diff; 1720 2042 } 1721 2043 2044 #if HAVE_MBRTOWC 2045 static int 2046 getmonth_mb (const char *s, size_t len) 2047 { 2048 char *month; 2049 register size_t i; 2050 register int lo = 0, hi = MONTHS_PER_YEAR, result; 2051 char *tmp; 2052 size_t wclength, mblength; 2053 const char **pp; 2054 const wchar_t **wpp; 2055 wchar_t *month_wcs; 2056 mbstate_t state; 2057 2058 while (len > 0 && ismbblank (s, len, &mblength)) 2059 { 2060 s += mblength; 2061 len -= mblength; 2062 } 2063 2064 if (len == 0) 2065 return 0; 2066 2067 month = (char *) alloca (len + 1); 2068 2069 tmp = (char *) alloca (len + 1); 2070 memcpy (tmp, s, len); 2071 tmp[len] = '\0'; 2072 pp = (const char **)&tmp; 2073 month_wcs = (wchar_t *) alloca ((len + 1) * sizeof (wchar_t)); 2074 memset (&state, '\0', sizeof(mbstate_t)); 2075 2076 wclength = mbsrtowcs (month_wcs, pp, len + 1, &state); 2077 assert (wclength != (size_t)-1 && *pp == NULL); 2078 2079 for (i = 0; i < wclength; i++) 2080 { 2081 month_wcs[i] = towupper(month_wcs[i]); 2082 if (iswblank (month_wcs[i])) 2083 { 2084 month_wcs[i] = L'\0'; 2085 break; 2086 } 2087 } 2088 2089 wpp = (const wchar_t **)&month_wcs; 2090 2091 mblength = wcsrtombs (month, wpp, len + 1, &state); 2092 assert (mblength != (-1) && *wpp == NULL); 2093 2094 do 2095 { 2096 int ix = (lo + hi) / 2; 2097 2098 if (strncmp (month, monthtab[ix].name, strlen (monthtab[ix].name)) < 0) 2099 hi = ix; 2100 else 2101 lo = ix; 2102 } 2103 while (hi - lo > 1); 2104 2105 result = (!strncmp (month, monthtab[lo].name, strlen (monthtab[lo].name)) 2106 ? monthtab[lo].val : 0); 2107 2108 return result; 2109 } 2110 #endif 2111 1722 2112 /* Compare two lines A and B trying every key in sequence until there 1723 2113 are no more keys or a difference is found. */ 1724 2114 1725 2115 static int 1726 keycompare (const struct line *a, const struct line *b)2116 keycompare_uni (const struct line *a, const struct line *b) 1727 2117 { 1728 2118 struct keyfield const *key = keylist; 1729 2119 … … 1896 2286 return key->reverse ? -diff : diff; 1897 2287 } 1898 2288 2289 #if HAVE_MBRTOWC 2290 static int 2291 keycompare_mb (const struct line *a, const struct line *b) 2292 { 2293 struct keyfield *key = keylist; 2294 2295 /* For the first iteration only, the key positions have been 2296 precomputed for us. */ 2297 char *texta = a->keybeg; 2298 char *textb = b->keybeg; 2299 char *lima = a->keylim; 2300 char *limb = b->keylim; 2301 2302 size_t mblength_a, mblength_b; 2303 wchar_t wc_a, wc_b; 2304 mbstate_t state_a, state_b; 2305 2306 int diff; 2307 2308 memset (&state_a, '\0', sizeof(mbstate_t)); 2309 memset (&state_b, '\0', sizeof(mbstate_t)); 2310 2311 for (;;) 2312 { 2313 unsigned char *translate = (unsigned char *) key->translate; 2314 bool const *ignore = key->ignore; 2315 2316 /* Find the lengths. */ 2317 size_t lena = lima <= texta ? 0 : lima - texta; 2318 size_t lenb = limb <= textb ? 0 : limb - textb; 2319 2320 /* Actually compare the fields. */ 2321 if (key->random) 2322 diff = compare_random (texta, lena, textb, lenb); 2323 else if (key->numeric | key->general_numeric) 2324 { 2325 char savea = *lima, saveb = *limb; 2326 2327 *lima = *limb = '\0'; 2328 if (force_general_numcompare) 2329 diff = general_numcompare (texta, textb); 2330 else 2331 diff = ((key->numeric ? numcompare : general_numcompare) 2332 (texta, textb)); 2333 *lima = savea, *limb = saveb; 2334 } 2335 else if (key->month) 2336 diff = getmonth (texta, lena) - getmonth (textb, lenb); 2337 else 2338 { 2339 if (ignore || translate) 2340 { 2341 char *copy_a = (char *) alloca (lena + 1 + lenb + 1); 2342 char *copy_b = copy_a + lena + 1; 2343 size_t new_len_a, new_len_b; 2344 size_t i, j; 2345 2346 /* Ignore and/or translate chars before comparing. */ 2347 # define IGNORE_CHARS(NEW_LEN, LEN, TEXT, COPY, WC, MBLENGTH, STATE) \ 2348 do \ 2349 { \ 2350 wchar_t uwc; \ 2351 char mbc[MB_LEN_MAX]; \ 2352 mbstate_t state_wc; \ 2353 \ 2354 for (NEW_LEN = i = 0; i < LEN;) \ 2355 { \ 2356 mbstate_t state_bak; \ 2357 \ 2358 state_bak = STATE; \ 2359 MBLENGTH = mbrtowc (&WC, TEXT + i, LEN - i, &STATE); \ 2360 \ 2361 if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1 \ 2362 || MBLENGTH == 0) \ 2363 { \ 2364 if (MBLENGTH == (size_t)-2 || MBLENGTH == (size_t)-1) \ 2365 STATE = state_bak; \ 2366 if (!ignore) \ 2367 COPY[NEW_LEN++] = TEXT[i++]; \ 2368 continue; \ 2369 } \ 2370 \ 2371 if (ignore) \ 2372 { \ 2373 if ((ignore == nonprinting && !iswprint (WC)) \ 2374 || (ignore == nondictionary \ 2375 && !iswalnum (WC) && !iswblank (WC))) \ 2376 { \ 2377 i += MBLENGTH; \ 2378 continue; \ 2379 } \ 2380 } \ 2381 \ 2382 if (translate) \ 2383 { \ 2384 \ 2385 uwc = towupper(WC); \ 2386 if (WC == uwc) \ 2387 { \ 2388 memcpy (mbc, TEXT + i, MBLENGTH); \ 2389 i += MBLENGTH; \ 2390 } \ 2391 else \ 2392 { \ 2393 i += MBLENGTH; \ 2394 WC = uwc; \ 2395 memset (&state_wc, '\0', sizeof (mbstate_t)); \ 2396 \ 2397 MBLENGTH = wcrtomb (mbc, WC, &state_wc); \ 2398 assert (MBLENGTH != (size_t)-1 && MBLENGTH != 0); \ 2399 } \ 2400 \ 2401 for (j = 0; j < MBLENGTH; j++) \ 2402 COPY[NEW_LEN++] = mbc[j]; \ 2403 } \ 2404 else \ 2405 for (j = 0; j < MBLENGTH; j++) \ 2406 COPY[NEW_LEN++] = TEXT[i++]; \ 2407 } \ 2408 COPY[NEW_LEN] = '\0'; \ 2409 } \ 2410 while (0) 2411 IGNORE_CHARS (new_len_a, lena, texta, copy_a, 2412 wc_a, mblength_a, state_a); 2413 IGNORE_CHARS (new_len_b, lenb, textb, copy_b, 2414 wc_b, mblength_b, state_b); 2415 diff = xmemcoll (copy_a, new_len_a, copy_b, new_len_b); 2416 } 2417 else if (lena == 0) 2418 diff = - NONZERO (lenb); 2419 else if (lenb == 0) 2420 goto greater; 2421 else 2422 diff = xmemcoll (texta, lena, textb, lenb); 2423 } 2424 2425 if (diff) 2426 goto not_equal; 2427 2428 key = key->next; 2429 if (! key) 2430 break; 2431 2432 /* Find the beginning and limit of the next field. */ 2433 if (key->eword != -1) 2434 lima = limfield (a, key), limb = limfield (b, key); 2435 else 2436 lima = a->text + a->length - 1, limb = b->text + b->length - 1; 2437 2438 if (key->sword != -1) 2439 texta = begfield (a, key), textb = begfield (b, key); 2440 else 2441 { 2442 texta = a->text, textb = b->text; 2443 if (key->skipsblanks) 2444 { 2445 while (texta < lima && ismbblank (texta, lima - texta, &mblength_a)) 2446 texta += mblength_a; 2447 while (textb < limb && ismbblank (textb, limb - textb, &mblength_b)) 2448 textb += mblength_b; 2449 } 2450 } 2451 } 2452 2453 return 0; 2454 2455 greater: 2456 diff = 1; 2457 not_equal: 2458 return key->reverse ? -diff : diff; 2459 } 2460 #endif 2461 1899 2462 /* Compare two lines A and B, returning negative, zero, or positive 1900 2463 depending on whether A compares less than, equal to, or greater than B. */ 1901 2464 … … 2765 3328 initialize_exit_failure (SORT_FAILURE); 2766 3329 2767 3330 hard_LC_COLLATE = hard_locale (LC_COLLATE); 2768 #if HAVE_ NL_LANGINFO3331 #if HAVE_LANGINFO_CODESET 2769 3332 hard_LC_TIME = hard_locale (LC_TIME); 2770 3333 #endif 2771 3334 … … 2786 3349 thousands_sep = -1; 2787 3350 } 2788 3351 3352 #if HAVE_MBRTOWC 3353 if (MB_CUR_MAX > 1) 3354 { 3355 inittables = inittables_mb; 3356 begfield = begfield_mb; 3357 limfield = limfield_mb; 3358 getmonth = getmonth_mb; 3359 keycompare = keycompare_mb; 3360 numcompare = numcompare_mb; 3361 } 3362 else 3363 #endif 3364 { 3365 inittables = inittables_uni; 3366 begfield = begfield_uni; 3367 limfield = limfield_uni; 3368 getmonth = getmonth_uni; 3369 keycompare = keycompare_uni; 3370 numcompare = numcompare_uni; 3371 } 3372 2789 3373 have_read_stdin = false; 2790 3374 inittables (); 2791 3375 … … 3037 3621 3038 3622 case 't': 3039 3623 { 3040 char newtab = optarg[0]; 3041 if (! newtab) 3624 char newtab[MB_LEN_MAX + 1]; 3625 size_t newtab_length = 1; 3626 strncpy (newtab, optarg, MB_LEN_MAX); 3627 if (! newtab[0]) 3042 3628 error (SORT_FAILURE, 0, _("empty tab")); 3043 if (optarg[1]) 3629 #if HAVE_MBRTOWC 3630 if (MB_CUR_MAX > 1) 3631 { 3632 wchar_t wc; 3633 mbstate_t state; 3634 size_t i; 3635 3636 memset (&state, '\0', sizeof (mbstate_t)); 3637 newtab_length = mbrtowc (&wc, newtab, strnlen (newtab, 3638 MB_LEN_MAX), 3639 &state); 3640 switch (newtab_length) 3641 { 3642 case (size_t) -1: 3643 case (size_t) -2: 3644 case 0: 3645 newtab_length = 1; 3646 } 3647 } 3648 #endif 3649 if (newtab_length == 1 && optarg[1]) 3044 3650 { 3045 3651 if (STREQ (optarg, "\\0")) 3046 newtab = '\0';3652 newtab[0] = '\0'; 3047 3653 else 3048 3654 { 3049 3655 /* Provoke with `sort -txx'. Complain about … … 3054 3660 quote (optarg)); 3055 3661 } 3056 3662 } 3057 if (tab != TAB_DEFAULT && tab != newtab) 3663 if (tab_length 3664 && (tab_length != newtab_length 3665 || memcmp (tab, newtab, tab_length) != 0)) 3058 3666 error (SORT_FAILURE, 0, _("incompatible tabs")); 3059 tab = newtab; 3667 memcpy (tab, newtab, newtab_length); 3668 tab_length = newtab_length; 3060 3669 } 3061 3670 break; 3062 3671 -
src/unexpand.c
diff -Naur coreutils-6.12.orig/src/unexpand.c coreutils-6.12/src/unexpand.c
old new 38 38 #include <stdio.h> 39 39 #include <getopt.h> 40 40 #include <sys/types.h> 41 42 /* Get mbstate_t, mbrtowc(), wcwidth(). */ 43 #if HAVE_WCHAR_H 44 # include <wchar.h> 45 #endif 46 41 47 #include "system.h" 42 48 #include "error.h" 43 49 #include "quote.h" 44 50 #include "xstrndup.h" 45 51 52 /* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 53 installation; work around this configuration error. */ 54 #if !defined MB_LEN_MAX || MB_LEN_MAX < 2 55 # define MB_LEN_MAX 16 56 #endif 57 58 /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 59 #if HAVE_MBRTOWC && defined mbstate_t 60 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 61 #endif 62 46 63 /* The official name of this program (e.g., no `g' prefix). */ 47 64 #define PROGRAM_NAME "unexpand" 48 65 … … 109 126 {NULL, 0, NULL, 0} 110 127 }; 111 128 129 static FILE *next_file (FILE *fp); 130 131 #if HAVE_MBRTOWC 132 static void 133 unexpand_multibyte (void) 134 { 135 FILE *fp; /* Input stream. */ 136 mbstate_t i_state; /* Current shift state of the input stream. */ 137 mbstate_t i_state_bak; /* Back up the I_STATE. */ 138 mbstate_t o_state; /* Current shift state of the output stream. */ 139 char buf[MB_LEN_MAX + BUFSIZ]; /* For spooling a read byte sequence. */ 140 char *bufpos; /* Next read position of BUF. */ 141 size_t buflen = 0; /* The length of the byte sequence in buf. */ 142 wint_t wc; /* A gotten wide character. */ 143 size_t mblength; /* The byte size of a multibyte character 144 which shows as same character as WC. */ 145 146 /* Index in `tab_list' of next tabstop: */ 147 int tab_index = 0; /* For calculating width of pending tabs. */ 148 int print_tab_index = 0; /* For printing as many tabs as possible. */ 149 unsigned int column = 0; /* Column on screen of next char. */ 150 int next_tab_column; /* Column the next tab stop is on. */ 151 int convert = 1; /* If nonzero, perform translations. */ 152 unsigned int pending = 0; /* Pending columns of blanks. */ 153 154 fp = next_file ((FILE *) NULL); 155 if (fp == NULL) 156 return; 157 158 memset (&o_state, '\0', sizeof(mbstate_t)); 159 memset (&i_state, '\0', sizeof(mbstate_t)); 160 161 for (;;) 162 { 163 if (buflen < MB_LEN_MAX && !feof(fp) && !ferror(fp)) 164 { 165 memmove (buf, bufpos, buflen); 166 buflen += fread (buf + buflen, sizeof(char), BUFSIZ, fp); 167 bufpos = buf; 168 } 169 170 /* Get a wide character. */ 171 if (buflen < 1) 172 { 173 mblength = 1; 174 wc = WEOF; 175 } 176 else 177 { 178 i_state_bak = i_state; 179 mblength = mbrtowc ((wchar_t *)&wc, bufpos, buflen, &i_state); 180 } 181 182 if (mblength == (size_t)-1 || mblength == (size_t)-2) 183 { 184 i_state = i_state_bak; 185 wc = L'\0'; 186 } 187 188 if (wc == L' ' && convert && column < INT_MAX) 189 { 190 ++pending; 191 ++column; 192 } 193 else if (wc == L'\t' && convert) 194 { 195 if (tab_size == 0) 196 { 197 /* Do not let tab_index == first_free_tab; 198 stop when it is 1 less. */ 199 while (tab_index < first_free_tab - 1 200 && column >= tab_list[tab_index]) 201 tab_index++; 202 next_tab_column = tab_list[tab_index]; 203 if (tab_index < first_free_tab - 1) 204 tab_index++; 205 if (column >= next_tab_column) 206 { 207 convert = 0; /* Ran out of tab stops. */ 208 goto flush_pend_mb; 209 } 210 } 211 else 212 { 213 next_tab_column = column + tab_size - column % tab_size; 214 } 215 pending += next_tab_column - column; 216 column = next_tab_column; 217 } 218 else 219 { 220 flush_pend_mb: 221 /* Flush pending spaces. Print as many tabs as possible, 222 then print the rest as spaces. */ 223 if (pending == 1) 224 { 225 putchar (' '); 226 pending = 0; 227 } 228 column -= pending; 229 while (pending > 0) 230 { 231 if (tab_size == 0) 232 { 233 /* Do not let print_tab_index == first_free_tab; 234 stop when it is 1 less. */ 235 while (print_tab_index < first_free_tab - 1 236 && column >= tab_list[print_tab_index]) 237 print_tab_index++; 238 next_tab_column = tab_list[print_tab_index]; 239 if (print_tab_index < first_free_tab - 1) 240 print_tab_index++; 241 } 242 else 243 { 244 next_tab_column = 245 column + tab_size - column % tab_size; 246 } 247 if (next_tab_column - column <= pending) 248 { 249 putchar ('\t'); 250 pending -= next_tab_column - column; 251 column = next_tab_column; 252 } 253 else 254 { 255 --print_tab_index; 256 column += pending; 257 while (pending != 0) 258 { 259 putchar (' '); 260 pending--; 261 } 262 } 263 } 264 265 if (wc == WEOF) 266 { 267 fp = next_file (fp); 268 if (fp == NULL) 269 break; /* No more files. */ 270 else 271 { 272 memset (&i_state, '\0', sizeof(mbstate_t)); 273 continue; 274 } 275 } 276 277 if (mblength == (size_t)-1 || mblength == (size_t)-2) 278 { 279 if (convert) 280 { 281 ++column; 282 if (convert_entire_line == 0) 283 convert = 0; 284 } 285 mblength = 1; 286 putchar (buf[0]); 287 } 288 else if (mblength == 0) 289 { 290 if (convert && convert_entire_line == 0) 291 convert = 0; 292 mblength = 1; 293 putchar ('\0'); 294 } 295 else 296 { 297 if (convert) 298 { 299 if (wc == L'\b') 300 { 301 if (column > 0) 302 --column; 303 } 304 else 305 { 306 int width; /* The width of WC. */ 307 308 width = wcwidth (wc); 309 column += (width > 0) ? width : 0; 310 if (convert_entire_line == 0) 311 convert = 0; 312 } 313 } 314 315 if (wc == L'\n') 316 { 317 tab_index = print_tab_index = 0; 318 column = pending = 0; 319 convert = 1; 320 } 321 fwrite (bufpos, sizeof(char), mblength, stdout); 322 } 323 } 324 buflen -= mblength; 325 bufpos += mblength; 326 } 327 } 328 #endif 329 330 112 331 void 113 332 usage (int status) 114 333 { … … 530 749 531 750 file_list = (optind < argc ? &argv[optind] : stdin_argv); 532 751 533 unexpand (); 752 #if HAVE_MBRTOWC 753 if (MB_CUR_MAX > 1) 754 unexpand_multibyte (); 755 else 756 #endif 757 unexpand (); 534 758 535 759 if (have_read_stdin && fclose (stdin) != 0) 536 760 error (EXIT_FAILURE, errno, "-"); -
coreutils-6.12
diff -Naur coreutils-6.12.orig/src/uniq.c coreutils-6.12/src/uniq.c
old new 22 22 #include <getopt.h> 23 23 #include <sys/types.h> 24 24 25 /* Get mbstate_t, mbrtowc(). */ 26 #if HAVE_WCHAR_H 27 # include <wchar.h> 28 #endif 29 30 /* Get isw* functions. */ 31 #if HAVE_WCTYPE_H 32 # include <wctype.h> 33 #endif 34 25 35 #include "system.h" 26 36 #include "argmatch.h" 27 37 #include "linebuffer.h" … … 31 41 #include "quote.h" 32 42 #include "xmemcoll.h" 33 43 #include "xstrtol.h" 34 #include "memcasecmp.h" 44 #include "xmemcoll.h" 45 46 /* MB_LEN_MAX is incorrectly defined to be 1 in at least one GCC 47 installation; work around this configuration error. */ 48 #if !defined MB_LEN_MAX || MB_LEN_MAX < 2 49 # define MB_LEN_MAX 16 50 #endif 51 52 /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ 53 #if HAVE_MBRTOWC && defined mbstate_t 54 # define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0) 55 #endif 56 35 57 36 58 /* The official name of this program (e.g., no `g' prefix). */ 37 59 #define PROGRAM_NAME "uniq" … … 110 132 /* Select whether/how to delimit groups of duplicate lines. */ 111 133 static enum delimit_method delimit_groups; 112 134 135 /* Function pointers. */ 136 static char * 137 (*find_field) (struct linebuffer *line); 138 113 139 static struct option const longopts[] = 114 140 { 115 141 {"count", no_argument, NULL, 'c'}, … … 206 232 return a pointer to the beginning of the line's field to be compared. */ 207 233 208 234 static char * 209 find_field (conststruct linebuffer *line)235 find_field_uni (struct linebuffer *line) 210 236 { 211 237 size_t count; 212 238 char *lp = line->buffer; … … 227 253 return lp + i; 228 254 } 229 255 256 #if HAVE_MBRTOWC 257 258 # define MBCHAR_TO_WCHAR(WC, MBLENGTH, LP, POS, SIZE, STATEP, CONVFAIL) \ 259 do \ 260 { \ 261 mbstate_t state_bak; \ 262 \ 263 CONVFAIL = 0; \ 264 state_bak = *STATEP; \ 265 \ 266 MBLENGTH = mbrtowc (&WC, LP + POS, SIZE - POS, STATEP); \ 267 \ 268 switch (MBLENGTH) \ 269 { \ 270 case (size_t)-2: \ 271 case (size_t)-1: \ 272 *STATEP = state_bak; \ 273 CONVFAIL++; \ 274 /* Fall through */ \ 275 case 0: \ 276 MBLENGTH = 1; \ 277 } \ 278 } \ 279 while (0) 280 281 static char * 282 find_field_multi (struct linebuffer *line) 283 { 284 size_t count; 285 char *lp = line->buffer; 286 size_t size = line->length - 1; 287 size_t pos; 288 size_t mblength; 289 wchar_t wc; 290 mbstate_t *statep; 291 int convfail; 292 293 pos = 0; 294 statep = &(line->state); 295 296 /* skip fields. */ 297 for (count = 0; count < skip_fields && pos < size; count++) 298 { 299 while (pos < size) 300 { 301 MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 302 303 if (convfail || !iswblank (wc)) 304 { 305 pos += mblength; 306 break; 307 } 308 pos += mblength; 309 } 310 311 while (pos < size) 312 { 313 MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 314 315 if (!convfail && iswblank (wc)) 316 break; 317 318 pos += mblength; 319 } 320 } 321 322 /* skip fields. */ 323 for (count = 0; count < skip_chars && pos < size; count++) 324 { 325 MBCHAR_TO_WCHAR (wc, mblength, lp, pos, size, statep, convfail); 326 pos += mblength; 327 } 328 329 return lp + pos; 330 } 331 #endif 332 230 333 /* Return false if two strings OLD and NEW match, true if not. 231 334 OLD and NEW point not to the beginnings of the lines 232 335 but rather to the beginnings of the fields to compare. … … 235 338 static bool 236 339 different (char *old, char *new, size_t oldlen, size_t newlen) 237 340 { 341 char *copy_old, *copy_new; 342 238 343 if (check_chars < oldlen) 239 344 oldlen = check_chars; 240 345 if (check_chars < newlen) … … 242 347 243 348 if (ignore_case) 244 349 { 245 /* FIXME: This should invoke strcoll somehow. */ 246 return oldlen != newlen || memcasecmp (old, new, oldlen); 350 size_t i; 351 352 copy_old = alloca (oldlen + 1); 353 copy_new = alloca (oldlen + 1); 354 355 for (i = 0; i < oldlen; i++) 356 { 357 copy_old[i] = toupper (old[i]); 358 copy_new[i] = toupper (new[i]); 359 } 247 360 } 248 else if (hard_LC_COLLATE)249 return xmemcoll (old, oldlen, new, newlen) != 0;250 361 else 251 return oldlen != newlen || memcmp (old, new, oldlen); 362 { 363 copy_old = (char *)old; 364 copy_new = (char *)new; 365 } 366 367 return xmemcoll (copy_old, oldlen, copy_new, newlen); 368 } 369 370 #if HAVE_MBRTOWC 371 static int 372 different_multi (const char *old, const char *new, size_t oldlen, size_t newlen, mbstate_t oldstate, mbstate_t newstate) 373 { 374 size_t i, j, chars; 375 const char *str[2]; 376 char *copy[2]; 377 size_t len[2]; 378 mbstate_t state[2]; 379 size_t mblength; 380 wchar_t wc, uwc; 381 mbstate_t state_bak; 382 383 str[0] = old; 384 str[1] = new; 385 len[0] = oldlen; 386 len[1] = newlen; 387 state[0] = oldstate; 388 state[1] = newstate; 389 390 for (i = 0; i < 2; i++) 391 { 392 copy[i] = alloca (len[i] + 1); 393 394 for (j = 0, chars = 0; j < len[i] && chars < check_chars; chars++) 395 { 396 state_bak = state[i]; 397 mblength = mbrtowc (&wc, str[i] + j, len[i] - j, &(state[i])); 398 399 switch (mblength) 400 { 401 case (size_t)-1: 402 case (size_t)-2: 403 state[i] = state_bak; 404 /* Fall through */ 405 case 0: 406 mblength = 1; 407 break; 408 409 default: 410 if (ignore_case) 411 { 412 uwc = towupper (wc); 413 414 if (uwc != wc) 415 { 416 mbstate_t state_wc; 417 418 memset (&state_wc, '\0', sizeof(mbstate_t)); 419 wcrtomb (copy[i] + j, uwc, &state_wc); 420 } 421 else 422 memcpy (copy[i] + j, str[i] + j, mblength); 423 } 424 else 425 memcpy (copy[i] + j, str[i] + j, mblength); 426 } 427 j += mblength; 428 } 429 copy[i][j] = '\0'; 430 len[i] = j; 431 } 432 433 return xmemcoll (copy[0], len[0], copy[1], len[1]); 252 434 } 435 #endif 253 436 254 437 /* Output the line in linebuffer LINE to standard output 255 438 provided that the switches say it should be output. … … 303 486 { 304 487 char *prevfield IF_LINT (= NULL); 305 488 size_t prevlen IF_LINT (= 0); 489 #if HAVE_MBRTOWC 490 mbstate_t prevstate; 491 492 memset (&prevstate, '\0', sizeof (mbstate_t)); 493 #endif 306 494 307 495 while (!feof (stdin)) 308 496 { 309 497 char *thisfield; 310 498 size_t thislen; 499 #if HAVE_MBRTOWC 500 mbstate_t thisstate; 501 #endif 502 311 503 if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 312 504 break; 313 505 thisfield = find_field (thisline); 314 506 thislen = thisline->length - 1 - (thisfield - thisline->buffer); 507 #if HAVE_MBRTOWC 508 if (MB_CUR_MAX > 1) 509 { 510 thisstate = thisline->state; 511 512 if (prevline->length == 0 || different_multi 513 (thisfield, prevfield, thislen, prevlen, thisstate, prevstate)) 514 { 515 fwrite (thisline->buffer, sizeof (char), 516 thisline->length, stdout); 517 518 SWAP_LINES (prevline, thisline); 519 prevfield = thisfield; 520 prevlen = thislen; 521 prevstate = thisstate; 522 } 523 } 524 else 525 #endif 315 526 if (prevline->length == 0 316 527 || different (thisfield, prevfield, thislen, prevlen)) 317 528 { … … 330 541 size_t prevlen; 331 542 uintmax_t match_count = 0; 332 543 bool first_delimiter = true; 544 #if HAVE_MBRTOWC 545 mbstate_t prevstate; 546 #endif 333 547 334 548 if (readlinebuffer_delim (prevline, stdin, delimiter) == 0) 335 549 goto closefiles; 336 550 prevfield = find_field (prevline); 337 551 prevlen = prevline->length - 1 - (prevfield - prevline->buffer); 552 #if HAVE_MBRTOWC 553 prevstate = prevline->state; 554 #endif 338 555 339 556 while (!feof (stdin)) 340 557 { 341 558 bool match; 342 559 char *thisfield; 343 560 size_t thislen; 561 #if HAVE_MBRTOWC 562 mbstate_t thisstate; 563 #endif 344 564 if (readlinebuffer_delim (thisline, stdin, delimiter) == 0) 345 565 { 346 566 if (ferror (stdin)) … … 349 569 } 350 570 thisfield = find_field (thisline); 351 571 thislen = thisline->length - 1 - (thisfield - thisline->buffer); 572 #if HAVE_MBRTOWC 573 if (MB_CUR_MAX > 1) 574 { 575 thisstate = thisline->state; 576 match = !different_multi (thisfield, prevfield, 577 thislen, prevlen, thisstate, prevstate); 578 } 579 else 580 #endif 352 581 match = !different (thisfield, prevfield, thislen, prevlen); 353 582 match_count += match; 354 583 … … 381 610 SWAP_LINES (prevline, thisline); 382 611 prevfield = thisfield; 383 612 prevlen = thislen; 613 #if HAVE_MBRTOWC 614 prevstate = thisstate; 615 #endif 384 616 if (!match) 385 617 match_count = 0; 386 618 } … … 426 658 427 659 atexit (close_stdout); 428 660 661 #if HAVE_MBRTOWC 662 if (MB_CUR_MAX > 1) 663 { 664 find_field = find_field_multi; 665 } 666 else 667 #endif 668 { 669 find_field = find_field_uni; 670 } 671 672 673 429 674 skip_chars = 0; 430 675 skip_fields = 0; 431 676 check_chars = SIZE_MAX; -
tests/Makefile.am
diff -Naur coreutils-6.12.orig/tests/Makefile.am coreutils-6.12/tests/Makefile.am
old new 191 191 misc/shuf \ 192 192 misc/sort \ 193 193 misc/sort-compress \ 194 misc/sort-mb-tests \ 194 195 misc/sort-merge \ 195 196 misc/sort-rand \ 196 197 misc/split-a \ … … 391 392 $(root_tests) 392 393 393 394 pr_data = \ 395 misc/mb1.X \ 396 misc/mb1.I \ 397 misc/mb2.X \ 398 misc/mb2.I \ 394 399 pr/0F \ 395 400 pr/0FF \ 396 401 pr/0FFnt \ -
tests/misc/mb1.I
diff -Naur coreutils-6.12.orig/tests/misc/mb1.I coreutils-6.12/tests/misc/mb1.I
old new 1 AppleïŒ 10 2 BananaïŒ 5 3 CitrusïŒ 20 4 CherryïŒ 30 -
tests/misc/mb1.X
diff -Naur coreutils-6.12.orig/tests/misc/mb1.X coreutils-6.12/tests/misc/mb1.X
old new 1 BananaïŒ 5 2 AppleïŒ 10 3 CitrusïŒ 20 4 CherryïŒ 30 -
tests/misc/mb2.I
diff -Naur coreutils-6.12.orig/tests/misc/mb2.I coreutils-6.12/tests/misc/mb2.I
old new 1 AppleïŒ ïŒ¡ïŒ¡10ïŒ ïŒ 20 2 BananaïŒ ïŒ¡ïŒ¡5ïŒ ïŒ 30 3 CitrusïŒ ïŒ¡ïŒ¡20ïŒ ïŒ 5 4 CherryïŒ ïŒ¡ïŒ¡30ïŒ ïŒ 10 -
tests/misc/mb2.X
diff -Naur coreutils-6.12.orig/tests/misc/mb2.X coreutils-6.12/tests/misc/mb2.X
old new 1 CitrusïŒ ïŒ¡ïŒ¡20ïŒ ïŒ 5 2 CherryïŒ ïŒ¡ïŒ¡30ïŒ ïŒ 10 3 AppleïŒ ïŒ¡ïŒ¡10ïŒ ïŒ 20 4 BananaïŒ ïŒ¡ïŒ¡5ïŒ ïŒ 30 -
tests/misc/sort-mb-tests
diff -Naur coreutils-6.12.orig/tests/misc/sort-mb-tests coreutils-6.12/tests/misc/sort-mb-tests
old new 1 #! /bin/sh 2 case $# in 3 0) xx='../src/sort';; 4 *) xx="$1";; 5 esac 6 test "$VERBOSE" && echo=echo || echo=: 7 $echo testing program: $xx 8 errors=0 9 test "$srcdir" || srcdir=. 10 test "$VERBOSE" && $xx --version 2> /dev/null 11 12 export LC_ALL=en_US.UTF-8 13 locale -k LC_CTYPE 2>&1 | grep -q charmap.*UTF-8 || exit 77 14 errors=0 15 16 $xx -t ïŒ -k2 -n misc/mb1.I > misc/mb1.O 17 code=$? 18 if test $code != 0; then 19 $echo "Test mb1 failed: $xx return code $code differs from expected value 0" 1>&2 20 errors=`expr $errors + 1` 21 else 22 cmp misc/mb1.O $srcdir/misc/mb1.X > /dev/null 2>&1 23 case $? in 24 0) if test "$VERBOSE"; then $echo "passed mb1"; fi;; 25 1) $echo "Test mb1 failed: files misc/mb1.O and $srcdir/misc/mb1.X differ" 1>&2 26 (diff -c misc/mb1.O $srcdir/misc/mb1.X) 2> /dev/null 27 errors=`expr $errors + 1`;; 28 2) $echo "Test mb1 may have failed." 1>&2 29 $echo The command "cmp misc/mb1.O $srcdir/misc/mb1.X" failed. 1>&2 30 errors=`expr $errors + 1`;; 31 esac 32 fi 33 34 $xx -t ïŒ -k4 -n misc/mb2.I > misc/mb2.O 35 code=$? 36 if test $code != 0; then 37 $echo "Test mb2 failed: $xx return code $code differs from expected value 0" 1>&2 38 errors=`expr $errors + 1` 39 else 40 cmp misc/mb2.O $srcdir/misc/mb2.X > /dev/null 2>&1 41 case $? in 42 0) if test "$VERBOSE"; then $echo "passed mb2"; fi;; 43 1) $echo "Test mb2 failed: files misc/mb2.O and $srcdir/misc/mb2.X differ" 1>&2 44 (diff -c misc/mb2.O $srcdir/misc/mb2.X) 2> /dev/null 45 errors=`expr $errors + 1`;; 46 2) $echo "Test mb2 may have failed." 1>&2 47 $echo The command "cmp misc/mb2.O $srcdir/misc/mb2.X" failed. 1>&2 48 errors=`expr $errors + 1`;; 49 esac 50 fi 51 52 if test $errors = 0; then 53 $echo Passed all 113 tests. 1>&2 54 else 55 $echo Failed $errors tests. 1>&2 56 fi 57 test $errors = 0 || errors=1 58 exit $errors
Note:
See TracBrowser
for help on using the repository browser.