Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

five simple cobol programs

2013-09-04
2013-09-15
  • steve williams
    steve williams
    2013-09-04

    I have five simple cobol programs showing common cobol techniques. Each program builds on its predecessor. I'd like to upload these to the OpenCobol contributions folder.

     
    • Simon Sobisch
      Simon Sobisch
      2013-09-04

      Hi Steve,

      sounds good. I guess they're heavily described via COBOL comments? What
      is the main purpose of these samples? I'd suggest to post them here so
      we can have a look at them.

      Simon

       
  • steve williams
    steve williams
    2013-09-04

    Hi Simon,

    Each program modifies its predecessor.

    The five programs are:

    1. read a CSV file, checking file status with a nested subprogram and report records read, elapsed time and records per second
    2. move the nested file checking code to a copylib, load and search a lookup table
    3. move the displays of records read, elapsed time and records per second and the display of data to print files.
    4. move the performance print file code to a called subroutine, add a sort verb and print summary data for selected records.
    5. select records with latitude and longitude in a defined polygon.

    I wouldn't say the programs are well-commented. I tried to make the code readable.

    Steve

    Here's the first program:

           identification division.
           program-id. worldcities0.
          *> =============================================
          *> 1) read a CSV file and create some run counts
          *> =============================================
          *> cobc worldcities0.cbl -free -x
          *> ./worldcities0
          *> =============================================
           environment division.
           input-output section.
           file-control.
          *>
          *>  download and untar
          *>  www.maxmind.com/en/worldcities
          *>  size is 151 mb
          *>
               select cities-file
                   assign to cities-file-name
                   file status is cities-file-status
                   organization is line sequential.
    
           data division.
           file section.
           fd  cities-file.
           01  city-record pic x(80).
    
           working-storage section.
    
           01  cities-file-name pic x(64) value './worldcitiespop.txt'.
           01  cities-file-status pic x(2).
           01  cities-count pic 9(9) value zero.
    
           01  city-columns.
               03  country pic x(3).
               03  city pic x(32).
               03  accent-city pic x(32).
               03  region pic x(3).
               03  population pic 9(9).
               03  latitude pic s9(3)v9(6).
               03  longitude pic s9(3)v9(6).
    
           01  current-time.
               03  ct-hour pic 99.
               03  ct-minute pic 99.
               03  ct-second pic 99.
               03  ct-hundredth pic 99.
    
           01  start-seconds pic 9(7)v99.
           01  end-seconds pic 9(7)v99.
           01  elapsed-seconds pic 9(7)v99.
           01  display-elapsed-seconds pic zzzzz9.99.
           01  display-count pic z,zzz,zzz.
           01  records-per-second pic z,zzz,zz9.
    
           procedure division.
           start-worldcities0.
               display 'starting worldcities0'.
    
               open input cities-file
               call 'checkfilestatus' using cities-file-name cities-file-status
    
               accept current-time from time
               compute start-seconds =
                   ct-hour * 60 * 60
                   + ct-minute * 60
                   + ct-second
                   + ct-hundredth / 100
    
               read cities-file
    
               perform until cities-file-status = '10'
                   add 1 to cities-count
    
                   unstring city-record delimited by ',' into
                       country
                       city
                       accent-city
                       region
                       population
                       latitude
                       longitude
    
          *>         compile with -fdebugging-line to see 10 records
          >>D        if cities-count <= 10
          >>D            display city-record
          >>D            display city-columns
          >>D        end-if
    
                   read cities-file
               end-perform
    
               accept current-time from time
               compute end-seconds =
                   ct-hour * 60 * 60
                   + ct-minute * 60
                   + ct-second
                   + ct-hundredth / 100
    
               close cities-file
    
               move cities-count to display-count
               display display-count space 'cities'
    
               compute elapsed-seconds = end-seconds - start-seconds
               move elapsed-seconds to display-elapsed-seconds
               display display-elapsed-seconds ' elapsed seconds'
    
               compute records-per-second = cities-count / elapsed-seconds
                   on size error move 0 to records-per-second
               end-compute
               display records-per-second ' cities per second'
    
               display 'ending worldcities0'
               .
    
           identification division.
           program-id. checkfilestatus.
    
           data division.
           working-storage section.
           01  status-message pic x(72).
           01  display-message pic x(72) value spaces.
    
           linkage section.
           01  file-name pic x(64).
           01  file-status pic x(2).
    
           procedure division using file-name file-status.
           start-checkfilestatus.
               if file-status = '00'
                   goback
               end-if
               evaluate file-status
               when 00 move 'SUCCESS.' TO status-message   
               when 02 move 'SUCCESS DUPLICATE.' TO status-message 
               when 04 move 'SUCCESS INCOMPLETE.' TO status-message 
               when 05 move 'SUCCESS OPTIONAL.' TO status-message 
               when 07 move 'SUCCESS NO UNIT.' TO status-message 
               when 10 move 'END OF FILE.' TO status-message 
               when 14 move 'OUT OF KEY RANGE.' TO status-message 
               when 21 move 'KEY INVALID.' TO status-message 
               when 22 move 'KEY EXISTS.' TO status-message 
               when 23 move 'KEY NOT EXISTS.' TO status-message 
               when 30 move 'PERMANENT ERROR.' TO status-message 
               when 31 move 'INCONSISTENT FILENAME.' TO status-message 
               when 34 move 'BOUNDARY VIOLATION.' TO status-message 
               when 35 move 'FILE NOT FOUND.' TO status-message 
               when 37 move 'PERMISSION DENIED.' TO status-message 
               when 38 move 'CLOSED WITH LOCK.' TO status-message 
               when 39 move 'CONFLICT ATTRIBUTE.' TO status-message 
               when 41 move 'ALREADY OPEN.' TO status-message 
               when 42 move 'NOT OPEN.' TO status-message 
               when 43 move 'READ NOT DONE.' TO status-message 
               when 44 move 'RECORD OVERFLOW.' TO status-message 
               when 46 move 'READ ERROR.' TO status-message 
               when 47 move 'INPUT DENIED.' TO status-message 
               when 48 move 'OUTPUT DENIED.' TO status-message 
               when 49 move 'I/O DENIED.' TO status-message 
               when 51 move 'RECORD LOCKED.' TO status-message 
               when 52 move 'END-OF-PAGE.' TO status-message 
               when 57 move 'I/O LINAGE.' TO status-message 
               when 61 move 'FILE SHARING FAILURE.' TO status-message 
               when 91 move 'FILE NOT AVAILABLE.' TO status-message    
               end-evaluate
               string 'ERROR ' delimited by size
                   file-name delimited by space
                   space delimited by size
                   status-message delimited by '.'
                   into display-message
               display display-message
               stop run
               .
           end program checkfilestatus.
           end program worldcities0.
    
     
    Last edit: Simon Sobisch 2013-09-05
  • steve williams
    steve williams
    2013-09-04

    Simon,

    As you see, I know nothing about sourceforge markdown. Trust me, the comment markers and indentations are in the original code.

    Steve

     
    • Simon Sobisch
      Simon Sobisch
      2013-09-05

      Hi Steve,

      nice piece of code so far. I did a little markup (as described in "Formating Help": for source code just place an empty line before and surround the source with two lines of tildes. For COBOL highlighting put :::cobol below the first line with tildes). Not sure if everything looks like the original source, if not please edit the post and paste it there again (allowing you to see the markup I've added).

      I like the idea of these samples. For showing the missing ISAM parts another version can be included between 3-5 importing the CSV-file into an ISAM file. Maybe we can upload the samples to contrib/samples/worldcities in subdirectories v1/v2/.../vn. What do you think about that?

      Because of licence issues (and the size of the download) I'd like you to switch the data source to http://download.geonames.org/export/dump/ before upload, with the bonus of allowing users to use the full list with allCountries.zip (232 MB) or a lightweight one-country-only list. This gives the bonus possibility for adding more files like iso-languagecodes.txt, timeZones.txt, ... (just in case).

      Simon

       
  • Brian Tiffin
    Brian Tiffin
    2013-09-05

    Welcome Steve. Nice.

    Simon; I'll leave you with the task of getting Steve write access to the source tree?

    Steve; Would you like a developer account here on the forge? Comes with webspace etc, and you can then tweak the presentation to your liking (or, host other open source codes as well). All we need to do is mark you as a member of the project and SourceForge provides the rest. Umm, knowing that a forge developer account is first and foremost for hosting open sources, and secondarily for developer branding etc.

    Simon; woohoo on the :::cobol highlighting. If I'm not mistaken, that's from the Pygments code that team Pocoo accepted a few months ago. Woohoo.

    On another tangent, we'll likely be getting notes from Ron Norman soon, as he might be willing to take on adding report writer. I'll make a full post soon, and this is just an early heads up.

    Thanks Simon and Steve.

     
  • steve williams
    steve williams
    2013-09-05

    Hi Simon,

    Thanks for the cleanup -- it looks beautiful.

    Right now the entire series of programs consists of the 5 cobol programs, 3 shell files for the more complicated examples, a checkfilestatus.cpy and a writerunfile.cbl. I have a tar file.

    I will modify the code as you suggest to use better data.

    I wanted to add SQL in subsequent examples, but my efforts to install ocesql.1.0.0 and the postgresql development software have been abject failures.

    I have no experience with OpenCOBOL ISAM but I'll give it a try.

    Brian,

    I'm so new at this I'd prefer working with you and Simon rather than assuming the responsibility myself. Perhaps later, when I see how to do it correctly.

    In any case, I have no interest in developer branding.

    I'm including the next program in the series to see if I got Simon's formatting instructions properly.

    Steve

    identification division.
    program-id. worldcities1.
    *> ================================================
    *> modify worldcities0.cbl
    
    *> 1) add a country lookup table
    *> 2) move checkfilestatus to a copylib
    *> ================================================
    *> cobc worldcities1.cbl -free -x
    *> ./worldcities1
    *> ================================================
    environment division.
    configuration section.
    repository. function all intrinsic.
    input-output section.
    file-control.
    *>
    *>  download and untar
    *>  www.maxmind.com/en/worldcities
    *>  size is 151 mb
    *>
        select cities-file
            assign to cities-file-name
            file status is cities-file-status
            organization is line sequential.
    *>
    *> display, select and save as /ISO3166-2.txt
    *> http://www.iso.org/iso/home/standards/country_codes
    *>      /country_names_and_code_elements_txt.htm
    *> 
         select countries-file
            assign to countries-file-name
            file status is countries-file-status
            organization is line sequential.
    
    data division.
    file section.
    fd  countries-file.
    01  country-record pic x(80).
    
    fd  cities-file.
    01  city-record pic x(80).
    
    working-storage section.
    
    01  countries-file-name pic x(64) value './ISO3166-2.txt'.
    01  countries-file-status pic x(2).
    01  country-idx pic 9(3).
    01  country-max pic 9(3) value zero.
    01  country-lim pic 9(3) value 900.
    01  unknown-country pic x(15) value 'UNKNOWN COUNTRY'.
    01  countries-table.
        03  country-entry occurs 900.
            05  country-name pic x(64).
            05  country-code pic x(2).
    
    01  cities-file-name pic x(64) value './worldcitiespop.txt'.
    01  cities-file-status pic x(2).
    
    01  cities-count pic 9(9) value zero.
    01  country-count pic 9(9) value zero.
    
    01  city-columns.
        03  country pic x(3).
        03  city pic x(32).
        03  accent-city pic x(32).
        03  region pic x(3).
        03  population pic 9(9).
        03  latitude pic s9(3)v9(6).
        03  longitude pic s9(3)v9(6).
    
    01  current-country pic x(3) value space.
    01  current-country-name pic x(64).
    01  current-cities pic 9(6).
    01  display-current-cities pic zzz,zz9.
    01  current-population pic 9(9).
    01  display-current-population pic zzz,zzz,zz9.
    
    01  current-time.
        03  ct-hour pic 99.
        03  ct-minute pic 99.
        03  ct-second pic 99.
        03  ct-hundredth pic 99.
    
    01  start-seconds pic 9(7)v99.
    01  end-seconds pic 9(7)v99.
    01  elapsed-seconds pic 9(7)v99.
    01  display-elapsed-seconds pic zz,zz9.99.
    01  display-count pic z,zzz,zzz.
    01  records-per-second pic z,zzz,zz9.
    
    procedure division.
    start-worldcities1.
        display 'starting worldcities1'.
    
    *>  load the countries lookup table
        open input countries-file
        call 'checkfilestatus' using countries-file-name countries-file-status
    
    *>  skip the first record
        read countries-file
        call 'checkfilestatus' using countries-file-name countries-file-status
    
        read countries-file
        call 'checkfilestatus' using countries-file-name countries-file-status
        perform until countries-file-status = '10'
        or country-max >= country-lim
            add 1 to country-max
            move spaces to country-entry(country-max)
            unstring country-record delimited by ';' into
                country-name(country-max)
                country-code(country-max)
            move lower-case(country-code(country-max)) to country-code(country-max)
            read countries-file
            call 'checkfilestatus' using countries-file-name countries-file-status
        end-perform
        close countries-file
        if country-max >= country-lim
            display 'ERROR: countries file exceeds ' country-lim ' records'
            stop run
        end-if
    
        open input cities-file
        call 'checkfilestatus' using cities-file-name cities-file-status
    
    *>  skip the first record (column names)
        read cities-file
        call 'checkfilestatus' using cities-file-name cities-file-status
    
        accept current-time from time
        compute start-seconds =
            ct-hour * 60 * 60
            + ct-minute * 60
            + ct-second
            + ct-hundredth / 100
    
        read cities-file
        call 'checkfilestatus' using cities-file-name cities-file-status
        perform until cities-file-status = '10'
    
            move spaces to city-columns
            unstring city-record delimited by ',' into
                country
                city
                accent-city
                region
                population
                latitude
                longitude
    
            if country <> current-country
                perform end-country
                perform begin-country
            end-if
    
            add 1 to cities-count
            add 1 to current-cities
            add population to current-population
    
            read cities-file
            call 'checkfilestatus' using cities-file-name cities-file-status
        end-perform
        perform end-country
    
        accept current-time from time
        compute end-seconds =
            ct-hour * 60 * 60
            + ct-minute * 60
            + ct-second
            + ct-hundredth / 100
    
        close cities-file
    
        display ' '
        move country-max to display-count
        display display-count space 'country codes loaded'
    
        move country-count to display-count
        display display-count ' countries found'
    
        move cities-count to display-count
        display display-count ' cities'
    
        display ' '
        compute elapsed-seconds = end-seconds - start-seconds
        move elapsed-seconds to display-elapsed-seconds
        display display-elapsed-seconds ' elapsed seconds'
    
        compute records-per-second = cities-count / elapsed-seconds
            on size error move 0 to records-per-second
        end-compute
        display records-per-second ' cities per second'
    
        display ' '
        display 'ending worldcities1'
        stop run
        .
    begin-country.
        move country to current-country
        move zero to current-cities current-population
    
    *>  lookup without the search verb
        perform varying country-idx from 1 by 1
        until country-idx > country-max
        or country-code(country-idx) = current-country
            continue
        end-perform
    
        if country-idx > country-max
            move unknown-country to current-country-name
        else
            move country-name(country-idx) to current-country-name
        end-if
        .
    end-country.
        if current-country <> spaces
            add 1 to country-count
            move current-cities to display-current-cities
            move current-population to display-current-population
            display current-country
                space display-current-cities
                space display-current-population
                space current-country-name
        end-if
        .
    copy checkfilestatus.
    end program worldcities1.
    
     
    Last edit: Brian Tiffin 2013-09-05
    • Brian Tiffin
      Brian Tiffin
      2013-09-05

      Steve; I stepped in and made one small change.

      The Pygments COBOL highlighter supports both :::cobol and :::cobolfree. Your sources were more appropriate as cobolfree.

      Awesome, by the way.

      And yes on working these way cool samples through Simon and myself.

      Another trick is using the Add attachments feature of the Discussion forum posts. I've not done any limit testing, but I think we can attach just about any type and size of file. That might not be applicable to the cities file for the reasons Simon gave, but it'll likely work for most data and source code files.

      Cheers,
      Brian

       
      Last edit: Brian Tiffin 2013-09-05
  • steve williams
    steve williams
    2013-09-05

    Simon, Brian,

    Here's a version of worldcities0.cbl modified to read a file taken from
    http://download.geonames.org/export/dump/

    Steve

    identification division.
    program-id. worldcities0.
    *> =============================================
    *> 1) read a CSV file and create some run counts
    *> =============================================
    *> cobc worldcities0.cbl -free -x
    *> ./worldcities0
    *> =============================================
    environment division.
    input-output section.
    file-control.
    *>  
        select cities-file
            assign to cities-file-name
            file status is cities-file-status
            organization is line sequential.
    
    data division.
    file section.
    fd  cities-file.
    01  city-record pic x(1000).
    
    working-storage section.
    
    01  cities-file-name pic x(64) value './CA.txt'.
    01  cities-file-status pic x(2).
    01  cities-count pic 9(9) value zero.
    
    01  city-columns.
        03  geonameid pic 9(9).
        03  name pic x(200).
        03  asciiname pic x(200).
        03  alternatenames pic x(5000).
        03  latitude pic s9(3)v9(6).
        03  longitude pic s9(3)v9(6).
        03  featureclass pic x.
        03  featurecode pic x(10).
        03  countrycode pic x(2).
        03  cc2 pic x(60).
        03  admin1code pic x(60).
        03  admin2code pic x(80).
        03  admin3code pic x(20).
        03  admin4code pic x(20).
        03  population binary-double.
        03  elevation binary-long.
        03  dem binary-long.
        03  timezone pic x(40).
        03  modificationdate pic x(10).
    
    01  city-lengths.
        03  name-length pic 9(3).
        03  asciiname-length pic 9(3).
        03  alternatenames-length pic 9(4).
        03  cc2-length pic 9(2).
        03  admin1code-length pic 9(2).
        03  admin2code-length pic 9(2).
        03  admin3code-length pic 9(2).
        03  admin4code-length pic 9(2).
        03  timezone-length pic 9(2).
    
    01  current-time.
        03  ct-hour pic 99.
        03  ct-minute pic 99.
        03  ct-second pic 99.
        03  ct-hundredth pic 99.
    
    01  start-seconds pic 9(7)v99.
    01  end-seconds pic 9(7)v99.
    01  elapsed-seconds pic 9(7)v99.
    01  display-elapsed-seconds pic zzzzz9.99.
    01  display-count pic z,zzz,zzz.
    01  records-per-second pic z,zzz,zz9.
    
    procedure division.
    start-worldcities0.
        display 'starting worldcities0'.
    
        open input cities-file
        call 'checkfilestatus' using cities-file-name cities-file-status
    
        accept current-time from time
        compute start-seconds =
            ct-hour * 60 * 60
            + ct-minute * 60
            + ct-second
            + ct-hundredth / 100
    
        read cities-file
    
        perform until cities-file-status = '10'
            add 1 to cities-count
    
            unstring city-record delimited by x'09' into
                geonameid
                name count in name-length
                asciiname count in asciiname-length
                alternatenames count in alternatenames-length
                latitude
                longitude
                featureclass
                featurecode
                countrycode
                cc2 count in cc2-length
                admin1code count in admin1code-length
                admin2code count in admin2code-length
                admin3code count in admin3code-length
                admin4code count in admin4code-length
                population
                elevation
                dem
                timezone count in timezone-length
                modificationdate
    
    *>         compile with -fdebugging-line to see some records
    >>D        if cities-count > 1000 and < 1100
    >>D               display space
    >>D               display 'geonameid ' geonameid
    >>D               display 'name ' name(1:name-length)
    >>D               display 'asciiname ' asciiname(1:asciiname-length)
    >>D               display 'alternatenames ' alternatenames(1:alternatenames-length)
    >>D               display 'latitude ' latitude
    >>D               display 'longitude ' longitude
    >>D               display 'featureclass ' featureclass
    >>D               display 'featurecode ' featurecode
    >>D               display 'countrycode ' countrycode
    >>D               display 'cc2 ' cc2(1:cc2-length)
    >>D               display 'admin1code ' admin1code(1:admin1code-length)
    >>D               display 'admin2code ' admin2code(1:admin2code-length)
    >>D               display 'admin3code ' admin3code(1:admin3code-length)
    >>D               display 'admin4code ' admin4code(1:admin4code-length)
    >>D               display 'population ' population
    >>D               display 'elevation ' elevation
    >>D               display 'dem ' dem
    >>D               display 'timezone ' timezone(1:timezone-length)
    >>D               display 'modificationdate ' modificationdate
    >>D        end-if
    
            read cities-file
        end-perform
    
        accept current-time from time
        compute end-seconds =
            ct-hour * 60 * 60
            + ct-minute * 60
            + ct-second
            + ct-hundredth / 100
    
        close cities-file
    
        move cities-count to display-count
        display display-count space 'cities'
    
        compute elapsed-seconds = end-seconds - start-seconds
        move elapsed-seconds to display-elapsed-seconds
        display display-elapsed-seconds ' elapsed seconds'
    
        compute records-per-second = cities-count / elapsed-seconds
            on size error move 0 to records-per-second
        end-compute
        display records-per-second ' cities per second'
    
        display 'ending worldcities0'
        .
    
    identification division.
    program-id. checkfilestatus.
    
    data division.
    working-storage section.
    01  status-message pic x(72).
    01  display-message pic x(72) value spaces.
    
    linkage section.
    01  file-name pic x(64).
    01  file-status pic x(2).
    
    procedure division using file-name file-status.
    start-checkfilestatus.
        if file-status = '00'
            goback
        end-if
        evaluate file-status
        when 00 move 'SUCCESS.' TO status-message   
        when 02 move 'SUCCESS DUPLICATE.' TO status-message 
        when 04 move 'SUCCESS INCOMPLETE.' TO status-message 
        when 05 move 'SUCCESS OPTIONAL.' TO status-message 
        when 07 move 'SUCCESS NO UNIT.' TO status-message 
        when 10 move 'END OF FILE.' TO status-message 
        when 14 move 'OUT OF KEY RANGE.' TO status-message 
        when 21 move 'KEY INVALID.' TO status-message 
        when 22 move 'KEY EXISTS.' TO status-message 
        when 23 move 'KEY NOT EXISTS.' TO status-message 
        when 30 move 'PERMANENT ERROR.' TO status-message 
        when 31 move 'INCONSISTENT FILENAME.' TO status-message 
        when 34 move 'BOUNDARY VIOLATION.' TO status-message 
        when 35 move 'FILE NOT FOUND.' TO status-message 
        when 37 move 'PERMISSION DENIED.' TO status-message 
        when 38 move 'CLOSED WITH LOCK.' TO status-message 
        when 39 move 'CONFLICT ATTRIBUTE.' TO status-message 
        when 41 move 'ALREADY OPEN.' TO status-message 
        when 42 move 'NOT OPEN.' TO status-message 
        when 43 move 'READ NOT DONE.' TO status-message 
        when 44 move 'RECORD OVERFLOW.' TO status-message 
        when 46 move 'READ ERROR.' TO status-message 
        when 47 move 'INPUT DENIED.' TO status-message 
        when 48 move 'OUTPUT DENIED.' TO status-message 
        when 49 move 'I/O DENIED.' TO status-message 
        when 51 move 'RECORD LOCKED.' TO status-message 
        when 52 move 'END-OF-PAGE.' TO status-message 
        when 57 move 'I/O LINAGE.' TO status-message 
        when 61 move 'FILE SHARING FAILURE.' TO status-message 
        when 91 move 'FILE NOT AVAILABLE.' TO status-message    
        end-evaluate
        string 'ERROR ' delimited by size
            file-name delimited by space
            space delimited by size
            status-message delimited by '.'
            into display-message
        display display-message
        stop run
        .
    end program checkfilestatus.
    end program worldcities0.
    
     
  • steve williams
    steve williams
    2013-09-07

    Simon, Brian

    Attached is a tar file of the five simple cobol programs, modified as Simon suggested, with associated shell scripts.
    There are no data files. Those must be downloaded from http://download.geonames.org/export/dump/

    Steve

     
    Attachments
    • Simon Sobisch
      Simon Sobisch
      2013-09-07

      <html><head></head><body>

      Hi Steve,

       
      I'll upload them soon to contrib/samples/worldcities and add the GPL licence, if you are OK with that.
       
      Simon

      </body></html>

       
  • steve williams
    steve williams
    2013-09-07

    Simon,

    I'm OK with that. Thank you for your help.

    Steve

     
    • Simon Sobisch
      Simon Sobisch
      2013-09-07

      I'm ready to check the sources in,but have a last change request (so far ;-):
      Please compile with -W and fix the errors/warnings. If you're unsure how to fix some issues we're here to help you (OpenCOBOL Forum would be useful). Adding

            >> SOURCE FORMAT IS FREE
      

      in the first line (starts in column 7) helps to remove the need for compile switch -free.

      Simon

       
  • steve williams
    steve williams
    2013-09-08

    Simon,

    I'm making the changes you requested.

    1) The compiler flags ENTRY statements as obsolete (the programmers guide doesn't say this). I will remove the ENTRY statements, but the fix will look strange IMHO and error-prone (some parameters required but not used).

    2) I will fix the picture mismatches but adding END markers to the DISPLAY, ADD, STRING, CALL, etc verbs just to appease the compiler seems unnecessary and, again IMHO, un-COBOL.

    As a comment, the worldcities4 program has a polygon defined across the Canadian/United States international boundary. One can download and use the allcities.txt file, but that is 240 megabytes zipped and 1.1 gigabytes unzipped.

    As a workaround I recommend concatenating the CA.txt and US.txt files:

    cat CA.txt US.txt > CAUS.txt
    export cityfile=CAUS.txt

    Steve

     
    • Brian Tiffin
      Brian Tiffin
      2013-09-08

      Ummm, I support using ENTRY. ;-)

      It can make linkage into C a lot cleaner, especially setting up callbacks.

      It's obsolete, but way handy and it'll be in OpenCOBOL for the foreseeable future, with modern uses.

      Cheers,
      Brian

       
  • Bill Woodger
    Bill Woodger
    2013-09-08

    Is the latest checkfilestatus the one shown in this thread? If so, I don't see how using in in the READ which can get 10 would work. checkfilestatus is going to STOP RUN.

    I would still put the FILE-STATUS in the output, and include WHEN OTHER to cover the unexpected.

    For more general use, with keyed files for instance, either it should only be called "when needed" (when an error is known, so even 00 should be an error) or it would need a list of file status codes which are OK this time.

     
    • steve williams
      steve williams
      2013-09-09

      Bill,

      My FILE STATUS code does a goback when it sees '00' or '10'. Not the right way to do it, I know. I wanted to show a lot of FILE STATUS checking because lots of cobol programmers and particularly new ones know nothing about FILE STATUS.

      Steve

       
  • steve williams
    steve williams
    2013-09-08

    Simon,

    I'm having trouble suppressing warning messages. The source data comes from a relational database and has definitions such as population bigint and alternate-names varchar(5000) or city-name varchar(200).

    Indeed, the potential size of an incoming row could be vastly more than the pic(1000) I have allocated in the FD. (Something like pic(10000) causes my poor laptop to freeze). One of the beauties of the line sequential file organization is that I don't have to worry about these matters and one of the beauties of the cobol language is that I don't have to worry about truncation or padding in data movement.

    Yes, these warnings may indicate problems in my code, but when I move pic binary-double to pic z,zzz,zz9, I assume some responsibility.

    My intent and hope in creating these programs was to show examples of simple and common cobol usage.

    I will continue to modify the programs, and I hope you will accept a few 'natural' warning messages.

    Steve

     
    • Simon Sobisch
      Simon Sobisch
      2013-09-08

      Hi Steve,

      this is good as this is real COBOL talk. I'd like to see this more.

      ENTRY is OK in this sample (and for that case "not a PROCEDURE parameter", too), we label this program as a sample using this feature :-) [I may add another 20xx-version of this library later]

      Personally, I like forcing the terminators (END-xyz) and for me it's very COBOL ;-)

      To the truncation issue binary-double to pic z,zzz,zz9: I think you should decide what to do with the truncation as this is a real issue: check the size and move 9999999 to your field (if you do this on import level or display/report is up to you).

      For the report stuff I'd say: if you want to truncate then use something like this (if you like to, use something like FUNCTION LENGTH or lvl 78 items instead of the numeric size constants):

      move sort-city-name (1:45) to report-city-name
      
      move sort-city-name (1:45) to report-city-name
      
      string sort-city-name
             delimited by size
             into report-city-name
             on overflow
                move x'85' to report-city-name (45:1)
      end-string
      

      To the file status stuff: I'd double Rogers opinions and for easier (and faster) file status checking I'd add DECLARATIVES (put the copy file there) - if you do a READ .... AT END EXIT PERFORM (or CONTINUE if you like this more in that case) you'll not enter DECLARATIVES in that case.

      I'm curious about your next version (the [currently empty] sample directory worldcities is already submitted).

      Simon

       
  • steve williams
    steve williams
    2013-09-09

    Simon,

    1) You say:

    Personally, I like forcing the terminators (END-xyz) and for me it's very COBOL ;-)

    I say:

    The programmer's guide marks these END clauses as OPTIONAL. In the centuries I have been programming COBOL, I can't think of a programmer who would append an unneeded END-ADD to ADD 1 TO COBOL.

    Indeed, I worry that someone reading my code with these unneeded END-xyz clauses might think I don't know what I'm doing.

    2) You say:

    To the truncation issue binary-double to pic z,zzz,zz9: I think you should decide what to do with the truncation as this is a real issue: check the size and move 9999999 to your field (if you do this on import level or display/report is up to you).

    I say:

    Here I have a real problem -- one that comes up in data warehouse ETL all the time.

    Cobol, and cobol programmers, have no trouble defining binary elementary items in group-level fields and writing these group-level fields to files and databases.

    In database bulkloads, the utility wants a field separator character (usually a pipe symbol or a tilde). But a binary item or a group item holding binary items may have something that looks like a field separator.

    Indeed, I initially coded the allcountry.txt unstring for items like city-population targeting a pic 9(7). But then I saw that the data was BIGINT in the source, and memories of binary data looking like it had an internal TAB came to mind.

    So I used binary-double in conformance with the source definition and hoped that the OpenCOBOL compiler would treat binary-double as an atomic entry and not look for an embedded TAB.

    As a rule I want to honor binary-long and binary-double data in incoming rows. My application knows what to do (world cities don't have populations over pic 9(7), so far) and therefore I assume the responsibility for the truncation warning message.

    You say:

    For the report stuff I'd say: if you want to truncate then use something like this (if you like to, use something like FUNCTION LENGTH or lvl 78 items instead of the numeric size constants):

    move sort-city-name (1:45) to report-city-name

    move sort-city-name (1:45) to report-city-name

    string sort-city-name
    delimited by size
    into report-city-name
    on overflow
    move x'85' to report-city-name (45:1)
    end-string

    I say:

    Yes, I know or can find the length of the target field and can impose that length on the source field in the move statement, but I worry that some future reader might think I've lost my mind.

    You say:

    To the file status stuff: I'd double Rogers opinions and for easier (and faster) file status checking I'd add DECLARATIVES (put the copy file there) - if you do a READ .... AT END EXIT PERFORM (or CONTINUE if you like this more in that case) you'll not enter DECLARATIVES in that case.

    I say:

    I don't know Roger's opinions, so I can't respond here intelligently.

    I confess I always want to see all the action before me in the immediate code. I use inline code as much as possible. I avoid unseen (unimmediate?) things such as triggers and declaratives. Things hidden in lower levels of copybooks (88 levels for instance) terrify me.

    I alway use the

    get
    perform until end
    process
    get
    end-perform

    sequential file-processing structure

    I mentioned this on in a Python forum many years ago and received a stinging rebuke from Alex Martelli that it was not 'Pythonic'. He wanted the get at the beginning of the loop with a break (exception) to immediately exit. Ugh.

    You say:

    I'm curious about your next version (the [currently empty] sample directory worldcities is already submitted).

    I say:

    Right now the code I've submitted is full of hard-coded parameters (file names and selection criteria). My next direction is to add screen coding to get the user involved.

    I am thinking of coding samples using ISAM, but to me that's a technique for retrieving and processing single records based on key values. Yes, I know you can start from a key value and proceed. I'm an SQL bigot.

    Finally, I've modified all the sample programs to minimize (not eliminate) the warning messages as you requested. I'll upload those when testing is complete.

    Steve

     
  • Bill Woodger
    Bill Woodger
    2013-09-09

    Steve, binary data subordinate to the field you UNSTRING will mess you up.

    I agree with your read-loop (priming read, plus read at end of loop). Clearest and most flexible way to do it.

    I agree with you about the delaratives:

    I have a program that process six separate files. I do not want it potentially flying off to DECLARATIVES in any one of at least 18 places. And then, unless I include code before it can fly off, DECLARATIVES has no clue where it has come fron. Talk about ALTER... TO PROCEED TO...

    I agree, Steve. If I see END-xyz, I wonder if the condition has been left out/deleted in error, or removed deliberately but sloppily without the END-xyz going the same way.

    And the END-xyz:

    COMPUTE A = A * B
    ON SIZE ERROR MOVE ZERO TO A
    END-COMPUTE

    MOVE ZERO TO B

    COMPUTE A = A * B
    ON SIZE ERROR MOVE ZERO TO A.

    MOVE ZERO TO B

    COMPUTE A = A * B
    ON SIZE ERROR MOVE ZERO TO A

    MOVE ZERO TO B

    COMMPUTE A = A * B
    END-COMPUTE

    MOVE ZERO TO B

    COMPUTE A = A * B.

    MOVE ZERO TO B

    COMPUTE A = A * B

    MOVE ZERO TO B

    If each COMPUTE/MOVE pair is in a "block" of its own, and only one block of code gives a different final value for B, that tells you where the END- has to be used.

    Use where it does not have to be used is a "style" thing. It is definitely not a COBOL thing to use it. END-xyz is very new in terms of COBOL (only 28 years old).

    I go with the "more information" approach: use END-xyz when necessary, else don't.

    Then anyone finding an unnecessary one in my code knows I've not done a good job with the code. This meaning is lost if END-xyz is used by rote.

    However, 88s I disagree, and you need to watch 9(7). It depends how someone defines a city. In the "metropolitan area" sense, many cities are well over 10m.

     
  • steve williams
    steve williams
    2013-09-09

    Bill,

    Thank you for your comments.

    I agree that binary data in an unstring is poison.

    Unfortunately, I'm working with a relational data dump with BIGINT and INTEGER columns and tab field separators. I would like to have a quiet word with the programmer who created that.

    As to coding and coding styles, one of the glories of COBOL is its readability when decently written. You can sit down with someone from Accounts Receivable and discuss the code. No other programming language can make that claim.

    As to 88s, they're a problem when deeply hidden in copybooks. "What was the test? Why did it/didn't it fire in a particular case? Can I modify it without destroying other people's code?

    Steve

     
  • steve williams
    steve williams
    2013-09-09

    Simon,

    Attached is a zip file of the five simple cobol programs and associated shell scripts. I have modified the code to eliminate warning messages as much as I can. I also have 'enhanced' the code here and there to improve it.

    Steve

     
    Attachments
  • steve williams
    steve williams
    2013-09-13

    Simon, Brian

    Attached is a tar file with a new worldcities5 cobol program, which is a modification of worldcities4.cob using ocesql-1.0.0, to create and load a postgresql table with the selected polygon cities.

    The tar file also contains the associated worldcities5.sh shell script which includes the ocesql preprocess step and also readpolygon.py, a python program to display the contents of the loaded table.

    Steve Williams

     
    Attachments
    • Brian Tiffin
      Brian Tiffin
      2013-09-15

      Got back from a family visit, to find presents under the tree, and it's still summer.

      Nice samples Steve, and once again, thanks for sharing. These are awesome.

      Cheers,
      Brian

       
      Last edit: Brian Tiffin 2013-09-15