******************************************************************************** * * LOAD.PIOPEN.B - Load utility to get PI/open unloaded files. * * Module %M% Version %I% Date %H% * * (c) Copyright 1998 Ardent Software Inc. - All Rights Reserved * This is unpublished proprietary source code of Ardent Software Inc. * The copyright notice above does not evidence any actual or intended * publication of such source code. * ******************************************************************************* * * Maintenence log - insert most recent change descriptions at top * * Date.... GTAR# WHO Description......................................... * 10/14/98 23801 SAP Change copyrights. * 02/08/94 14513 JC Changed so that records do not get overwritten. * 06/27/94 12303 JC Inital code release * ******************************************************************************* * * * This program will load data into a file from a text file created * by the UNLOAD.PIOPEN utility. For the format of the text file, * see the file UNLD.PIOPEN.B. * * Command format: * * LOAD.PIOPEN [DICT] file.name [[source.dir] text.file.name] * EQUATE ASCII.DATA.CODE TO "A" EQUATE FM.DATA.CODE TO "F" EQUATE HEX.DATA.CODE TO "H" EQUATE REC.ID.CODE TO "I" EQUATE REC.ID.HEX.CODE TO "J" line.type.list = ASCII.DATA.CODE line.type.list := FM.DATA.CODE line.type.list := HEX.DATA.CODE line.type.list := REC.ID.CODE line.type.list := REC.ID.HEX.CODE GOSUB parse.command.line GOSUB open.files PRINT "Loading ":target.desc:" from ":source.desc:"." * Main processing loop end.of.input = 0 data.error = 0 lines.read = 0 records.written = 0 rec.id = "" rec.data = "" LOOP READSEQ line FROM text.file ELSE end.of.input = 1 UNTIL end.of.input DO lines.read += 1 line.type = INDEX(line.type.list, line[1,1], 1) * This ON ... GOSUB must match the order of line.type.list ON line.type + 1 GOSUB invalid.line, ascii.data.line, fm.data.line, hex.data.line, rec.id.line, rec.id.hex.line IF data.error THEN STOP REPEAT GOSUB end.of.record * All done: close files, etc. CLOSE target.file CLOSESEQ text.file PRINT lines.read:" lines read from ":source.desc:"." PRINT records.written:" records written to ":target.desc:"." STOP ********************************************************************** * parse.command.line: * * Parse the command line * cmd = CONVERT(" ", @FM, TRIM(@SENTENCE)) field.count = DCOUNT(cmd, @FM) IF field.count < 2 THEN GOSUB print.usage.message STOP END dict.spec = "" default.suffix = "_DATA" target.file.name = cmd<2> IF target.file.name = "DICT" THEN dict.spec = "DICT" default.suffix = "_DICT" target.file.name = cmd<3> target.desc = "the dictionary of " : target.file.name next.field = 4 END ELSE target.desc = target.file.name next.field = 3 END source.dir = "&UFD&" BEGIN CASE CASE next.field > field.count * Source not specified; assume &UFD&, file.name_[DICT | DATA] text.file.name = target.file.name : default.suffix source.desc = text.file.name CASE next.field = field.count * Directory not specified, assume &UFD& text.file.name = cmd source.desc = text.file.name CASE next.field < field.count * More to come; extract directory and file name IF field.count > (next.field + 1) THEN GOSUB print.usage.message STOP END source.dir = cmd text.file.name = cmd source.desc = text.file.name:" in ":source.dir END CASE RETURN ********************************************************************** * open.files: * * Open the files * OPENSEQ source.dir, text.file.name TO text.file ELSE IF STATUS() = 0 THEN PRINT "Error: ":source.desc:" does not exist!" END ELSE PRINT "Error opening ":source.desc:"!" PRINT "Status code ":STATUS() END STOP END OPEN dict.spec, target.file.name TO target.file ELSE PRINT "Can't open ":target.desc PRINT "Status code ":STATUS() STOP END RETURN ********************************************************************** * print.usage.message: * * In case of error, print a message giving the command syntax. * PRINT "Usage: ":cmd<1>:" [DICT] file.name [[source.dir] text.file.name]" RETURN ********************************************************************** * invalid.line: * error.type = "invalid line type ":line[1,1] GOSUB got.data.error RETURN ********************************************************************** * got.data.error: * PRINT "Error: ":error.type:"." PRINT "At line ":lines.read:" of ":source.desc:"." data.error = 1 RETURN ********************************************************************** * ascii.data.line: * * Key A * What ASCII data * Format data characters rec.data := line[2, LEN(line) - 2] RETURN ********************************************************************** * fm.data.line: * * Key F * What ASCII data with implied field mark * Format data characters rec.data := @FM : line[2, LEN(line) - 2] RETURN ********************************************************************** * hex.data.line: * * Key H * What Hexadecimal data * Format hex codes for data characters rec.data := ICONV(line[2, LEN(line)], "MX0C") RETURN ********************************************************************** * rec.id.line: * * Key I * What Record ID, in plain text * Format * GOSUB end.of.record IF data.error THEN RETURN GOSUB extract.record.length IF data.error THEN RETURN rec.id = line[first.space + 1, (len(line) - first.space - 1)] RETURN ********************************************************************** * extract.record.length: * * Extract the record length field from a record ID line. * * Inputs: line * * Outputs: first.space Position of delimiting space * rec.length Record length * data.error Set if line format is wrong * first.space = INDEX(line, " ", 1) IF first.space = 0 THEN error.type = "incorrect line format; no spaces" GOSUB got.data.error RETURN END rec.length = line[2, first.space - 2] IF NUM(rec.length) THEN rec.length += 0 END ELSE error.type = "non-numeric record length '":rec.length:"'" GOSUB got.data.error RETURN END RETURN ********************************************************************** * rec.id.hex.line: * * Key J * What Hex-encoded record ID * Format * GOSUB end.of.record IF data.error THEN RETURN GOSUB extract.record.length IF data.error THEN RETURN rec.id = ICONV(line[first.space + 1, len(line)], "MX0C") RETURN ********************************************************************** * end.of.record: * * This routine is called whenever there may be a record to be written. * It expects the following variables to be set up: * * rec.id record ID, or empty if there is no record * rec.length expected length of record * rec.data record data read in so far * IF LEN(rec.id) = 0 THEN * Nothing to do RETURN END IF rec.length # LEN(rec.data) THEN error.type = "data length error: expected ":rec.length error.type := ", found ":LEN(rec.data) GOSUB got.data.error RETURN END READ dummy FROM target.file, rec.id ELSE WRITE rec.data ON target.file, rec.id END records.written += 1 rec.id = "" rec.length = 0 rec.data = "" RETURN END