home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 1 / ARM_CLUB_CD.iso / contents / apps / desktop / t / utils / !Convert_C_Convert < prev    next >
Encoding:
Text File  |  1993-11-21  |  16.6 KB  |  711 lines

  1. /*
  2.  *      Title     : Convert text files.
  3.  *      System    : N/A */
  4. #define Version     "2.2"
  5. /*      Copyright : (c) John Winters
  6.  *      Date      : 5th November, 1989
  7.  *      Author    : John H. Winters
  8.  *
  9.  *      Function  : Convert text files between Risc-Os and
  10.  *                  IBM format.
  11.  *
  12.  *      Description :
  13.  *
  14.  *              IBM text files use carriage return, line
  15.  *              feed pairs as line seperators.  Risc-Os (and
  16.  *              Unix) use just a line feed.  MS-Dos also
  17.  *              uses tabs which tend to mess up a Risc-OS
  18.  *              display.  This program converts between the
  19.  *              two formats.
  20.  *
  21.  *              The type of conversion required is decided
  22.  *              on the basis of the original file type.
  23.  *              Files which are apparently text (text,
  24.  *              exec, obey etc.) are converted to IBM
  25.  *              format.  Files which are of type "Data" or "DOS",
  26.  *              which is the type created by putfile, are
  27.  *              assumed to be in IBM format and are
  28.  *              converted to Risc-OS form.
  29.  *
  30.  *              Files which aren't text at all will probably
  31.  *              be screwed up by this utility.
  32.  *
  33.  *
  34.  *      Modification history.
  35.  *
  36.  *      Version   : 1.01
  37.  *      Date      : 22nd November, 1989
  38.  *      Author    : John H. Winters
  39.  *      Changes   : Make sure Archimedes format files end with
  40.  *                  a line feed. (MS-DOS ones sometimes don't.)
  41.  *
  42.  *      Version   : 2.0
  43.  *      Date      : 16th May, 1993
  44.  *      Author    : John H. Winters
  45.  *      Changes   : Removed the use of RiscOSLib.  Recognize DOS type files.
  46.  *
  47.  *      Version   : 2.1
  48.  *      Date      : 25th May, 1993
  49.  *      Author    : John H. Winters
  50.  *      Changes   : Updated for Risc OS 3
  51.  *
  52.  *      Version   : 2.2
  53.  *      Date      : 21st November, 1993
  54.  *      Author    : John H. Winters
  55.  *      Changes   : Updated for new message handling.
  56.  *
  57.  *      Version   : 
  58.  *      Date      : 
  59.  *      Author    : 
  60.  *      Changes   : 
  61.  *
  62.  */
  63.  
  64. #include <stddef.h>
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #include <stdio.h>
  68. #include "kernel.h"
  69. #include "swis.h"
  70. #include "winapp.h"
  71. #include "wimplib.h"
  72. #include "global.h"
  73. #include "logging.h"
  74.  
  75. /*
  76.  *============================================================================
  77.  *
  78.  *  Hash defines.
  79.  *
  80.  *============================================================================
  81.  */
  82.  
  83. #define INFO_NAME "ProgInfo"
  84. #define MENU_INFO 0
  85. #define MENU_QUIT 1
  86.  
  87. #define TFN_VERSION 4
  88.  
  89. #define TEXT_FILE 0x0fff
  90. #define EXEC_FILE 0x0ffe
  91. #define DATA_FILE 0x0ffd
  92. #define OBEY_FILE 0x0feb
  93. #define DOS_FILE  0x0fe4
  94.  
  95. #define WORK_FILE "<Convert$Dir>.workfile"
  96.  
  97. /*
  98.  *============================================================================
  99.  *
  100.  *  Local data.
  101.  *
  102.  *============================================================================
  103.  */
  104.  
  105. static t_dbox InfoDbox ;
  106. static u8     version_string [] = Version " (21st Nov, 1993)" ;
  107.  
  108. /*
  109.  *============================================================================
  110.  *
  111.  *  Global data.
  112.  *
  113.  *============================================================================
  114.  */
  115.  
  116. const u8 WA_resource_dir [] = "Convert" ;
  117. const u8 WA_task_name []    = "Text file converter" ;
  118.  
  119. /*
  120.  *============================================================================
  121.  *
  122.  *  Forward declarations.
  123.  *
  124.  *============================================================================
  125.  */
  126.  
  127. /*
  128. static void AcknowledgeLoad (
  129.     const t_message_block *mb) ;
  130.  
  131. static uint ConvertFromIbm (
  132.     const u8 *name) ;
  133.  
  134. static uint ConvertToIbm (
  135.     const u8 *name) ;
  136. */
  137. static uint FileHandler (
  138.     t_poll_block *poll_block,
  139.     void         *reference) ;
  140.  
  141. static void HourglassOff (void) ;
  142.  
  143. static void HourglassOn (void) ;
  144.  
  145. static void MenuHandler (
  146.     void      *reference,
  147.     const int *hit) ;
  148.  
  149. static uint LogMessageHandler (
  150.     t_LOG_Severity /* severity */,
  151.     const U8 *     /* message */,
  152.     const U8 *     /* timestamp */) ;
  153.  
  154. static void SetType (
  155.     const u8 *name,
  156.     const u8 *type) ;
  157.  
  158. /*
  159.  *============================================================================
  160.  *
  161.  *  Externally visible routines.
  162.  *
  163.  *============================================================================
  164.  */
  165.  
  166. uint WA_BeginProcessing (void)
  167.  
  168. /*
  169.  *  Function :
  170.  *                Routine to start processing.
  171.  *
  172.  *  Parameters :
  173.  *                The usual.
  174.  *
  175.  *  Returns :
  176.  *                TRUE for success, FALSE for failure.
  177.  *
  178.  */
  179.  
  180. {
  181.     t_menu_block *menu ;
  182.     uint          result ;
  183.  
  184.     result = FALSE ;
  185.     menu = WA_BuildMenu ("Convert",
  186.                          ">Info,Quit") ;
  187.     if (menu != NULL)
  188.     {
  189.         /*
  190.          *  Put an icon on the icon bar.
  191.          */
  192.         if (WA_IconToBar ("!Convert", TRUE))
  193.         {
  194.             /*
  195.              *  Register a menu to be triggered when the icon is clicked on.
  196.              */
  197.             if (WA_AttachMenu (ICON_BAR,
  198.                                menu,
  199.                                MenuHandler,
  200.                                NULL))
  201.             {
  202.                 InfoDbox = WA_CreateDbox (INFO_NAME, FALSE, NULL, NULL) ;
  203.                 if (InfoDbox == NULL)
  204.                 {
  205.                     LOG_Error ("Can't create information dbox.\n") ;
  206.                 }
  207.                 else
  208.                 {
  209.                     WA_SetDboxField (InfoDbox,
  210.                                      TFN_VERSION,
  211.                                      version_string) ;
  212.                     /*
  213.                      *  Register a handler to deal with files dragged on to the icon.
  214.                      */
  215.                     if (WA_ClaimMessage (Message_DataLoad,
  216.                                          FileHandler,
  217.                                          NULL))
  218.                     {
  219.                         result = TRUE ;
  220.                     }
  221.                 }
  222.             }
  223.         }
  224.     }
  225.     return (result) ;
  226. }
  227.  
  228.  
  229. uint WA_LoadResources (void)
  230.  
  231. /*
  232.  *  Function :
  233.  *                  Load our resources as required.
  234.  *
  235.  *  Parameters :
  236.  *                  None.
  237.  *
  238.  *  Returns :
  239.  *                  TRUE for success, FALSE for failure.
  240.  *
  241.  */
  242.  
  243. {
  244.     t_LOG_HandlerMask mask ;
  245.  
  246.     mask.value = 0 ;
  247.     mask.b.LHM_Debug       = TRUE ;
  248.     mask.b.LHM_Info        = TRUE ;
  249.     mask.b.LHM_Warning     = TRUE ;
  250.     mask.b.LHM_Error       = TRUE ;
  251.     mask.b.LHM_SevereError = TRUE ;
  252.     if ((LOG_AddHandler (mask,
  253.                          LogMessageHandler)) &&
  254.         (WA_LoadSprites ("!Sprites")) &&
  255.         (WA_LoadTemplate ("Templates", INFO_NAME)))
  256.     {
  257.         return (TRUE) ;
  258.     }
  259.     else
  260.     {
  261.         return (FALSE) ;
  262.     }
  263. }
  264.  
  265. /*
  266.  *============================================================================
  267.  *
  268.  *  Local routines.
  269.  *
  270.  *============================================================================
  271.  */
  272.  
  273. static void AcknowledgeLoad (
  274.     const t_message_block *mb)
  275.  
  276. /*
  277.  *  Function :
  278.  *                  Send a data load ack message.
  279.  *
  280.  *  Parameters :
  281.  *                  mb  Incoming data load message.
  282.  *
  283.  *  Returns :
  284.  *                  None.
  285.  *
  286.  */
  287.  
  288. {
  289.     t_destinee      destinee ;
  290.     t_message_block reply ;
  291.  
  292.     destinee.value = mb->sender ;
  293.     reply          = *mb ;
  294.     reply.my_ref   = 0 ;
  295.     reply.your_ref = mb->my_ref ;
  296.     reply.action   = Message_DataLoadAck ;
  297.     LOG_OSError (WIMP_SendMessage (ET_UserMessage,
  298.                                    &reply,
  299.                                    destinee,
  300.                                    0)) ;
  301. }
  302.  
  303.  
  304. static uint ConvertFromIbm (
  305.     const u8 *name)
  306.  
  307. /*
  308.  * Function :
  309.  *                Convert a named text file which is in IBM format to
  310.  *                Archimedes format.
  311.  *
  312.  * Parameters :
  313.  *                name    The name of the file to convert.
  314.  *
  315.  * Returns :
  316.  *                TRUE if it succeeds, FALSE otherwise.
  317.  *
  318.  */
  319.  
  320. {
  321.     sint  character ;
  322.     FILE *in_stream ;
  323.     uint  offset = 0 ;
  324.     FILE *out_stream ;
  325.  
  326.     in_stream = fopen (name, "rb") ;
  327.     if (in_stream == NULL)
  328.     {
  329.         LOG_Error ("Can't find file - \"%s\".\n",
  330.                    name) ;
  331.         return (FALSE) ;
  332.     }
  333.     else
  334.     {
  335.         out_stream = fopen (WORK_FILE, "w") ;
  336.         if (out_stream == NULL)
  337.         {
  338.             LOG_Error ("Can't open work file.\n") ;
  339.             fclose (in_stream) ;
  340.             return (FALSE) ;
  341.         }
  342.         else
  343.         {
  344.             /*
  345.              *  Process from source to work file.
  346.              */
  347.             while (character = getc (in_stream),
  348.                    ((character != EOF) &&
  349.                     (character != '\x1A')))
  350.             {
  351.                 switch (character)
  352.                 {
  353.                     case '\r' :
  354.                         /*
  355.                          *  Throw these away.
  356.                          */
  357.                          break ;
  358.  
  359.                     case '\t' :
  360.                         /*
  361.                          *  Have to inject spaces up to the next tab
  362.                          *  position. N.B. Always insert at least one.
  363.                          */
  364.                         do
  365.                         {
  366.                             putc (' ', out_stream) ;
  367.                             offset++ ;
  368.                         }
  369.                         while (((offset / 8) * 8) != offset) ;
  370.                         break ;
  371.  
  372.                     case '\n' :
  373.                         offset = 0 ;
  374.                         putc (character, out_stream) ;
  375.                         break ;
  376.  
  377.                     default :
  378.                         offset++ ;
  379.                         putc (character, out_stream) ;
  380.                         break ;
  381.  
  382.                 }
  383.             }
  384.             if (offset != 0)
  385.             {
  386.                 putc ('\n', out_stream) ;
  387.             }
  388.             fclose (out_stream) ;
  389.             fclose (in_stream) ;
  390.             /*
  391.              *  Now copy the whole caboodle back again.
  392.              */
  393.             in_stream = fopen (WORK_FILE, "r") ;
  394.             if (in_stream == NULL)
  395.             {
  396.                 LOG_Error ("Can't open work file at second attempt.\n") ;
  397.                 return (FALSE) ;
  398.             }
  399.             else
  400.             {
  401.                 out_stream = fopen (name, "w") ;
  402.                 if (out_stream == NULL)
  403.                 {
  404.                     LOG_Error ("Can't overwrite file - \"%s\".\n",
  405.                                name) ;
  406.                     fclose (in_stream) ;
  407.                     return (FALSE) ;
  408.                 }
  409.                 else
  410.                 {
  411.                     while ((character = getc (in_stream)) != EOF)
  412.                     {
  413.                         putc (character, out_stream) ;
  414.                     }
  415.                     fclose (in_stream) ;
  416.                     fclose (out_stream) ;
  417.                     /*
  418.                      *  Delete the temporary file and return success.
  419.                      */
  420.                     remove (WORK_FILE) ;
  421.                     SetType (name, "Text") ;
  422.                     return (TRUE) ;
  423.                 }
  424.             }
  425.         }
  426.     }
  427. }
  428.  
  429.  
  430. static uint ConvertToIbm (
  431.     const u8 *name)
  432.  
  433. /*
  434.  * Function :
  435.  *                Convert a named text file to IBM format.
  436.  *
  437.  * Parameters :
  438.  *                name    The name of the file to convert.
  439.  *
  440.  * Returns :
  441.  *                TRUE if it is succesfully converted, FALSE otherwise.
  442.  *
  443.  */
  444.  
  445. {
  446.     sint  character ;
  447.     FILE *in_stream ;
  448.     FILE *out_stream ;
  449.  
  450.     in_stream = fopen (name, "r") ;
  451.     if (in_stream == NULL)
  452.     {
  453.         LOG_Error ("Can't read file - \"%s\".\n",
  454.                    name) ;
  455.         return (FALSE) ;
  456.     }
  457.     else
  458.     {
  459.         out_stream = fopen (WORK_FILE, "wb") ;
  460.         if (out_stream == NULL)
  461.         {
  462.             LOG_Error ("Can't open work file.\n") ;
  463.             fclose (in_stream) ;
  464.             return (FALSE) ;
  465.         }
  466.         else
  467.         {
  468.             /*
  469.              *  Process from source to work file.
  470.              */
  471.             while ((character = getc (in_stream)) != EOF)
  472.             {
  473.                 if (character == '\n')
  474.                 {
  475.                     putc ('\r', out_stream) ;
  476.                 }
  477.                 putc (character, out_stream) ;
  478.             }
  479.             putc ('\x1A', out_stream) ;
  480.             fclose (out_stream) ;
  481.             fclose (in_stream) ;
  482.             /*
  483.              *  Now copy the whole caboodle back again.
  484.              */
  485.             in_stream = fopen (WORK_FILE, "rb") ;
  486.             if (in_stream == NULL)
  487.             {
  488.                 LOG_Error ("Can't open work file at second attempt.\n") ;
  489.                 return (FALSE) ;
  490.             }
  491.             else
  492.             {
  493.                 out_stream = fopen (name, "wb") ;
  494.                 if (out_stream == NULL)
  495.                 {
  496.                     LOG_Error ("Can't overwrite file - \"%s\".\n",
  497.                                name) ;
  498.                     fclose (in_stream) ;
  499.                     return (FALSE) ;
  500.                 }
  501.                 else
  502.                 {
  503.                     while ((character = getc (in_stream)) != EOF)
  504.                     {
  505.                         putc (character, out_stream) ;
  506.                     }
  507.                     fclose (in_stream) ;
  508.                     fclose (out_stream) ;
  509.                     /*
  510.                      *  Delete the temporary file and return success.
  511.                      */
  512.                     remove (WORK_FILE) ;
  513.                     SetType (name, "DOS") ;
  514.                     return (TRUE) ;
  515.                 }
  516.             }
  517.         }
  518.     }
  519. }
  520.  
  521.  
  522. static uint FileHandler (
  523.     t_poll_block *poll_block,
  524.     void         *reference)
  525.  
  526. /*
  527.  *  Function :
  528.  *                Handle a file load indication.
  529.  * 
  530.  *  Parameters :
  531.  *                poll_block    Poll block containing relevant event.
  532.  *
  533.  *  Returns :
  534.  *                None.
  535.  *
  536.  */
  537.  
  538. {
  539.     uint result ;
  540.  
  541.     result = FALSE ;
  542.     reference = reference ;
  543.     /*
  544.      *  This is potentially one for us.
  545.      */
  546.     switch (poll_block->data.mb.data.da.file_type)
  547.     {
  548.         case TEXT_FILE :
  549.         case OBEY_FILE :
  550.         case EXEC_FILE :
  551.             HourglassOn () ;
  552.             if (ConvertToIbm (poll_block->data.mb.data.da.file_name))
  553.             {
  554.                 AcknowledgeLoad (&poll_block->data.mb) ;
  555.                 result = TRUE ;
  556.             }
  557.             HourglassOff () ;
  558.             break ;
  559.  
  560.         case DATA_FILE :
  561.         case DOS_FILE :
  562.             HourglassOn () ;
  563.             if (ConvertFromIbm (poll_block->data.mb.data.da.file_name))
  564.             {
  565.                 AcknowledgeLoad (&poll_block->data.mb) ;
  566.                 result = TRUE ;
  567.             }
  568.             HourglassOff () ;
  569.             break ;
  570.  
  571.         default :
  572.             LOG_Error ("File type %04.4x is unsuitable for conversion.\n",
  573.                        poll_block->data.mb.data.da.file_type) ;
  574.             break ;
  575.  
  576.     }
  577.     return (result) ;
  578. }
  579.  
  580.  
  581. static void HourglassOff (void)
  582.  
  583. /*
  584.  *  Function :
  585.  *                  Turn the hourglass off.
  586.  *
  587.  *  Parameters :
  588.  *                  None.
  589.  *
  590.  *  Returns :
  591.  *                  None.
  592.  *
  593.  */
  594.  
  595. {
  596.     _kernel_swi_regs r ;
  597.  
  598.     _kernel_swi (Hourglass_Off, &r, &r) ;
  599. }
  600.  
  601.  
  602. static void HourglassOn (void)
  603.  
  604. /*
  605.  *  Function :
  606.  *                  Turn the hourglass on.
  607.  *
  608.  *  Parameters :
  609.  *                  None.
  610.  *
  611.  *  Returns :
  612.  *                  None.
  613.  *
  614.  */
  615.  
  616. {
  617.     _kernel_swi_regs r ;
  618.  
  619.     _kernel_swi (Hourglass_On, &r, &r) ;
  620. }
  621.  
  622.  
  623. static void MenuHandler (
  624.     void      *reference,
  625.     const int *hit)
  626.  
  627. /*
  628.  * Function :
  629.  *                Handle a user selection from a menu.
  630.  *
  631.  * Parameters :
  632.  *                handle    The handle of the menu the user has selected
  633.  *                          from.
  634.  *                hit       Pointer to indication of user's selection.
  635.  *
  636.  * Returns :
  637.  *                None.
  638.  *
  639.  */
  640.  
  641. {
  642.     reference = reference ;
  643.  
  644.     switch (*hit)
  645.     {
  646.         case MENU_INFO :
  647.             WA_DisplayDbox (InfoDbox) ;
  648.             break ;
  649.  
  650.         case MENU_QUIT :
  651.             WA_WindUp () ;
  652.             break ;
  653.  
  654.     }
  655. }
  656.  
  657.  
  658. static uint LogMessageHandler (
  659.     t_LOG_Severity severity,
  660.     const U8 *     message,
  661.     const U8 *     timestamp)
  662.  
  663. /*
  664.  *  Function :
  665.  *                  Display error messages.
  666.  *
  667.  *  Parameters :
  668.  *                  severity    Severity of the error.
  669.  *                  message     Text of message.
  670.  *                  timestamp   Time stamp.
  671.  *
  672.  *  Returns :
  673.  *                  TRUE
  674.  *
  675.  */
  676.  
  677. {
  678.     timestamp = timestamp ;
  679.     if ((severity == LS_Error) ||
  680.         (severity == LS_SevereError))
  681.     {
  682.         WA_Report (message) ;
  683.     }
  684.     return (TRUE) ;
  685. }
  686.  
  687.  
  688. static void SetType (
  689.     const u8 *name,
  690.     const u8 *type)
  691.  
  692. /*
  693.  *  Function :
  694.  *                      Set the type of a file (not the best way).
  695.  *
  696.  *  Parameters :
  697.  *                      name    Name of file to change.
  698.  *                      type    Type to set it to.
  699.  *
  700.  *  Returns :
  701.  *                      None.
  702.  *
  703.  */
  704.  
  705. {
  706.     u8 buffer [512] ;
  707.  
  708.     sprintf (buffer, "settype %s %s", name, type) ;
  709.     system (buffer) ;
  710. }
  711.