home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / deskutils / _a_l / boota / C-source / c / UnNum < prev   
Encoding:
Text File  |  1993-03-03  |  21.9 KB  |  579 lines

  1. /* > c.UnNum  - (c) Paul Witheridge - Version 2.01 - 03 Mar 1993     */
  2.  
  3. /*===================================================================*/
  4. /*                                                                   */
  5. /*  UnNum  -  unnumber file                                          */
  6. /*  ------                                                           */
  7. /*                                                                   */
  8. /*  This utility removes line numbers from a file.                   */
  9. /*                                                                   */
  10. /*  If the file is fixed-blocked with a line length of 80 bytes,     */
  11. /*  then columns 73-80 are assumed to be the columns occuppied by    */
  12. /*  the line sequence number.                                        */
  13. /*                                                                   */
  14. /*  If the file is not fixed-blocked with a line length of 80 bytes, */
  15. /*  then the line sequence number is assumed to occuppy columns      */
  16. /*  1-8 of each line.                                                */
  17. /*                                                                   */
  18. /*  The utility checks that all lines are numbered (and that the     */
  19. /*  last line does end with a newline character). If not error       */
  20. /*  messages are issued. If so, the columns containing the line      */
  21. /*  sequence characters are deleted from the file. Any trailing      */
  22. /*  blanks in each line are also deleted.                            */
  23. /*                                                                   */
  24. /*-------------------------------------------------------------------*/
  25. /*                                                                   */
  26. /*  COPYRIGHT NOTICE                                                 */
  27. /*                                                                   */
  28. /*  UnNum is subject to Copyright.                                   */
  29. /*                                                                   */
  30. /*  Permission is granted by the author to any recipient of this     */
  31. /*  material to use and make/disseminate copies of the application   */
  32. /*  provided that no charges are made for doing so (other than to    */
  33. /*  cover any cost of media or postage) and that this notice is      */
  34. /*  included with all copies.                                        */
  35. /*                                                                   */
  36. /*===================================================================*/
  37.  
  38. #include "kernel.h"                     /* ARC specifics             */
  39. #include <ctype.h>                      /* Character handling        */
  40. #include <limits.h>                     /* Implementation limits     */
  41. #include <stddef.h>                     /* Standard definitions      */
  42. #include <stdio.h>                      /* Input/output              */
  43. #include <stdlib.h>                     /* General utilities         */
  44. #include <string.h>                     /* String handling           */
  45. #include "Beep.h"                       /* Beep header               */
  46. #include "GetDirs.h"                    /* GetDirs header            */
  47. #include "ArgFuncs.h"                   /* Arg functions etc         */
  48. #include "Useful.h"                     /* Useful definitions        */
  49.  
  50. /*-------------------------------------------------------------------*/
  51. /*  Global data declarations and definitions.                        */
  52. /*-------------------------------------------------------------------*/
  53.  
  54. static unsigned char flags = '\0' ;     /* Processing flags          */
  55.  
  56.   #define flgfnd 0x01                   /* Found file to process     */
  57.   #define flgovr 0x10                   /* Overwrite mode            */
  58.   #define flgrcs 0x20                   /* Recursive mode            */
  59.   #define flgtst 0x40                   /* Test mode                 */
  60.  
  61. static int filecount = 0 ;              /* Count of files processed. */
  62.  
  63. static const char *argptr = NULL ;      /* Pointer to file spec.     */
  64. static const char *pfxptr = "_" ;       /* Pointer to output prefix  */
  65.  
  66. /*-------------------------------------------------------------------*/
  67. /*  Declare functions local in scope to this file.                   */
  68. /*-------------------------------------------------------------------*/
  69.  
  70. static enum boolean cnvtfunc(           /* Convert function          */
  71.   const char *path,
  72.   direntry *ptr) ;
  73.  
  74. /*===================================================================*/
  75. /*                                                                   */
  76. /*  Main program                                                     */
  77. /*  ------------                                                     */
  78. /*                                                                   */
  79. /*  Analyse arguments. Then call the "GetDirentrys" function to      */
  80. /*  read all the file-names in the specified directory (plus any     */
  81. /*  sub directories). Provide "GetDirentrys" with pointer to         */
  82. /*  function to process the specified files.                         */
  83. /*                                                                   */
  84. /*===================================================================*/
  85.  
  86. int main(
  87.   const int argc,                     /* Number of arguments         */
  88.   const char *argv[])                 /* Array of pointers to args   */
  89. {
  90.   /*-----------------------------------------------------------------*/
  91.   /*  Local definitions.                                             */
  92.   /*-----------------------------------------------------------------*/
  93.  
  94.   int returncode ;
  95.  
  96.   static const char options[] =  /* Used to match option argument    */
  97.   {
  98.     'O',                            /* Overwrite mode                */
  99.     'P',                            /* Output prefix                 */
  100.     'R',                            /* Recursive mode                */
  101.     'T',                            /* Test mode                     */
  102.     '0'                             /* Null byte terminator          */
  103.   } ;
  104.  
  105.   static const char **posval[] = /* Ptrs to ptrs to posit'nal values */ 
  106.   {
  107.     &argptr
  108.   } ;
  109.   static const char **(*posargs)[] = &posval ; /* Ptr to array       */
  110.  
  111.   static const unsigned char optflags[] = /* Used to set option flgs */
  112.   {
  113.     flgovr,                         /* Overwrite mode                */
  114.     0,                              /* Output prefix                 */
  115.     flgrcs,                         /* Recursive mode                */
  116.     flgtst,                         /* Test mode                     */
  117.   } ;
  118.  
  119.   static const char **optval[] = /* Ptrs to ptrs to option values    */
  120.   {
  121.     NULL,                           /* No value allowed              */
  122.     &pfxptr,                        /* Output file prefix            */
  123.     NULL,                           /* No value allowed              */
  124.     NULL,                           /* No value allowed              */
  125.   } ;
  126.  
  127.   static const char helpdata[] = /* Help text to be displayed        */
  128.  
  129.     "Unnum removes line-numbers from cols 73-80 of card-image "
  130.     "text files or from cols 1-8 of other text files (i.e. "
  131.     "files with standard IBM S/370 line sequence numbers).\x1f"
  132.     "\x1f"
  133.     "WARNING:\x01This utility converts files IN-PLACE if the "
  134.     "'-o' option is used to replace the input text "
  135.     "file with the output unnumbered file.\x1f"
  136.     "\x1f"
  137.     "Syntax:\x01*Unnum  [path.]object  [options]\x1f"
  138.     "\x1f"
  139.     "object:\x01Specifies one of the following:\x1f"
  140.     "\x01(a) a single non-wildcarded file name\x1f"
  141.     "\x01(b) a single non-wildcarded directory name\x1f"
  142.     "\x01(c) a wildcarded name.\x1f"
  143.     "\x1f"
  144.     "\x01In case (a) the file is unnumbered provided "
  145.     "that it has a file-type of TEXT, contains no "
  146.     "unprintable characters and has decimal digits "
  147.     "in the correct sequence number columns.\x1f"
  148.     "\x1f"
  149.     "\x01In case (b) all files in the specified "
  150.     "directory which meet the above conditions are "
  151.     "unnumbered. If the RECURSION option is specified "
  152.     "all files in all subdirectories are also "
  153.     "unnumbered.\x1f"
  154.     "\x1f"
  155.     "\x01In case (c) all matching files which meet the "
  156.     "above conditions are unnumbered. If no matching "
  157.     "files are found, then the first matching "
  158.     "directory name is taken and all eligible files "
  159.     "therein are unnumbered. If the RECURSION option "
  160.     "is specified, all matching files are unnumbered, "
  161.     "plus all files in all subdirectories.\x1f"
  162.     "\x1f"
  163.     "\x01In all cases, only files which have a filetype "
  164.     "of TEXT (hex FFF), which contain no unprintable "
  165.     "characters (except newline - hex 0A) and which "
  166.     "contain valid decimal digits in the correct "
  167.     "sequence number columns, will be unnumbered.\x1f"
  168.     "\x1f"
  169.     "path:\x01Specifies the directory to be searched for "
  170.     "the object file/directory. If omitted the current "
  171.     "directory is searched.\x1f"
  172.     "\x1f"
  173.     "options:\x01Specifies processing options which can be "
  174.     "one or more ofthe following:\x1f"
  175.     "\x1f"
  176.     "\x01-o\x02-\x03OVERWRITE mode; output file will have "
  177.     "same name and will replace input file.\x1f"
  178.     "\x1f"
  179.     "\x01-p xxx\x02-\x03specify PREFIX which will be used to "
  180.     "create name for output file if '-o' is not specified; "
  181.     "'xxx' can be one or more characters including directory "
  182.     "specification (e.g. 'unnumdir.'); if not specified a "
  183.     "default of '_' is used.\x1f"
  184.     "\x1f"
  185.     "\x01-r\x02-\x03RECURSION mode which causes all eligible "
  186.     "files in all subdirectories to be unnumbered.\x1f"
  187.     "\x1f"
  188.     "\x01-t\x02-\x03TEST mode; a list of files to be converted "
  189.     "is displayed but no output is actually written; useful for "
  190.     "checking when specifying a directory or wildcarded filename.\x1f"
  191.     "\x1f"
  192.     "UnNum - copyright Paul Witheridge, 1993\x1f"
  193.     "\x1f" ;
  194.  
  195.   static const unsigned char helptabs[] =  /* Help text tab settings */
  196.   {
  197.     1,10,17,19
  198.   } ;
  199.  
  200.   /*-----------------------------------------------------------------*/
  201.   /*  Executable statements                                          */
  202.   /*-----------------------------------------------------------------*/
  203.  
  204.   puts("\nUnnum Version 2.01 - 03 March 1993\n") ;
  205.  
  206.   /*-----------------------------------------------------------------*/
  207.   /*  Analyse arguments for file-name and option flags.              */
  208.   /*-----------------------------------------------------------------*/
  209.  
  210.   analargs(argc,argv,1,&posargs,options,&flags,optflags,optval) ;
  211.  
  212.   /*-----------------------------------------------------------------*/
  213.   /*  Set paged scrolling mode                                       */
  214.   /*-----------------------------------------------------------------*/
  215.  
  216.   _kernel_oswrch(12) ;
  217.   _kernel_oswrch(14) ;
  218.  
  219.   puts(" PRESS SHIFT KEY TO ALLOW WINDOW TO SCROLL\n") ;
  220.   
  221.   /*-----------------------------------------------------------------*/
  222.   /*  If no file name operand just display help text.                */
  223.   /*-----------------------------------------------------------------*/
  224.  
  225.   if ( argptr == NULL )
  226.   {
  227.     displaytext(helpdata,helptabs) ;
  228.     _kernel_oswrch(15) ;
  229.     return 0 ;
  230.   }
  231.  
  232.   /*-----------------------------------------------------------------*/
  233.   /*  If TEST MODE issue message.                                    */
  234.   /*-----------------------------------------------------------------*/
  235.  
  236.   if ( flags & flgtst )
  237.   {
  238.     puts("TEST MODE (files will be identified, not converted).\n") ;
  239.   }
  240.  
  241.   /*-----------------------------------------------------------------*/
  242.   /*  Invoke GetDirs function to read the directory entry(s) of the  */
  243.   /*  file(s) to be processed. Pass it a pointer of a processing     */
  244.   /*  function to be called.                                         */
  245.   /*-----------------------------------------------------------------*/
  246.  
  247.   returncode = 4 ;
  248.  
  249.   if ( getdirentrys(argptr,
  250.        ( flags & flgrcs ? RECURSE_ALWAYS : RECURSE_ONCE ),cnvtfunc) )
  251.   {
  252.     if ( flags & flgfnd )
  253.     {
  254.       printf("\n%d text file(s) ",filecount) ;
  255.       if ( flags & flgtst )
  256.       {
  257.         printf("would be ") ;
  258.       }
  259.       puts("unnumbered.\n") ;
  260.       returncode = 0 ;
  261.     }
  262.     else
  263.     {
  264.       printf("No text files found matching '%s'\n",argptr) ;
  265.       beep() ;
  266.     }
  267.   }
  268.   
  269.   /*-----------------------------------------------------------------*/
  270.   /*  Return to caller. All done.                                    */
  271.   /*-----------------------------------------------------------------*/
  272.  
  273.   _kernel_oswrch(15) ;
  274.   return returncode ;
  275. }
  276.  
  277. /*===================================================================*/
  278. /*                                                                   */
  279. /*  cnvtfunc  -  perform actual file conversion                      */
  280. /*  --------                                                         */
  281. /*                                                                   */
  282. /*  This function is called by the "getdirentrys" function for each  */
  283. /*  file-name that it encounters.                                    */
  284. /*                                                                   */
  285. /*  Only files which have a filetype of "text" (0xFFF) will be       */
  286. /*  processed.                                                       */
  287. /*                                                                   */
  288. /*===================================================================*/
  289.  
  290. static enum boolean cnvtfunc(
  291.   const char *path,                   /* Pointer to path name.       */
  292.   direntry *ptr)                      /* Pointer to direntry info.   */
  293. {
  294.   char *infile ;                      /* Ptr to path + leafname      */
  295.   char *oufile ;                      /* Ptr tp path + leafname      */
  296.   int result ;                        /* Result from OS-File SWI     */
  297.   enum boolean cardimage ;            /* Cardimage format switch     */
  298.   char *workarea ;                    /* Ptr to start of work area   */
  299.   char *workend ;                     /* Ptr to end of work area     */
  300.   char *lineptr ;                     /* Working ptr to line start   */
  301.   char *endlineptr ;                  /* Working ptr to line end     */
  302.   char *cptr ;                        /* Working ptr to next char    */
  303.   char *optr ;                        /* Ptr to next output char     */
  304.  
  305.   _kernel_osfile_block osfileblock ;  /* OS File parameter block     */
  306.  
  307.   /*-----------------------------------------------------------------*/
  308.   /*  Executable statements                                          */
  309.   /*                                                                 */
  310.   /*  Return immediately if not a text file                          */
  311.   /*-----------------------------------------------------------------*/
  312.  
  313.   if ( ptr->type != 0xFFF )
  314.   {
  315.     return TRUE ;
  316.   }
  317.  
  318.   /*-----------------------------------------------------------------*/
  319.   /*  Create input and output filespecs                              */
  320.   /*-----------------------------------------------------------------*/
  321.   
  322.   if ( ( infile = malloc(2 * (strlen(path) + strlen(ptr->name) + 1)
  323.                          + strlen(pfxptr) ) ) == NULL )
  324.   {
  325.     puts("Out of memory") ;
  326.     return FALSE ;
  327.   } 
  328.   
  329.   oufile = infile + sprintf(infile,"%s%s",path,ptr->name) + 1 ;
  330.   sprintf(oufile,"%s%s%s",path,flags & flgovr ? "" : pfxptr,ptr->name) ;
  331.   
  332.   /*-----------------------------------------------------------------*/
  333.   /*  If test mode display heading on first time through             */
  334.   /*-----------------------------------------------------------------*/
  335.  
  336.   if ( (flags & flgtst) && !(flags & flgfnd) )
  337.   {
  338.     puts("The following files would be unnumbered:\n") ;
  339.   }
  340.  
  341.   flags |= flgfnd ;
  342.  
  343.   /*-----------------------------------------------------------------*/
  344.   /*  Check input file has non-zero length                           */
  345.   /*-----------------------------------------------------------------*/
  346.  
  347.   if ( ptr->length == 0 )
  348.   {
  349.     printf("'%s' is empty\n",infile) ;
  350.   }
  351.  
  352.   /*-----------------------------------------------------------------*/
  353.   /*  Allocate memory for file and load file                         */
  354.   /*-----------------------------------------------------------------*/
  355.  
  356.   if ( (workarea = malloc((ptr->length)+1) ) == NULL )
  357.   {
  358.     printf("'%s%s' too large to load",path,ptr->name) ;
  359.     goto error4 ;
  360.   }
  361.  
  362.   workend = workarea + ptr->length ;
  363.  
  364.   osfileblock.load  = (int)workarea ;
  365.   osfileblock.exec  = 0 ;
  366.   result = _kernel_osfile(16,infile,&osfileblock) ;
  367.  
  368.   if (result == _kernel_ERROR)
  369.   {
  370.     printf("'%s' load failed - %s\n",infile,
  371.           _kernel_last_oserror()->errmess) ;
  372.     goto error3 ;
  373.   }
  374.  
  375.   /*-----------------------------------------------------------------*/
  376.   /*  If file contains any CRLF combinations convert these to        */
  377.   /*  Archimedes newline characters (linefeed only)                  */
  378.   /*-----------------------------------------------------------------*/
  379.  
  380.   *workend = 0 ;
  381.  
  382.   for ( cptr = optr = workarea ; cptr < workend ; cptr++, optr++ )
  383.   {
  384.     if ( *cptr == 0x1A )
  385.     {
  386.       break ;
  387.     }
  388.     if ( *cptr == 0x0d && *(cptr+1) == 0x0A )
  389.     {
  390.       cptr++;
  391.     }
  392.     *optr = *cptr ;
  393.   }
  394.  
  395.   workend = optr ;
  396.   
  397.   /*-----------------------------------------------------------------*/
  398.   /*  Check for fixed-blocked 80 byte lines (cardimage file)         */
  399.   /*-----------------------------------------------------------------*/
  400.  
  401.   *workend = '\n' ;
  402.   lineptr = workarea ;
  403.   cardimage = TRUE ;
  404.  
  405.   while ( lineptr < workend )
  406.   {
  407.     endlineptr = memchr(lineptr,'\n',INT_MAX) ;
  408.     if ( endlineptr - lineptr != 80 )
  409.     {
  410.       cardimage = FALSE ;
  411.     }
  412.     lineptr = endlineptr + 1 ;
  413.   }
  414.  
  415.   /*-----------------------------------------------------------------*/
  416.   /*  Error message if no newline at end of file                     */
  417.   /*-----------------------------------------------------------------*/
  418.  
  419.   if ( lineptr != workend )
  420.   {
  421.     printf("'%s' not valid text file - "
  422.            "does not end with newline character\n",infile) ;
  423.     goto noconversion ;
  424.   }
  425.  
  426.   /*-----------------------------------------------------------------*/
  427.   /*  Process cardimage file - delete cols 73-80 & trailing blanks   */
  428.   /*-----------------------------------------------------------------*/
  429.  
  430.   optr = workarea ;
  431.  
  432.   if ( cardimage )
  433.   {
  434.     for ( lineptr = workarea ;
  435.           lineptr < workend ;
  436.           lineptr = endlineptr + 1 )
  437.     {
  438.       endlineptr = lineptr + 72 ;
  439.       for ( cptr = lineptr ; cptr < endlineptr ; cptr++ )
  440.       {
  441.         if ( !isprint(*cptr) )
  442.         {
  443.           printf("'%s' not valid text file - "
  444.                  "contains unprintable characters\n",
  445.                  infile) ;
  446.           goto noconversion ;
  447.         }
  448.       }
  449.       endlineptr = lineptr + 80 ;
  450.       for ( ; cptr < endlineptr ; cptr++ )
  451.       {
  452.         if ( !isdigit(*cptr) )
  453.         {
  454.           printf("'%s' not numbered file (cols 73-80)\n",
  455.                  infile) ;
  456.           goto noconversion ;
  457.         }
  458.       }
  459.       for ( cptr = lineptr + 71 ;
  460.             cptr >= lineptr && *cptr == ' ' ;
  461.             cptr-- ) ;
  462.       for ( ; lineptr <= cptr ; lineptr++ )
  463.       {
  464.         *(optr++) = *lineptr ;
  465.       }
  466.       *(optr++) = '\n' ;
  467.     }
  468.   }
  469.  
  470.   /*-----------------------------------------------------------------*/
  471.   /*  Process non-cardimage file. Delete cols 1-8 plus any           */
  472.   /*  trailing blanks                                                */
  473.   /*-----------------------------------------------------------------*/
  474.  
  475.   else
  476.   {
  477.     lineptr = workarea ;
  478.  
  479.     while ( lineptr < workend )
  480.     {
  481.       endlineptr = lineptr + 8 ;
  482.       for ( cptr = lineptr ;
  483.             cptr < endlineptr ;
  484.             cptr++ )
  485.       {
  486.         if ( !isdigit(*cptr) )
  487.         {
  488.           printf("'%s' not numbered file (cols 1-8)\n",
  489.                  infile) ;
  490.           goto noconversion ;
  491.         }
  492.       }
  493.       lineptr = endlineptr ;
  494.       for ( ; *endlineptr != '\n' ; endlineptr++ )
  495.       {
  496.         if ( !isprint(*cptr) )
  497.         {
  498.           printf("'%s' not valid text file - "
  499.                  "contains unprintable characters\n",
  500.                  infile) ;
  501.           goto noconversion ;
  502.         }
  503.       }
  504.       for ( cptr = endlineptr - 1 ;
  505.             cptr >= lineptr && *cptr == ' ' ;
  506.             cptr-- ) ;
  507.       for ( ; lineptr <= cptr ; lineptr++ )
  508.       {
  509.         *(optr++) = *lineptr ;
  510.       }
  511.       *(optr++) = '\n' ;
  512.  
  513.       lineptr = endlineptr + 1 ;
  514.     }
  515.   }
  516.  
  517.   /*-----------------------------------------------------------------*/
  518.   /*  If not test mode, save modified file                           */
  519.   /*-----------------------------------------------------------------*/
  520.  
  521.   if ( !(flags & flgtst) )
  522.   {
  523.     osfileblock.start = (int)workarea ;
  524.     osfileblock.end   = (int)optr ;
  525.     osfileblock.load  = 0xfff ;
  526.  
  527.     result = _kernel_osfile(10,oufile,&osfileblock) ;
  528.  
  529.     if (result == _kernel_ERROR)
  530.     {
  531.       printf("'%s' save failed - %s\n",oufile,
  532.              _kernel_last_oserror()->errmess);
  533.       goto error3 ;
  534.     }
  535.   }
  536.  
  537.   /*-----------------------------------------------------------------*/
  538.   /*  Valid numbered text file - bump file count                     */
  539.   /*-----------------------------------------------------------------*/
  540.   
  541.   filecount++ ;
  542.  
  543.   /*-----------------------------------------------------------------*/
  544.   /*  Display file name (plus "unnumbered" if not test mode)         */
  545.   /*-----------------------------------------------------------------*/
  546.  
  547.   printf("'%s'",infile) ;
  548.   if ( !(flags & flgtst) )
  549.   {
  550.     printf(" unnumbered") ;
  551.     if ( !(flags & flgovr) )
  552.     {
  553.       printf(" and saved as '%s'",oufile) ;
  554.     }
  555.   }
  556.   putchar('\n') ;
  557.  
  558.   /*-----------------------------------------------------------------*/
  559.   /*  Free work area and return with good completion code            */
  560.   /*-----------------------------------------------------------------*/
  561.  
  562.   noconversion: free(workarea) ;
  563.                 free(infile) ;
  564.  
  565.   return TRUE ;
  566.  
  567.   /*-----------------------------------------------------------------*/
  568.   /*  Error exits                                                    */
  569.   /*-----------------------------------------------------------------*/
  570.  
  571.   error3: free(workarea) ;
  572.   error4: free(infile) ;
  573.           beep() ;
  574.  
  575.   return FALSE ;
  576. }
  577.  
  578. /*=====================================================================*/
  579.