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

  1. /* > c.1stUnMake  - (c) Paul Witheridge - Version 2.01 - 03 Mar 1993 */
  2.  
  3. /*===================================================================*/
  4. /*                                                                   */
  5. /*  1stUnMake  -  convert 1stWord+ document to text file file        */
  6. /*  ---------                                                        */
  7. /*                                                                   */
  8. /*  This utility converts 1stWord+ documents to plain text files,    */
  9. /*  deleting all the embedded 1stWord+ control information.          */
  10. /*                                                                   */
  11. /*  Note that this can also be done straight from 1stWord+ by        */
  12. /*  turning off the "WP" mode and saving to disk, but 1stUnMake      */
  13. /*  also deletes trailing blanks and can process multiple files.     */
  14. /*                                                                   */
  15. /*-------------------------------------------------------------------*/
  16. /*                                                                   */
  17. /*  COPYRIGHT NOTICE                                                 */
  18. /*                                                                   */
  19. /*  1stUnMake is subject to Copyright.                               */
  20. /*                                                                   */
  21. /*  Permission is granted by the author to any recipient of this     */
  22. /*  material to use and make/disseminate copies of the application   */
  23. /*  provided that no charges are made for doing so (other than to    */
  24. /*  cover any cost of media or postage) and that this notice is      */
  25. /*  included with all copies.                                        */
  26. /*                                                                   */
  27. /*===================================================================*/
  28.  
  29. #include "kernel.h"                     /* ARC specifics             */
  30. #include <ctype.h>                      /* Character handling        */
  31. #include <limits.h>                     /* Implementation limits     */
  32. #include <stddef.h>                     /* Standard definitions      */
  33. #include <stdio.h>                      /* Input/output              */
  34. #include <stdlib.h>                     /* General utilities         */
  35. #include <string.h>                     /* String handling           */
  36. #include "Beep.h"                       /* Beep header               */
  37. #include "GetDirs.h"                    /* GetDirs header            */
  38. #include "ArgFuncs.h"                   /* Arg functions etc         */
  39. #include "Useful.h"                     /* Useful definitions        */
  40.  
  41. /*-------------------------------------------------------------------*/
  42. /*  Global data declarations and definitions.                        */
  43. /*-------------------------------------------------------------------*/
  44.  
  45. static unsigned char flags = '\0' ;        /* Processing flags       */
  46.   #define flgfnd 0x01                      /* Found file to process  */
  47.   #define flgftn 0x02                      /* Footnote found         */
  48.   #define flggrf 0x04                      /* Graphics found         */
  49.   #define flgovr 0x10                      /* Overwrite mode         */
  50.   #define flgrcs 0x20                      /* Recursive mode         */
  51.   #define flgtst 0x40                      /* Test mode              */
  52.  
  53. static int filecount = 0 ;              /* Count of files processed. */
  54.  
  55. static const char *argptr = NULL ;      /* Pointer to file spec.     */
  56. static const char *pfxptr = "_" ;       /* Pointer to output prefix  */
  57.  
  58. /*-------------------------------------------------------------------*/
  59. /*  Declare functions local in scope to this file.                   */
  60. /*-------------------------------------------------------------------*/
  61.  
  62. static enum boolean cnvtfunc(           /* Convert function          */
  63.   const char *path,
  64.   direntry *ptr) ;
  65.  
  66. static enum boolean footnotewarning(    /* Issue warning message      */
  67.   const char *filenameptr) ;
  68.  
  69. /*===================================================================*/
  70. /*                                                                   */
  71. /*  Main program                                                     */
  72. /*  ------------                                                     */
  73. /*                                                                   */
  74. /*  Analyse arguments. Then call the "GetDirentrys" function to read */
  75. /*  all the file-names in the specified directory (plus any sub      */
  76. /*  directories). Provide "GetDirentrys" with pointer to function    */
  77. /*  to process the specified files.                                  */
  78. /*                                                                   */
  79. /*===================================================================*/
  80.  
  81. int main(
  82.   const int argc,                     /* Number of arguments         */
  83.   const char *argv[])                 /* Array of pointers to args   */
  84. {
  85.   /*-----------------------------------------------------------------*/
  86.   /*  Local definitions.                                             */
  87.   /*-----------------------------------------------------------------*/
  88.  
  89.   int returncode ;
  90.  
  91.   static const char **posval[] = /* Ptrs to ptrs to posit'nal values */ 
  92.   {
  93.     &argptr
  94.   } ;
  95.   static const char **(*posargs)[] = &posval ;    /* Ptr to array    */
  96.  
  97.   static const char options[] =  /* Used to match option argument    */
  98.   {
  99.     'O',                            /* Overwrite mode                */
  100.     'P',                            /* Output prefix                 */
  101.     'R',                            /* Recursive mode                */
  102.     'T',                            /* Test mode                     */
  103.     '0'                             /* Null byte terminator          */
  104.   } ;
  105.  
  106.   static const unsigned char optflags[] = /* Used to set option flgs */
  107.   {
  108.     flgovr,                         /* Overwrite mode                */
  109.     0,                              /* Output prefix                 */
  110.     flgrcs,                         /* Recursive mode                */
  111.     flgtst,                         /* Test mode                     */
  112.   } ;
  113.  
  114.   static const char **optval[] = /* Ptrs to ptrs to option values    */
  115.   {
  116.     NULL,                           /* No value allowed              */
  117.     &pfxptr,                        /* Output file prefix            */
  118.     NULL,                           /* No value allowed              */
  119.     NULL,                           /* No value allowed              */
  120.   } ;
  121.  
  122.   static const char helpdata[] = /* Help text to be displayed        */
  123.  
  124.     "1stUnMake converts a 1stWord+ document file to a plain "
  125.     "text file by removing all the 1stWord+ control information "
  126.     "from the file.\x1f"
  127.     "\x1f"
  128.     "WARNING:\x01" "This utility converts files IN-PLACE if the "
  129.     "'-o' option is used to replace the 1stWord+ document with "
  130.     "the plain text output file.\x1f"
  131.     "\x1f"
  132.     "Syntax:\x01" "*1stUnMake  [path.]object  [options]\x1f"
  133.     "\x1f"
  134.     "object:\x01" "Specifies one of the following:\x1f"
  135.     "\x01" "(a) a single non-wildcarded file name\x1f"
  136.     "\x01" "(b) a single non-wildcarded directory name\x1f"
  137.     "\x01" "(c) a wildcarded name.\x1f"
  138.     "\x1f"
  139.     "\x01" "In case (a) the file is converted provided that it has a "
  140.     "file-type of 1WPDOC.\x1f"
  141.     "\x1f"
  142.     "\x01" "In case (b) all 1WPDOC files in the specified directory "
  143.     "are converted. If the RECURSION option is specified all files "
  144.     "in all subdirectories are also converted.\x1f"
  145.     "\x1f"
  146.     "\x01" "In case (c) all matching 1WPDOC files are converted. If "
  147.     "no matching files are found, then the first matching "
  148.     "directory name is taken and all 1WPDOC files therein are "
  149.     "converted. If the RECURSION option is specified, all matching "
  150.     "1WPDOC files are converted, plus all !WPDOC files in all "
  151.     "subdirectories.\x1f"
  152.     "\x1f"
  153.     "\x01" "In all cases, only files which have a filetype of 1WPDOC "
  154.     "(hex AF8) will be converted.\x1f"
  155.     "\x1f"
  156.     "path:\x01" "Specifies the directory to be searched for the "
  157.     "object file/directory. If omitted the current directory "
  158.     "is searched.\x1f"
  159.     "\x1f"
  160.     "options:\x01" "Specifies processing options which can be one "
  161.     "or more ofthe following:\x1f"
  162.     "\x1f"
  163.     "\x01" "-o\x02" "-\x03" "OVERWRITE mode; output file will have "
  164.     "same name and will replace input file.\x1f"
  165.     "\x1f"
  166.     "\x01" "-p xxx\x02" "-\x03" "specify PREFIX which will be used "
  167.     "to create name for output file if '-o' is not specified; "
  168.     "'xxx' can be one or more characters including directory "
  169.     "specification (e.g. 'txtdir.'); if not specified a default "
  170.     "of '_' is used.\x1f"
  171.     "\x1f"
  172.     "\x01" "-r\x02" "-\x03" "RECURSION mode which causes all eligible "
  173.     "files in all subdirectories to be converted.\x1f"
  174.     "\x1f"
  175.     "\x01" "-t\x02" "-\x03" "TEST mode; a list of files to be converted "
  176.     "is displayed but no output is actually written; useful for "
  177.     "checking when specifying a directory or wildcarded filename.\x1f"
  178.     "\x1f"
  179.     "1stUnMake - copyright Paul Witheridge, 1993\x1f"
  180.     "\x1f" ;
  181.  
  182.   static const unsigned char helptabs[] =  /* Help text tab settings */
  183.   {
  184.     1,10,17,19
  185.   } ;
  186.  
  187.   /*-----------------------------------------------------------------*/
  188.   /*  Executable statements                                          */
  189.   /*-----------------------------------------------------------------*/
  190.  
  191.   puts("\n1stUnMake Version 2.01 - 03 March 1993\n") ;
  192.  
  193.   /*-----------------------------------------------------------------*/
  194.   /*  Analyse arguments for file-name and option flags.              */
  195.   /*-----------------------------------------------------------------*/
  196.  
  197.   analargs(argc,argv,1,&posargs,options,&flags,optflags,optval) ;
  198.  
  199.   /*-----------------------------------------------------------------*/
  200.   /*  Set paged scrolling mode                                       */
  201.   /*-----------------------------------------------------------------*/
  202.  
  203.   _kernel_oswrch(12) ;
  204.   _kernel_oswrch(14) ;
  205.  
  206.   puts(" PRESS SHIFT KEY TO ALLOW WINDOW TO SCROLL\n") ;
  207.   
  208.   /*-----------------------------------------------------------------*/
  209.   /*  If no file name operand just display help text.                */
  210.   /*-----------------------------------------------------------------*/
  211.  
  212.   if ( argptr == NULL )
  213.   {
  214.     displaytext(helpdata,helptabs) ;
  215.     _kernel_oswrch(15) ;
  216.     return 0 ;
  217.   }
  218.  
  219.   /*-----------------------------------------------------------------*/
  220.   /*  If TEST MODE issue message.                                    */
  221.   /*-----------------------------------------------------------------*/
  222.  
  223.   if ( flags & flgtst )
  224.   {
  225.     puts("TEST MODE (files will be identified, not converted).\n") ;
  226.   }
  227.  
  228.   /*-----------------------------------------------------------------*/
  229.   /*  Invoke GetDirs function to read the directory entry(s) of the  */
  230.   /*  file(s) to be processed. Pass it a pointer of a processing     */
  231.   /*  function to be called.                                         */
  232.   /*-----------------------------------------------------------------*/
  233.  
  234.   returncode = 4 ;
  235.  
  236.   if ( getdirentrys(argptr,
  237.        ( flags & flgrcs ? RECURSE_ALWAYS : RECURSE_ONCE ),cnvtfunc) )
  238.   {
  239.     if ( flags & flgfnd )
  240.     {
  241.       printf("\n%d 1stWord+ document(s) ",filecount) ;
  242.       if ( flags & flgtst )
  243.       {
  244.         printf("would be ") ;
  245.       }
  246.       puts("converted.\n") ;
  247.       returncode = 0 ;
  248.     }
  249.     else
  250.     {
  251.       printf("No 1stWord+ documents found matching '%s'\n",argptr) ;
  252.       beep() ;
  253.     }
  254.   }
  255.   
  256.   /*-----------------------------------------------------------------*/
  257.   /*  Return to caller. All done.                                    */
  258.   /*-----------------------------------------------------------------*/
  259.  
  260.   _kernel_oswrch(15) ;
  261.   return returncode ;
  262. }
  263.  
  264. /*===================================================================*/
  265. /*                                                                   */
  266. /*  cnvtfunc  -  perform actual file conversion                      */
  267. /*  --------                                                         */
  268. /*                                                                   */
  269. /*  This function is called by the "getdirentrys" function for each  */
  270. /*  file-name that it encounters.                                    */
  271. /*                                                                   */
  272. /*  Only files which have a filetype of "text" (0xFFF) will be       */
  273. /*  processed.                                                       */
  274. /*                                                                   */
  275. /*===================================================================*/
  276.  
  277. static enum boolean cnvtfunc(
  278.   const char *path,                   /* Pointer to path name.       */
  279.   direntry *ptr)                      /* Pointer to direntry info.   */
  280. {
  281.   char *infile ;                      /* Ptr to path + leafname      */
  282.   char *oufile ;                      /* Ptr tp path + leafname      */
  283.   int result;                         /* Result from OS-File SWI     */
  284.   char *workarea ;                    /* Ptr to start of work area   */
  285.   char *workend ;                     /* Ptr to end of work area     */
  286.   char *iptr ;                        /* Working ptr to next char    */
  287.   char *optr ;                        /* Ptr to next output char     */
  288.   char *wptr ;                        /* Working pointer             */
  289.   int c ;                             /* Working character           */
  290.   int i ;                             /* Working integer             */
  291.  
  292.   _kernel_osfile_block osfileblock ;  /* OS File parameter block     */
  293.  
  294.   char footnotework[24] ;             /* Footnote workarea           */
  295.  
  296.   static const char overlapmsg[] =    /* Common error message        */
  297.     "Conversion overlap error in file '%s' - conversion failed\n" ;
  298.  
  299.   /*-----------------------------------------------------------------*/
  300.   /*  Executable statements                                          */
  301.   /*                                                                 */
  302.   /*  Return immediately if not a 1stWord+ document                  */
  303.   /*-----------------------------------------------------------------*/
  304.  
  305.   if ( ptr->type != 0xaf8 )
  306.   {
  307.     return TRUE ;
  308.   }
  309.  
  310.   /*-----------------------------------------------------------------*/
  311.   /*  If test mode just display file name                            */
  312.   /*-----------------------------------------------------------------*/
  313.  
  314.   if ( flags & flgtst )
  315.   {
  316.     if ( !(flags & flgfnd) )
  317.     {
  318.       puts("The following files would be converted:\n") ;
  319.       flags |= flgfnd ;
  320.     }
  321.     printf("%s%s\n",path,ptr->name) ;
  322.     filecount++ ;
  323.     return TRUE ;
  324.   }
  325.  
  326.   /*-----------------------------------------------------------------*/
  327.   /*  Create input and output filespecs                              */
  328.   /*-----------------------------------------------------------------*/
  329.   
  330.   if ( ( infile = malloc(2 * (strlen(path) + strlen(ptr->name) + 1)
  331.                          + strlen(pfxptr) ) ) == NULL )
  332.   {
  333.     puts("Out of memory") ;
  334.     return FALSE ;
  335.   } 
  336.   
  337.   oufile = infile + sprintf(infile,"%s%s",path,ptr->name) + 1 ;
  338.   sprintf(oufile,"%s%s%s",path,flags & flgovr ? "" : pfxptr,ptr->name) ;
  339.   
  340.   /*-----------------------------------------------------------------*/
  341.   /*  Check input file has non-zero length                           */
  342.   /*-----------------------------------------------------------------*/
  343.  
  344.   if ( ptr->length == 0 )
  345.   {
  346.     printf("'%s' is empty\n",infile) ;
  347.   }
  348.  
  349.   /*-----------------------------------------------------------------*/
  350.   /*  Allocate memory for file and load file                         */
  351.   /*-----------------------------------------------------------------*/
  352.  
  353.   if ( (workarea = malloc((ptr->length)+2) ) == NULL )
  354.   {
  355.     printf("'%s' too large to load",infile) ;
  356.     goto error4 ;
  357.   }
  358.   workend   = workarea + ptr->length + 1 ;
  359.  
  360.   osfileblock.load  = (int)(workarea + 1) ;
  361.   osfileblock.exec  = 0 ;
  362.   result = _kernel_osfile(16,infile,&osfileblock) ;
  363.  
  364.   if (result == _kernel_ERROR)
  365.   {
  366.     printf("'%s' load failed - %s\n",infile,
  367.           _kernel_last_oserror()->errmess) ;
  368.     goto error3 ;
  369.   }
  370.  
  371.   /*-----------------------------------------------------------------*/
  372.   /*  Convert document.                                              */
  373.   /*-----------------------------------------------------------------*/
  374.  
  375.   *workarea = '\0' ;
  376.   *workend  = '\n' ;
  377.   flags &= ALLON ^ (flgftn | flggrf) ;
  378.  
  379.   iptr = optr = workarea + 1 ;
  380.  
  381.   while ( iptr < workend ) 
  382.   {
  383.     switch ( c = *iptr )
  384.     {
  385.       /*-------------------------------------------------------------*/
  386.       /*  0A = newline - truncate trailing blanks                    */
  387.       /*-------------------------------------------------------------*/
  388.  
  389.       case 0x0a :
  390.  
  391.         for ( optr-- ; *optr == ' ' ; optr-- ) ;
  392.         optr++ ;
  393.         *(optr++) = '\n' ;
  394.         break ;
  395.       
  396.       /*-------------------------------------------------------------*/
  397.       /*  0B = keep - followed by 1 byte line count (+0x10)          */
  398.       /*              discard both bytes                             */
  399.       /*-------------------------------------------------------------*/
  400.  
  401.       case 0x0b : 
  402.  
  403.         iptr++ ;
  404.         break ;
  405.       
  406.       /*-------------------------------------------------------------*/
  407.       /*  0C = hard new page - discard byte                          */
  408.       /*-------------------------------------------------------------*/
  409.       
  410.       case 0x0c :
  411.  
  412.         break ;
  413.     
  414.       /*-------------------------------------------------------------*/
  415.       /*  18 = footnote ref - followed footnote line count,          */
  416.       /*       a comma, the footnote number and another byte         */
  417.       /*       of 0x18                                               */
  418.       /*-------------------------------------------------------------*/
  419.  
  420.       case 0x18 :
  421.  
  422.         if ( sscanf(iptr+1,"%*d,%d%c",&i,&footnotework[0]) != 2 ||
  423.              footnotework[0] != 0x18 )
  424.         {
  425.           printf("Invalid footnote reference in file '%s'\n",
  426.                  infile) ;
  427.           goto noconversion ;
  428.         }
  429.         iptr = strchr(iptr+1,0x18) ;
  430.         if ( !footnotewarning(infile) )
  431.         {
  432.           goto noconversion ;
  433.         }
  434.         i = sprintf(footnotework,"[%d]",i) ;
  435.         memcpy(optr,footnotework,i) ;
  436.         optr += i ;
  437.         if ( optr > iptr )
  438.         {
  439.           printf(overlapmsg,infile) ;
  440.           goto noconversion ;
  441.         }
  442.         break ;
  443.       
  444.       /*-------------------------------------------------------------*/
  445.       /*  19 = soft hyphen - replace by hyphen                       */
  446.       /*-------------------------------------------------------------*/
  447.  
  448.       case 0x19 :
  449.  
  450.         *(optr++) = '-' ;
  451.         break ;
  452.       
  453.       /*-------------------------------------------------------------*/
  454.       /*  1B = font specification - followed by one byte of          */
  455.       /*       flags indicating font combination required;           */
  456.       /*       discard both bytes                                    */
  457.       /*-------------------------------------------------------------*/
  458.  
  459.       case 0x1b :
  460.  
  461.         iptr++ ;
  462.         break ;
  463.       
  464.       /*-------------------------------------------------------------*/
  465.       /*  1C, 1D, 1E = indent, stretch and soft spaces;              */
  466.       /*               replace by blank                              */
  467.       /*-------------------------------------------------------------*/
  468.  
  469.       case 0x1c :
  470.       case 0x1d :
  471.       case 0x1e :
  472.  
  473.         *(optr++) = ' ' ;
  474.         break ;
  475.  
  476.       /*-------------------------------------------------------------*/
  477.       /*  1F = full line of control info                             */
  478.       /*                                                             */
  479.       /*       x01f N  =  start of footnote                          */
  480.       /*       x01f E  =  end of footnotes                           */
  481.       /*       x01f 8  =  graphics                                   */
  482.       /*                                                             */
  483.       /*  Other types are just skipped                               */
  484.       /*-------------------------------------------------------------*/
  485.  
  486.       case 0x1f :
  487.  
  488.         wptr = iptr ;
  489.  
  490.         iptr = memchr(iptr,'\n',INT_MAX) ;
  491.            
  492.         switch ( *(wptr + 1) )
  493.         {
  494.           case 'N' :  /* Footnote header */
  495.  
  496.             if ( sscanf(wptr+2,"%3d",&i) != 1 )
  497.             {
  498.               printf("Invalid footnote in file '%s'\n",infile) ;
  499.               goto noconversion ;
  500.             }
  501.             if ( !footnotewarning(infile) )
  502.             {
  503.               goto noconversion ;
  504.             }
  505.             i = sprintf(footnotework,"**Footnote [%d]\n",i) ;
  506.             memcpy(optr,footnotework,i) ;
  507.             optr += i ;
  508.             if ( optr > iptr )
  509.             {
  510.               printf(overlapmsg,infile) ;
  511.               goto noconversion ;
  512.             }
  513.             break ;
  514.  
  515.           case 'E' :  /* Footnote trailer */
  516.  
  517.             if ( !footnotewarning(infile) )
  518.             {
  519.               goto noconversion ;
  520.             }
  521.             memcpy(optr,"**End footnote(s)\n",18) ;
  522.             optr += 18 ;
  523.             if ( optr > iptr )
  524.             {
  525.               printf(overlapmsg,infile) ;
  526.               goto noconversion ;
  527.             }
  528.             break ;
  529.  
  530.           case '8' :  /* Name of sprite file */
  531.  
  532.             if ( !(flags & flggrf) )
  533.             {
  534.               flags |= flggrf ;
  535.               if ( flags & flgovr )
  536.               {
  537.                 printf("Graphics found in file '%s' - "
  538.                        "REPLACE (-o) option in effect - "
  539.                        "file will not be converted\n",
  540.                        infile) ;
  541.                 goto noconversion ;
  542.               }
  543.               else
  544.               {
  545.                 printf("WARNING - graphics found in file '%s'\n",
  546.                        infile) ;
  547.               }
  548.             }
  549.             *iptr = '\0' ;
  550.             strncpy(footnotework,wptr+11,sizeof(footnotework)-1) ;
  551.             footnotework[sizeof(footnotework)-1] = '\0' ;
  552.             optr += sprintf(optr,"**Graphics [%s]\n",footnotework) ;
  553.             if ( optr > iptr )
  554.             {
  555.               printf(overlapmsg,infile) ;
  556.               goto noconversion ;
  557.             }
  558.             break ;
  559.           }
  560.  
  561.         break ;
  562.       
  563.       /*-------------------------------------------------------------*/
  564.       /*  Keep all remaining characters. Issue warning if            */
  565.       /*  any other CTRL characters found.                           */
  566.       /*-------------------------------------------------------------*/
  567.       
  568.       default :
  569.  
  570.         if ( iscntrl(c) )
  571.         {
  572.           printf("WARNING - CTRL [%2.2d] character "
  573.                  "encountered in file '%s'\n",
  574.                  c,infile) ;
  575.         }
  576.         *(optr++) = c ;
  577.  
  578.     }
  579.     iptr++ ;
  580.   }
  581.  
  582.   /*-----------------------------------------------------------------*/
  583.   /*  Save modified file                                             */
  584.   /*-----------------------------------------------------------------*/
  585.  
  586.   osfileblock.start = (int)(workarea + 1) ;
  587.   osfileblock.end   = (int)optr ;
  588.   osfileblock.load  = 0xfff ;
  589.  
  590.   result = _kernel_osfile(10,oufile,&osfileblock) ;
  591.  
  592.   if (result == _kernel_ERROR)
  593.   {
  594.     printf("'%s' save failed - %s\n",oufile,
  595.           _kernel_last_oserror()->errmess);
  596.     goto error3 ;
  597.   }
  598.  
  599.   /*-----------------------------------------------------------------*/
  600.   /*  Valid numbered text file - bump file count                     */
  601.   /*-----------------------------------------------------------------*/
  602.   
  603.   filecount++ ;
  604.   flags |= flgfnd ;
  605.  
  606.   /*-----------------------------------------------------------------*/
  607.   /*  Display file name                                              */
  608.   /*-----------------------------------------------------------------*/
  609.  
  610.   printf("'%s' converted",infile) ;
  611.   if ( !(flags & flgovr) )
  612.   {
  613.     printf(" and saved as '%s'",oufile) ;
  614.   }
  615.   putchar('\n') ;
  616.  
  617.   /*-----------------------------------------------------------------*/
  618.   /*  Free work area and return with good completion code            */
  619.   /*-----------------------------------------------------------------*/
  620.  
  621.   noconversion:
  622.  
  623.     free(workarea) ;
  624.     free(infile) ;
  625.     
  626.     return TRUE ;
  627.  
  628.   /*-----------------------------------------------------------------*/
  629.   /*  Error exits                                                    */
  630.   /*-----------------------------------------------------------------*/
  631.  
  632.   error3: free(workarea) ;
  633.   error4: free(infile) ;
  634.           beep() ;
  635.  
  636.     return FALSE ;
  637. }
  638.  
  639. /*===================================================================*/
  640. /*  footnotewarning  -  issue warning message about footnotes        */
  641. /*===================================================================*/
  642.  
  643. static enum boolean footnotewarning(
  644.   const char *filenameptr)             /* Ptr to filename            */
  645. {
  646.   if ( flags & flgovr )
  647.   {
  648.     printf("Footnotes found in file '%s' - REPLACE (-o) option in "
  649.            "effect - file will not be converted\n",filenameptr) ;
  650.     return FALSE ;
  651.   }
  652.  
  653.   if ( !(flags & flgftn) )
  654.   {
  655.     printf("WARNING - footnotes found in file '%s'\n",filenameptr) ;
  656.     flags |= flgftn ;
  657.   }
  658.  
  659.   return TRUE ;
  660. }
  661.  
  662. /*===================================================================*/
  663.