home *** CD-ROM | disk | FTP | other *** search
- /* > c.UnNum - (c) Paul Witheridge - Version 2.01 - 03 Mar 1993 */
-
- /*===================================================================*/
- /* */
- /* UnNum - unnumber file */
- /* ------ */
- /* */
- /* This utility removes line numbers from a file. */
- /* */
- /* If the file is fixed-blocked with a line length of 80 bytes, */
- /* then columns 73-80 are assumed to be the columns occuppied by */
- /* the line sequence number. */
- /* */
- /* If the file is not fixed-blocked with a line length of 80 bytes, */
- /* then the line sequence number is assumed to occuppy columns */
- /* 1-8 of each line. */
- /* */
- /* The utility checks that all lines are numbered (and that the */
- /* last line does end with a newline character). If not error */
- /* messages are issued. If so, the columns containing the line */
- /* sequence characters are deleted from the file. Any trailing */
- /* blanks in each line are also deleted. */
- /* */
- /*-------------------------------------------------------------------*/
- /* */
- /* COPYRIGHT NOTICE */
- /* */
- /* UnNum is subject to Copyright. */
- /* */
- /* Permission is granted by the author to any recipient of this */
- /* material to use and make/disseminate copies of the application */
- /* provided that no charges are made for doing so (other than to */
- /* cover any cost of media or postage) and that this notice is */
- /* included with all copies. */
- /* */
- /*===================================================================*/
-
- #include "kernel.h" /* ARC specifics */
- #include <ctype.h> /* Character handling */
- #include <limits.h> /* Implementation limits */
- #include <stddef.h> /* Standard definitions */
- #include <stdio.h> /* Input/output */
- #include <stdlib.h> /* General utilities */
- #include <string.h> /* String handling */
- #include "Beep.h" /* Beep header */
- #include "GetDirs.h" /* GetDirs header */
- #include "ArgFuncs.h" /* Arg functions etc */
- #include "Useful.h" /* Useful definitions */
-
- /*-------------------------------------------------------------------*/
- /* Global data declarations and definitions. */
- /*-------------------------------------------------------------------*/
-
- static unsigned char flags = '\0' ; /* Processing flags */
-
- #define flgfnd 0x01 /* Found file to process */
- #define flgovr 0x10 /* Overwrite mode */
- #define flgrcs 0x20 /* Recursive mode */
- #define flgtst 0x40 /* Test mode */
-
- static int filecount = 0 ; /* Count of files processed. */
-
- static const char *argptr = NULL ; /* Pointer to file spec. */
- static const char *pfxptr = "_" ; /* Pointer to output prefix */
-
- /*-------------------------------------------------------------------*/
- /* Declare functions local in scope to this file. */
- /*-------------------------------------------------------------------*/
-
- static enum boolean cnvtfunc( /* Convert function */
- const char *path,
- direntry *ptr) ;
-
- /*===================================================================*/
- /* */
- /* Main program */
- /* ------------ */
- /* */
- /* Analyse arguments. Then call the "GetDirentrys" function to */
- /* read all the file-names in the specified directory (plus any */
- /* sub directories). Provide "GetDirentrys" with pointer to */
- /* function to process the specified files. */
- /* */
- /*===================================================================*/
-
- int main(
- const int argc, /* Number of arguments */
- const char *argv[]) /* Array of pointers to args */
- {
- /*-----------------------------------------------------------------*/
- /* Local definitions. */
- /*-----------------------------------------------------------------*/
-
- int returncode ;
-
- static const char options[] = /* Used to match option argument */
- {
- 'O', /* Overwrite mode */
- 'P', /* Output prefix */
- 'R', /* Recursive mode */
- 'T', /* Test mode */
- '0' /* Null byte terminator */
- } ;
-
- static const char **posval[] = /* Ptrs to ptrs to posit'nal values */
- {
- &argptr
- } ;
- static const char **(*posargs)[] = &posval ; /* Ptr to array */
-
- static const unsigned char optflags[] = /* Used to set option flgs */
- {
- flgovr, /* Overwrite mode */
- 0, /* Output prefix */
- flgrcs, /* Recursive mode */
- flgtst, /* Test mode */
- } ;
-
- static const char **optval[] = /* Ptrs to ptrs to option values */
- {
- NULL, /* No value allowed */
- &pfxptr, /* Output file prefix */
- NULL, /* No value allowed */
- NULL, /* No value allowed */
- } ;
-
- static const char helpdata[] = /* Help text to be displayed */
-
- "Unnum removes line-numbers from cols 73-80 of card-image "
- "text files or from cols 1-8 of other text files (i.e. "
- "files with standard IBM S/370 line sequence numbers).\x1f"
- "\x1f"
- "WARNING:\x01This utility converts files IN-PLACE if the "
- "'-o' option is used to replace the input text "
- "file with the output unnumbered file.\x1f"
- "\x1f"
- "Syntax:\x01*Unnum [path.]object [options]\x1f"
- "\x1f"
- "object:\x01Specifies one of the following:\x1f"
- "\x01(a) a single non-wildcarded file name\x1f"
- "\x01(b) a single non-wildcarded directory name\x1f"
- "\x01(c) a wildcarded name.\x1f"
- "\x1f"
- "\x01In case (a) the file is unnumbered provided "
- "that it has a file-type of TEXT, contains no "
- "unprintable characters and has decimal digits "
- "in the correct sequence number columns.\x1f"
- "\x1f"
- "\x01In case (b) all files in the specified "
- "directory which meet the above conditions are "
- "unnumbered. If the RECURSION option is specified "
- "all files in all subdirectories are also "
- "unnumbered.\x1f"
- "\x1f"
- "\x01In case (c) all matching files which meet the "
- "above conditions are unnumbered. If no matching "
- "files are found, then the first matching "
- "directory name is taken and all eligible files "
- "therein are unnumbered. If the RECURSION option "
- "is specified, all matching files are unnumbered, "
- "plus all files in all subdirectories.\x1f"
- "\x1f"
- "\x01In all cases, only files which have a filetype "
- "of TEXT (hex FFF), which contain no unprintable "
- "characters (except newline - hex 0A) and which "
- "contain valid decimal digits in the correct "
- "sequence number columns, will be unnumbered.\x1f"
- "\x1f"
- "path:\x01Specifies the directory to be searched for "
- "the object file/directory. If omitted the current "
- "directory is searched.\x1f"
- "\x1f"
- "options:\x01Specifies processing options which can be "
- "one or more ofthe following:\x1f"
- "\x1f"
- "\x01-o\x02-\x03OVERWRITE mode; output file will have "
- "same name and will replace input file.\x1f"
- "\x1f"
- "\x01-p xxx\x02-\x03specify PREFIX which will be used to "
- "create name for output file if '-o' is not specified; "
- "'xxx' can be one or more characters including directory "
- "specification (e.g. 'unnumdir.'); if not specified a "
- "default of '_' is used.\x1f"
- "\x1f"
- "\x01-r\x02-\x03RECURSION mode which causes all eligible "
- "files in all subdirectories to be unnumbered.\x1f"
- "\x1f"
- "\x01-t\x02-\x03TEST mode; a list of files to be converted "
- "is displayed but no output is actually written; useful for "
- "checking when specifying a directory or wildcarded filename.\x1f"
- "\x1f"
- "UnNum - copyright Paul Witheridge, 1993\x1f"
- "\x1f" ;
-
- static const unsigned char helptabs[] = /* Help text tab settings */
- {
- 1,10,17,19
- } ;
-
- /*-----------------------------------------------------------------*/
- /* Executable statements */
- /*-----------------------------------------------------------------*/
-
- puts("\nUnnum Version 2.01 - 03 March 1993\n") ;
-
- /*-----------------------------------------------------------------*/
- /* Analyse arguments for file-name and option flags. */
- /*-----------------------------------------------------------------*/
-
- analargs(argc,argv,1,&posargs,options,&flags,optflags,optval) ;
-
- /*-----------------------------------------------------------------*/
- /* Set paged scrolling mode */
- /*-----------------------------------------------------------------*/
-
- _kernel_oswrch(12) ;
- _kernel_oswrch(14) ;
-
- puts(" PRESS SHIFT KEY TO ALLOW WINDOW TO SCROLL\n") ;
-
- /*-----------------------------------------------------------------*/
- /* If no file name operand just display help text. */
- /*-----------------------------------------------------------------*/
-
- if ( argptr == NULL )
- {
- displaytext(helpdata,helptabs) ;
- _kernel_oswrch(15) ;
- return 0 ;
- }
-
- /*-----------------------------------------------------------------*/
- /* If TEST MODE issue message. */
- /*-----------------------------------------------------------------*/
-
- if ( flags & flgtst )
- {
- puts("TEST MODE (files will be identified, not converted).\n") ;
- }
-
- /*-----------------------------------------------------------------*/
- /* Invoke GetDirs function to read the directory entry(s) of the */
- /* file(s) to be processed. Pass it a pointer of a processing */
- /* function to be called. */
- /*-----------------------------------------------------------------*/
-
- returncode = 4 ;
-
- if ( getdirentrys(argptr,
- ( flags & flgrcs ? RECURSE_ALWAYS : RECURSE_ONCE ),cnvtfunc) )
- {
- if ( flags & flgfnd )
- {
- printf("\n%d text file(s) ",filecount) ;
- if ( flags & flgtst )
- {
- printf("would be ") ;
- }
- puts("unnumbered.\n") ;
- returncode = 0 ;
- }
- else
- {
- printf("No text files found matching '%s'\n",argptr) ;
- beep() ;
- }
- }
-
- /*-----------------------------------------------------------------*/
- /* Return to caller. All done. */
- /*-----------------------------------------------------------------*/
-
- _kernel_oswrch(15) ;
- return returncode ;
- }
-
- /*===================================================================*/
- /* */
- /* cnvtfunc - perform actual file conversion */
- /* -------- */
- /* */
- /* This function is called by the "getdirentrys" function for each */
- /* file-name that it encounters. */
- /* */
- /* Only files which have a filetype of "text" (0xFFF) will be */
- /* processed. */
- /* */
- /*===================================================================*/
-
- static enum boolean cnvtfunc(
- const char *path, /* Pointer to path name. */
- direntry *ptr) /* Pointer to direntry info. */
- {
- char *infile ; /* Ptr to path + leafname */
- char *oufile ; /* Ptr tp path + leafname */
- int result ; /* Result from OS-File SWI */
- enum boolean cardimage ; /* Cardimage format switch */
- char *workarea ; /* Ptr to start of work area */
- char *workend ; /* Ptr to end of work area */
- char *lineptr ; /* Working ptr to line start */
- char *endlineptr ; /* Working ptr to line end */
- char *cptr ; /* Working ptr to next char */
- char *optr ; /* Ptr to next output char */
-
- _kernel_osfile_block osfileblock ; /* OS File parameter block */
-
- /*-----------------------------------------------------------------*/
- /* Executable statements */
- /* */
- /* Return immediately if not a text file */
- /*-----------------------------------------------------------------*/
-
- if ( ptr->type != 0xFFF )
- {
- return TRUE ;
- }
-
- /*-----------------------------------------------------------------*/
- /* Create input and output filespecs */
- /*-----------------------------------------------------------------*/
-
- if ( ( infile = malloc(2 * (strlen(path) + strlen(ptr->name) + 1)
- + strlen(pfxptr) ) ) == NULL )
- {
- puts("Out of memory") ;
- return FALSE ;
- }
-
- oufile = infile + sprintf(infile,"%s%s",path,ptr->name) + 1 ;
- sprintf(oufile,"%s%s%s",path,flags & flgovr ? "" : pfxptr,ptr->name) ;
-
- /*-----------------------------------------------------------------*/
- /* If test mode display heading on first time through */
- /*-----------------------------------------------------------------*/
-
- if ( (flags & flgtst) && !(flags & flgfnd) )
- {
- puts("The following files would be unnumbered:\n") ;
- }
-
- flags |= flgfnd ;
-
- /*-----------------------------------------------------------------*/
- /* Check input file has non-zero length */
- /*-----------------------------------------------------------------*/
-
- if ( ptr->length == 0 )
- {
- printf("'%s' is empty\n",infile) ;
- }
-
- /*-----------------------------------------------------------------*/
- /* Allocate memory for file and load file */
- /*-----------------------------------------------------------------*/
-
- if ( (workarea = malloc((ptr->length)+1) ) == NULL )
- {
- printf("'%s%s' too large to load",path,ptr->name) ;
- goto error4 ;
- }
-
- workend = workarea + ptr->length ;
-
- osfileblock.load = (int)workarea ;
- osfileblock.exec = 0 ;
- result = _kernel_osfile(16,infile,&osfileblock) ;
-
- if (result == _kernel_ERROR)
- {
- printf("'%s' load failed - %s\n",infile,
- _kernel_last_oserror()->errmess) ;
- goto error3 ;
- }
-
- /*-----------------------------------------------------------------*/
- /* If file contains any CRLF combinations convert these to */
- /* Archimedes newline characters (linefeed only) */
- /*-----------------------------------------------------------------*/
-
- *workend = 0 ;
-
- for ( cptr = optr = workarea ; cptr < workend ; cptr++, optr++ )
- {
- if ( *cptr == 0x1A )
- {
- break ;
- }
- if ( *cptr == 0x0d && *(cptr+1) == 0x0A )
- {
- cptr++;
- }
- *optr = *cptr ;
- }
-
- workend = optr ;
-
- /*-----------------------------------------------------------------*/
- /* Check for fixed-blocked 80 byte lines (cardimage file) */
- /*-----------------------------------------------------------------*/
-
- *workend = '\n' ;
- lineptr = workarea ;
- cardimage = TRUE ;
-
- while ( lineptr < workend )
- {
- endlineptr = memchr(lineptr,'\n',INT_MAX) ;
- if ( endlineptr - lineptr != 80 )
- {
- cardimage = FALSE ;
- }
- lineptr = endlineptr + 1 ;
- }
-
- /*-----------------------------------------------------------------*/
- /* Error message if no newline at end of file */
- /*-----------------------------------------------------------------*/
-
- if ( lineptr != workend )
- {
- printf("'%s' not valid text file - "
- "does not end with newline character\n",infile) ;
- goto noconversion ;
- }
-
- /*-----------------------------------------------------------------*/
- /* Process cardimage file - delete cols 73-80 & trailing blanks */
- /*-----------------------------------------------------------------*/
-
- optr = workarea ;
-
- if ( cardimage )
- {
- for ( lineptr = workarea ;
- lineptr < workend ;
- lineptr = endlineptr + 1 )
- {
- endlineptr = lineptr + 72 ;
- for ( cptr = lineptr ; cptr < endlineptr ; cptr++ )
- {
- if ( !isprint(*cptr) )
- {
- printf("'%s' not valid text file - "
- "contains unprintable characters\n",
- infile) ;
- goto noconversion ;
- }
- }
- endlineptr = lineptr + 80 ;
- for ( ; cptr < endlineptr ; cptr++ )
- {
- if ( !isdigit(*cptr) )
- {
- printf("'%s' not numbered file (cols 73-80)\n",
- infile) ;
- goto noconversion ;
- }
- }
- for ( cptr = lineptr + 71 ;
- cptr >= lineptr && *cptr == ' ' ;
- cptr-- ) ;
- for ( ; lineptr <= cptr ; lineptr++ )
- {
- *(optr++) = *lineptr ;
- }
- *(optr++) = '\n' ;
- }
- }
-
- /*-----------------------------------------------------------------*/
- /* Process non-cardimage file. Delete cols 1-8 plus any */
- /* trailing blanks */
- /*-----------------------------------------------------------------*/
-
- else
- {
- lineptr = workarea ;
-
- while ( lineptr < workend )
- {
- endlineptr = lineptr + 8 ;
- for ( cptr = lineptr ;
- cptr < endlineptr ;
- cptr++ )
- {
- if ( !isdigit(*cptr) )
- {
- printf("'%s' not numbered file (cols 1-8)\n",
- infile) ;
- goto noconversion ;
- }
- }
- lineptr = endlineptr ;
- for ( ; *endlineptr != '\n' ; endlineptr++ )
- {
- if ( !isprint(*cptr) )
- {
- printf("'%s' not valid text file - "
- "contains unprintable characters\n",
- infile) ;
- goto noconversion ;
- }
- }
- for ( cptr = endlineptr - 1 ;
- cptr >= lineptr && *cptr == ' ' ;
- cptr-- ) ;
- for ( ; lineptr <= cptr ; lineptr++ )
- {
- *(optr++) = *lineptr ;
- }
- *(optr++) = '\n' ;
-
- lineptr = endlineptr + 1 ;
- }
- }
-
- /*-----------------------------------------------------------------*/
- /* If not test mode, save modified file */
- /*-----------------------------------------------------------------*/
-
- if ( !(flags & flgtst) )
- {
- osfileblock.start = (int)workarea ;
- osfileblock.end = (int)optr ;
- osfileblock.load = 0xfff ;
-
- result = _kernel_osfile(10,oufile,&osfileblock) ;
-
- if (result == _kernel_ERROR)
- {
- printf("'%s' save failed - %s\n",oufile,
- _kernel_last_oserror()->errmess);
- goto error3 ;
- }
- }
-
- /*-----------------------------------------------------------------*/
- /* Valid numbered text file - bump file count */
- /*-----------------------------------------------------------------*/
-
- filecount++ ;
-
- /*-----------------------------------------------------------------*/
- /* Display file name (plus "unnumbered" if not test mode) */
- /*-----------------------------------------------------------------*/
-
- printf("'%s'",infile) ;
- if ( !(flags & flgtst) )
- {
- printf(" unnumbered") ;
- if ( !(flags & flgovr) )
- {
- printf(" and saved as '%s'",oufile) ;
- }
- }
- putchar('\n') ;
-
- /*-----------------------------------------------------------------*/
- /* Free work area and return with good completion code */
- /*-----------------------------------------------------------------*/
-
- noconversion: free(workarea) ;
- free(infile) ;
-
- return TRUE ;
-
- /*-----------------------------------------------------------------*/
- /* Error exits */
- /*-----------------------------------------------------------------*/
-
- error3: free(workarea) ;
- error4: free(infile) ;
- beep() ;
-
- return FALSE ;
- }
-
- /*=====================================================================*/
-