home *** CD-ROM | disk | FTP | other *** search
- /* > c.1stUnMake - (c) Paul Witheridge - Version 2.01 - 03 Mar 1993 */
-
- /*===================================================================*/
- /* */
- /* 1stUnMake - convert 1stWord+ document to text file file */
- /* --------- */
- /* */
- /* This utility converts 1stWord+ documents to plain text files, */
- /* deleting all the embedded 1stWord+ control information. */
- /* */
- /* Note that this can also be done straight from 1stWord+ by */
- /* turning off the "WP" mode and saving to disk, but 1stUnMake */
- /* also deletes trailing blanks and can process multiple files. */
- /* */
- /*-------------------------------------------------------------------*/
- /* */
- /* COPYRIGHT NOTICE */
- /* */
- /* 1stUnMake 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 flgftn 0x02 /* Footnote found */
- #define flggrf 0x04 /* Graphics found */
- #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) ;
-
- static enum boolean footnotewarning( /* Issue warning message */
- const char *filenameptr) ;
-
- /*===================================================================*/
- /* */
- /* 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 **posval[] = /* Ptrs to ptrs to posit'nal values */
- {
- &argptr
- } ;
- static const char **(*posargs)[] = &posval ; /* Ptr to array */
-
- 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 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 */
-
- "1stUnMake converts a 1stWord+ document file to a plain "
- "text file by removing all the 1stWord+ control information "
- "from the file.\x1f"
- "\x1f"
- "WARNING:\x01" "This utility converts files IN-PLACE if the "
- "'-o' option is used to replace the 1stWord+ document with "
- "the plain text output file.\x1f"
- "\x1f"
- "Syntax:\x01" "*1stUnMake [path.]object [options]\x1f"
- "\x1f"
- "object:\x01" "Specifies 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"
- "\x01" "In case (a) the file is converted provided that it has a "
- "file-type of 1WPDOC.\x1f"
- "\x1f"
- "\x01" "In case (b) all 1WPDOC files in the specified directory "
- "are converted. If the RECURSION option is specified all files "
- "in all subdirectories are also converted.\x1f"
- "\x1f"
- "\x01" "In case (c) all matching 1WPDOC files are converted. If "
- "no matching files are found, then the first matching "
- "directory name is taken and all 1WPDOC files therein are "
- "converted. If the RECURSION option is specified, all matching "
- "1WPDOC files are converted, plus all !WPDOC files in all "
- "subdirectories.\x1f"
- "\x1f"
- "\x01" "In all cases, only files which have a filetype of 1WPDOC "
- "(hex AF8) will be converted.\x1f"
- "\x1f"
- "path:\x01" "Specifies the directory to be searched for the "
- "object file/directory. If omitted the current directory "
- "is searched.\x1f"
- "\x1f"
- "options:\x01" "Specifies processing options which can be one "
- "or more ofthe following:\x1f"
- "\x1f"
- "\x01" "-o\x02" "-\x03" "OVERWRITE mode; output file will have "
- "same name and will replace input file.\x1f"
- "\x1f"
- "\x01" "-p xxx\x02" "-\x03" "specify 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. 'txtdir.'); if not specified a default "
- "of '_' is used.\x1f"
- "\x1f"
- "\x01" "-r\x02" "-\x03" "RECURSION mode which causes all eligible "
- "files in all subdirectories to be converted.\x1f"
- "\x1f"
- "\x01" "-t\x02" "-\x03" "TEST 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"
- "1stUnMake - copyright Paul Witheridge, 1993\x1f"
- "\x1f" ;
-
- static const unsigned char helptabs[] = /* Help text tab settings */
- {
- 1,10,17,19
- } ;
-
- /*-----------------------------------------------------------------*/
- /* Executable statements */
- /*-----------------------------------------------------------------*/
-
- puts("\n1stUnMake 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 1stWord+ document(s) ",filecount) ;
- if ( flags & flgtst )
- {
- printf("would be ") ;
- }
- puts("converted.\n") ;
- returncode = 0 ;
- }
- else
- {
- printf("No 1stWord+ documents 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 */
- char *workarea ; /* Ptr to start of work area */
- char *workend ; /* Ptr to end of work area */
- char *iptr ; /* Working ptr to next char */
- char *optr ; /* Ptr to next output char */
- char *wptr ; /* Working pointer */
- int c ; /* Working character */
- int i ; /* Working integer */
-
- _kernel_osfile_block osfileblock ; /* OS File parameter block */
-
- char footnotework[24] ; /* Footnote workarea */
-
- static const char overlapmsg[] = /* Common error message */
- "Conversion overlap error in file '%s' - conversion failed\n" ;
-
- /*-----------------------------------------------------------------*/
- /* Executable statements */
- /* */
- /* Return immediately if not a 1stWord+ document */
- /*-----------------------------------------------------------------*/
-
- if ( ptr->type != 0xaf8 )
- {
- return TRUE ;
- }
-
- /*-----------------------------------------------------------------*/
- /* If test mode just display file name */
- /*-----------------------------------------------------------------*/
-
- if ( flags & flgtst )
- {
- if ( !(flags & flgfnd) )
- {
- puts("The following files would be converted:\n") ;
- flags |= flgfnd ;
- }
- printf("%s%s\n",path,ptr->name) ;
- filecount++ ;
- 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) ;
-
- /*-----------------------------------------------------------------*/
- /* 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)+2) ) == NULL )
- {
- printf("'%s' too large to load",infile) ;
- goto error4 ;
- }
- workend = workarea + ptr->length + 1 ;
-
- osfileblock.load = (int)(workarea + 1) ;
- 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 ;
- }
-
- /*-----------------------------------------------------------------*/
- /* Convert document. */
- /*-----------------------------------------------------------------*/
-
- *workarea = '\0' ;
- *workend = '\n' ;
- flags &= ALLON ^ (flgftn | flggrf) ;
-
- iptr = optr = workarea + 1 ;
-
- while ( iptr < workend )
- {
- switch ( c = *iptr )
- {
- /*-------------------------------------------------------------*/
- /* 0A = newline - truncate trailing blanks */
- /*-------------------------------------------------------------*/
-
- case 0x0a :
-
- for ( optr-- ; *optr == ' ' ; optr-- ) ;
- optr++ ;
- *(optr++) = '\n' ;
- break ;
-
- /*-------------------------------------------------------------*/
- /* 0B = keep - followed by 1 byte line count (+0x10) */
- /* discard both bytes */
- /*-------------------------------------------------------------*/
-
- case 0x0b :
-
- iptr++ ;
- break ;
-
- /*-------------------------------------------------------------*/
- /* 0C = hard new page - discard byte */
- /*-------------------------------------------------------------*/
-
- case 0x0c :
-
- break ;
-
- /*-------------------------------------------------------------*/
- /* 18 = footnote ref - followed footnote line count, */
- /* a comma, the footnote number and another byte */
- /* of 0x18 */
- /*-------------------------------------------------------------*/
-
- case 0x18 :
-
- if ( sscanf(iptr+1,"%*d,%d%c",&i,&footnotework[0]) != 2 ||
- footnotework[0] != 0x18 )
- {
- printf("Invalid footnote reference in file '%s'\n",
- infile) ;
- goto noconversion ;
- }
- iptr = strchr(iptr+1,0x18) ;
- if ( !footnotewarning(infile) )
- {
- goto noconversion ;
- }
- i = sprintf(footnotework,"[%d]",i) ;
- memcpy(optr,footnotework,i) ;
- optr += i ;
- if ( optr > iptr )
- {
- printf(overlapmsg,infile) ;
- goto noconversion ;
- }
- break ;
-
- /*-------------------------------------------------------------*/
- /* 19 = soft hyphen - replace by hyphen */
- /*-------------------------------------------------------------*/
-
- case 0x19 :
-
- *(optr++) = '-' ;
- break ;
-
- /*-------------------------------------------------------------*/
- /* 1B = font specification - followed by one byte of */
- /* flags indicating font combination required; */
- /* discard both bytes */
- /*-------------------------------------------------------------*/
-
- case 0x1b :
-
- iptr++ ;
- break ;
-
- /*-------------------------------------------------------------*/
- /* 1C, 1D, 1E = indent, stretch and soft spaces; */
- /* replace by blank */
- /*-------------------------------------------------------------*/
-
- case 0x1c :
- case 0x1d :
- case 0x1e :
-
- *(optr++) = ' ' ;
- break ;
-
- /*-------------------------------------------------------------*/
- /* 1F = full line of control info */
- /* */
- /* x01f N = start of footnote */
- /* x01f E = end of footnotes */
- /* x01f 8 = graphics */
- /* */
- /* Other types are just skipped */
- /*-------------------------------------------------------------*/
-
- case 0x1f :
-
- wptr = iptr ;
-
- iptr = memchr(iptr,'\n',INT_MAX) ;
-
- switch ( *(wptr + 1) )
- {
- case 'N' : /* Footnote header */
-
- if ( sscanf(wptr+2,"%3d",&i) != 1 )
- {
- printf("Invalid footnote in file '%s'\n",infile) ;
- goto noconversion ;
- }
- if ( !footnotewarning(infile) )
- {
- goto noconversion ;
- }
- i = sprintf(footnotework,"**Footnote [%d]\n",i) ;
- memcpy(optr,footnotework,i) ;
- optr += i ;
- if ( optr > iptr )
- {
- printf(overlapmsg,infile) ;
- goto noconversion ;
- }
- break ;
-
- case 'E' : /* Footnote trailer */
-
- if ( !footnotewarning(infile) )
- {
- goto noconversion ;
- }
- memcpy(optr,"**End footnote(s)\n",18) ;
- optr += 18 ;
- if ( optr > iptr )
- {
- printf(overlapmsg,infile) ;
- goto noconversion ;
- }
- break ;
-
- case '8' : /* Name of sprite file */
-
- if ( !(flags & flggrf) )
- {
- flags |= flggrf ;
- if ( flags & flgovr )
- {
- printf("Graphics found in file '%s' - "
- "REPLACE (-o) option in effect - "
- "file will not be converted\n",
- infile) ;
- goto noconversion ;
- }
- else
- {
- printf("WARNING - graphics found in file '%s'\n",
- infile) ;
- }
- }
- *iptr = '\0' ;
- strncpy(footnotework,wptr+11,sizeof(footnotework)-1) ;
- footnotework[sizeof(footnotework)-1] = '\0' ;
- optr += sprintf(optr,"**Graphics [%s]\n",footnotework) ;
- if ( optr > iptr )
- {
- printf(overlapmsg,infile) ;
- goto noconversion ;
- }
- break ;
- }
-
- break ;
-
- /*-------------------------------------------------------------*/
- /* Keep all remaining characters. Issue warning if */
- /* any other CTRL characters found. */
- /*-------------------------------------------------------------*/
-
- default :
-
- if ( iscntrl(c) )
- {
- printf("WARNING - CTRL [%2.2d] character "
- "encountered in file '%s'\n",
- c,infile) ;
- }
- *(optr++) = c ;
-
- }
- iptr++ ;
- }
-
- /*-----------------------------------------------------------------*/
- /* Save modified file */
- /*-----------------------------------------------------------------*/
-
- osfileblock.start = (int)(workarea + 1) ;
- 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++ ;
- flags |= flgfnd ;
-
- /*-----------------------------------------------------------------*/
- /* Display file name */
- /*-----------------------------------------------------------------*/
-
- printf("'%s' converted",infile) ;
- 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 ;
- }
-
- /*===================================================================*/
- /* footnotewarning - issue warning message about footnotes */
- /*===================================================================*/
-
- static enum boolean footnotewarning(
- const char *filenameptr) /* Ptr to filename */
- {
- if ( flags & flgovr )
- {
- printf("Footnotes found in file '%s' - REPLACE (-o) option in "
- "effect - file will not be converted\n",filenameptr) ;
- return FALSE ;
- }
-
- if ( !(flags & flgftn) )
- {
- printf("WARNING - footnotes found in file '%s'\n",filenameptr) ;
- flags |= flgftn ;
- }
-
- return TRUE ;
- }
-
- /*===================================================================*/
-