#! /usr/bin/python3 # Last edited on 2026-01-21 22:26:32 by stolfi # Library function that reads a table that maps strings to strings. # To be imported by python programs. from process_funcs import basic_line_loop import re from sys import stderr as err def read_table(fname,invert,verbose): # Reads the contents of the table {tbl} from file {fname}. # Returns the table as a python {dict}. # Blank lines and #-comments in file {fname} are ignored. Each data # line must have two non-blank fields {X} and {Y}, separated by one or # more blanks. The fields cannot have embedded blanks. # If {invert} is false, {tbl[X]} is set to {Y}. If {invert} is true, the two fields # are conceptually reversed, that is, {tbl[Y]} is set to {X}. # If {verbose} is true, prints a summary of entries read. tbl = dict() def process_line(nread, line): nonlocal tbl line = line.strip() if re.match(r"^[ \011]*([#]|$)", line): return line = re.sub(r"[ \011]*[#].*$", "", line) fld = re.split(r"[ \011]+", line) if len(fld) != 2: err.write(f"{fname}:{nread}: ** bad field count\n [[{line}]]\n") sys.exit(1) if invert: x, y = fld[1], fld[0] else: x, y = fld[0], fld[1] if x in tbl: err.write(f"{fname}:{nread}: ** repeated key = {x}\n [[{line}]]\n") sys.exit(1) tbl[x] = y return # .................................................................... rd = open(fname, "r") nread = basic_line_loop(rd, process_line) if len(tbl) == 0: err.write(f"{fname}:{nread}: ** no entries in table file {fname}\n [[{line}]]\n") sys.exit(1) if verbose: err.write("loaded {len(tbl)} pairs from {fname}\n") rd.close() return tbl # ----------------------------------------------------------------------