chomp.bush

# File : chomp.bush

    #!/usr/local/bin/bush
    --
    -- Morph
    --
    -- Program to convert one kind of text file to another
    -- Created by Ken O. Burtch
    --
    -- Like chomp2, but without praga ada_95

    pragma restriction( no_external_commands );

    -- Error codes

    error_syntax   : constant short_short_integer := 192;
    error_no_file  : constant short_short_integer := 193;
    error_internal : constant short_short_integer := 194;

    -- Script Flags

    type text_types is ( unknown, dos, mac, unix, broken, binary, c, strip );
    -- conversions we can do

    target_type : text_types := unknown;
    verbose : boolean := true; -- was false

    -- Files

    input      : file_type;
    sourcepath : string;
    output     : file_type;
    targetpath : string;

    -- Misc

    textline   : string;
    len        : natural;
    ch         : character;
    out_cnt    : natural := 0;

    -- Usage

    if $# < 3 then
       if $# > 0 then
          if $1 = "-h" or $1 = "--help" then
             put( "usage: " )
               @( source_info.file );
             put_line( " -cdmsuv sourcefile targetfile" );
             new_line;
             put_line( "  Morph text files into different formats." );
             new_line;
             put_line( "  -d convert to MS-DOS or Windows (CR+LF)" )
                    @( "  -m convert to Apple or Mac (CR)" )
                    @( "  -u convert to UNIX or Linux (LF)" )
                    @( "  -c convert to C or C++ (NUL)" )
                    @( "  -s strip CR and LF" )
                    @( "  -v verbose" );
             command_line.set_exit_status( 0 );
             return;
          end if;
       end if;
       put( standard_error, source_info.file );
       put_line( standard_error, ": use -h for help" );
       command_line.set_exit_status( error_syntax );
       return;
    end if;

    -- Process arguments

    for i in 1..$#-2 loop
       if command_line.argument(i) = "-d" then
          if target_type /= unknown then
             put( standard_error, source_info.file )
               @( standard_error, ":" )
               @( standard_error, source_info.line );
             put_line( standard_error, ": more than 1 conversion" );
             command_line.set_exit_status( error_syntax );
             return;
          end if;
          target_type := dos;
       elsif command_line.argument(i) = "-m" then
          if target_type /= unknown then
             put( standard_error, source_info.file )
               @( standard_error, ":" )
               @( standard_error, source_info.line );
             put_line( standard_error, ": more than 1 conversion" );
             command_line.set_exit_status( error_syntax );
             return;
          end if;
          target_type := mac;
       elsif command_line.argument(i) = "-u" then
          if target_type /= unknown then
             put( standard_error, source_info.file )
               @( standard_error, ":" )
               @( standard_error, source_info.line );
             put_line( standard_error, ": more than 1 conversion" );
             command_line.set_exit_status( error_syntax );
             return;
          end if;
          target_type := unix;
       elsif command_line.argument(i) = "-c" then
          if target_type /= unknown then
             put( standard_error, source_info.file )
               @( standard_error, ":" )
               @( standard_error, source_info.line );
             put_line( standard_error, ": more than 1 conversion" );
             command_line.set_exit_status( error_syntax );
             return;
          end if;
          target_type := c;
       elsif command_line.argument(i) = "-s" then
          if target_type /= unknown then
             put( standard_error, source_info.file )
               @( standard_error, ":" )
               @( standard_error, source_info.line );
             put_line( standard_error, ": more than 1 conversion" );
             command_line.set_exit_status( error_syntax );
             return;
          end if;
          target_type := strip;
       elsif command_line.argument(i) = "-v" then
          verbose := true;
       else
          put( standard_error, source_info.file )
            @( standard_error, ":" )
            @( standard_error, source_info.line );
          put_line( standard_error, ": unknown option: " & command_line.argument(i) );
          command_line.set_exit_status( error_syntax );
          return;
       end if;
    end loop;

    -- Check files

    sourcepath := command_line.argument(command_line.argument_count-1);
    targetpath := command_line.argument(command_line.argument_count);
    if not files.is_readable_file( sourcepath ) then
       put( standard_error, source_info.file )
         @( standard_error, ":" )
         @( standard_error, source_info.line );
       put_line( standard_error, ": " & sourcepath & " doesn't exist or is not readable" );
       command_line.set_exit_status( error_no_file );
       return;
    end if;

    -- Do it

    create( output, out_file, targetpath );
    open( input, in_file, sourcepath );
    while not end_of_file( input ) loop
       -- strip end-of-line terminators
       -- Note: BUSH should do this automatically.
       textline := get_line( input );
       if verbose then
          put( standard_error, "<< " );
          put_line( standard_error, strings.to_escaped( textline ) );
       end if;
       len := strings.length( textline );
       ch := strings.element( textline, positive( len ) );
       if ch = ASCII.LF then
          textline := strings.delete( textline, positive(len), len );
          len := len - 1;
          ch := strings.element( textline, positive( len ) );
          if ch = ASCII.CR then
             textline := strings.delete( textline, positive( len ), len );
          end if;
      elsif ch = ASCII.CR then
          textline := strings.delete( textline, positive( len ), len );
      end if;
      -- now add the correct ones
      case target_type is
      when dos =>
           textline := @ & ASCII.CR & ASCII.LF;
      when mac =>
           textline := @ & ASCII.CR;
      when unix =>
           textline := @ & ASCII.LF;
      when c =>
           textline := @ & ASCII.NUL;
      when strip =>
           null;
      when others =>
           put( standard_error, source_info.file )
             @( standard_error, ":" )
             @( standard_error, source_info.line );
           put_line( standard_error,  ": internal error: target type in case" );

           command_line.set_exit_status( error_internal );
           return;
      end case;
      if verbose then
         put( standard_error, ">> " );
         put_line( standard_error, strings.to_escaped( textline ) );
      end if;
      len := strings.length( textline );
      out_cnt := @+len;
      put( output, textline ); -- NOT put_line
    end loop;
    close( input ) @ ( output );

    if verbose then
       put( standard_error, "Wrote" ) @ ( standard_error, out_cnt );
       put_line( standard_error, " chars" );
    end if;
    command_line.set_exit_status( 0 );