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

📄 sort.c

📁 代码检索工具GLOBAL源码。可用来浏览分析LINUX源码。
💻 C
📖 第 1 页 / 共 4 页
字号:
      i = n_temp_files;      for (node = temphead.next; i > 0; node = node->next)	tempfiles[--i] = node->name;      merge (tempfiles, n_temp_files, ofp, output_file);      free ((char *) tempfiles);    }}/* Insert key KEY at the end of the list (`keyhead'). */static voidinsertkey (struct keyfield *key){  struct keyfield *k = &keyhead;  while (k->next)    k = k->next;  k->next = key;  key->next = NULL;}static voidbadfieldspec (const char *s){  error (SORT_FAILURE, 0, _("invalid field specification `%s'"), s);}/* Handle interrupts and hangups. */static voidsighandler (int sig){#ifdef SA_INTERRUPT  struct sigaction sigact;  sigact.sa_handler = SIG_DFL;  sigemptyset (&sigact.sa_mask);  sigact.sa_flags = 0;  sigaction (sig, &sigact, NULL);#else				/* !SA_INTERRUPT */  signal (sig, SIG_DFL);#endif				/* SA_INTERRUPT */  cleanup ();#ifdef __MINGW32__  raise (sig);#else  kill (getpid (), sig);#endif}/* Set the ordering options for KEY specified in S.   Return the address of the first character in S that   is not a valid ordering option.   BLANKTYPE is the kind of blanks that 'b' should skip. */static char *set_ordering (register const char *s, struct keyfield *key,	      enum blanktype blanktype){  while (*s)    {      switch (*s)	{	case 'b':	  if (blanktype == bl_start || blanktype == bl_both)	    key->skipsblanks = 1;	  if (blanktype == bl_end || blanktype == bl_both)	    key->skipeblanks = 1;	  break;	case 'd':	  key->ignore = nondictionary;	  break;	case 'f':	  key->translate = fold_toupper;	  break;	case 'g':	  key->general_numeric = 1;	  break;	case 'i':	  key->ignore = nonprinting;	  break;	case 'M':	  key->month = 1;	  break;	case 'n':	  key->numeric = 1;	  break;	case 'r':	  key->reverse = 1;	  break;	default:	  return (char *) s;	}      ++s;    }  return (char *) s;}static voidkey_init (struct keyfield *key){  memset (key, 0, sizeof (*key));  key->eword = -1;}intmain (int argc, char **argv){  struct keyfield *key = NULL, gkey;  char *s;  int i, t, t2;  int checkonly = 0, mergeonly = 0, nfiles = 0;  char *minus = "-", *outfile = minus, **files, *tmp;  FILE *ofp;#ifdef SA_INTERRUPT  struct sigaction oldact, newact;#endif				/* SA_INTERRUPT */  program_name = argv[0];  setlocale (LC_ALL, "");  bindtextdomain (PACKAGE, LOCALEDIR);  textdomain (PACKAGE);#ifdef ENABLE_NLS  hard_LC_COLLATE = hard_locale (LC_COLLATE);  hard_LC_CTYPE = hard_locale (LC_CTYPE);# if HAVE_NL_LANGINFO  hard_LC_TIME = hard_locale (LC_TIME);# endif  /* Let's get locale's representation of the decimal point */  {    struct lconv *lconvp = localeconv ();    /* If the locale doesn't define a decimal point, or if the decimal       point is multibyte, use the C decimal point.  We don't support       multibyte decimal points yet.  */    decimal_point = *lconvp->decimal_point;    if (! decimal_point || lconvp->decimal_point[1])      decimal_point = C_DECIMAL_POINT;    /* We don't support multibyte thousands separators yet.  */    th_sep = *lconvp->thousands_sep;    if (! th_sep || lconvp->thousands_sep[1])      th_sep = CHAR_MAX + 1;  }#endif /* NLS */  parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,		      AUTHORS, usage);  have_read_stdin = 0;  inittables ();  temp_dir = getenv ("TMPDIR");  if (temp_dir == NULL)    temp_dir = DEFAULT_TMPDIR;  /* Change the way xmalloc and xrealloc fail.  */  xalloc_exit_failure = SORT_FAILURE;  xalloc_fail_func = cleanup;#ifdef SA_INTERRUPT  newact.sa_handler = sighandler;  sigemptyset (&newact.sa_mask);  newact.sa_flags = 0;  sigaction (SIGINT, NULL, &oldact);  if (oldact.sa_handler != SIG_IGN)    sigaction (SIGINT, &newact, NULL);  sigaction (SIGHUP, NULL, &oldact);  if (oldact.sa_handler != SIG_IGN)    sigaction (SIGHUP, &newact, NULL);  sigaction (SIGPIPE, NULL, &oldact);  if (oldact.sa_handler != SIG_IGN)    sigaction (SIGPIPE, &newact, NULL);  sigaction (SIGTERM, NULL, &oldact);  if (oldact.sa_handler != SIG_IGN)    sigaction (SIGTERM, &newact, NULL);#else				/* !SA_INTERRUPT */  if (signal (SIGINT, SIG_IGN) != SIG_IGN)    signal (SIGINT, sighandler);#ifdef SIGHUP  if (signal (SIGHUP, SIG_IGN) != SIG_IGN)    signal (SIGHUP, sighandler);#endif#ifdef SIGPIPE  if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)    signal (SIGPIPE, sighandler);#endif  if (signal (SIGTERM, SIG_IGN) != SIG_IGN)    signal (SIGTERM, sighandler);#endif				/* !SA_INTERRUPT */  gkey.sword = gkey.eword = -1;  gkey.ignore = NULL;  gkey.translate = NULL;  gkey.numeric = gkey.general_numeric = gkey.month = gkey.reverse = 0;  gkey.skipsblanks = gkey.skipeblanks = 0;  files = (char **) xmalloc (sizeof (char *) * argc);  for (i = 1; i < argc; ++i)    {      if (argv[i][0] == '+')	{	  if (key)	    insertkey (key);	  key = (struct keyfield *) xmalloc (sizeof (struct keyfield));	  key_init (key);	  s = argv[i] + 1;	  if (! (ISDIGIT (*s) || (*s == '.' && ISDIGIT (s[1]))))	    badfieldspec (argv[i]);	  for (t = 0; ISDIGIT (*s); ++s)	    t = 10 * t + *s - '0';	  t2 = 0;	  if (*s == '.')	    for (++s; ISDIGIT (*s); ++s)	      t2 = 10 * t2 + *s - '0';	  if (t2 || t)	    {	      key->sword = t;	      key->schar = t2;	    }	  else	    key->sword = -1;	  s = set_ordering (s, key, bl_start);	  if (*s)	    badfieldspec (argv[i]);	}      else if (argv[i][0] == '-' && argv[i][1])	{	  s = argv[i] + 1;	  if (ISDIGIT (*s) || (*s == '.' && ISDIGIT (s[1])))	    {	      if (!key)		{		  /* Provoke with `sort -9'.  */		  error (0, 0, _("when using the old-style +POS and -POS \key specifiers,\nthe +POS specifier must come first"));		  usage (SORT_FAILURE);		}	      for (t = 0; ISDIGIT (*s); ++s)		t = t * 10 + *s - '0';	      t2 = 0;	      if (*s == '.')		for (++s; ISDIGIT (*s); ++s)		  t2 = t2 * 10 + *s - '0';	      key->eword = t;	      key->echar = t2;	      s = set_ordering (s, key, bl_end);	      if (*s)		badfieldspec (argv[i]);	      insertkey (key);	      key = NULL;	    }	  else	    while (*s)	      {		s = set_ordering (s, &gkey, bl_both);		switch (*s)		  {		  case '\0':		    break;		  case 'c':		    checkonly = 1;		    break;		  case 'k':		    if (s[1])		      ++s;		    else		      {			if (i == argc - 1)			  error (SORT_FAILURE, 0,				 _("option `-k' requires an argument"));			else			  s = argv[++i];		      }		    if (key)		      insertkey (key);		    key = (struct keyfield *)		      xmalloc (sizeof (struct keyfield));		    key_init (key);		    /* Get POS1. */		    if (!ISDIGIT (*s))		      badfieldspec (argv[i]);		    for (t = 0; ISDIGIT (*s); ++s)		      t = 10 * t + *s - '0';		    if (t == 0)		      {			/* Provoke with `sort -k0' */			error (0, 0, _("the starting field number argument \to the `-k' option must be positive"));			badfieldspec (argv[i]);		      }		    --t;		    t2 = 0;		    if (*s == '.')		      {			if (!ISDIGIT (s[1]))			  {			    /* Provoke with `sort -k1.' */			    error (0, 0, _("starting field spec has `.' but \lacks following character offset"));			    badfieldspec (argv[i]);			  }			for (++s; ISDIGIT (*s); ++s)			  t2 = 10 * t2 + *s - '0';			if (t2 == 0)			  {			    /* Provoke with `sort -k1.0' */			    error (0, 0, _("starting field character offset \argument to the `-k' option\nmust be positive"));			    badfieldspec (argv[i]);			  }			--t2;		      }		    if (t2 || t)		      {			key->sword = t;			key->schar = t2;		      }		    else		      key->sword = -1;		    s = set_ordering (s, key, bl_start);		    if (*s == 0)		      {			key->eword = -1;			key->echar = 0;		      }		    else if (*s != ',')		      badfieldspec (argv[i]);		    else if (*s == ',')		      {			/* Skip over comma.  */			++s;			if (*s == 0)			  {			    /* Provoke with `sort -k1,' */			    error (0, 0, _("field specification has `,' but \lacks following field spec"));			    badfieldspec (argv[i]);			  }			/* Get POS2. */			for (t = 0; ISDIGIT (*s); ++s)			  t = t * 10 + *s - '0';			if (t == 0)			  {			    /* Provoke with `sort -k1,0' */			    error (0, 0, _("ending field number argument \to the `-k' option must be positive"));			    badfieldspec (argv[i]);			  }			--t;			t2 = 0;			if (*s == '.')			  {			    if (!ISDIGIT (s[1]))			      {				/* Provoke with `sort -k1,1.' */				error (0, 0, _("ending field spec has `.' \but lacks following character offset"));				badfieldspec (argv[i]);			      }			    for (++s; ISDIGIT (*s); ++s)			      t2 = t2 * 10 + *s - '0';			  }			else			  {			    /* `-k 2,3' is equivalent to `+1 -3'.  */			    ++t;			  }			key->eword = t;			key->echar = t2;			s = set_ordering (s, key, bl_end);			if (*s)			  badfieldspec (argv[i]);		      }		    insertkey (key);		    key = NULL;		    goto outer;		  case 'm':		    mergeonly = 1;		    break;		  case 'o':		    if (s[1])		      outfile = s + 1;		    else		      {			if (i == argc - 1)			  error (SORT_FAILURE, 0,				 _("option `-o' requires an argument"));			else			  outfile = argv[++i];		      }		    goto outer;		  case 's':		    stable = 1;		    break;		  case 't':		    if (s[1])		      tab = *++s;		    else if (i < argc - 1)		      {			tab = *argv[++i];			goto outer;		      }		    else		      error (SORT_FAILURE, 0,			     _("option `-t' requires an argument"));		    break;		  case 'T':		    if (s[1])		      temp_dir = ++s;		    else		      {			if (i < argc - 1)			  temp_dir = argv[++i];			else			  error (SORT_FAILURE, 0,				 _("option `-T' requires an argument"));		      }		    goto outer;		    /* break; */		  case 'u':		    unique = 1;		    break;		  case 'z':		    eolchar = 0;		    break;		  case 'y':		    /* Accept and ignore e.g. -y0 for compatibility with		       Solaris 2.  */		    goto outer;		  default:		    fprintf (stderr, _("%s: unrecognized option `-%c'\n"),			     argv[0], *s);		    usage (SORT_FAILURE);		  }		if (*s)		  ++s;	      }	}      else			/* Not an option. */	{	  files[nfiles++] = argv[i];	}    outer:;    }  if (key)    insertkey (key);  /* Inheritance of global options to individual keys. */  for (key = keyhead.next; key; key = key->next)    if (!key->ignore && !key->translate && !key->skipsblanks && !key->reverse	&& !key->skipeblanks && !key->month && !key->numeric        && !key->general_numeric)      {	key->ignore = gkey.ignore;	key->translate = gkey.translate;	key->skipsblanks = gkey.skipsblanks;	key->skipeblanks = gkey.skipeblanks;	key->month = gkey.month;	key->numeric = gkey.numeric;	key->general_numeric = gkey.general_numeric;	key->reverse = gkey.reverse;      }  if (!keyhead.next && (gkey.ignore || gkey.translate || gkey.skipsblanks			|| gkey.skipeblanks || gkey.month || gkey.numeric                        || gkey.general_numeric))    insertkey (&gkey);  reverse = gkey.reverse;  if (nfiles == 0)    {      nfiles = 1;      files = &minus;    }  if (checkonly)    {      /* POSIX requires that sort return 1 IFF invoked with -c and the	 input is not properly sorted.  */      exit (check (files, nfiles) == 0 ? 0 : 1);    }  if (!STREQ (outfile, "-"))    {      struct stat outstat;      if (stat (outfile, &outstat) == 0)	{	  /* The following code prevents a race condition when	     people use the brain dead shell programming idiom:		  cat file | sort -o file	     This feature is provided for historical compatibility,	     but we strongly discourage ever relying on this in	     new shell programs. */	  /* Temporarily copy each input file that might be another name	     for the output file.  When in doubt (e.g. a pipe), copy.  */	  for (i = 0; i < nfiles; ++i)	    {	      char buf[8192];	      FILE *in_fp;	      FILE *out_fp;	      int cc;	      if (S_ISREG (outstat.st_mode) && !STREQ (outfile, files[i]))		{		  struct stat instat;		  if ((STREQ (files[i], "-")		       ? fstat (STDIN_FILENO, &instat)		       : stat (files[i], &instat)) != 0)		    {		      error (0, errno, "%s", files[i]);		      cleanup ();		      exit (SORT_FAILURE);		    }		  if (S_ISREG (instat.st_mode) && !SAME_INODE (instat, outstat))		    {		      /* We know the files are distinct.  */		      continue;		    }		}	      in_fp = xfopen (files[i], "r");	      tmp = tempname ();	      out_fp = xtmpfopen (tmp);	      /* FIXME: maybe use copy.c(copy) here. */	      while ((cc = fread (buf, 1, sizeof buf, in_fp)) > 0)		write_bytes (buf, cc, out_fp, tmp);	      if (ferror (in_fp))		{		  error (0, errno, "%s", files[i]);		  cleanup ();		  exit (SORT_FAILURE);		}	      xfclose (out_fp);	      xfclose (in_fp);	      files[i] = tmp;	    }	  ofp = xfopen (outfile, "w");	}      else	{	  /* A non-`-' outfile was specified, but the file doesn't yet exist.	     Before opening it for writing (thus creating it), make sure all	     of the input files exist.  Otherwise, creating the output file	     could create an otherwise missing input file, making sort succeed	     when it should fail.  */	  for (i = 0; i < nfiles; ++i)	    {	      struct stat sb;	      if (STREQ (files[i], "-"))		continue;	      if (stat (files[i], &sb))		{		  error (0, errno, "%s", files[i]);		  cleanup ();		  exit (SORT_FAILURE);		}	    }	  ofp = xfopen (outfile, "w");	}    }  else    {      ofp = stdout;    }  if (mergeonly)    merge (files, nfiles, ofp, outfile);  else    sort (files, nfiles, ofp, outfile);  cleanup ();  /* If we wait for the implicit flush on exit, and the parent process     has closed stdout (e.g., exec >&- in a shell), then the output file     winds up empty.  I don't understand why.  This is under SunOS,     Solaris, Ultrix, and Irix.  This premature fflush makes the output     reappear. --karl@cs.umb.edu  */  if (fflush (ofp) < 0)    error (SORT_FAILURE, errno, _("%s: write error"), outfile);  if (have_read_stdin && fclose (stdin) == EOF)    error (SORT_FAILURE, errno, "%s", outfile);  if (ferror (stdout) || fclose (stdout) == EOF)    error (SORT_FAILURE, errno, _("%s: write error"), outfile);  exit (EXIT_SUCCESS);}

⌨️ 快捷键说明

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