Task: Read a configuration file





Java: import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ConfigReader {
    private static final Pattern             LINE_PATTERN = Pattern.compile( "([^ =]+)[ =]?(.*)" );
    private static final Map<String, Object> DEFAULTS     = new HashMap<String, Object>() {{
        put( "needspeeling", false );
        put( "seedsremoved", false );
    }};

    public static void main( final String[] args ) {
        System.out.println( parseFile( args[ 0 ] ) );
    }

    public static Map<String, Object> parseFile( final String fileName ) {
        final Map<String, Object> result = new HashMap<String, Object>( DEFAULTS );
         BufferedReader      reader = null;

        try {
            reader = new BufferedReader( new FileReader( fileName ) );
            for ( String line; null != ( line = reader.readLine() );  ) {
                parseLine( line, result );
            }
        } catch ( final IOException x ) {
            throw new RuntimeException( "Oops: " + x, x );
        } finally {
            if ( null != reader ) try {
                reader.close();
            } catch ( final IOException x2 ) {
                System.err.println( "Could not close " + fileName + " - " + x2 );
            }
        }

        return result;
    }

    private static void parseLine( final String line, final Map<String, Object> map ) {
        if ( "".equals( line.trim() ) || line.startsWith( "#" ) || line.startsWith( ";" ) )
            return;

        final Matcher matcher = LINE_PATTERN.matcher( line );

        if ( ! matcher.matches() ) {
            System.err.println( "Bad config line: " + line );
            return;
        }

        final String key   = matcher.group( 1 ).trim().toLowerCase();
        final String value = matcher.group( 2 ).trim();

        if ( "".equals( value ) ) {
            map.put( key, true );
        } else if ( -1 == value.indexOf( ',' ) ) {
            map.put( key, value );
        } else {
            final String[] values = value.split( "," );

            for ( int i = 0; i < values.length; i++ ) {
                values[ i ] = values[ i ].trim();
            }
            map.put( key, Arrays.asList( values ) );
        }
    }
}





COBOL:        identification division.
       program-id. ReadConfiguration.

       environment division.
       configuration section.
       repository.
           function all intrinsic.

       input-output section.
       file-control.
           select config-file     assign to "Configuration.txt"
                                  organization line sequential.
       data division.
       file section.

       fd  config-file.
       01  config-record          pic is x(128).

       working-storage section.
       77  idx                    pic 9(3).
       77  pos                    pic 9(3).
       77  last-pos               pic 9(3).
       77  config-key             pic x(32).
       77  config-value           pic x(64).
       77  multi-value            pic x(64).
       77  full-name              pic x(64).
       77  favourite-fruit        pic x(64).
       77  other-family           pic x(64) occurs 10.
       77  need-speeling          pic x(5) value "false".
       77  seeds-removed          pic x(5) value "false".

       procedure division.
       main.
           open input config-file
           perform until exit
              read config-file
                 at end
                    exit perform
              end-read  
              move trim(config-record) to config-record
              if config-record(1:1) = "#" or ";" or spaces
                 exit perform cycle
              end-if
              unstring config-record delimited by spaces into config-key
              move trim(config-record(length(trim(config-key)) + 1:)) to config-value
              if config-value(1:1) = "="
                 move trim(config-value(2:)) to config-value
              end-if
              evaluate upper-case(config-key)
                 when "FULLNAME"
                    move config-value to full-name
                 when "FAVOURITEFRUIT"
                    move config-value to favourite-fruit
                 when "NEEDSPEELING"
                    if config-value = spaces
                       move "true" to config-value
                    end-if
                    if config-value = "true" or "false"
                       move config-value to need-speeling
                    end-if
                 when "SEEDSREMOVED"
                    if config-value = spaces
                       move "true" to config-value
                    end-if,
                    if config-value = "true" or "false"
                       move config-value to seeds-removed
                    end-if
                 when "OTHERFAMILY"
                    move 1 to idx, pos
                    perform until exit
                       unstring config-value delimited by "," into multi-value with pointer pos
                          on overflow
                             move trim(multi-value) to other-family(idx)
                             move pos to last-pos
                          not on overflow
                             if config-value(last-pos:) <> spaces
                                move trim(config-value(last-pos:)) to other-family(idx)
                             end-if,
                             exit perform
                       end-unstring
                       add 1 to idx
                    end-perform
              end-evaluate
           end-perform
           close config-file

           display "fullname = " full-name
           display "favouritefruit = " favourite-fruit
           display "needspeeling = " need-speeling
           display "seedsremoved = " seeds-removed
           perform varying idx from 1 by 1 until idx > 10
              if other-family(idx) <> low-values
                 display "otherfamily(" idx ") = " other-family(idx)
              end-if
           end-perform
           .