{"id":14492,"date":"2026-08-07T01:00:00","date_gmt":"2026-08-07T05:00:00","guid":{"rendered":"https:\/\/www.both.org\/?p=14492"},"modified":"2026-07-27T13:46:10","modified_gmt":"2026-07-27T17:46:10","slug":"cleaning-up-fortran-77-code","status":"publish","type":"post","link":"http:\/\/www.both.org\/?p=14492","title":{"rendered":"Cleaning up FORTRAN 77 code"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"14492\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p class=\"wp-block-paragraph\">I used to write a lot of FORTRAN 77 programs when I was an undergraduate physics student in the 1990s. Old-style FORTRAN has some interesting rules that date back to when the language was developed using punched cards: lines needed to follow strict column rules, and all text needed to be uppercase. For example, entering <code>C<\/code> or <code>*<\/code> in column 1 meant that line was a comment. Line labels could go in columns 1 to 5. Column 6 was reserved for a \u201ccontinuation\u201d marker. And columns 7 to 72 were for program statements.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As an eager, young FORTRAN 77 programmer, I got in the habit of tapping out 6 spaces every time I started a new line of code. But after a while, you get tired of that, and you start to look for shortcuts. One way that I made my programming easier was to start a new line with a tab. FORTRAN 77 didn\u2019t officially recognize a tab, but most FORTRAN compilers recognized a tab as \u201cadd 8 spaces, and start in column 9.\u201d So you \u201clost\u201d 2 spaces (starting in column 9 instead of column 7) but the convenience was a good trade-off.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Writing clean code<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To make my undergraduate programming a bit easier, I wrote a small <a href=\"https:\/\/www.both.org\/?p=14224\">untab77 utility<\/a> to expand tabs to spaces, but in a special way: a tab in columns 1 to 6 added enough spaces to start the line in column 7, and tabs after that were turned into a single space. I later wrote an <a href=\"https:\/\/www.both.org\/?p=14329\">upper77 command<\/a> that converted any lowercase letters to uppercase. Most FORTRAN compilers will recognize lowercase letters anyway, but since the FORTRAN 77 specification said \u201cuppercase only,\u201d this tool allowed me to guarantee that my programs were always \u201cclean.\u201d<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While those programs are not hard to write, the best program is the one you didn\u2019t need to write. And you don\u2019t actually need to write those programs; you can use existing Unix tools to do that for you. These are the tools you need to know:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9799919799\/utilities\/expand.html\">expand<\/a> will turn tabs into spaces<\/li>\n\n\n\n<li><a href=\"https:\/\/pubs.opengroup.org\/onlinepubs\/9699919799\/utilities\/tr.html\">tr<\/a> will convert characters from one range to another<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">Tabs to spaces<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <strong>expand<\/strong> command reads input and converts tabs into spaces. By default, this expands tabs to 8 spaces, so an initial tab before text means the text will start in column 9. However, you can use the <code>-t<\/code> option to set the tab stops. Using <code>-t 6<\/code> will expand tabs to 6 spaces, so text starts in column 7, as it should with FORTRAN programs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can also use a list with the <code>-t<\/code> option, to indicate what the following tab stops should be. The official man page notes that \u201cIn the event of expand having to process a <em>tab<\/em> at a position beyond the last of those specified in a multiple tab-stop list, the <em>tab<\/em> shall be replaced by a single <em>space<\/em> in the output.\u201d So you can use <code>-t 6,7<\/code> to specify the first tab stop as 6 spaces, and the next tab stop as 1 space after that. Any tabs after that become a single space.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s test it with a simple file. The first line is just a list of numbers from 1 to 9, to act as a guide for the tab stops. The next line starts with a tab, then the word \u201ctab.\u201d The third line is similar, with two tabs, then the word \u201ctabtab.\u201d I\u2019ll use the <strong>cat<\/strong> command with the <code>-t<\/code> option to show the tabs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cat -t tabs\n123456789\n^Itab\n^I^Itabtab<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If we turn these tabs into spaces using the <strong>expand<\/strong> command, we can see the default action turns the tabs into 8 spaces, with the second line of text starting at column 9:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ expand tabs\n123456789\n        tab\n                tabtab<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">However, using the <code>-t 6,7<\/code> option expands the tabs so the first tab becomes 6 spaces, and the following tabs are 1 space:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ expand -t 6,7 tabs\n123456789\n      tab\n       tabtab<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is the behavior we want to convert tabs to spaces in a FORTRAN 77 program.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Lowercase to uppercase<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Using the <strong>tr<\/strong> command to convert lowercase to uppercase is very simple. This command takes two strings: one to use as \u201cthe list to convert <em>from<\/em>\u201d and the other as \u201cthe list to convert <em>to<\/em>\u201d \u2014 for example, using <code>a b<\/code> converts any letter <strong>a<\/strong> to the letter <strong>b<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ echo ab | tr a b\nbb<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You can also specify a range of characters. That flexibility is a very powerful feature in the <strong>tr<\/strong> command. The only caveat is that the <em>from<\/em> and <em>to<\/em> lists must be the same size, such as lowercase (26 letters) to uppercase (26 letters). To specify a range, use a hyphen:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ echo ab | tr a-z A-Z\nAB<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Cleaning up FORTRAN 77 code<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">With these two command line tools, we can create a very short script that cleans up FORTRAN 77 code like I might have written as an undergraduate student. A leading tab gets expanded into spaces so program instructions start in column 7, and following tabs become a single space. At the same time, lowercase letters are converted to uppercase.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\nexpand -t 6,7 \"$@\" | tr a-z A-Z<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I\u2019ve specified the Bash shell here so I can use the <code>\"$@\"<\/code> expansion. Bash uses this to expand its command line arguments so that any spaces in filenames are preserved.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Save this script as <code>clean77<\/code> and make it executable using the <strong>chmod<\/strong> command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ chmod +x clean77<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s see an example. Here is a short FORTRAN 77 program that iterates a variable through the values 1 to 10. For each loop, it prints the text \u201cHELLO WORLD\u201d to the screen. I\u2019ve added a few features to the program to test the script: each program statement starts with a leading tab. The <code>DO<\/code> instruction also has tabs between each word on the line. We can see the tabs as <code>^I<\/code> if we use the <strong>cat<\/strong> command with the <code>-t<\/code> option:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ cat -t hi.f\nc23456789\n^Iinteger i\n^Ido^I10^Ii^I=^I1,10,1\n10^Iprint*,'hello world'\n^Iend<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Using the new <code>clean77<\/code> script converts the leading tabs to 6 spaces, so instructions start in column 7. Following tabs (like the ones in the <code>DO<\/code> line) become a single space. At the same time, letters are converted to uppercase.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ clean77 hi.f\nC23456789\n      INTEGER I\n      DO 10 I = 1,10,1\n10    PRINT*,'HELLO WORLD'\n      END<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is the same behavior as using the <code>untab77<\/code> and <code>upper77<\/code> programs that I explored in an earlier article:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ untab77 &lt; hi.f | upper77\nC23456789\n      INTEGER I\n      DO 10 I = 1,10,1\n10    PRINT*,'HELLO WORLD'\n      END<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Using existing Unix tools means we can solve the same problems, but without writing new code. In this case, using <strong>expand<\/strong> and <strong>tr<\/strong> allowed us to do the same job in a 2-line Bash script that otherwise required over 100 lines of C code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The best program is the one you didn\u2019t need to write<\/p>\n","protected":false},"author":33,"featured_media":7678,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":"","_members_access_role":[],"_members_access_error":""},"categories":[100,798,768],"tags":[104,152],"class_list":["post-14492","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-command-line","category-fortran-77","category-unix","tag-command-line","tag-programming"],"modified_by":"Jim Hall","_links":{"self":[{"href":"http:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/14492","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/33"}],"replies":[{"embeddable":true,"href":"http:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=14492"}],"version-history":[{"count":5,"href":"http:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/14492\/revisions"}],"predecessor-version":[{"id":14497,"href":"http:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/14492\/revisions\/14497"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/7678"}],"wp:attachment":[{"href":"http:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=14492"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=14492"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=14492"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}