%%s 0/0/0 %%d D 1.1 25-Mar-82 12:07:07 v1.1 1 0 %%c Version 1.1 is the Spring 1982 Distribution of the LBL/Hughes release %%c of the Software Tools Virtual Operating System software and documentation. %%T %%I 1 #-h- defns 1176 asc 25-mar-82 08:00:30 v1.1 (sw-tools v1.1) # TCS data file keys define(STATS,"%%s ") # statistics define(VERKEY,"%%d ") # key field on history-info lines define(COMMENT,"%%c ") define(ENDKEY,"%%T") # end of header define(INSERT,"%%I ") # begin "inserted in this version" define(DELETE,"%%D ") # begin "deleted in this version" define(ENDSEG,"%%E ") # end of segment define(KEYSIZ,5) # pts AFTER blank at end of key define(WEWANT,2) # positional info from PARSE define(VDATE,3) define(VTIME,4) define(VUSER,5) define(THISVER,6) define(PREVVER,7) define(MAXVER,100) # max number of (direct) ancestors define(OFF,0) define(ON,1) # flow control during DIFF processing # values for "flag" define(INHIST, 1) define(INRVSN, 2) define(MATCHING, 3) # simulated "structure" during DIFF tree generation define(PREV, 0) define(ALINE, 1) define(BLINE, 2) define(CANDSIZ, 3) # size of a candidate "struct" # definitions to convert long names to 6 characters define(save,#) define(ancestry,anstry) define(myances,myancs) define(seekptr,seekpt) define(lineget,linget) define(outfile,outfil) define(aputlin,aputln) define(outarray,outara) define(filename,filnam) define(passthru,psthru) define(currnest,curnst) #-h- decls 402 asc 25-mar-82 08:00:31 v1.1 (sw-tools v1.1) common /tcs/ ancestry(MAXVER), # family lineage fdhis, fdrev, fdscr, # file descriptors flag, # flag during history-file generation insert, # flag during lineget, init'd by rstget myances, # closest ancestor's "absolute" version number maxver, # last "absolute" version number seekptr(2) # note/seek pointer integer ancestry, fdhis, fdrev, fdscr, flag, insert, myances, maxver, seekptr #-h- get.r 11463 asc 25-mar-82 08:00:34 v1.1 (sw-tools v1.1) #-h- main 2848 asc 25-mar-82 08:00:09 v1.1 (sw-tools v1.1) #-p- # # # # MAIN # # author: Neil P. Groundwater (ADI) date: 11-SEP-81 # # # # Purpose: Validates calling arguments. Allows user to extract history # info or a version of the file. History info extraction is performed # in MAIN. Copies of versions of the file are retrieved by SETGET and # LINEGET. # # # Calling convention: main # # Global Variables Changed # fdhis: file descriptor of historyfile # fdout: file descriptor of output file # # # Modules called by MAIN # create # error # cant # query # putch # putlin # parse # aputlin # close # scopy # setget # rstget # bmatch # clower # getarg # getlin # lineget # open # # # #-p- subroutine main include "defns" include "decls" define(GET,#) # gets rid of unneeded stuff integer bmatch, clower, getarg, getlin, open integer lineget, create character inbuf(MAXLINE) character wanted(40) # the desired version number character arg(FILENAMESIZE) character outfile(FILENAMESIZE) integer argnum, fdout, i integer array(16) string usage "usage: get [-h][-rM.N] historyfile [resultfile]" call query(usage) if (getarg(1, arg, FILENAMESIZE) == EOF) call error(usage) argnum = 2 if (arg(1) == '-') { # look for keys argnum = 3 # for result-filename (later) if (clower(arg(2)) == 'h') { # just print out the history messages if (getarg(2, arg, FILENAMESIZE) == EOF) # re-use arg call error(usage) fdhis = open(arg, READ) if (fdhis == ERR) call cant(arg) while (getlin(inbuf, fdhis) != EOF) { if (bmatch(inbuf, 1, VERKEY) != 0) { call putch('@n', STDOUT) call putlin("*** Version # ", STDOUT) call parse(inbuf, KEYSIZ, array, ' ') call aputlin(inbuf, array(WEWANT), STDOUT) call putch(' ', STDOUT) call aputlin(inbuf, array(VDATE), STDOUT) call putch(' ', STDOUT) call aputlin(inbuf, array(VTIME), STDOUT) call putch(' ', STDOUT) call aputlin(inbuf, array(VUSER), STDOUT) call putch('@n', STDOUT) } if (bmatch(inbuf, 1, COMMENT) != 0) { call aputlin(inbuf, KEYSIZ, STDOUT) } } call close(fdhis) return # done } else { if (clower(arg(2)) == 'r') { call scopy(arg, 3, wanted, 1) # pick up number or EOS # 2nd argument is historyfile... get filename if (getarg(2, arg, FILENAMESIZE) == EOF) call error(usage) } else call error("Illegal keyletter.") } } # 'arg' has the historyfile name... it will be opened in 'setget' # check for a resultfile name if (getarg(argnum, outfile, FILENAMESIZE) != EOF) { # optional fdout = create(outfile, WRITE) if (fdout == ERR) call cant(outfile) } else fdout = STDOUT # if no name given, send out to terminal call setget(arg, wanted) # opens file 'arg' with file des 'fdhis call rstget() # Fetch the text. while (lineget(inbuf, NO) != EOF) call putlin(inbuf, fdout) call close(fdhis) end #-h- parse 1880 asc 25-mar-82 08:00:11 v1.1 (sw-tools v1.1) #-p- #****************************************************************************** #* #* #* PARSE #* #* author: Neil P Groundwater date: 12-AUG-81 #* #* #* #* Purpose: Decompose the "Ad" lines in the history file return the #* members of the line via an array of indexes into the original text #* line. Replace the delimiter character with EOS characters. #* #* #* Calling convention: parse(inbuf, from, outarray, delim) #* #* #* Formal Parameters #* inbuf: Input string (array) #* from: Starting index in inbuf #* outarray: Returned array of member-offsets in inbuf #* delim: Delimiter character supplied by caller #* #* #* Modules which call PARSE #* main #* #* #* Description of algorithm: Move "pointer" across input line and set #* outarray with pertinent values. #* #* #****************************************************************************** #-p- # Subroutine: PARSE(INBUF, FROM, OUTARRAY, DELIMITER) # Enter the chars from the inbuf, # break it into its components # Outarray will contain pointers to the start of each memeber of inbuf # Convert the delimiters to EOS, in place. # The string is assumed to be '@n' terminated. define(NULL,0) subroutine parse(inbuf, from, outarray, delim) character inbuf(MAXLINE) integer from # start offset in inbuf integer outarray(16) # point to each "token" character delim integer ptr ptr = from while (inbuf(ptr) == delim) # skip to 1st field ptr = ptr+1 for (i=1; inbuf(ptr) != '@n'; i=i+1) { outarray(i) = ptr # skip thru field while ((inbuf(ptr) != delim) & (inbuf(ptr) != '@n')) ptr = ptr+1 # zap and skip delimiters while ((inbuf(ptr) == delim) & (inbuf(ptr) != '@n')) { inbuf(ptr) = EOS ptr = ptr+1 } } inbuf(ptr) = EOS outarray(i) = NULL return end #-h- bmatch 310 asc 25-mar-82 08:00:12 v1.1 (sw-tools v1.1) # bmatch - most basic match, Software Tools p. 140. (renamed) integer function bmatch(lin, from, pat) character lin (MAXLINE), pat(MAXLINE) integer from, i, j i = from for (j=1; pat(j) != EOS; j = j + 1) { if (lin(i)!=pat(j)) { bmatch = 0 return # with no match } i = i + 1 } bmatch = i return end #-h- bmch2 308 asc 25-mar-82 08:00:12 v1.1 (sw-tools v1.1) # bmch2 - basic match, also compares the LENGTH of the args integer function bmch2(lin, from, pat) character lin (MAXLINE), pat(MAXLINE) integer from integer equal character temp(MAXLINE) call scopy(lin, from, temp, 1) # copy string to temp return(equal(temp, pat)) # returns YES if exactly equal end #-h- ctoi2 959 asc 25-mar-82 08:00:13 v1.1 (sw-tools v1.1) #-p- #****************************************************************************** #* #* #* CTOI2 #* #* author: Neil P Groundwater date: 12-AUG-81 #* #* #* #* Purpose: Calls CTOI but allows the caller of CTOI2 to pass a #* fixed-value argument. #* #* #* Calling convention: ctoi2(buf, fixed) #* #* #* Formal Parameters #* buf: input string #* fixed: offset in buf to begin conversion. May be a FIXED NUMBER #* (like 3). #* #* #* Module Returns: An integer value. #* #* #* Modules called by CTOI2 #* ctoi #* #* #* Modules which call CTOI2 #* main #* #* #****************************************************************************** #-p- # convert character string to integer - allows "constant" index as arg integer function ctoi2(buf, fixed) character buf integer fixed integer ctoi integer ptr ptr = fixed return(ctoi(buf, ptr)) end #-h- setget 2476 asc 25-mar-82 08:00:14 v1.1 (sw-tools v1.1) # subroutine SETGET (FILENAME, WANTED) # Set up ANCESTRY of the previous version of the file. # # Used in conjunction with LINEGET which will return # the next line from the desired version and RSTGET # which puts the file pointer at the start of the # "content" portion of the file in preparation for # a new series of LINEGET calls. subroutine setget (filename, wanted) character filename(FILENAMESIZE) character wanted(FILENAMESIZE) include "decls" integer bmatch, bmch2, close, ctoi2, getlin, open, note # functions integer junk character inbuf(MAXLINE) integer array(16) # holds pointers returned by PARSE integer i integer thread, iprev, ithis # trace family tree fdhis = open(filename, READ) if (fdhis == ERR) call error("Cannot locate TCS history file.") for (i=1; i<=MAXVER; i=i+1) # initialize ancestry(i) = NO thread = -1 # follows back up tree repeat { i = getlin(inbuf, fdhis) if (i == EOF) call error("Unexpected EOF on history-info scan.") GET call putlin(inbuf, fdscr) # keep it for posterity if (bmatch(inbuf, 1, ENDKEY) != 0) call error("Nonexistant revision level requested.") # Screen for version-info lines if (bmatch(inbuf, 1, VERKEY) != 0) { call parse(inbuf, KEYSIZ, array, ' ') ithis = ctoi2(inbuf, array(THISVER)) # thread values iprev = ctoi2(inbuf, array(PREVVER)) if (thread < 0) { # When the FIRST version-info line is detected, get # the "absolute" version number so that it may be # added later to the family tree. maxver = ithis thread = 0 } if (thread == 0) { # started yet? # Was either no version specified or # is this the requested version? if ((wanted(1) == EOS) | # if none, take latest version (bmch2(inbuf, array(WEWANT), wanted) == YES)) { # yes, start recording ancestry ancestry(ithis) = YES GET myances = ithis # parent of new stuff thread = iprev # predecessor # announce version number if user didn't specify if (wanted(1) == EOS) { call putlin("Version # ", ERROUT) call aputlin(inbuf, array(WEWANT), ERROUT) call putch('@n', ERROUT) } if (thread == 0) # reached root break } else next # not a match, go on to next info-line } else # next on the tree? if (ithis == thread) { ancestry(ithis) = YES thread = iprev if (thread == 0) break # scan thru header is complete } } } junk = note(seekptr, fdhis) # tag the start of the text portion of the file return end #-h- rstget 139 asc 25-mar-82 08:00:15 v1.1 (sw-tools v1.1) subroutine rstget() include "decls" call seek(seekptr, fdhis) # point to start of data portion insert = OFF # current mode return end #-h- lineget 1422 asc 25-mar-82 08:00:16 v1.1 (sw-tools v1.1) # Ancestry has been established. Develop the particular version. # Returns a line-at-a-time to caller. integer function lineget (inbuf, passthru) character inbuf(MAXLINE) integer passthru # send text to new-history file include "decls" integer bmatch, ctoi2, getlin integer currnest, i save currnest repeat { i = getlin(inbuf, fdhis) if (i == EOF) call error("Unexpected EOF on history-data scan.") if (bmatch(inbuf, 1, ENDSEG) != 0) { if (ctoi2(inbuf, KEYSIZ) == 1) { # done GET if (passthru == YES) GET call putlin(inbuf, fdscr) # last line break } if (insert == OFF) if (ctoi2(inbuf, KEYSIZ) == currnest) insert = ON } else if (bmatch(inbuf, 1, INSERT) != 0) if (ancestry(ctoi2(inbuf, KEYSIZ)) == YES) insert = ON else { # not in one of its ancestors, # skip to matching ENDSEG line if (insert == ON) { currnest = ctoi2(inbuf, KEYSIZ) insert = OFF } } else if (bmatch(inbuf, 1, DELETE) != 0) { if (ancestry(ctoi2(inbuf, KEYSIZ)) == YES) # skip to matching ENDSEG line if (insert == ON) { currnest = ctoi2(inbuf, KEYSIZ) insert = OFF } } else if (insert == ON) return (i) # text returned in "inbuf" GET # pass all other lines thru to the output file GET if (passthru == YES) { GET if (flag == INHIST) { GET call puttag(ENDSEG) GET flag = MATCHING GET } GET call putlin(inbuf, fdscr) GET } } return (EOF) # at EOF end #-h- aputlin 464 asc 25-mar-82 08:00:16 v1.1 (sw-tools v1.1) # aputlin - call putlin, but start at a (given) offset in the line subroutine aputlin(str, off, outfd) character str(MAXLINE) integer off, outfd character tmplin(MAXLINE) integer i, j i = off-1 j = 1 # start of buffer repeat { i = i+1 # point TO the char xferred tmplin(j) = str(i) j = j+1 # point AFTER the char just xferred } until ((str(i) == EOS) | (str(i) == '@n')) tmplin(j) = EOS # terminate the string call putlin(tmplin, outfd) return end #-h- get.fmt 2281 asc 25-mar-82 08:00:38 v1.1 (sw-tools v1.1) .so ~bin/manhdr .hd Get (1) 14-Sep-81 get generation from TCS file .sy get [-h][-rM.N] historyfile [resultfile] .ds Get retrieves earlier versions of text from "historyfile" as computed by DELTA. The possible flags are: .br .in +10 (none) - The latest version of the file is retrieved. -h - Print out the history information associated with the versions. The dates, times, and user IDs will be retrieved, along with the comments added while performing the DELTAs. -rM.N - Retrieve the specified version M.N into the "result" file. .in -10 The retrieved version will be put in the "result" file if specified, otherwise it is sent to the standard output. History informatin is always sent to the terminal. .fl .sa admin, delta .di .in +10 .ti -10 usage: get [-h][-rM.N] historyfile [resultfile] .br Correct calling format is provided when called without arguments. .ti -10 Unexpected EOF on history-info scan. .ti -10 .br The source file does not contain the code which identifies it as a TCS history file. The code may be entered via the ADMIN command. .ti -10 Unexpected EOF on history-data scan. .br The file format has been tampered with and is no longer recognizable. Refer to a guru for repair. .ti -10 - missing from keyletter .br First argument is expected to qualify whether versions and/or histories are to be extracted. .br .ti -10 Illegal keyletter .br Only 'h' and 'r' are valid keys. .br .ti -10 Nonexistant revision level requested. .br The version number specified is not contained in the history. Try "get -h file.tcs" to view the versions available. .br .ti -10 Invalid history file .br The history file specifies impossible line-number correlations. Either out-of-sequence changes or line numbers in descending order. .br .ti -10 Cannot locate TCS history file. .br Could not find file supplied for historyfile. .br .in -10 .au An Algorithm for Differential File Comparison by J.W.Hunt and M.D.McIlroy (BTL Computing Science Technical Report #41). Original code by Wil Baden; converted from MORTRAN by Dave Murray. Modifications and conversion to BTL-SCCS style by Neil Groundwater at ADI. The Source Code Control System was introduced by Marc J. Rochkind in the December, 1975, IEEE Transactions on Software Engineering. .bu .br %%E 1