Task 239: .FOR File Format
Task 239: .FOR File Format
1. List of All Properties of the .FOR File Format Intrinsic to Its File System
The .FOR file format is a plain-text source code format for Fortran 77 (and compatible with later standards in fixed-form mode), originating from punched-card era conventions. It is not a binary or structured file system like FAT or NTFS but a simple text-based format with rigid column-based layout rules to ensure compatibility with early compilers and hardware. The intrinsic properties define how source code is organized per line, without metadata headers, footers, or encoding beyond standard text. Based on the Fortran 77 standard and compatible implementations:
- Encoding: ASCII (7-bit) or extended ASCII; no Unicode or BOM required, though modern tools may accept UTF-8.
- Line Terminator: Standard newline (\n on Unix/Linux, \r\n on Windows); each line represents one card equivalent.
- Maximum Line Length: 72 characters for the scanned statement field (columns 1-72); longer lines are truncated, shorter lines padded with spaces.
- Statement Label Field: Columns 1-5 (optional 1-5 digit numeric labels for GOTO targets or references; must be right-justified with leading spaces if shorter).
- Continuation Indicator Field: Column 6 (non-blank, non-zero character, e.g., '0'-'9', any letter, or symbol like '*', indicates the line continues a statement from the previous line).
- Statement Field: Columns 7-72 (contains the actual Fortran code, keywords, variables, etc.; code must start here for non-comment/blank lines).
- Comment Indicator: Column 1 contains 'C', 'c', or '*' (makes the entire line a comment); in Fortran 90+ extensions, '!' in column 1 or anywhere in the statement field comments from that point onward.
- Sequence Number Field: Columns 73-80 (optional, ignored by compilers; used historically for card sorting but not part of the functional format).
- Blank Lines: Treated as non-executable; no special encoding.
- Case Sensitivity: Insensitive (all uppercase traditionally, but modern compilers accept mixed case).
- File Extension Convention: .FOR indicates fixed-form source (vs. .F90 for free-form).
These properties enforce a columnar "file system" for parsing without delimiters, ensuring deterministic reading by line.
2. Two Direct Download Links for Files of Format .FOR
- xntg.for – A sample Fortran 77 program for geographic boundary processing.
- guess.for – A simple guessing game example in Fortran 77.
3. Ghost Blog Embedded HTML JavaScript for Drag-and-Drop .FOR File Analysis
Embed this full HTML snippet into a Ghost blog post (via the HTML card or custom integration). It creates a drag-and-drop zone that reads the .FOR file as text, parses it according to the format properties, and dumps the extracted properties (e.g., counts and compliance checks) to a results div below.
4. Python Class for .FOR File Handling
This class opens a .FOR file, reads and decodes it (parses properties), prints them to console, and supports writing the file back (or a modified version).
import os
class FORFile:
def __init__(self, filename):
self.filename = filename
self.lines = []
self.properties = {}
def read(self):
with open(self.filename, 'r', encoding='ascii', errors='ignore') as f:
self.lines = f.readlines()
def decode(self):
self.properties = self._parse_properties()
def _parse_properties(self):
num_lines = len(self.lines)
num_blank = sum(1 for line in self.lines if line.strip() == '')
num_comments = sum(1 for line in self.lines if line and line[0] in {'C', 'c', '*'})
num_continuations = sum(1 for line in self.lines if len(line) > 5 and line[5] != ' ' and line[5] != '0')
num_labels = sum(1 for line in self.lines if line and line[:5].strip().isdigit())
max_length = max(len(line.rstrip()) for line in self.lines) if self.lines else 0
violations = [f"Line {i+1}: Length {len(line.rstrip())} > 72" for i, line in enumerate(self.lines) if len(line.rstrip()) > 72]
return {
'total_lines': num_lines,
'blank_lines': num_blank,
'comment_lines': num_comments,
'continuation_lines': num_continuations,
'label_lines': num_labels,
'max_line_length': max_length,
'violations': violations if violations else ['None']
}
def write(self, output_filename=None):
output_filename = output_filename or self.filename
with open(output_filename, 'w', encoding='ascii') as f:
f.writelines(self.lines)
def print_properties(self):
for key, value in self.properties.items():
print(f"{key.replace('_', ' ').title()}: {value}")
# Example usage:
# f = FORFile('example.for')
# f.read()
# f.decode()
# f.print_properties()
# f.write('output.for')
5. Java Class for .FOR File Handling
This Java class uses java.nio.file
for reading/writing. Compile with javac FORFile.java
and run with java FORFile example.for
.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class FORFile {
private String filename;
private List<String> lines;
private Map<String, Object> properties;
public FORFile(String filename) {
this.filename = filename;
this.lines = new ArrayList<>();
this.properties = new HashMap<>();
}
public void read() throws IOException {
Path path = Paths.get(filename);
lines = Files.readAllLines(path);
}
public void decode() {
properties = parseProperties();
}
private Map<String, Object> parseProperties() {
int numLines = lines.size();
int numBlank = (int) lines.stream().filter(l -> l.trim().isEmpty()).count();
int numComments = (int) lines.stream().filter(l -> !l.isEmpty() && (l.charAt(0) == 'C' || l.charAt(0) == 'c' || l.charAt(0) == '*')).count();
int numContinuations = (int) lines.stream().filter(l -> l.length() > 5 && l.charAt(5) != ' ' && l.charAt(5) != '0').count();
int numLabels = (int) lines.stream().filter(l -> !l.isEmpty() && l.substring(0, Math.min(5, l.length())).trim().matches("\\d+")).count();
int maxLength = lines.stream().mapToInt(String::length).max().orElse(0);
List<String> violations = new ArrayList<>();
for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i);
if (line.length() > 72) {
violations.add("Line " + (i + 1) + ": Length " + line.length() + " > 72");
}
}
Map<String, Object> props = new HashMap<>();
props.put("totalLines", numLines);
props.put("blankLines", numBlank);
props.put("commentLines", numComments);
props.put("continuationLines", numContinuations);
props.put("labelLines", numLabels);
props.put("maxLineLength", maxLength);
props.put("violations", violations.isEmpty() ? List.of("None") : violations);
return props;
}
public void write(String outputFilename) throws IOException {
Path path = Paths.get(outputFilename != null ? outputFilename : filename);
Files.write(path, lines);
}
public void printProperties() {
properties.forEach((k, v) -> System.out.println(k.replace("_", " ").toUpperCase() + ": " + v));
}
public static void main(String[] args) throws IOException {
if (args.length == 0) {
System.out.println("Usage: java FORFile <file.for>");
return;
}
FORFile f = new FORFile(args[0]);
f.read();
f.decode();
f.printProperties();
// f.write("output.for");
}
}
6. JavaScript Class for .FOR File Handling
This Node.js class (run with node forfile.js example.for
). Requires no external deps; uses built-in fs
.
const fs = require('fs');
class FORFile {
constructor(filename) {
this.filename = filename;
this.lines = [];
this.properties = {};
}
read() {
this.lines = fs.readFileSync(this.filename, 'ascii').split(/\r?\n/);
}
decode() {
this.properties = this.parseProperties();
}
parseProperties() {
const numLines = this.lines.length;
const numBlank = this.lines.filter(l => l.trim() === '').length;
const numComments = this.lines.filter(l => l && ['C', 'c', '*'].includes(l[0])).length;
const numContinuations = this.lines.filter(l => l.length > 5 && l[5] !== ' ' && l[5] !== '0').length;
const numLabels = this.lines.filter(l => l && /^\s*\d{1,5}/.test(l.substring(0, 5))).length;
const maxLength = Math.max(...this.lines.map(l => l.length), 0);
const violations = [];
this.lines.forEach((line, i) => {
if (line.length > 72) {
violations.push(`Line ${i + 1}: Length ${line.length} > 72`);
}
});
return {
totalLines: numLines,
blankLines: numBlank,
commentLines: numComments,
continuationLines: numContinuations,
labelLines: numLabels,
maxLineLength: maxLength,
violations: violations.length ? violations : ['None']
};
}
write(outputFilename = null) {
const filename = outputFilename || this.filename;
fs.writeFileSync(filename, this.lines.join('\n') + '\n', 'ascii');
}
printProperties() {
Object.entries(this.properties).forEach(([key, value]) => {
console.log(`${key.replace(/_/g, ' ').toUpperCase()}: ${value}`);
});
}
}
// Example usage:
// const f = new FORFile('example.for');
// f.read();
// f.decode();
// f.printProperties();
// f.write('output.for');
7. C "Class" (Struct with Functions) for .FOR File Handling
C doesn't have classes, so this uses a struct with functions. Compile with gcc forfile.c -o forfile
and run ./forfile example.for
.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINES 10000
#define MAX_LINE_LEN 132
typedef struct {
char filename[256];
char lines[MAX_LINES][MAX_LINE_LEN];
int num_lines;
int properties[6]; // 0:total, 1:blank, 2:comment, 3:cont, 4:label, 5:max_len
char violations[1024];
} FORFile;
void read_file(FORFile *f) {
FILE *fp = fopen(f->filename, "r");
if (!fp) {
perror("Error opening file");
return;
}
f->num_lines = 0;
while (fgets(f->lines[f->num_lines], MAX_LINE_LEN, fp) && f->num_lines < MAX_LINES - 1) {
f->num_lines++;
}
fclose(fp);
}
void decode(FORFile *f) {
int total = f->num_lines;
int blank = 0, comment = 0, cont = 0, label = 0;
int max_len = 0;
char *viol = f->violations;
*viol = '\0';
for (int i = 0; i < total; i++) {
char *line = f->lines[i];
int len = strlen(line);
if (len > 0) line[len - 1] = '\0'; // trim \n
int tlen = strlen(line);
max_len = (tlen > max_len) ? tlen : max_len;
if (tlen == 0) {
blank++;
continue;
}
char col1 = line[0];
if (col1 == 'C' || col1 == 'c' || col1 == '*') {
comment++;
continue;
}
// label
char label_buf[6];
strncpy(label_buf, line, 5);
label_buf[5] = '\0';
char *end = label_buf;
while (*end == ' ') end++;
int is_label = 0;
while (*end >= '0' && *end <= '9') end++;
if (end > label_buf && *end == '\0') is_label = 1;
if (is_label) label++;
// cont
char col6 = (tlen > 5) ? line[5] : ' ';
if (col6 != ' ' && col6 != '0') cont++;
if (tlen > 72) {
char buf[100];
sprintf(buf, "Line %d: Length %d > 72\n", i + 1, tlen);
strncat(viol, buf, sizeof(f->violations) - strlen(viol) - 1);
}
}
f->properties[0] = total;
f->properties[1] = blank;
f->properties[2] = comment;
f->properties[3] = cont;
f->properties[4] = label;
f->properties[5] = max_len;
if (*f->violations == '\0') strcat(f->violations, "None");
}
void write_file(FORFile *f, char *output_filename) {
FILE *fp = fopen(output_filename ? output_filename : f->filename, "w");
if (!fp) {
perror("Error writing file");
return;
}
for (int i = 0; i < f->num_lines; i++) {
fprintf(fp, "%s\n", f->lines[i]);
}
fclose(fp);
}
void print_properties(FORFile *f) {
printf("Total Lines: %d\n", f->properties[0]);
printf("Blank Lines: %d\n", f->properties[1]);
printf("Comment Lines: %d\n", f->properties[2]);
printf("Continuation Lines: %d\n", f->properties[3]);
printf("Label Lines: %d\n", f->properties[4]);
printf("Max Line Length: %d\n", f->properties[5]);
printf("Violations:\n%s\n", f->violations);
}
int main(int argc, char **argv) {
if (argc < 2) {
printf("Usage: %s <file.for>\n", argv[0]);
return 1;
}
FORFile f;
strcpy(f.filename, argv[1]);
read_file(&f);
decode(&f);
print_properties(&f);
// write_file(&f, "output.for");
return 0;
}