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

📄 texindex.c

📁 linux下bash的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Prepare TeX index dribble output into an actual index.   Version 1.45   Copyright (C) 1987, 1991, 1992 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 2, 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. */#include <stdio.h>#include <ctype.h>#include <errno.h>#include "getopt.h"#include "bashansi.h"#if !defined (errno)extern int errno;#endif#if defined (HAVE_UNISTD_H)#  include <unistd.h>#else /* !HAVE_UNISTD_H */extern long lseek ();#endif /* !HAVE_UNISTD_H */extern char *mktemp ();#if !defined (HAVE_STRERROR)extern int sys_nerr;extern char *sys_errlist[];#endif#include <sys/types.h>#if defined (_AIX) || !defined (_POSIX_VERSION)#  include <sys/file.h>#endif#include <fcntl.h>#define TI_NO_ERROR 0#define TI_FATAL_ERROR 1#if !defined (SEEK_SET)#  define SEEK_SET 0#  define SEEK_CUR 1#  define SEEK_END 2#endif /* !SEEK_SET *//* 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 {    char *text;		/* The start of the key (for textual comparison). */    long number;	/* 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;	/* Number of words to skip. */  int startchars;	/* Number of additional chars to skip. */  int endwords;		/* Number of words to ignore at end. */  int endchars;		/* Ditto for characters of last word. */  char ignore_blanks;	/* Non-zero means ignore spaces and tabs. */  char fold_case;	/* Non-zero means case doesn't matter. */  char reverse;		/* Non-zero means compare in reverse order. */  char numeric;		/* Non-zeros means field is ASCII numeric. */  char positional;	/* Sort according to file position. */  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 null pointer. */char **infiles;/* Vector of corresponding output file names, or NULL, meaning default it   (add an `s' to the end). */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 nlines;/* 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 .*//* Nonzero means do not delete tempfiles -- for debugging. */int keep_tempfiles;/* The name this program was run with. */char *program_name;/* 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_field ();int compare_full ();long readline ();int merge_files ();int merge_direct ();void pfatal_with_name ();void fatal ();void error ();void *xmalloc (), *xrealloc ();char *concat ();char *maketempname ();void flush_tempfiles ();char *tempcopy ();#define MAX_IN_CORE_SORT 500000voidmain (argc, argv)     int argc;     char **argv;{  int i;  tempcount = 0;  last_deleted_tempcount = 0;  program_name = argv[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;      desc = open (infiles[i], O_RDONLY, 0);      if (desc < 0)	pfatal_with_name (infiles[i]);      lseek (desc, 0L, SEEK_END);      ptr = lseek (desc, 0L, SEEK_CUR);      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 (TI_NO_ERROR);}voidusage (){  fprintf (stderr, "\Usage: %s [-k] infile [-o outfile] ...\n", program_name);  exit (1);}/* Decode 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 optc;  char **ip;  char **op;  /* Store default values into parameter variables. */  tempdir = getenv ("TMPDIR");  if (tempdir == NULL)    tempdir = "/tmp/";  else    tempdir = concat (tempdir, "/", "");  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;  while ((optc = getopt (argc, argv, "-ko:")) != EOF)    {      switch (optc)	{	case 1:		/* Non-option filename. */	  *ip++ = optarg;	  *op++ = NULL;	  break;	case 'k':	  keep_tempfiles = 1;	  break;	case 'o':	  if (op > outfiles)	    *(op - 1) = optarg;	  break;	default:	  usage ();	}    }  /* Record number of keyfields and terminate list of filenames. */  num_infiles = ip - infiles;  *ip = 0;  if (num_infiles == 0)    usage ();}/* Return 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 TO_COUNT. */voidflush_tempfiles (to_count)     int to_count;{  if (keep_tempfiles)    return;  while (last_deleted_tempcount < to_count)    unlink (maketempname (++last_deleted_tempcount));}/* Copy the input file open on IDESC 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 LINE1 and LINE2 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 LINE1 and LINE2, 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;}/* Return 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. */      while ((c = *p) == ' ' || c == '\t')	p++;      while ((c = *p) && c != '\n' && !(c == ' ' || c == '\t'))	p++;      if (!*p || *p == '\n')	return p;    }  while (*p == ' ' || *p == '\t')    p++;  for (i = 0; i < chars; i++)    {      if (!*p || *p == '\n')	break;      p++;    }  return p;}/* Like find_pos but assumes that each field is surrounded by braces   and that braces within fields are balanced. */

⌨️ 快捷键说明

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