read(`code_utilities.txt`): Help_dbfiles:=proc() print(` OpenDB(fname) , CloseDB(file:=true) `): print(` ResetDB(file:=true) , NextEntry(file) `): print(` PrevEntry(file) , EncapsulateData(S,F,P,G,L,E) `): print(` EncapsulateDataGen(S,data,E) `): end: #Table of open files DBTable:=table(): #Open a file in DB access form #If already open, return the already-open file descriptor OpenDB:=proc(fname) local fd: global DBTable: if ({indices(DBTable)}<>{}) and ([fname] in {indices(DBTable)}) then return DBTable[fname]: fi: try: fd:=fopen(fname,READ): catch: #File is already open, but not in DB access form #Maple is terrible at handling file descriptors #I choose to force close it and then reopen it fclose(fname): fd:=fopen(fname,READ): end try: DBTable[fname]:=fd: return fd: end: #Close a file currently open in DB access form #file can be a file name, a file descriptor, or true #if file is true, then close all open DB files CloseDB:=proc(file:=true) local fname: global DBTable: if file=true then for fname in indices(DBTable) do fclose(DBTable[op(fname)]): od: DBTable:=table(): elif type(file,string) then fclose(DBTable[file]): DBTable[file] := evaln(DBTable[file]) else fclose(file): for fname in indices(DBTable) do if DBTable[op(fname)]=file then DBTable[op(fname)] := evaln(DBTable[op(fname)]) fi: od: fi: return: end: #Reset a file currently open in DB access form #(put back at beginning) #file can be a file name, a file descriptor, or true #if file is true, then reset all open DB files ResetDB:=proc(file:=true) local fname: global DBTable: if file=true then for fname in indices(DBTable) do Position(DBTable[op(fname)],0): od: elif type(file,string) then Position(DBTable[file],0): else Position(file,0): fi: return: end: #Get the next entry from a file currently open in DB access form #file can be a file name or a file descriptor #Entry is in form S,F,P,G,L,{E} #Returns false if reached end of file NextEntry:=proc(file) local S,F,P,G,L,E,line,spline,fd,chrd,temp: global DBTable: if type(file,string) then fd:=DBTable[file]: else fd:=file: fi: S:=false: E:={}: while true do line:=ReadLine(fd): if (line="" or {line}={}) and S<>false then break: elif {line}={} then return false: fi: chrd:=line[1]: line:=line[3..-1]: spline:=Split(line): temp:=parse(sprintf("%a",spline)): if chrd="S" then S:={seq(parse(temp[i]),i=1..nops(temp))}: elif chrd="F" then F:=[seq(parse(temp[i]),i=1..nops(temp))]: elif chrd="P" then P:=[seq(parse(temp[i]),i=1..nops(temp))]: elif chrd="G" then G:=parse(line): elif chrd="L" then L:=parse(line): elif chrd="E" then E:=E union {{seq(parse(temp[i]),i=1..nops(temp))}}: fi: od: return S,F,P,G,L,E: end: #Get the previous entry from a file currently open in #DB access form #file can be a file name or a file descriptor #Entry is in form S,F,P,G,L,{E} #Returns false if reached beginning of file PrevEntry:=proc(file) local S,F,P,G,L,E,line,spline,fd,chrd, temp,once,going,psn: global DBTable: if type(file,string) then fd:=DBTable[file]: else fd:=file: fi: S:=false: E:={}: once:=false: going:=false: while true do if not going then: psn:=Position(fd): if psn <= 0 then return false: fi: Position(fd,psn-1): chrd:=ReadCharacter(fd): Position(fd,psn-1): fi: if (chrd="S" and once) or going then going:=true: line:=ReadLine(fd): if (line="" or {line}={}) and S<>false then break: elif {line}={} then return false: fi: chrd:=line[1]: line:=line[3..-1]: spline:=Split(line): temp:=parse(sprintf("%a",spline)): if chrd="S" then S:={seq(parse(temp[i]),i=1..nops(temp))}: elif chrd="F" then F:=[seq(parse(temp[i]),i=1..nops(temp))]: elif chrd="P" then P:=[seq(parse(temp[i]),i=1..nops(temp))]: elif chrd="G" then G:=parse(line): elif chrd="L" then L:=parse(line): elif chrd="E" then E:=E union {{seq(parse(temp[i]),i=1..nops(temp))}}: fi: elif chrd="S" then once:=true: fi: od: return S,F,P,G,L,E: end: #Convert an entry to a string to be written EncapsulateData:=proc(S,F,P,G,L,E) local SL,s,f,p,g,l,mcont, lmcont,first,e,fix: fix:=proc(strg) return SubstituteAll(strg[2..-2],",",""): end: SL:=sort([op(S)]): s:=cat("S ",fix(sprintf("%a",SL))): f:=cat("F ",fix(sprintf("%a",F))): p:=cat("P ",fix(sprintf("%a",P))): g:=cat("G ",convert(G,string)): l:=cat("L ",convert(L,string)): first:=true: e:="": for mcont in E do if not first then e:=cat(e,"\n"): fi: first:=false: lmcont:=sort([op(mcont)]): e:=cat(e,cat("E ",fix(sprintf("%a",lmcont)))): od: return cat(s,"\n",f,"\n",p,"\n",g,"\n",l,"\n",e): end: #Convert a generalized entry to a string to be written EncapsulateDataGen:=proc(S,data,E) local SL,s,f,p,g,l,mcont, lmcont,first,e,fix,F,P,i,dstr,is: fix:=proc(strg) return SubstituteAll(strg[2..-2],",",""): end: SL:=sort([op(S)]): s:=cat("S ",fix(sprintf("%a",SL))): dstr:="": for i from 1 to nops(data) do F:=data[i][2]: P:=data[i][1]: is:=convert(i-1, string): f:=cat("F", is, " ", fix(sprintf("%a",F))): p:=cat("P", is, " ", fix(sprintf("%a",P))): g:=cat("G", is, " ", convert(nops(F),string)): l:=cat("L", is, " ", convert(nops(P),string)): dstr:=cat(dstr,f,"\n",p,"\n",g,"\n",l,"\n"): od: first:=true: e:="": for mcont in E do if not first then e:=cat(e,"\n"): fi: first:=false: lmcont:=sort([op(mcont)]): e:=cat(e,cat("E ",fix(sprintf("%a",lmcont)))): od: return cat(s,"\n",dstr,e): end: