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

📄 csplit.c

📁 国外网站上的一些精典的C程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Donated to public domain * * Designation:  CSplit * * Description:  This program is used to process source files for *               the purpose of transmission through a FidoNet (tm) *               echo in such a manner as to circumvent over-size *               message problems. * *  This program implements the following specifications: * *  1) a. Combine multiple source files. *     b. Split source into 90 line sections. *     c. Add header and trailer marker lines delimiting each *        section and file. *  2) a. Delete any trailing whitespace. *     b. Replace tabs with spaces honoring tabstop boundaries. *     c. Default to 4 columns per tabstop. *     d. Allow user to specify alternate tabstop column number. *  3) a. Wrap lines longer than 75 characters long using the C *        "\ at the end of a line" notation (using space break). *     b. Distinguish wrapped lines from user-continued lines by *        inserting a line with a single "\" character between the *        two lines that contain the wrapped text. *  4) a. Calculate a CRC for each section and include it in the *        section trailer marker lines. *  5) a. Provide a help display for program usage when the *        program is executed without parameters. *  6) a. Provide as detailed of explanation as possible when *        an unexpected condition occurs. *     b. Attempt to continue execution for all but the most severe *        errors. * * * Syntax: * * Split:     CSPLIT  [/tn] [/wn] [/ln] [/sc]  outfile  src.ext [ ... ] *|* Extract:   CSPLIT  /x  infile  [ ... ] * * Where:      /t n - For TAB character expansion, the number of columns *                    for each TAB stop.  (defaults to every 4 columns) *             /w n - For width control, the column number to be used for *                    breaking long lines.  (the default is column 75) *             /l n - For length control, the number of lines to limit|*                    each section or 0 for no split.  (default is 90) *             /s c - Use 'c' as an alternate line separator character *                    instead of the default separator character, '>'.|*                    Ignored for extraction - matches separator found|*                    in extract file.  However, the extract file must|*                    only use one separator character. *           infile - Input file name.  An extension indicates that the *                    file contains the sections in proper consecutive|*                    order ready for extraction.  Otherwise, infile.001,|*                    infile.002, etc., will be used.|*          outfile - Name of the output file(s).  The extension will|*                    be ignored if specified and each output file will|*                    be named such that the section number will be the|*                    extension (e.g., outfile.001, outfile.002, etc..) *          src.ext - The first source file..etc  Wildcard filespecs are *                    supported only under non-ANSI compiling conditions. *|* Notes:  Paths are supported for all filenames, however, the paths|*         are not preserved internally during the split operation.|*         The extraction process will therefore only create files in|*         the current directory. * * Revision History:  ( thanks to all the contributors ) * * 08/31/93  Fred Cole  Original draft * 09/05/93  Fred Cole  Added CRC calculation and extraction ability. *                      Fixed a line wrap problem. * 09/14/93  Fred Cole  Added conditional compilation directives to *                      allow non-ANSI filespec support.  Squashed an *                      extract() function bug. * 11/21/93  Thad Smith Test for incomplete input file on extraction. *                      Remove spaces added in message transmission. *                      Default to 90 lines/section.  Fix tab expansion. * 12/03/93  Fred Cole  Fixed a cleanup() function bug. * 12/09/93  Keith Campbell / TS *                      Fixed bug with options preceded by '-' and fixed *                      tempfile opening bug. * 01/02/94  David Nugent / FC *                      Additions for findfirst/findnext support for *                      MSC6 (& 7) and OS/2 in initlist() routine and *                      portable.h header file. * 01/02/94  Auke Reitsma / FC *                      Increased number of chars read in to prevent line *                      numbers from becoming out-of-sync with input. * 01/12/94  Chad Wagner / FC *                      Correction to initlist() function to eliminate *                      redundant line increment. *--- v2.0 -------------------------------------------------------------- * 07/23/94  Keith Campbell / FC *                      Modified to not abort extraction when a CRC *                      mismatch occurs - just issue warning message. * 07/30/94  Auke Reitsma / FC *                      Added multiple file extraction ability. * 09/17/94  Keith Campbell / FC *                      Added version separator lines. * 10/28/94  Bob Stout / FC *                      Added separator character, width and length *                      command line options. * 12/18/94  Fred Cole  Revised code to facilitate maintenance. * 12/27/94  Fred Cole  Limited the minimum width for breaking long *                      lines to column 55 since this is the length *                      of the longest separator line. * 01/15/95  David Gersic / FC *                      Modified the line wrap logic to handle long *                      sequences of characters lacking whitespace. *--- v2.1 -------------------------------------------------------------- * 10/30/95  Phi Nguyen / FC *                      Added file extraction messages. * 10/31/95  Fred Cole  Added ability to extract unconcatenated files. *                      Added path support except for extracted files *                      ( i.e., paths are not preserved internally ). * 11/06/95  Fred Cole  Corrected tabstop calculation on wrapped lines. * 11/07/95  Fred Cole  Increased max section length to SHRT_MAX lines. * 11/08/95  Bob Stout / FC *                      Disable the split logic when a 0 section length *                      is specified with the /L command line option. *--- v2.2 -------------------------------------------------------------- * 11/22/95  Fred Cole  Modified logic to ignore leading whitespace added *                      to separator lines ( mail reader quoting? ). * 11/22/95  Doug Nazar (DN2) / FC *                      Modified sscanf() format specifiers to correctly *                      convert CRC values for 32 bit platforms. * 11/22/95  Fred Cole  Changed TRUE/FALSE enum to macros to accommodate *                      systems where these identifiers already exist. * 11/29/95  Bob Stout / FC *                      Added unsigned casts to allow signed 'length' to *                      be compared to SHRT_MAX on 16-bit platforms. * 11/29/95  Doug Nazar (DN2) / FC *                      Added setbuf() statement to unbuffer stdout. * 06/02/96  Fred Cole  Renamed TRUE/FALSE macros to avoid possible *                      identifier conflicts. * 06/02/96  Darin McBride / FC *                      Modified logic to allow source files located on *                      on another drive to be processed.  This change *                      assumes that ':' is not a valid character for a *                      file name. * 06/02/96  Fred Cole  Corrected error in extract logic when file does *                      not exist. */#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>#include "csplit.h"char tempfile[MAXFSPEC + 1]; /* necessary evils - global variables */FILE *finp = NULL;FILE *fout = NULL;FILE *ftmp = NULL;SLST *head = NULL;SLST *cur  = NULL;int main (int argc, char *argv[]){  char     sepchar = SEP_CDEF;  char     outfile[MAXFSPEC + 1];  char    *sptr    = 0;  int      argndx  = 1;  int      chr     = 0;  int      extract = B_FALSE;  int      length  = LENDEF;  int      retc    = 0;  int      tabstop = TABDEF;  int      width   = WIDDEF;  setbuf (stdout, 0);                  /* DN2: buffered output fix */  printf ("\nCSplit %s  (pd) 1993-1996 by Fred Cole\n", VERSION);  printf ("This executable program is public domain.\n\n");  if (1 == argc)  {    disp_help ();    return SYNTAX;  }  while (('/' == argv[argndx][0]) || ('-' == argv[argndx][0]))  {    chr = toupper (argv[argndx][1]);    switch (chr)    {      case '?':      case 'H':                   /* /H,/? help option */        disp_help ();        return SYNTAX;      case 'X':                   /* /X extract option */        extract = B_TRUE;        break;      case 'T':                   /* /T tab option */        tabstop = atoi (&argv[argndx][2]);        if ((tabstop < TABMIN) || (tabstop > TABMAX))          printf ("Invalid tab parameter \"%s\" (%d-%d).\n", argv[argndx], TABMIN, TABMAX);        if (tabstop < TABMIN)          tabstop = TABMIN;        else if (tabstop > TABMAX)          tabstop = TABMAX;        break;      case 'W':                   /* /W width option */        width = atoi (&argv[argndx][2]);        if ((width < WIDMIN) || (width > WIDMAX))          printf ("Invalid width parameter \"%s\" (%d-%d).\n", argv[argndx], WIDMIN, WIDMAX);        if (width < WIDMIN)          width = WIDMIN;        else if (width > WIDMAX)          width = WIDMAX;        break;      case 'L':                   /* /L length option */        if (('0' == argv[argndx][2]) && ('\0' == argv[argndx][3]))          length = 0;        else        {          length = atoi (&argv[argndx][2]);          if ((length < LENMIN) || ((unsigned)length > LENMAX))            printf ("Invalid length parameter \"%s\" (0,%d-%d).\n", argv[argndx], LENMIN, LENMAX);          if (length < LENMIN)            length = LENDEF;          else if ((unsigned)length > LENMAX)            length = LENMAX;        }        break;      case 'S':                   /* /S separator character option */        sscanf (&argv[argndx][2], "%c", &sepchar);        if (0 == isgraph (sepchar))        {          printf ("Invalid input parameter \"%s\".\n", argv[argndx]);          sepchar = SEP_CDEF;        }        break;      default:        printf ("Ignoring unknown input parameter \"%s\".\n", argv[argndx]);    }    ++argndx;  }  if (B_TRUE == extract)  {    if (argndx == argc)    {      printf ("No file argument specified for extraction.\n");      return SYNTAX;    }    /* AR: handle multiple files; break on error */    for ( ; argndx < argc; ++argndx)      if (NOERR != (retc = extr_file (argv[argndx], sepchar)))        break;    cleanup ();    return retc;  }  if ((argc - argndx) < 2)  {    printf ("Missing input and/or output file name arguments.\n");    disp_help ();    return SYNTAX;  }  if (NULL != (sptr = strrchr (argv[argndx], '\\')))  /* ignore path */  {    if (NULL != (sptr = strchr (sptr, '.')))      *sptr = '\0';                              /* truncate any ext */  }  else if (NULL != (sptr = strchr (argv[argndx], '.')))  {    *sptr = '\0';                                /* truncate any ext */  }  if (strlen (argv[argndx]) > MAXFSPEC)  {    printf ("Output file name argument too long.\n");    return SYNTAX;  }  strncpy (outfile, argv[argndx], MAXFSPEC);  outfile[MAXFSPEC] = '\0';                      /* ensure termination */  if (NOERR != (retc = init_list (argc, argv, ++argndx)))  {    cleanup ();    return retc;  }  retc = split_src (head, outfile, length, width, tabstop, sepchar);  cleanup ();  return retc;}/* * add_list - Add a file name to linked list of files to be processed. */SLST *add_list (char *fname){  SLST *new = NULL;  if (NULL == (new = (SLST *)malloc (sizeof(SLST))))  {    puts ("Error allocating memory.\n");  }  else  {    strcpy (new->srcfile, fname);    new->next = NULL;    if (NULL == cur)      head = new;    else      cur->next = new;  }  cur = new;  return cur;}/* * cleanup - Just a convenient way to provide centralized housekeeping. */void cleanup (void){  free_list ();  if (NULL != finp)  fclose (finp);  if (NULL != fout)  fclose (fout);  if (NULL != ftmp)  fclose (ftmp);  /* Now, does it really exist? */  if (NULL != (ftmp = fopen (tempfile, "r")))  {    fclose (ftmp);    remove (tempfile);  }}/* * csp_fgets - A custom fgets() function that expands *             tabs, deletes trailing whitespace and *             performs line wrapping. */char *csp_fgets (char *s, int len, FILE * fp, int tabstop){  static char  sbuf[LLENMAX * 2]; /* big enough for TAB expansion */  static char *beg  = sbuf;  static int   tofs = 0;  static int   wrap = B_FALSE;  char *e = 0;  char *w = 0;  char *p = s;  char *q = 0;  int   ch     = 0;  int   cnt    = 0;  int   i      = 0;  int   spaces = 0;  if (B_TRUE == wrap)             /* if line wrap */  {    tofs += (int)(beg - sbuf);    /* adj. TAB column offset */    strcpy (s, "\\\n");    memmove (sbuf, beg, strlen (beg) + 1); /* DG: Modification for  */    beg  = sbuf;                           /* DG: long lines w/o WS */    wrap = B_FALSE;    return s;  }  while ((cnt < len-1) && ('\n' != ch))  {                                    /* get next char from buffer */    if (0 == (ch = *beg++))            /* if buffer empty */    {      memset (sbuf, 0, sizeof (sbuf));      beg = fgets (sbuf, LLENMAX, fp); /* grab another string */      if (NULL == beg)                 /* if end of file... */      {        beg = sbuf;        *beg = 0;        if (0 == cnt)          return NULL;                 /*  and buffer empty */      }      else      {        w = e = &sbuf[i = strlen (sbuf)]; /* find 1st trailing ws char */        while ((w > sbuf) && (isspace (*(w - 1))))          --w;        if (('\n' == *(e - 1)) || /* if terminated w/newline char */            (i < (len-1)))        /* or unterminated short line */        {          *w++ = '\n';            /* terminate with newline char */        }

⌨️ 快捷键说明

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