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

📄 texindex.c

📁 linux下bash的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
     char *s;     int n;{  register char *p;  for (p = s; n--; )    *p++ = '\0';}voidinit_index (){  pending = 0;  lastinitial = lastinitial1;  lastinitial1[0] = 0;  lastinitial1[1] = 0;  lastinitiallength = 0;  lastprimarylength = 100;  lastprimary = (char *) xmalloc (lastprimarylength + 1);  xbzero (lastprimary, lastprimarylength + 1);  lastsecondarylength = 100;  lastsecondary = (char *) xmalloc (lastsecondarylength + 1);  xbzero (lastsecondary, lastsecondarylength + 1);}/* Indexify.  Merge entries for the same name,   insert headers for each initial character, etc.  */voidindexify (line, ostream)     char *line;     FILE *ostream;{  char *primary, *secondary, *pagenumber;  int primarylength, secondarylength = 0, pagelength;  int nosecondary;  int initiallength;  char *initial;  char initial1[2];  register char *p;  /* First, analyze the parts of the entry fed to us this time. */  p = find_braced_pos (line, 0, 0, 0);  if (*p == '{')    {      initial = p;      /* Get length of inner pair of braces starting at `p',	 including that inner pair of braces.  */      initiallength = find_braced_end (p + 1) + 1 - p;    }  else    {      initial = initial1;      initial1[0] = *p;      initial1[1] = 0;      initiallength = 1;      if (initial1[0] >= 'a' && initial1[0] <= 'z')	initial1[0] -= 040;    }  pagenumber = find_braced_pos (line, 1, 0, 0);  pagelength = find_braced_end (pagenumber) - pagenumber;  if (pagelength == 0)    abort ();  primary = find_braced_pos (line, 2, 0, 0);  primarylength = find_braced_end (primary) - primary;  secondary = find_braced_pos (line, 3, 0, 0);  nosecondary = !*secondary;  if (!nosecondary)    secondarylength = find_braced_end (secondary) - secondary;  /* If the primary is different from before, make a new primary entry. */  if (strncmp (primary, lastprimary, primarylength))    {      /* Close off current secondary entry first, if one is open. */      if (pending)	{	  fputs ("}\n", ostream);	  pending = 0;	}      /* If this primary has a different initial, include an entry for	 the initial. */      if (initiallength != lastinitiallength ||	  strncmp (initial, lastinitial, initiallength))	{	  fprintf (ostream, "\\initial {");	  fwrite (initial, 1, initiallength, ostream);	  fprintf (ostream, "}\n", initial);	  if (initial == initial1)	    {	      lastinitial = lastinitial1;	      *lastinitial1 = *initial1;	    }	  else	    {	      lastinitial = initial;	    }	  lastinitiallength = initiallength;	}      /* Make the entry for the primary.  */      if (nosecondary)	fputs ("\\entry {", ostream);      else	fputs ("\\primary {", ostream);      fwrite (primary, primarylength, 1, ostream);      if (nosecondary)	{	  fputs ("}{", ostream);	  pending = 1;	}      else	fputs ("}\n", ostream);      /* Record name of most recent primary. */      if (lastprimarylength < primarylength)	{	  lastprimarylength = primarylength + 100;	  lastprimary = (char *) xrealloc (lastprimary,					   1 + lastprimarylength);	}      strncpy (lastprimary, primary, primarylength);      lastprimary[primarylength] = 0;      /* There is no current secondary within this primary, now. */      lastsecondary[0] = 0;    }  /* Should not have an entry with no subtopic following one with a subtopic. */  if (nosecondary && *lastsecondary)    error ("entry %s follows an entry with a secondary name", line);  /* Start a new secondary entry if necessary. */  if (!nosecondary && strncmp (secondary, lastsecondary, secondarylength))    {      if (pending)	{	  fputs ("}\n", ostream);	  pending = 0;	}      /* Write the entry for the secondary.  */      fputs ("\\secondary {", ostream);      fwrite (secondary, secondarylength, 1, ostream);      fputs ("}{", ostream);      pending = 1;      /* Record name of most recent secondary. */      if (lastsecondarylength < secondarylength)	{	  lastsecondarylength = secondarylength + 100;	  lastsecondary = (char *) xrealloc (lastsecondary,					     1 + lastsecondarylength);	}      strncpy (lastsecondary, secondary, secondarylength);      lastsecondary[secondarylength] = 0;    }  /* Here to add one more page number to the current entry. */  if (pending++ != 1)    fputs (", ", ostream);	/* Punctuate first, if this is not the first. */  fwrite (pagenumber, pagelength, 1, ostream);}/* Close out any unfinished output entry. */voidfinish_index (ostream)     FILE *ostream;{  if (pending)    fputs ("}\n", ostream);  free (lastprimary);  free (lastsecondary);}/* Copy the lines in the sorted order.   Each line is copied out of the input file it was found in. */voidwritelines (linearray, nlines, ostream)     char **linearray;     int nlines;     FILE *ostream;{  char **stop_line = linearray + nlines;  char **next_line;  init_index ();  /* Output the text of the lines, and free the buffer space. */  for (next_line = linearray; next_line != stop_line; next_line++)    {      /* If -u was specified, output the line only if distinct from previous one.  */      if (next_line == linearray      /* Compare previous line with this one, using only the         explicitly specd keyfields. */	  || compare_general (*(next_line - 1), *next_line, 0L, 0L, num_keyfields - 1))	{	  char *p = *next_line;	  char c;	  while ((c = *p++) && c != '\n')	    /* Do nothing. */ ;	  *(p - 1) = 0;	  indexify (*next_line, ostream);	}    }  finish_index (ostream);}/* Assume (and optionally verify) that each input file is sorted;   merge them and output the result.   Returns nonzero if any input file fails to be sorted.   This is the high-level interface that can handle an unlimited   number of files.  */#define MAX_DIRECT_MERGE 10intmerge_files (infiles, nfiles, outfile)     char **infiles;     int nfiles;     char *outfile;{  char **tempfiles;  int ntemps;  int i;  int value = 0;  int start_tempcount = tempcount;  if (nfiles <= MAX_DIRECT_MERGE)    return merge_direct (infiles, nfiles, outfile);  /* Merge groups of MAX_DIRECT_MERGE input files at a time,     making a temporary file to hold each group's result.  */  ntemps = (nfiles + MAX_DIRECT_MERGE - 1) / MAX_DIRECT_MERGE;  tempfiles = (char **) xmalloc (ntemps * sizeof (char *));  for (i = 0; i < ntemps; i++)    {      int nf = MAX_DIRECT_MERGE;      if (i + 1 == ntemps)	nf = nfiles - i * MAX_DIRECT_MERGE;      tempfiles[i] = maketempname (++tempcount);      value |= merge_direct (&infiles[i * MAX_DIRECT_MERGE], nf, tempfiles[i]);    }  /* All temporary files that existed before are no longer needed     since their contents have been merged into our new tempfiles.     So delete them.  */  flush_tempfiles (start_tempcount);  /* Now merge the temporary files we created.  */  merge_files (tempfiles, ntemps, outfile);  free (tempfiles);  return value;}/* Assume (and optionally verify) that each input file is sorted;   merge them and output the result.   Returns nonzero if any input file fails to be sorted.   This version of merging will not work if the number of   input files gets too high.  Higher level functions   use it only with a bounded number of input files.  */intmerge_direct (infiles, nfiles, outfile)     char **infiles;     int nfiles;     char *outfile;{  struct linebuffer *lb1, *lb2;  struct linebuffer **thisline, **prevline;  FILE **streams;  int i;  int nleft;  int lossage = 0;  int *file_lossage;  struct linebuffer *prev_out = 0;  FILE *ostream = stdout;  if (outfile)    {      ostream = fopen (outfile, "w");    }  if (!ostream)    pfatal_with_name (outfile);  init_index ();  if (nfiles == 0)    {      if (outfile)	fclose (ostream);      return 0;    }  /* For each file, make two line buffers.     Also, for each file, there is an element of `thisline'     which points at any time to one of the file's two buffers,     and an element of `prevline' which points to the other buffer.     `thisline' is supposed to point to the next available line from the file,     while `prevline' holds the last file line used,     which is remembered so that we can verify that the file is properly sorted. */  /* lb1 and lb2 contain one buffer each per file. */  lb1 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer));  lb2 = (struct linebuffer *) xmalloc (nfiles * sizeof (struct linebuffer));  /* thisline[i] points to the linebuffer holding the next available line in file i,     or is zero if there are no lines left in that file.  */  thisline = (struct linebuffer **)    xmalloc (nfiles * sizeof (struct linebuffer *));  /* prevline[i] points to the linebuffer holding the last used line     from file i.  This is just for verifying that file i is properly     sorted.  */  prevline = (struct linebuffer **)    xmalloc (nfiles * sizeof (struct linebuffer *));  /* streams[i] holds the input stream for file i.  */  streams = (FILE **) xmalloc (nfiles * sizeof (FILE *));  /* file_lossage[i] is nonzero if we already know file i is not     properly sorted.  */  file_lossage = (int *) xmalloc (nfiles * sizeof (int));  /* Allocate and initialize all that storage. */  for (i = 0; i < nfiles; i++)    {      initbuffer (&lb1[i]);      initbuffer (&lb2[i]);      thisline[i] = &lb1[i];      prevline[i] = &lb2[i];      file_lossage[i] = 0;      streams[i] = fopen (infiles[i], "r");      if (!streams[i])	pfatal_with_name (infiles[i]);      readline (thisline[i], streams[i]);    }  /* Keep count of number of files not at eof. */  nleft = nfiles;  while (nleft)    {      struct linebuffer *best = 0;      struct linebuffer *exch;      int bestfile = -1;      int i;      /* Look at the next avail line of each file; choose the least one.  */      for (i = 0; i < nfiles; i++)	{	  if (thisline[i] &&	      (!best ||	       0 < compare_general (best->buffer, thisline[i]->buffer,				 (long) bestfile, (long) i, num_keyfields)))	    {	      best = thisline[i];	      bestfile = i;	    }	}      /* Output that line, unless it matches the previous one and we	 don't want duplicates. */      if (!(prev_out &&	    !compare_general (prev_out->buffer,			      best->buffer, 0L, 1L, num_keyfields - 1)))	indexify (best->buffer, ostream);      prev_out = best;      /* Now make the line the previous of its file, and fetch a new	 line from that file.  */      exch = prevline[bestfile];      prevline[bestfile] = thisline[bestfile];      thisline[bestfile] = exch;      while (1)	{	  /* If the file has no more, mark it empty. */	  if (feof (streams[bestfile]))	    {	      thisline[bestfile] = 0;	      /* Update the number of files still not empty. */	      nleft--;	      break;	    }	  readline (thisline[bestfile], streams[bestfile]);	  if (thisline[bestfile]->buffer[0] || !feof (streams[bestfile]))	    break;	}    }  finish_index (ostream);  /* Free all storage and close all input streams. */  for (i = 0; i < nfiles; i++)    {      fclose (streams[i]);      free (lb1[i].buffer);      free (lb2[i].buffer);    }  free (file_lossage);  free (lb1);  free (lb2);  free (thisline);  free (prevline);  free (streams);  if (outfile)    fclose (ostream);  return lossage;}/* Print error message and exit.  */voidfatal (s1, s2)     char *s1, *s2;{  error (s1, s2);  exit (TI_FATAL_ERROR);}/* Print error message.  S1 is printf control string, S2 is arg for it. */voiderror (s1, s2)     char *s1, *s2;{  printf ("%s: ", program_name);  printf (s1, s2);  printf ("\n");}#if !defined (HAVE_STRERROR)static char *strerror (n)     int n;{  static char ebuf[40];  if (n < sys_nerr)    return sys_errlist[n];  else    {      sprintf (ebuf, "Unknown error %d", n);      return ebuf;    }}#endifvoidperror_with_name (name)     char *name;{  char *s;  s = concat ("", strerror (errno), " for %s");  error (s, name);}voidpfatal_with_name (name)     char *name;{  char *s;  s = concat ("", strerror (errno), " for %s");  fatal (s, name);}/* Return a newly-allocated string whose contents concatenate those of   S1, S2, S3.  */char *concat (s1, s2, s3)     char *s1, *s2, *s3;{  int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);  char *result = (char *) xmalloc (len1 + len2 + len3 + 1);  strcpy (result, s1);  strcpy (result + len1, s2);  strcpy (result + len1 + len2, s3);  *(result + len1 + len2 + len3) = 0;  return result;}/* Just like malloc, but kills the program in case of fatal error. */void *xmalloc (nbytes)     int nbytes;{  void *temp = (void *) malloc (nbytes);  if (nbytes && temp == (void *)NULL)    memory_error ("xmalloc", nbytes);  return (temp);}/* Like realloc (), but barfs if there isn't enough memory. */void *xrealloc (pointer, nbytes)     void *pointer;     int nbytes;{  void *temp;  if (!pointer)    temp = (void *)xmalloc (nbytes);  else    temp = (void *)realloc (pointer, nbytes);  if (nbytes && !temp)    memory_error ("xrealloc", nbytes);  return (temp);}memory_error (callers_name, bytes_wanted)     char *callers_name;     int bytes_wanted;{  char printable_string[80];  sprintf (printable_string,	   "Virtual memory exhausted in %s ()!  Needed %d bytes.",	   callers_name, bytes_wanted);  error (printable_string, "");  abort ();}

⌨️ 快捷键说明

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