Category talk:ALGOL 68-files

From Rosetta Code

Source code

# files.incl.a68: file related operators, procedure etc.                      #

    PRIO EACHLINE = 9;

    # applies p to each line of the file with path file name                  #
    # returns the number of lines in the file if sucessful,                   #
    #         -1 if the file couldn't be opened                               #
    OP   EACHLINE = ( STRING file name, PROC(STRING)VOID p )INT:
         IF FILE input file;
            open( input file, file name, stand in channel ) /= 0
         THEN -1                                    # failed to open the file #
         ELSE                                                # file opened OK #
            BOOL at eof := FALSE;
            # set the EOF handler for the file                                #
            on logical file end
               ( input file
               , ( REF FILE f )BOOL: # note that we reached EOF on the latest #
                     at eof := TRUE  # read and return TRUE so processing can #
                                     #                               continue #
               );
            INT count := 0;
            WHILE STRING line;
                  get( input file, ( line, newline ) );
                  NOT at eof
            DO
                count +:= 1;
                p( line )
            OD;
            close( input file );
            count
         FI # EACHLINE # ;

    # applies p to each line of the file with path file name                  #
    # returns if sucessful, the number of lines in the file where p           #
    #         returned TRUE if sucessful, -1 if the file couldn't be opened   #
    OP   EACHLINE = ( STRING file name, PROC(STRING,INT)BOOL p )INT:
         IF FILE input file;
            open( input file, file name, stand in channel ) /= 0
         THEN -1                                    # failed to open the file #
         ELSE                                                # file opened OK #
            BOOL at eof := FALSE;
            # set the EOF handler for the file                                #
            on logical file end
               ( input file
               , ( REF FILE f )BOOL: # note that we reached EOF on the latest #
                     at eof := TRUE  # read and return TRUE so processing can #
                                     #                               continue #
               );
            INT count := 0;
            WHILE STRING line;
                  get( input file, ( line, newline ) );
                  NOT at eof
            DO
                IF p( line, count ) THEN count +:= 1 FI
            OD;
            close( input file );
            count
         FI # EACHLINE # ;

    # prints all lines from file name                                         #
    # returns the number of lines in the file if successful,                  #
    #         -1 if the file could not be opened                              #
    OP   PRINTLINES = ( STRING file name )INT:
         BEGIN PROC print line = ( STRING line )VOID: print( ( line, newline ) );
               file name EACHLINE print line
         END # PRINTLINES # ;

    # returns the lines from file name or an empty row if the file couldn't   #
    #         be opened                                                       #
    OP   READLINES = ( STRING file name )REF[]STRING:
         BEGIN
            REF[]STRING lines := HEAP[ 1 : 2000 ]STRING;
            INT line pos := 0;

            # adds line to lines, extending lines if necessary                #
            PROC read line = ( STRING line )VOID:
                 BEGIN
                    IF ( line pos +:= 1 ) > UPB lines THEN
                        # lines isn't big enoough                             #
                        REF[]STRING new lines := HEAP[ 1 : UPB lines + 2000 ]STRING;
                        new lines[ 1 : UPB lines ] := lines;
                        lines := new lines
                    FI;
                    lines[ line pos ] := line
                 END # read line # ;

            VOID( file name EACHLINE read line );
            HEAP[ 1 : line pos ]STRING := lines[ 1 : line pos ]
         END # READLINES # ;

    PRIO APPENDLINES = 9;

    # appends lines to the the end of the file named file name                #
    # the file is created if it doesn't exist                                 #
    # returns TRUE if sucessful, FALSE if the file could not be opened        #
    OP   APPENDLINES = ( STRING file name, []STRING lines )BOOL:
         IF   REF[]STRING existing lines = READLINES file name;
              FILE output file;
              IF   open( output file, file name, stand out channel ) = 0
              THEN 0      # OK - file already exists and will be overwritten #
              ELSE       # failed to open the file - try creating a new file #
                   establish( output file, file name, stand out channel )
              FI /= 0
         THEN FALSE                     # unable to open the file for writing #
         ELSE                                         # output file opened OK #
              FOR i FROM LWB existing lines TO UPB existing lines DO
                  put( output file, ( existing lines[ i ], newline ) )
              OD;
              FOR i FROM LWB lines TO UPB lines DO
                  put( output file, ( lines[ i ], newline ) )
              OD;
              close( output file );
              TRUE
         FI # APPENDLINES # ;


# END files.incl.a68                                                          #