⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 texindex.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Prepare Tex index dribble output into an actual index.   Copyright (C) 1987 Free Software Foundation, Inc.    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 1, or (at your option)    any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. In other words, you are welcome to use, share and improve this program. You are forbidden to forbid anyone else to use, share and improve what you give them.   Help stamp out software-hoarding!  */#include <stdio.h>#include <ctype.h>#ifdef VMS#include <file.h>#define EXIT_SUCCESS ((1 << 28) | 1)#define EXIT_FATAL ((1 << 28) | 4)#define unlink delete#define tell(fd) lseek(fd, 0L, 1)#else#include <sys/file.h>#define EXIT_SUCCESS 0#define EXIT_FATAL 1#endif#ifndef L_XTND#define L_XTND 2#endif/* When sorting in core, this structure describes one line and the position and length of its first keyfield.  */struct lineinfo  {    char *text;		/* The actual text of the line */    union      {			/* The start of the key (for textual comparison) */	char *text;	long number;	/* or the numeric value (for numeric comparison) */      } key;    long keylen;	/* Length of key field */  };/* This structure describes a field to use as a sort key */struct keyfield  {    int startwords;		/* # words to skip  */    int startchars;		/*  and # additional chars to skip, to start of field */    int endwords;		/* similar, from beg (or end) of line, to find end of field */    int endchars;    char ignore_blanks;		/* Ignore spaces and tabs within the field */    char fold_case;		/* Convert upper case to lower before comparing */    char reverse;		/* Compare in reverse order */    char numeric;		/* Parse text as an integer and compare the integers */    char positional;		/* Sort according to position within the file */    char braced;		/* Count balanced-braced groupings as fields */  };/* Vector of keyfields to use */struct keyfield keyfields[3];/* Number of keyfields stored in that vector.  */int num_keyfields = 3;/* Vector of input file names, terminated with a zero (null pointer) */char **infiles;/* Vector of corresponding output file names, or zero meaning default it */char **outfiles;/* Length of `infiles' */int num_infiles;/* Pointer to the array of pointers to lines being sorted */char **linearray;/* The allocated length of `linearray'. */long lines;/* Directory to use for temporary files.  On Unix, it ends with a slash.  */char *tempdir;/* Start of filename to use for temporary files.  */char *tempbase;/* Number of last temporary file.  */int tempcount;/* Number of last temporary file already deleted. Temporary files are deleted by `flush_tempfiles' in order of creation.  */int last_deleted_tempcount;/* During in-core sort, this points to the base of the data block which contains all the lines of data.  */char *text_base;/* Additional command switches */int keep_tempfiles;	/* Nonzero means do not delete tempfiles -- for debugging *//* Forward declarations of functions in this file */void decode_command ();void sort_in_core ();void sort_offline ();char **parsefile ();char *find_field ();char *find_pos ();long find_value ();char *find_braced_pos ();char *find_braced_end ();void writelines ();int compare_full ();long readline ();int merge_files ();int merge_direct ();char *concat ();char *maketempname ();void flush_tempfiles ();char *tempcopy ();extern char *mktemp ();#define MAX_IN_CORE_SORT 500000intmain (argc, argv)     int argc;     char **argv;{  int i;  tempcount = 0;  last_deleted_tempcount = 0;  /* Describe the kind of sorting to do. */  /* The first keyfield uses the first braced field and folds case */  keyfields[0].braced = 1;  keyfields[0].fold_case = 1;  keyfields[0].endwords = -1;  keyfields[0].endchars = -1;  /* The second keyfield uses the second braced field, numerically */  keyfields[1].braced = 1;  keyfields[1].numeric = 1;  keyfields[1].startwords = 1;  keyfields[1].endwords = -1;  keyfields[1].endchars = -1;  /* The third keyfield (which is ignored while discarding duplicates)     compares the whole line */  keyfields[2].endwords = -1;  keyfields[2].endchars = -1;  decode_command (argc, argv);  tempbase = mktemp (concat ("txiXXXXXX", "", ""));  /* Process input files completely, one by one.  */  for (i = 0; i < num_infiles; i++)    {      int desc;      long ptr;      char *outfile;      char *p;      desc = open (infiles[i], 0, 0);      if (desc < 0) pfatal_with_name (infiles[i]);      lseek (desc, 0, L_XTND);      ptr = tell (desc);      close (desc);      outfile = outfiles[i];      if (!outfile)	{	  outfile = concat (infiles[i], "s", "");	}      if (ptr < MAX_IN_CORE_SORT)        /* Sort a small amount of data */        sort_in_core (infiles[i], ptr, outfile);      else        sort_offline (infiles[i], ptr, outfile);    }  flush_tempfiles (tempcount);  exit (EXIT_SUCCESS);}/* This page decodes the command line arguments to set the parameter variables and set up the vector of keyfields and the vector of input files */voiddecode_command (argc, argv)     int argc;     char **argv;{  int i;  char **ip;  char **op;  /* Store default values into parameter variables */#ifdef VMS  tempdir = "sys$scratch:";#else  tempdir = "/tmp/";#endif  keep_tempfiles = 0;  /* Allocate argc input files, which must be enough.  */  infiles = (char **) xmalloc (argc * sizeof (char *));  outfiles = (char **) xmalloc (argc * sizeof (char *));  ip = infiles;  op = outfiles;  /* First find all switches that control the default kind-of-sort */  for (i = 1; i < argc; i++)    {      int tem = classify_arg (argv[i]);      char c;      char *p;      if (tem <= 0)	{	  *ip++ = argv[i];	  *op++ = 0;	  continue;	}      if (tem > 1)	{	  if (i + 1 == argc)	    fatal ("switch %s given with no argument following it", argv[i]);	  else if (!strcmp (argv[i], "-T"))	    tempdir = argv[i + 1];	  else if (!strcmp (argv[i], "-o"))	    *(op - 1) = argv[i + 1];	  i += tem - 1;	  continue;	}      p = &argv[i][1];      while (c = *p++)	switch (c)	  {	  case 'k':	    keep_tempfiles = 1;	    break;	  default:	    fatal ("invalid command switch %c", c);	  }    switchdone: ;    }  /* Record number of keyfields, terminate list of filenames */  num_infiles = ip - infiles;  *ip = 0;}/* Return 0 for an argument that is not a switch; for a switch, return 1 plus the number of following arguments that the switch swallows.*/intclassify_arg (arg)     char *arg;{  if (!strcmp (arg, "-T") || !strcmp (arg, "-o"))    return 2;  if (arg[0] == '-')    return 1;  return 0;}/* Create a name for a temporary file */char *maketempname (count)     int count;{  char tempsuffix[10];  sprintf (tempsuffix, "%d", count);  return concat (tempdir, tempbase, tempsuffix);}/* Delete all temporary files up to the specified count */voidflush_tempfiles (to_count)     int to_count;{  if (keep_tempfiles) return;  while (last_deleted_tempcount < to_count)    unlink (maketempname (++last_deleted_tempcount));}/* Copy an input file into a temporary file, and return the temporary file name */#define BUFSIZE 1024char *tempcopy (idesc)     int idesc;{  char *outfile = maketempname (++tempcount);  int odesc;  char buffer[BUFSIZE];  odesc = open (outfile, O_WRONLY | O_CREAT, 0666);  if (odesc < 0) pfatal_with_name (outfile);  while (1)    {      int nread = read (idesc, buffer, BUFSIZE);      write (odesc, buffer, nread);      if (!nread) break;    }  close (odesc);  return outfile;}/* Compare two lines, provided as pointers to pointers to text, according to the specified set of keyfields */intcompare_full (line1, line2)     char **line1, **line2;{  int i;  /* Compare using the first keyfield;     if that does not distinguish the lines, try the second keyfield; and so on. */  for (i = 0; i < num_keyfields; i++)    {      long length1, length2;      char *start1 = find_field (&keyfields[i], *line1, &length1);      char *start2 = find_field (&keyfields[i], *line2, &length2);      int tem = compare_field (&keyfields[i], start1, length1, *line1 - text_base,					      start2, length2, *line2 - text_base);      if (tem)	{	  if (keyfields[i].reverse)	    return - tem;          return tem;	}    }  return 0;    /* Lines match exactly */}/* Compare two lines described by structures in which the first keyfield is identified in advance. For positional sorting, assumes that the order of the lines in core reflects their nominal order.  */intcompare_prepared (line1, line2)     struct lineinfo *line1, *line2;{  int i;  int tem;  char *text1, *text2;  /* Compare using the first keyfield, which has been found for us already */  if (keyfields->positional)    {      if (line1->text - text_base > line2->text - text_base)	tem = 1;      else	tem = -1;    }  else if (keyfields->numeric)    tem = line1->key.number - line2->key.number;  else    tem = compare_field (keyfields, line1->key.text, line1->keylen, 0, line2->key.text, line2->keylen, 0);  if (tem)    {      if (keyfields->reverse)	return - tem;      return tem;    }  text1 = line1->text;  text2 = line2->text;  /* Compare using the second keyfield;     if that does not distinguish the lines, try the third keyfield; and so on. */  for (i = 1; i < num_keyfields; i++)    {      long length1, length2;      char *start1 = find_field (&keyfields[i], text1, &length1);      char *start2 = find_field (&keyfields[i], text2, &length2);      int tem = compare_field (&keyfields[i], start1, length1, text1 - text_base,					      start2, length2, text2 - text_base);      if (tem)	{	  if (keyfields[i].reverse)	    return - tem;          return tem;	}    }  return 0;    /* Lines match exactly */}/* Like compare_full but more general. You can pass any strings, and you can say how many keyfields to use. `pos1' and `pos2' should indicate the nominal positional ordering of the two lines in the input.  */intcompare_general (str1, str2, pos1, pos2, use_keyfields)     char *str1, *str2;     long pos1, pos2;     int use_keyfields;{  int i;  /* Compare using the first keyfield;     if that does not distinguish the lines, try the second keyfield; and so on. */  for (i = 0; i < use_keyfields; i++)    {      long length1, length2;      char *start1 = find_field (&keyfields[i], str1, &length1);      char *start2 = find_field (&keyfields[i], str2, &length2);      int tem = compare_field (&keyfields[i], start1, length1, pos1, start2, length2, pos2);      if (tem)	{	  if (keyfields[i].reverse)	    return - tem;          return tem;	}    }  return 0;    /* Lines match exactly */}/* Find the start and length of a field in `str' according to `keyfield'. A pointer to the starting character is returned, and the length is stored into the int that `lengthptr' points to.  */char *find_field (keyfield, str, lengthptr)     struct keyfield *keyfield;     char *str;     long *lengthptr;{  char *start;  char *end;  char *(*fun) ();  if (keyfield->braced) fun = find_braced_pos;  else fun = find_pos;  start = ( *fun )(str, keyfield->startwords, keyfield->startchars,	       keyfield->ignore_blanks);  if (keyfield->endwords < 0)    {      if (keyfield->braced)	end = find_braced_end (start);      else	{	  end = start;	  while (*end && *end != '\n') end++;	}    }  else    {      end = ( *fun )(str, keyfield->endwords, keyfield->endchars, 0);      if (end - str < start - str) end = start;    }  *lengthptr = end - start;  return start;}/* Find a pointer to a specified place within `str', skipping (from the beginning) `words' words and then `chars' chars. If `ignore_blanks' is nonzero, we skip all blanks after finding the specified word.  */char *find_pos (str, words, chars, ignore_blanks)     char *str;     int words, chars;     int ignore_blanks;{  int i;  char *p = str;  for (i = 0; i < words; i++)    {      char c;      /* Find next bunch of nonblanks and skip them. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -