# File : chomp2.bush

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

    pragma ada_95;
    pragma restriction( no_external_commands );

    procedure chomp2 is

    -- 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;

       procedure usage is
       begin
         put( "usage: " );
         put( 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)" );
         put_line( "  -m convert to Apple or Mac (CR)" );
         put_line( "  -u convert to UNIX or Linux (LF)" );
         put_line( "  -c convert to C or C++ (NUL)" );
         put_line( "  -s strip CR and LF" );
         put_line( "  -v verbose" );
       end usage;

    begin

    -- Usage

    if command_line.argument_count < 3 then
       if command_line.argument_count > 0 then
          if command_line.argument(1) = "-h" or command_line.argument(1) = "--help" then
             usage;
             command_line.set_exit_status( 192 );
             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..command_line.argument_count-2 loop
       if command_line.argument(i) = "-d" then
          if target_type /= unknown then
             put( standard_error, source_info.file );
             put( standard_error, ":" );
             put( 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 );
             put( standard_error, ":" );
             put( 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 );
             put( standard_error, ":" );
             put( 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 );
             put( standard_error, ":" );
             put( 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 );
             put( standard_error, ":" );
             put( 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 );
          put( standard_error, ":" );
          put( 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 );
       put( standard_error, ":" );
       put( 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 := textline & ASCII.CR & ASCII.LF;
      when mac =>
           textline := textline & ASCII.CR;
      when unix =>
           textline := textline & ASCII.LF;
      when c =>
           textline := textline & ASCII.NUL;
      when strip =>
           null;
      when others =>
           put( standard_error, source_info.file );
           put( standard_error, ":" );
           put( 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 := out_cnt+len;
      put( output, textline ); -- NOT put_line
    end loop;
    close( input );
    close( output );

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

    end chomp2;