root/trunk/texinfo/texinfo-4.8a-fixes-1.patch
| Revision 1821, 20.2 kB (checked in by robert, 1 year ago) |
|---|
-
texinfo-4.8/doc/texindex.1
old new 1 .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.3 4.2 .TH TEXINDEX "1" " December 2004" "texindex 4.8" "User Commands"1 .\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.35. 2 .TH TEXINDEX "1" "November 2006" "texindex 4.8.90" "User Commands" 3 3 .SH NAME 4 4 texindex \- sort Texinfo index files 5 5 .SH SYNOPSIS … … 13 13 \fB\-h\fR, \fB\-\-help\fR 14 14 display this help and exit 15 15 .TP 16 \fB\-k\fR, \fB\-\-keep\fR17 keep temporary files around after processing18 .TP19 \fB\-\-no\-keep\fR20 do not keep temporary files around after processing (default)21 .TP22 16 \fB\-o\fR, \fB\-\-output\fR FILE 23 17 send output to FILE 24 18 .TP … … 29 23 general questions and discussion to help\-texinfo@gnu.org. 30 24 Texinfo home page: http://www.gnu.org/software/texinfo/ 31 25 .SH COPYRIGHT 32 Copyright \(co 2004 Free Software Foundation, Inc. 33 There is NO warranty. You may redistribute this software 26 Copyright \(co 2005 Free Software Foundation, Inc. 27 There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A 28 PARTICULAR PURPOSE. You may redistribute copies of GNU texinfo 34 29 under the terms of the GNU General Public License. 35 For more information about these matters, see the file snamed COPYING.30 For more information about these matters, see the file named COPYING. 36 31 .SH "SEE ALSO" 37 32 The full documentation for 38 33 .B texindex -
texinfo-4.8/util/texindex.c
old new 1 1 /* texindex -- sort TeX index dribble output into an actual index. 2 $Id: texindex.c,v 1.1 1 2004/04/11 17:56:47karl Exp $2 $Id: texindex.c,v 1.19 2007/02/22 00:24:19 karl Exp $ 3 3 4 4 Copyright (C) 1987, 1991, 1992, 1996, 1997, 1998, 1999, 2000, 2001, 5 2002, 2003, 2004 Free Software Foundation, Inc.5 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 6 6 7 7 This program is free software; you can redistribute it and/or modify 8 8 it under the terms of the GNU General Public License as published by … … 16 16 17 17 You should have received a copy of the GNU General Public License 18 18 along with this program; if not, write to the Free Software 19 Foundation, Inc., 5 9 Temple Place - Suite 330, Boston, MA 02111-1307. */19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301. */ 20 20 21 21 #include "system.h" 22 22 #include <getopt.h> 23 23 24 staticchar *program_name = "texindex";24 char *program_name = "texindex"; 25 25 26 26 #if defined (emacs) 27 27 # include "../src/config.h" … … 37 37 #define memset(ptr, ignore, count) bzero (ptr, count) 38 38 #endif 39 39 40 char *mktemp (char *);41 42 40 #if !defined (SEEK_SET) 43 41 # define SEEK_SET 0 44 42 # define SEEK_CUR 1 45 43 # define SEEK_END 2 46 44 #endif /* !SEEK_SET */ 47 45 48 struct linebuffer;49 50 46 /* When sorting in core, this structure describes one line 51 47 and the position and length of its first keyfield. */ 52 48 struct lineinfo … … 96 92 /* The allocated length of `linearray'. */ 97 93 long nlines; 98 94 99 /* Directory to use for temporary files. On Unix, it ends with a slash. */100 char *tempdir;101 102 /* Number of last temporary file. */103 int tempcount;104 105 /* Number of last temporary file already deleted.106 Temporary files are deleted by `flush_tempfiles' in order of creation. */107 int last_deleted_tempcount;108 109 95 /* During in-core sort, this points to the base of the data block 110 96 which contains all the lines of data. */ 111 97 char *text_base; … … 117 103 determine whether we need initials in the sorted form. */ 118 104 char first_initial; 119 105 120 /* Additional command switches .*/121 122 /* Nonzero means do not delete tempfiles -- for debugging. */123 int keep_tempfiles;124 125 106 /* Forward declarations of functions in this file. */ 126 107 void decode_command (int argc, char **argv); 127 108 void sort_in_core (char *infile, int total, char *outfile); 128 void sort_offline (char *infile, off_t total, char *outfile);129 109 char **parsefile (char *filename, char **nextline, char *data, long int size); 130 110 char *find_field (struct keyfield *keyfield, char *str, long int *lengthptr); 131 111 char *find_pos (char *str, int words, int chars, int ignore_blanks); … … 137 117 long int length1, long int pos1, char *start2, 138 118 long int length2, long int pos2); 139 119 int compare_full (const void *, const void *); 140 long readline (struct linebuffer *linebuffer, FILE *stream);141 int merge_files (char **infiles, int nfiles, char *outfile);142 int merge_direct (char **infiles, int nfiles, char *outfile);143 120 void pfatal_with_name (const char *name); 144 121 void fatal (const char *format, const char *arg); 145 122 void error (const char *format, const char *arg); 146 123 void *xmalloc (), *xrealloc (); 147 char *concat (char *s1, char *s2); 148 void flush_tempfiles (int to_count); 124 static char *concat3 (const char *, const char *, const char *); 149 125 150 #define MAX_IN_CORE_SORT 500000151 152 126 int 153 127 main (int argc, char **argv) 154 128 { 155 129 int i; 156 130 157 tempcount = 0;158 last_deleted_tempcount = 0;159 160 131 #ifdef HAVE_SETLOCALE 161 132 /* Set locale via LC_ALL. */ 162 133 setlocale (LC_ALL, ""); … … 220 191 221 192 outfile = outfiles[i]; 222 193 if (!outfile) 223 outfile = concat (infiles[i], "s");194 outfile = concat3 (infiles[i], "s", ""); 224 195 225 196 need_initials = 0; 226 197 first_initial = '\0'; 227 198 228 if (ptr < MAX_IN_CORE_SORT) 229 /* Sort a small amount of data. */ 230 sort_in_core (infiles[i], (int)ptr, outfile); 231 else 232 sort_offline (infiles[i], ptr, outfile); 199 if (ptr != (int)ptr) 200 { 201 fprintf (stderr, "%s: %s: file too large\n", program_name, 202 infiles[i]); 203 xexit (1); 204 } 205 sort_in_core (infiles[i], (int)ptr, outfile); 233 206 } 234 207 235 flush_tempfiles (tempcount);236 208 xexit (0); 237 209 return 0; /* Avoid bogus warnings. */ 238 210 } … … 250 222 TEXINDEX_OPTION texindex_options[] = { 251 223 { "--help", "-h", (int *)NULL, 0, (char *)NULL, 252 224 N_("display this help and exit") }, 253 { "--keep", "-k", &keep_tempfiles, 1, (char *)NULL,254 N_("keep temporary files around after processing") },255 { "--no-keep", 0, &keep_tempfiles, 0, (char *)NULL,256 N_("do not keep temporary files around after processing (default)") },257 225 { "--output", "-o", (int *)NULL, 0, "FILE", 258 226 N_("send output to FILE") }, 259 227 { "--version", (char *)NULL, (int *)NULL, 0, (char *)NULL, … … 308 276 char **ip; 309 277 char **op; 310 278 311 /* Store default values into parameter variables. */312 313 tempdir = getenv ("TMPDIR");314 if (tempdir == NULL)315 tempdir = getenv ("TEMP");316 if (tempdir == NULL)317 tempdir = getenv ("TMP");318 if (tempdir == NULL)319 tempdir = DEFAULT_TMPDIR;320 else321 tempdir = concat (tempdir, "/");322 323 keep_tempfiles = 0;324 325 279 /* Allocate ARGC input files, which must be enough. */ 326 280 327 281 infiles = (char **) xmalloc (argc * sizeof (char *)); … … 339 293 { 340 294 printf ("texindex (GNU %s) %s\n", PACKAGE, VERSION); 341 295 puts (""); 342 puts ("Copyright (C) 2004 Free Software Foundation, Inc."); 343 printf (_("There is NO warranty. You may redistribute this software\n\ 296 printf (_("\ 297 Copyright (C) %s Free Software Foundation, Inc.\n\ 298 There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n\ 299 PARTICULAR PURPOSE. You may redistribute copies of GNU %s\n\ 344 300 under the terms of the GNU General Public License.\n\ 345 For more information about these matters, see the files named COPYING.\n")); 301 For more information about these matters, see the file named COPYING.\n"), 302 "2005", PACKAGE); 346 303 xexit (0); 347 304 } 348 305 else if ((strcmp (arg, "--keep") == 0) || 349 306 (strcmp (arg, "-k") == 0)) 350 307 { 351 keep_tempfiles = 1; 308 /* Ignore, for backward compatibility */ 352 309 } 353 310 else if ((strcmp (arg, "--help") == 0) || 354 311 (strcmp (arg, "-h") == 0)) … … 384 341 usage (1); 385 342 } 386 343 387 /* Return a name for temporary file COUNT. */388 389 static char *390 maketempname (int count)391 {392 static char *tempbase = NULL;393 char tempsuffix[10];394 395 if (!tempbase)396 {397 int fd;398 tempbase = concat (tempdir, "txidxXXXXXX");399 400 fd = mkstemp (tempbase);401 if (fd == -1)402 pfatal_with_name (tempbase);403 }404 405 sprintf (tempsuffix, ".%d", count);406 return concat (tempbase, tempsuffix);407 }408 409 410 /* Delete all temporary files up to TO_COUNT. */411 412 void413 flush_tempfiles (int to_count)414 {415 if (keep_tempfiles)416 return;417 while (last_deleted_tempcount < to_count)418 unlink (maketempname (++last_deleted_tempcount));419 }420 421 422 344 /* Compare LINE1 and LINE2 according to the specified set of keyfields. */ 423 345 424 346 int … … 801 723 } 802 724 } 803 725 804 /* A `struct linebuffer' is a structure which holds a line of text.805 `readline' reads a line from a stream into a linebuffer806 and works regardless of the length of the line. */807 808 struct linebuffer809 {810 long size;811 char *buffer;812 };813 814 /* Initialize LINEBUFFER for use. */815 816 void817 initbuffer (struct linebuffer *linebuffer)818 {819 linebuffer->size = 200;820 linebuffer->buffer = (char *) xmalloc (200);821 }822 823 /* Read a line of text from STREAM into LINEBUFFER.824 Return the length of the line. */825 826 long827 readline (struct linebuffer *linebuffer, FILE *stream)828 {829 char *buffer = linebuffer->buffer;830 char *p = linebuffer->buffer;831 char *end = p + linebuffer->size;832 833 while (1)834 {835 int c = getc (stream);836 if (p == end)837 {838 buffer = (char *) xrealloc (buffer, linebuffer->size *= 2);839 p += buffer - linebuffer->buffer;840 end += buffer - linebuffer->buffer;841 linebuffer->buffer = buffer;842 }843 if (c < 0 || c == '\n')844 {845 *p = 0;846 break;847 }848 *p++ = c;849 }850 851 return p - buffer;852 }853 854 /* Sort an input file too big to sort in core. */855 856 void857 sort_offline (char *infile, off_t total, char *outfile)858 {859 /* More than enough. */860 int ntemps = 2 * (total + MAX_IN_CORE_SORT - 1) / MAX_IN_CORE_SORT;861 char **tempfiles = (char **) xmalloc (ntemps * sizeof (char *));862 FILE *istream = fopen (infile, "r");863 int i;864 struct linebuffer lb;865 long linelength;866 int failure = 0;867 868 initbuffer (&lb);869 870 /* Read in one line of input data. */871 872 linelength = readline (&lb, istream);873 874 if (lb.buffer[0] != '\\' && lb.buffer[0] != '@')875 {876 error (_("%s: not a texinfo index file"), infile);877 return;878 }879 880 /* Split up the input into `ntemps' temporary files, or maybe fewer,881 and put the new files' names into `tempfiles' */882 883 for (i = 0; i < ntemps; i++)884 {885 char *outname = maketempname (++tempcount);886 FILE *ostream = fopen (outname, "w");887 long tempsize = 0;888 889 if (!ostream)890 pfatal_with_name (outname);891 tempfiles[i] = outname;892 893 /* Copy lines into this temp file as long as it does not make file894 "too big" or until there are no more lines. */895 896 while (tempsize + linelength + 1 <= MAX_IN_CORE_SORT)897 {898 tempsize += linelength + 1;899 fputs (lb.buffer, ostream);900 putc ('\n', ostream);901 902 /* Read another line of input data. */903 904 linelength = readline (&lb, istream);905 if (!linelength && feof (istream))906 break;907 908 if (lb.buffer[0] != '\\' && lb.buffer[0] != '@')909 {910 error (_("%s: not a texinfo index file"), infile);911 failure = 1;912 goto fail;913 }914 }915 fclose (ostream);916 if (feof (istream))917 break;918 }919 920 free (lb.buffer);921 922 fail:923 /* Record number of temp files we actually needed. */924 925 ntemps = i;926 927 /* Sort each tempfile into another tempfile.928 Delete the first set of tempfiles and put the names of the second929 into `tempfiles'. */930 931 for (i = 0; i < ntemps; i++)932 {933 char *newtemp = maketempname (++tempcount);934 sort_in_core (tempfiles[i], MAX_IN_CORE_SORT, newtemp);935 if (!keep_tempfiles)936 unlink (tempfiles[i]);937 tempfiles[i] = newtemp;938 }939 940 if (failure)941 return;942 943 /* Merge the tempfiles together and indexify. */944 945 merge_files (tempfiles, ntemps, outfile);946 }947 948 726 /* Sort INFILE, whose size is TOTAL, 949 727 assuming that is small enough to be done in-core, 950 728 then indexify it and send the output to OUTFILE (or to stdout). */ … … 1348 1126 1349 1127 for (next_line = linearray; next_line != stop_line; next_line++) 1350 1128 { 1351 /* If -u was specified, output the line only if distinct from 1352 previous one. */ 1129 /* Output the line only if distinct from previous one. */ 1353 1130 if (next_line == linearray 1354 1131 /* Compare previous line with this one, using only the 1355 1132 explicitly specd keyfields. */ … … 1369 1146 finish_index (ostream); 1370 1147 } 1371 1148 1372 /* Assume (and optionally verify) that each input file is sorted;1373 merge them and output the result.1374 Returns nonzero if any input file fails to be sorted.1375 1376 This is the high-level interface that can handle an unlimited1377 number of files. */1378 1379 #define MAX_DIRECT_MERGE 101380 1381 int1382 merge_files (char **infiles, int nfiles, char *outfile)1383 {1384 char **tempfiles;1385 int ntemps;1386 int i;1387 int value = 0;1388 int start_tempcount = tempcount;1389 1390 if (nfiles <= MAX_DIRECT_MERGE)1391 return merge_direct (infiles, nfiles, outfile);1392 1393 /* Merge groups of MAX_DIRECT_MERGE input files at a time,1394 making a temporary file to hold each group's result. */1395 1396 ntemps = (nfiles + MAX_DIRECT_MERGE - 1) / MAX_DIRECT_MERGE;1397 tempfiles = (char **) xmalloc (ntemps * sizeof (char *));1398 for (i = 0; i < ntemps; i++)1399 {1400 int nf = MAX_DIRECT_MERGE;1401 if (i + 1 == ntemps)1402 nf = nfiles - i * MAX_DIRECT_MERGE;1403 tempfiles[i] = maketempname (++tempcount);1404 value |= merge_direct (&infiles[i * MAX_DIRECT_MERGE], nf, tempfiles[i]);1405 }1406 1407 /* All temporary files that existed before are no longer needed1408 since their contents have been merged into our new tempfiles.1409 So delete them. */1410 flush_tempfiles (start_tempcount);1411 1412 /* Now merge the temporary files we created. */1413 1414 merge_files (tempfiles, ntemps, outfile);1415 1416 free (tempfiles);1417 1418 return value;1419 }1420 1421 /* Assume (and optionally verify) that each input file is sorted;1422 merge them and output the result.1423 Returns nonzero if any input file fails to be sorted.1424 1425 This version of merging will not work if the number of1426 input files gets too high. Higher level functions1427 use it only with a bounded number of input files. */1428 1429 int1430 merge_direct (char **infiles, int nfiles, char *outfile)1431 {1432 struct linebuffer *lb1, *lb2;1433 struct linebuffer **thisline, **prevline;1434 FILE **streams;1435 int i;1436 int nleft;1437 int lossage = 0;1438 int *file_lossage;1439 struct linebuffer *prev_out = 0;1440 FILE *ostream = stdout;1441 1442 if (outfile)1443 {1444 ostream = fopen (outfile, "w");1445 }1446 if (!ostream)1447 pfatal_with_name (outfile);1448 1449 init_index ();1450 1451 if (nfiles == 0)1452 {1453 if (outfile)1454 fclose (ostream);1455 return 0;1456 }1457 1458 /* For each file, make two line buffers. Also, for each file, there1459 is an element of `thisline' which points at any time to one of the1460 file's two buffers, and an element of `prevline' which points to1461 the other buffer. `thisline' is supposed to point to the next1462 available line from the file, while `prevline' holds the last file1463 line used, which is remembered so that we can verify that the file1464 is properly sorted. */1465 1466 /* lb1 and lb2 contain one buffer each per file. */1467 lb1 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer));1468 lb2 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer));1469 1470 /* thisline[i] points to the linebuffer holding the next available1471 line in file i, or is zero if there are no lines left in that file. */1472 thisline = (struct linebuffer **)1473 xmalloc (nfiles * sizeof (struct linebuffer *));1474 /* prevline[i] points to the linebuffer holding the last used line1475 from file i. This is just for verifying that file i is properly1476 sorted. */1477 prevline = (struct linebuffer **)1478 xmalloc (nfiles * sizeof (struct linebuffer *));1479 /* streams[i] holds the input stream for file i. */1480 streams = (FILE **) xmalloc (nfiles * sizeof (FILE *));1481 /* file_lossage[i] is nonzero if we already know file i is not1482 properly sorted. */1483 file_lossage = (int *) xmalloc (nfiles * sizeof (int));1484 1485 /* Allocate and initialize all that storage. */1486 1487 for (i = 0; i < nfiles; i++)1488 {1489 initbuffer (&lb1[i]);1490 initbuffer (&lb2[i]);1491 thisline[i] = &lb1[i];1492 prevline[i] = &lb2[i];1493 file_lossage[i] = 0;1494 streams[i] = fopen (infiles[i], "r");1495 if (!streams[i])1496 pfatal_with_name (infiles[i]);1497 1498 readline (thisline[i], streams[i]);1499 }1500 1501 /* Keep count of number of files not at eof. */1502 nleft = nfiles;1503 1504 while (nleft)1505 {1506 struct linebuffer *best = 0;1507 struct linebuffer *exch;1508 int bestfile = -1;1509 int i;1510 1511 /* Look at the next avail line of each file; choose the least one. */1512 1513 for (i = 0; i < nfiles; i++)1514 {1515 if (thisline[i] &&1516 (!best ||1517 0 < compare_general (best->buffer, thisline[i]->buffer,1518 (long) bestfile, (long) i, num_keyfields)))1519 {1520 best = thisline[i];1521 bestfile = i;1522 }1523 }1524 1525 /* Output that line, unless it matches the previous one and we1526 don't want duplicates. */1527 1528 if (!(prev_out &&1529 !compare_general (prev_out->buffer,1530 best->buffer, 0L, 1L, num_keyfields - 1)))1531 indexify (best->buffer, ostream);1532 prev_out = best;1533 1534 /* Now make the line the previous of its file, and fetch a new1535 line from that file. */1536 1537 exch = prevline[bestfile];1538 prevline[bestfile] = thisline[bestfile];1539 thisline[bestfile] = exch;1540 1541 while (1)1542 {1543 /* If the file has no more, mark it empty. */1544 1545 if (feof (streams[bestfile]))1546 {1547 thisline[bestfile] = 0;1548 /* Update the number of files still not empty. */1549 nleft--;1550 break;1551 }1552 readline (thisline[bestfile], streams[bestfile]);1553 if (thisline[bestfile]->buffer[0] || !feof (streams[bestfile]))1554 break;1555 }1556 }1557 1558 finish_index (ostream);1559 1560 /* Free all storage and close all input streams. */1561 1562 for (i = 0; i < nfiles; i++)1563 {1564 fclose (streams[i]);1565 free (lb1[i].buffer);1566 free (lb2[i].buffer);1567 }1568 free (file_lossage);1569 free (lb1);1570 free (lb2);1571 free (thisline);1572 free (prevline);1573 free (streams);1574 1575 if (outfile)1576 fclose (ostream);1577 1578 return lossage;1579 }1580 1581 1149 /* Print error message and exit. */ 1582 1150 1583 1151 void … … 1612 1180 } 1613 1181 1614 1182 1615 /* Return a newly-allocated string concatenating S1 and S2. */1183 /* Return a newly-allocated string concatenating S1, S2, and S3. */ 1616 1184 1617 char *1618 concat (char *s1, char *s2)1185 static char * 1186 concat3 (const char *s1, const char *s2, const char *s3) 1619 1187 { 1620 int len1 = strlen (s1), len2 = strlen (s2) ;1621 char *result = (char *) xmalloc (len1 + len2 + 1);1188 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); 1189 char *result = (char *) xmalloc (len1 + len2 + len3 + 1); 1622 1190 1623 1191 strcpy (result, s1); 1624 1192 strcpy (result + len1, s2); 1625 *(result + len1 + len2) = 0; 1193 strcpy (result + len1 + len2, s3); 1194 *(result + len1 + len2 + len3) = 0; 1626 1195 1627 1196 return result; 1628 1197 }
Note: See TracBrowser for help on using the browser.
