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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
> 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).
*> 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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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/
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
>>SOURCEFORMATISFREE
in the first line (starts in column 7) helps to remove the need for compile switch -free.
Simon
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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):
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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.
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.
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
Hi Simon,
Each program modifies its predecessor.
The five programs are:
I wouldn't say the programs are well-commented. I tried to make the code readable.
Steve
Here's the first program:
Last edit: Simon Sobisch 2013-09-05
Simon,
As you see, I know nothing about sourceforge markdown. Trust me, the comment markers and indentations are in the original code.
Steve
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
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.
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
:::cobolfree
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
*> skip the first record (column names)
read cities-file
call 'checkfilestatus' using cities-file-name cities-file-status
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
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
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
Simon, Brian,
Here's a version of worldcities0.cbl modified to read a file taken from
http://download.geonames.org/export/dump/
Steve
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
<html><head></head><body>
Simon,
I'm OK with that. Thank you for your help.
Steve
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
in the first line (starts in column 7) helps to remove the need for compile switch -free.
Simon
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
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
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.
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
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
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):
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
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
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.
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
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
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
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