|
DataMuseum.dkPresents historical artifacts from the history of: RC4000/8000/9000 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about RC4000/8000/9000 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 92160 (0x16800) Types: TextFile Names: »tcatupdate«
└─⟦00964e8f7⟧ Bits:30007478 RC8000 Dump tape fra HCØ. └─⟦b2ec5d50f⟧ └─⟦0b92c64d5⟧ »ctb« └─⟦this⟧
(boptions = set 100 disc boptions = slang lister.no scope user boptions print boptions words.2 integer 0.2) s. a20 w. 77 11 02, 57 ; version id: a0, a1 ; top of devices, number devices a2 ; max number of private disc kits a3 ; no of free disc drives p. <:options:> ; ...include boss 2 options... a0 = e24+e17 ; define top of devicelist a1 = e17 ; no of devices a2 = i30 ; max no of private disc kits a3 = i29-1 ; no of free disc drives......... c.i27,a3=a3-1 z.; .......... e.e. (catupdate = set 100 disc catupdate = algol spill.yes list.no xref.no scope user catupdate ) \f <* bbj 9 9 76 catupdate ...1... *> begin comment this program is intended to create and update the usercat, nescessary for the boss2-operating-system. there are several comments throughout the program, in order to facilitate the understanding of the text, but for certain of the actions, the reader is kindly requested to confer with the actual boss2-program-text. (this is especially recommended for reading the option- actions (because they are - more or less - directly translated from slang into algol6).) apart from this, i have used long variable-names, instead of having comments...; \f <* bbj 9 9 76 description of catalog catupdate ...2... *> <* bbj 15-1-76 The usercatalog in Boss The usercatalog is built as an hierarchical structure of subcatalogs with each subcatalog consisting of records of varying length. These records describe all the information available in the catalog. The catalog is placed on the system disc with the name USERCAT and is re- served by the operating system BOSS. The catalog is terminated by a re- cord of type 0 and with a project number 2**23-1 (described later). The first segment(s) is (are) used as an index to gain faster access to the catalog. The first word of the index table is the maximum number of permanent ca- talog entries which are promised to the projects in the usercatalog (in negative representation). If there exist more than one index segment the next word will contain -1. The number of words with -1 is the number of index segments -1. The following words contain the number of the project with the highest number on that segment. The address of the segment is the number of the index word (absolute segment addressing). The following figure illustrates how the indextable and the catalog en- tries work Usercat ! ! !------------------------------! -- 0 ! - no. of catalog entries ! ! !------------------------------! ! 2 ! -1 ! ! !------------------------------! ! segment 1 4 ! (project number) 0 ! ! !------------------------------! ! 6 ! do 0 ! ! !------------------------------! ! 8 ! do 1 ! ! !------------------------------! ! ! ! ! ---------! . ! > index table segment 2 ! . ! ! ! . ! ! !------------------------------! ! ! 2**23-1 ! ! !------------------------------! ! ! 2**23-1 ! ! ---------!------------------------------!---! ! ! segment 3 ! ! !------------------------------! ! inf. about project 0 ! ---------!------------------------------! ! ! ! ! segment 4 !------------------------------! ! inf. about project 0 ! ---------!------------------------------! ! ! ! ! segment 5 !------------------------------! ! inf. about project 1 ! ---------!------------------------------! ! ! ! ! Each record describes a piece of information for a project or a user. The records have the common feature that the two first bytes describe the type and the length of the record. Type 0 and type 2 are special records. Type 0 describes the projects and type 2 the users within the projects. All common information and resour- ces are gathered under a type 0 record and all information for each user is gathered under a type 2 record. All information about projects and users are necessary in the catalog, all other types of records are optional. The following is a list of all the record types and for each type the meaning of each byte (word) of the record. Many of the records are concerned with different claims (for instance disc or drum) with both a standard value and a maximum value, therefore the record types can assume two values an even integer if standard va- lues are used and an odd integer if maximum values are used. If only one of the two types can be used the record is marked with a *. More information about the catalog can be found in ref1 ch4 p2-3, ref2 ch1 p1-3 and ref3 ch7. \f bbj 9 9 76 records in the catalog catupdate ...3... Record-types in the catalog * type 0 project - 0 - 0, 12 - 2 - project number - 4 - max-interval - 8 - rest entries, rest slices on disc - 10 - total entries, total slices on disc * type 2 user - 0 - 2, 16 - 2 - user name (8 bytes) - 10 - user interval start - 12 - standard interval length - 14 - number of user indices * type 4 - 0 - 4, 6 - 2 - standard value of priority - 4 - minimum value of late * type 6 private disc kits - 0 - 6, 12 - 2 - device name - 10 - rest entries, rest slices - 12 - total entries, total slices type 8 - 0 - 8 , 6 - 2 - first word with device bits - 4 - second word - - - type 10 accounts (ref1, ch2, p2) - 0 - 10, 4 - 2 - number of account buffers type 12 area processes (ref1, ch2, p2) - 0 - 12, 4 - 2 - area claim type 14 mess. buffer (ref1, ch2, p3) - 0 - 14, 4 - 2 - buffer claim type 16 convert operations (ref1, ch2, p3) - 0 - 16, 4 - 2 - cbuf claim \f bbj 9 9 76 records in the catalog catupdate ...4... type 18 internal processes (ref1, ch2, p3) - 0 - 18, 4 - 2 - internal claim type 20 keys (ref1, ch2, p4) - 0 - 20, 4 - 2 - number of protection keys type 22 mounts (ref1, ch2, p5) - 0 - 22, 4 - 2 - number of mounts type 24 output (ref1, ch2, p6) - 0 - 24, 4 - 2 - number of output characters type 26 size (ref1, ch2, p7) - 0 - 26, 4 - 2 - number of bytes in core store type 28 stations (ref1, ch2, p7) - 0 - 28, 4 - 2 - number of standard tape stations type 30 tapes (ref1, ch2, p4) - 0 - 30, 4 - 2 - number of papertapes to be loaded type 32 time (ref1, ch2, p8) - 0 - 32, 4 - 2 - net run time * type 34 user with userpool - 0 - 34, 10 - 2 - user max interval - 6 - rest entries, rest slices - 8 - total entries, total slices * type 36 drum, key 1 - 0 - 36, 4 - 2 - entries, slices * type 38 disc, key 1 - 0 - 38, 4 - 2 - entries, slices \f bbj 9 9 76 records in the catalog catupdate ...5... * type 40 disc, key 3 - 0 - 40, 4 - 2 - entries, slices * type 42 output identification - 0 - 42 , variable length - 2 - user name and address * type 44 drum, key 3 - 0 - 44, 6 - 2 - rest entries, rest slices - 4 - total entries, total slices * type 46 drum, key 3 - 0 - 46, 4 - 2 - user entries, slices * type 48 special device, key 3 - 0 - 48, 12 - 2 - device name - 10 - user entries, slices * type 50 max turn around time (ref1, ch2, p4) - 0 - 50, 4 - 2 - maximum wait type 52 information for accountjob - 0 - 52, 16 - 2 - project identification in textform - 14 - * type 54 program - 0 - 54, 4 - 2 - name of program to be loaded type 56 available suspend buffers (ref1, ch2, p7) - 0 - 56, 4 - 2 - suspendings type 58 online - 0 - 58, 4 - 2 - conversational jobs allowed (0) / not allowed (1) type 60 corelock (ref1, ch2, p3) - 0 - 60, 4 - 2 - corelock time \f bbj 9 9 76 records in the catalog catupdate ...6... type 62 degree of information (ref1, ch2, p5) - 0 - 62, 4 - 2 - minimal yes (1) / no (0) type 64 priority - 0 - 64, 4 - 2 - start priority factor type 66 deliberate waiting (ref1, ch2, p8) - 0 - 66, 4 - 2 - maximum wait time type 68 catalog preservation (ref1, ch2, p6) - 0 - 68, 4 - 2 - preserve yes (1) / no (0) type 70 terminal user rights (privileges) - 0 - 70, 4 - 2 - privilege-bits type 72 link - 0 - 72,4 - 2 - no. of simultaneous used links References (1) Boss 2 Users Manual (2) Monitor 3 (3) Boss 2 Installation and Maintenance *> \f <* bbj 9 9 76 declarations catupdate ...7... *> real array transname, vartransname, newcatname (1:2); integer max_devicenumber, max_option, max_record_type, worksize, std_usercat_index, max_no_of_disckits, intervaltable_size, varlength, maxlength, no_of_trans, no_of_vartrans, no_of_privkits, no_of_priv_discdrives; boolean nooldcat, leftside, updatetest; comment definitions of standard-values ... may be changed; max_devicenumber := 44; comment length of devicelist; max_option := 26; comment length of option-table; max_record_type := 72; worksize := 8; comment size of workareas; std_usercat_index:= 2; comment no of index segments in usercat; max_no_of_disckits:=50; comment length of kittable; intervaltable_size := 200; comment i.e. max number of projects + greatest no of users in single project; varlength := 512//2; comment maxlength of username - 10 (in bytes...); updatetest := true; comment testoutput is selected by the edit-command: g b/comment iiff updatetest/if updatetest/ ; begin integer print, no_of_devices; integer array devicenumber(1:max_devicenumber); long array devicename(1:5); begin integer projno, updateinf, usercatsegm, state, neutralstate, projectstate, userstate, linetype, inlinetype, linelength, freeparam, rectypelgth, typeofrec,valueofpar, paramno, number_of_params, first_paramno, first_free_proj, last, permanent_disc; long username1, username2, name, deviceword, maxdeviceword; boolean nosource, list, userpool, device, maxdevice, project; integer field i, j, if2, if4, if12, basis, int1, int2, int3, int4, int5, int6, int7; long field lg6, lg10, long1, long2, lastoption, nameptr; boolean field p1; integer array p(0:10), line, kind(1:(varlength-10)//2), alphabettable(0:5*128-1), option(1:5*max_option+2); real array fpparam, fpparam1(1:2); integer array field rec; zone in, trans, vartrans(128, 1, stderror); \f <* bbj 9 9 76 help procedures catupdate ...8... *> procedure output(z, length); zone z; integer length; comment the procedure initializes the next transaction- record, with project-number, username and recordtype and -length, and information whether creation, changing or deleting. furthermore the two special cases are handled: l. only checking of transactions (i.e. no leftside in program call) 2. the transactions are allready sorted and may be used directly to form a new usercat. ; begin no_of_trans:= no_of_trans + 1; outrec6(z, length); z.if2:= projno; z.lg6:= username1; z.lg10:= username2; z.if12:= rectypelgth shift 4 add (if inlinetype<-1 then 0 else updateinf); z.basis:= rectypelgth; end; procedure move_username(z, length); value length; zone z; integer length; comment the procedure moves the first parameter on the input line (i.e. the username) to the zone; begin j:= p(0) * 2; comment start of text; last := p(1) * 2; comment last of text; rectypelgth := rectypelgth + last - j + 2; output(z,length); i:= int1 - 2; for i:= i+2 while j <> last do begin comment move...; z.i := line.j; j := j+2; end; end move_username; procedure checkparam(min, max, number, type); integer min, max, number, type; comment the procedure checks, that the number_of_params is within the limits min,max (incl.) and that all parameters are of legal type. (notice the jensen-device...). if any inconsistency is found the alarm-procedure is called; if number_of_params < min or number_of_params > max then alarm(<:number of params:>) else for number := 0 step 1 until number_of_params-1 do if type shift (-kind(p(number))) extract 1 = 0 then alarm(<:illegal type:>); comment notice: if the actual type contains ..1 shift m.. it means, that an actual parameter with kind=m is legal...; procedure alarm(text); string text; begin write(out, <:***:>, text, <:<10>:>); goto alarmprint; end; \f <* bbj 9 9 76 proc parameter error catupdate ...9... *> procedure parameter_error; comment if any parameter error is found in the fp-command, this procedure is called. it writes the faulty parameters on current output, and returns to ...next_source... with paramno pointing at the next parameter; begin write(out, <: <10>***parameter error: :>); for i:= system(4, paramno, fpparam), system(4, paramno, fpparam) while i shift (-12) = 8 do begin write(out, if i shift (-12) = 8 then <:.:> else <: :>); j := 1; if i extract 12 = 10 then write(out, string fpparam(increase(j))) else write(out, <<d>, fpparam(1)); paramno := paramno + 1; end; write(out, <:<10>:>); goto next_source; end parameter_error; procedure testvalues(rectype,val1); value rectype,val1; integer rectype,val1; <* the routine checks the parametervalues for byte/word overflow/underflow where it is possible *> begin integer i,j; j:=rectype//2; if j>max_record_type then begin write(out,<:<10>case out of range in testvalues<10>:>); goto exittest; end; i := case j of (3,3,3,3,1,1,1,1,1,1, 1,2,2,1,1,2,3,3,3,3, 3,3,3,3,2,3,3,1,3,2, 3,1,2,3,3,1 ); <* i-value : 1- the parameter must be within a byte 2- - - - - - a word 3- no check *> case i of begin <*1*> if (val1<0) or (val1>=4095) then write(out,<: ***value should not exceed a byte:>); <*2*> if (val1<0) or (val1>=8388607) then write(out,<: ***value should not exceed a word:>); <*3 - nothing *> ; end case i; exittest: end proc testvalues; \f <* bbj 9 9 76 initialization catupdate ...10... *> comment initialization of fields in transaction-records; if2 := 2; if4 := 4; lg6 := 6; lg10 := 10; if12 := 12; comment standard values of program options; nooldcat:= false; list := false; nosource := true; print := 0; comment no listing of usercatalog; comment initialize state-values; neutralstate := 1 - (-1) * 3; comment (=1-(smallest type)*3); projectstate := 1 + neutralstate; userstate := 1 + projectstate; state := neutralstate; comment initialize the primitive interval-routine, in case of newcat-mode; first_free_proj := 1 shift 23 + 2; usercatsegm := std_usercat_index; comment number of indexsegments; comment initialize the charactertable for reading of username; for i := 0 step 1 until 5*128-1 do alphabettable(i) := 0; for i := 33 step 1 until 125 do alphabettable(i) := 1 shift 12 + 128; comment shift-chars; for i := 12, 25, 59 do alphabettable(i) := 1 shift 12 + 256; comment shift back; for i := 32 step 1 until 125 do alphabettable(i+128) := 6 shift 12 + i; comment normal chars; alphabettable(10) := 6 shift 12 + 10; for i := 10+128, 12+128, 25+128, 59+128 do alphabettable(i) := 1 shift 12 + 0; comment shift chars; alphabettable(95) := 6 shift 12 + 32; comment underline is space; comment initialize the charactertable for reading of normal lines; for i := 97 step 1 until 125 do alphabettable(i+256) := 6 shift 12 + i; comment letters; for i := 9, 14 step 1 until 94, 96, 126 do alphabettable(i+256) := 7 shift 12 + i; comment delimiters; for i := 9, 32 step 1 until 125 do alphabettable(i+384) := alphabettable(i+512) := 7 shift 12 + i; for i := 48 step 1 until 57 do alphabettable(i+256) := 2 shift 12 + i; comment digits; for i := 43, 45 do alphabettable(i+256) := 3 shift 12 + i; comment sign; for i := 10, 12, 25 do alphabettable(i+256) := 8 shift 12 + i; comment terminators; alphabettable(40+256) := 1 shift 12 + 384; comment shift-char; alphabettable(59+256) := 1 shift 12 + 512; comment shift-char; for i := 10, 12, 25 do alphabettable(i+384) := alphabettable(i+512) := 1 shift 12 + 256; comment shift back; alphabettable(41+384) := 1 shift 12 + 256; comment shift back; for i := 0 step 128 until 512 do alphabettable(26+i) := 7 shift 12 + 38; comment sub char; intable(alphabettable); tableindex := 256; \f <* bbj 9 9 76 initialization of optiontable catupdate ...11... *> comment initialization of the option table: each entry contains: 1. option name 2. action number 3. legal parametertypes for this option (3 bytes) (notice: 1 shift m means that parameters, whose readall-kind (-value) is m, are legal) 4. recordtype in usercat 5. recordlength in usercat ; begin integer type_2, type_6, type_8, type_2_6, type_2_8; boolean field byte; procedure pack(optionname, actionno, partype1, partype2, partype3, rectype, reclength); string optionname; integer actionno, partype1, partype2, partype3, rectype, reclength; begin comment the procedure packs the parameters in the next free elements of the option table; option.lastoption := long optionname; byte := lastoption; for i := actionno, partype1, partype2, partype3, rectype, reclength do begin byte := byte + 1; option.byte := false add i; end; lastoption := lastoption + 10; end pack; type_2 := 1 shift 2; comment integer parameter; type_6 := 1 shift 6; comment text parameter; type_8 := 1 shift 8; comment end of line; type_2_6 := type_2 + type_6; comment integer or text parameter; type_2_8 := type_2 + type_8; comment integer param or end of line; lastoption := 4; pack(<:acco:>, 1, type_2, type_8, type_8, 10, 4); pack(<:area:>, 1, type_2, type_8, type_8, 12, 4); pack(<:buf:> , 1, type_2, type_8, type_8, 14, 4); pack(<:cbuf:>, 1, type_2, type_8, type_8, 16, 4); pack(<:core:>, 1, type_2, type_8, type_8, 60, 4); pack(<:devi:>, 2, type_2_6, type_8, type_8, 8,6); pack(<:inte:>, 1, type_2, type_8, type_8, 18, 4); pack(<:key:> , 1, type_2, type_8, type_8, 20, 4); pack(<:late:>, 3, type_2, type_2_8, type_8,50,4); pack(<:mini:>, 9, type_6, type_8, type_8, 62, 4); pack(<:moun:>, 1, type_2, type_8, type_8, 22, 4); pack(<:onli:>, 9, type_6, type_8, type_8, 58, 4); pack(<:outp:>, 1, type_2, type_8, type_8, 24, 4); pack(<:perm:>, 7, type_6, type_2, type_2, 40, 4); pack(<:pres:>, 9, type_6, type_8, type_8, 68, 4); pack(<:prio:>, 1, type_2, type_8, type_8, 64, 4); pack(<:priv:>, 4, type_2, type_8, type_8, 70, 4); pack(<:prog:>, 5, type_6, type_8, type_8, 54,10); pack(<:link:>, 1, type_2, type_8, type_8, 72, 4); pack(<:size:>, 1, type_2, type_8, type_8, 26, 4); pack(<:stat:>, 1, type_2, type_8, type_8, 28, 4); pack(<:susp:>, 1, type_2, type_8, type_8, 56, 4); pack(<:tape:>, 1, type_2, type_8, type_8, 30, 4); pack(<:temp:>, 8, type_6, type_2, type_2_8,36,4); pack(<:time:>, 6, type_2, type_2_8, type_2_8, 32, 4); pack(<:wait:>, 1, type_2, type_8, type_8, 66, 4); comment now lastoption points at a place just after the the option names; end initialize option table; \f <* bbj 9 9 76 initialization catupdate ...12... *> comment initialize the tables of system devices, to be used by the action ..device..; for i := 1 step 1 until 5 do devicename(i) := long (case i of (<: :>, <:prin:>, <:card:>, <:punc:>, <:plot:>)); open(trans, 4, <:boptions:>, 0); inrec6(trans, 4); write(out, <:<12><10>; catupdate version:>, trans.if2, trans.if4, <:<10><10>:>); inrec6(trans, 508); no_of_devices := trans.if4; p1 := trans.if2-4; comment top of devicelist...; rec:= 0; no_of_privkits:= trans.rec(3); no_of_priv_discdrives:= trans.rec(4); for i:=1 step 1 until no_of_devices do begin devicenumber(i) := trans.p1 extract 11 - trans.p1 shift(-11) extract 1 shift 11; p1 := p1 - 1; end; close(trans, true); comment initialize the transaction-zone and update the newcat-option...; for i:= 3 step 1 until 10 do line(i):= 0; open(trans, 4, <::>, 0); line(1) := worksize; line(2) := 1; comment pref. disc; monitor(40) create entry:(trans, 0, line); open(vartrans, 4, <::>, 0); line(1):= line(2):= 1; monitor(40) create entry:(vartrans, 0, line); getzone6(trans, line); for i:= 1, 2 do transname(i):= real<::> add line(i*2) shift 24 add line(i*2+1); getzone6(vartrans, line); for i:= 1,2 do vartransname(i):= real<::> add line(i*2) shift 24 add line(i*2+1); \f <* bbj 9 9 76 fp-command catupdate ...13... *> <* examination of the fp-command *> <* ----------------------------- *> comment examine the parameter list: 1. if there is a leftside parameter, the transaction zone is connected to the specified area (and the option ..leftside.. is set to true) 2. if the first parameter group is cat.yes the transactions are not merged with the old usercat (and the option ..newcat.. is set to true) ; paramno := 1; comment point at a possible programname; i := system(4, paramno, fpparam); comment get parameter 1 ; leftside := false; if i = 6 shift 12 + 10 <* = followed by a name *> then begin leftside:= true; system(4, 0, newcatname); <*leftside := newcatname *> paramno:= paramno + 1; i:= system(4, paramno, fpparam); <* fpparam := catupdate *> end; first_paramno := paramno + 1; comment now paramno is the number of the first real parameter, and fpparam contains the parameter, while i contains the parameterhead...; comment test if the first parameter group is cat.yes...; if if i = 4 shift 12 + 10 <* . followed by a name *> then fpparam(1) = real <:cat:> else false then begin comment the parameter group may be cat.yes ; if system(4, paramno + 1, fpparam) = 8 shift 12 + 10 and fpparam(1) = real <:yes:> and system(4, paramno + 2, fpparam) shift (-12) <> 8 then begin paramno := paramno + 2; nooldcat:= true; end cat.yes; end first parameter = <:cat:>; comment initialize fields in transaction records; basis := 14; int1 := 2 + basis; int2 := 4 + basis; long1 := int2; int3 := 6 + basis; int4 := 8 + basis; long2 := int4; int5 := 10+ basis; int6 := 12+ basis; int7 := 14+ basis; maxlength := int7; comment last byte of longest record; maxlength := ((maxlength + 3) // 4) * 4; comment must be a multiple of 4 bytes; no_of_trans:= no_of_vartrans:= 0; \f <* bbj 9 9 76 fp-command catupdate ...14... *> comment initialize the input zone, and update the list-option...; next_source: ; comment *************** ; comment paramno is the number of the next fpparameter; i := system(4, paramno, fpparam); comment get the parameter; if i = 0 then begin comment the list is empty; if nosource then print := 1 shift 3; comment print all catalog...; linetype := -1; comment simulate a finis-record; goto select; end; if i <> 4 shift 12 + 10 <* space followed by name *> then parameter_error; i := system(4, paramno + 1, fpparam1); comment examine the following parameter...; if i shift (-12) = 8 then begin comment parameter group ... must be list.on or list.off; if i = 8 shift 12 + 10 <* . and name follows *> and fpparam(1) = real <:list:> and system(4, paramno + 2, fpparam) shift (-12) <> 8 then begin list := fpparam1(1) = real <:on:>; paramno := paramno + 2; goto next_source; end list.on or list.off else parameter_error; end parameter group; comment the parameter is the name of the next source; paramno := paramno + 1; nosource := false; if paramno = first_paramno then system(9, 0, <:<10>***call :>); close(in, true); i := 1; open(in, 4, string fpparam(increase(i)), 0); comment examine if it is something else than a backing store area; i := monitor(42, in, 1, line); comment lookup entry; if i = 0 and line(1) < 0 then begin comment it is a filedescriptor...; close(in, true); comment i.e. regret the open...; i := 2; open(in, line(1) extract 23, string (real <::> add line(increase(i)) shift 24 add line(increase(i))), 0); end; comment position the input, according to the catalog entry...; if line(1) > 0 or line(1) extract 12 = 4 or line(1) extract 12 = 18 then setposition(in, line(7), line(8)); comment ... only in case of backing store area or mag.tape...; goto first_line; <* end fp-command *> <* -------------- *> \f <* bbj 9 9 76 input catupdate ...15... *> print_line: ; comment *************** ; if list then begin alarmprint: ; comment *************** ; write(out, <<d>, inlinetype); for i := 1 step 1 until (abs linelength)-1 do case kind(i) of begin comment kind 1; write(out, <:***number out of range:>); comment kind 2; write(out, <<d>, line(i)); comment kind 3,4,5; ;;; comment kind 6; begin write(out, string (real <::> add line(increase(i)) shift 24 add line(increase(i)))); i := i-1; end; comment kind 7; write(out, false add line(i), 1); end case kind; write(out, <:<10>:>); if inlinetype = 5 then testvalues(typeofrec,valueofpar); end print line; comment reading of input ; comment ---------------- ; tableindex := 256; comment select std alfabet; for i := readchar(in, i) while i <> 8 do ; comment skip any possible line-rest; first_line: ; comment *************** ; if list then begin comment copy input until sign, digits or endline; for i:=readchar(in, j) while i<>3 and i<>2 and j<>25 do write(out, false add j, 1); repeatchar(in); end; if read(in, inlinetype) = 0 then goto next_source; repeatchar(in); linetype := inlinetype; if inlinetype = -1 then goto select; comment finis-record; linetype := abs linetype; if linetype = 3 or linetype=12 then tableindex := 0; <* name and add or accounting *> comment this special alfabet skips the preceding spaces on a line, and terminates reading when a semicolon or end_medium char occurs; linelength := readall(in, line, kind, 1); repeatchar(in); freeparam := linelength + 1; if linetype > 12 or inlinetype < -1 then alarm(<:illegal linetype:>); if linelength < 0 then alarm(<:line too long:>); if linetype = 0 then goto select; comment end-record; if linetype <> 3 and linetype <> 12 and linelength < 3 and linelength <> 0 then alarm(<:too few parameters on line:>); comment check the type of the line; \f <* bbj 9 9 76 search kind catupdate ...16... *> comment search the kind-array and find the start of the parameters ; i := 1; number_of_params := -1; comment i is the element in ...kind... to be checked, while number_of_params is the corresponding parameter number in the line (notice: parameters are counted from 0...); for number_of_params := number_of_params + 1 while kind(i) <> 8 do begin if number_of_params > 6 then alarm(<:too many parameters:>); if (1 shift 1 + 1 shift 2 + 1 shift 6) shift (-kind(i)) extract 1 = 0 then number_of_params := number_of_params - 1 else p(number_of_params) := i; comment if the kind of the element is not integer or text then skip the element, else indicate the start of the current parameter in the array ..p.. in this way p(J) is the start index of parameter j of the current line; for i:= i+1 while kind(i) = kind(i-1) do ; comment skip the following elements with the same kind; end; p(number_of_params) := i; comment the end_of_line element; select: ; comment *************** ; comment dependent of the type of the line, rectypelgth is initialized with the standard value. (each input line normally produces one record in the usercat). some of the special action may however set another rectypelgth; comment: linetype is in the range from -1 to 12 (both incl.) -1 0 1 2 3 4 5 6 7 8 9 10 11 12 ; rectypelgth := case linetype+2 of (-1, -1, 0, 2, 42, 6, -1, -1, 4, 44, 34, 0, 2, 52) shift 12 add (case linetype+2 of (-1, -1, 12, 16, 0, 16, 0, 0, 6, 6, 0, 12, 16, 0) ); comment ... notice that the rectypelgth of linetype 0 is explicitly used at ...initsort... ; comment select the corresponding action, depending on line type and state; goto case linetype*3 + state of (initsort , termproj , termuser , print_line, termproj , termuser , linetype1 , termproj , termuser , linetype2 , termproj , termuser , illegal , linetype3 , linetype3, illegal , linetype4 , linetype4, illegal , linetype5 , linetype5, illegal , linetype6 , linetype6, illegal , linetype7 , linetype7, illegal , linetype8 , linetype8, illegal , illegal , linetype9, linetype10, termproj , termuser , linetype11, termproj , termuser , illegal , linetype12, linetype12); \f <* bbj 9 9 76 linetypes catupdate ...17... *> linetype1: ; comment create project *************** **************** ; checkparam(4, 5, 0, 1 shift 2); comment 4 or 5 integer parameters; if number_of_params = 4 and line(p(1)) = 0 then alarm(<:number of params:>); comment convert project width into primitive project interval...; p(5) := increase(freeparam); line(p(5)) := first_free_proj + line(p(4)) - 1; p(4) := increase(freeparam); line(p(4)) := first_free_proj; comment now: p(4) points at lower proj-interval, p(5) points at upper proj-interval; goto initproj; linetype2: ; comment create user *************** ************* ; checkparam(3, 5, i, if i=0 then 1 shift 6 else 1 shift 2); comment 3, 4 or 5 parameters, first is name, rest are integers; comment initialize standard values; if number_of_params = 3 then begin comment insert std job-interval-width; p(3) := increase(freeparam); line(p(3)) := 1; end; if number_of_params < 5 then begin comment insert std number of sim. jobs; p(4) := increase(freeparam); line(p(4)) := 10; end; comment compute primitive user interval; p(5) := increase(freeparam); line(p(5)) := first_free_proj; comment now: p(3) points at job-interval-width. p(4) points at number of simult. jobs, p(5) points at lower user interval; goto inituser; linetype3: ; comment username record *************** ***************** ; checkparam(1, 1, i, 1 shift 6); comment exactly one text parameter; comment: the record is copied to a special file, vartrans, in order to facilitate the sorting of the transactions (because the sorting then may concentrate on fixlength records...); no_of_trans:= no_of_trans - 1; no_of_vartrans:= no_of_vartrans + 1; move_username(vartrans, varlength); goto print_line; \f <* bbj 9 9 76 linetypes catupdate ...18... *> linetype4: ; comment resources on special disc-kits *************** ******************************** ; checkparam(4, 4, i, if i=0 then 1 shift 6 else 1 shift 2); comment 4 parameters, the first is text, the rest integers; if -, project then userpool:= true; nameptr := p(0) * 2 + 2; comment point at kit-name; if line.nameptr = long <:disc:> or line.nameptr = long <:drum:> then alarm(<:illegal devicename:>); output(trans, maxlength); trans.long1 := line.nameptr; nameptr := nameptr + 4; trans.long2 := if kind(p(0)+2) <> 6 then extend 0 else line.nameptr; trans.int5 := trans.int6 := line(p(2)) shift 12 add line(p(1)); trans.int7 := line(p(3)); goto print_line; linetype5: ; comment standard values for options *************** ***************************** ; linetype6: ; comment maximum values for options *************** **************************** ; checkparam(2, 4, i, if i=0 then 1 shift 6 else -1); comment 2 to 4 parameters, the first is text, the rest may be anything; nameptr := p(0) * 2 + 2; comment point at option name; name := line.nameptr shift (-16) shift 16; comment extract the first four letters...; option.lastoption := name; comment insert last in table...; comment scan the option table to find the proper option...; nameptr := -6; for nameptr := nameptr + 10 while option.nameptr <> name do ; if nameptr = lastoption then alarm(<:option unknown:>); p1 := nameptr + 2; comment point at first parameter type...; for i := 1 step 1 until 3 do begin comment check the parameters in the option line...; if kind(p(i)) = 8 then begin p(i+1) := p(i) + 1; kind(p(i+1)) := 8; end else if -, option.p1 shift (-kind(p(i))) then alarm(<:parameter kind:>); p1 := p1 + 1; end; i:= nameptr+5; <*point at recordtype*> typeofrec:= option.i shift (-12); i := nameptr + 6; comment point at rectypelgth element; rectypelgth := option.i; if linetype = 6 then rectypelgth := 1 shift 12 + rectypelgth; comment maximum-value-records have an odd recordtype...; p1 := nameptr + 1; comment point at action-number byte; goto case option.p1 extract 12 of (action1, action2, action3, action4, action5, action6, action7, action8, action9); \f <* bbj 9 9 76 linetypes catupdate ...19... *> linetype7: ; comment jobpriority and respite *************** ************************* ; <* used by older versions, does not exist in newer versions *> checkparam(2, 2, 0, 1 shift 2); comment 2 integer parameters; output(trans, maxlength); trans.int1 := line(p(0)); comment jobpriority; trans.int2 := (line(p(1)) * (extend 10000)) shift (-13);; comment respite; goto print_line; linetype8: ; comment permanent drum *************** **************** ; checkparam(2, 2, 0, 1 shift 2); comment 2 integer parameters; output(trans, maxlength); trans.int1 := trans.int2 := line(p(1)) shift 12 add line(p(0)); goto print_line; linetype9: ; comment userpool *************** ********** ; checkparam(2, 2, 0, 1 shift 2); comment 2 integer parameters; permanent_disc := permanent_disc + line(p(1)) shift 12 add line(p(0)); userpool := true; goto print_line; linetype10: ; comment abs create proj *************** ***************** ; checkparam(6, 6, 0, 1 shift 2); comment 6 integer parameters; goto initproj; \f <* bbj 9 9 76 linetypes catupdate ...20... *> linetype11: ; comment abs create user *************** ***************** ; checkparam(6, 6, i, if i=0 then 1 shift 6 else 1 shift 2); comment 6 parameters, the first is text, the rest are integers; goto inituser; linetype12: ; comment project id (account inf.) *************** *************************** ; checkparam(1, 1, 0, 1 shift 6); comment 1 text parameter; for i := p(1), i+1 while p(0)+7 > i do line(i) := 0; p(1) := p(0) + 7; comment extend the text into 21 chars...; move_username(trans, maxlength); goto print_line; initproj: ; comment *************** ; <* the parameter pointed at by p(1) is : 0 - new project or user 1 - change - - - 2 - delete - - - *> projno := line(p(0)); if projno < 0 or projno > 999999 then alarm(<:illegal projno:>); if line(p(1)) < 0 or line(p(1)) > 2 then alarm(<:illegal update identification:>); updateinf := (if line(p(1)) = 2 then 0 else line(p(1)) + 1) shift 1 add (if linetype=1 then 1 else 0); if updateinf = 1 then alarm(<:illegal update information:>); project := true; username1 := username2 := 0; output(trans, maxlength); maxdeviceword := -1; comment no devices allowed; deviceword := 0; comment no devices requested; maxdevice := device := false; trans.int1 := projno; trans.int2 := line(p(4)); comment lower proj interv.; trans.int3 := line(p(5)); comment upper proj interv.; trans.int4 := trans.int5 := line(p(3)) shift 12 add line(p(2)); state := if updateinf = 0 then neutralstate else projectstate; goto print_line; \f <* bbj 9 9 76 linetypes catupdate ...21... *> inituser: ; comment *************** ; projno := line(p(1)); if line(p(2)) < 0 or line(p(2)) > 2 then alarm(<:illegal update identification:>); updateinf := (if line(p(2)) = 2 then 0 else line(p(2)) + 1) shift 1 add (if linetype=2 then 1 else 0); if updateinf = 1 then alarm(<:illegal update information:>); project := false; nameptr := p(0) * 2 + 2; comment point at username...; username1 := line.nameptr; nameptr := nameptr + 4; username2 := if kind(p(0) + 2) <> 6 then extend 0 else line.nameptr shift (-24) shift 24; comment if the username is shorter than 7 characters, the name is extended with null-chars, otherwise the name allways is cut down to at most 9 chars; output(trans, maxlength); maxdeviceword := -1; comment no devices allowed; deviceword := 0; comment no devices requested; maxdevice := device := false; userpool := false; permanent_disc:= 0; trans.long1:= username1; trans.long2:= username2; trans.int5 := line(p(5)); comment user interval start; trans.int6 := line(p(3)); comment job-interval-width; trans.int7 := line(p(4)); comment number of simult. jobs; state := if updateinf = 0 then neutralstate else userstate; goto print_line; \f <* bbj 9 9 76 linetypes catupdate ...22... *> termuser: ; comment *************** ; if userpool then begin comment output the max-interval record; rectypelgth := 34 shift 12 add 10; output(trans, maxlength); trans.int3 := trans.int4 := permanent_disc; end; termproj: ; comment *************** ; if device then begin comment output the device record; rectypelgth := 8 shift 12 add 6; output(trans, maxlength); trans.long1 := deviceword; end; if maxdevice then begin comment output the max-device record; rectypelgth := 9 shift 12 add 6; output(trans, maxlength); trans.long1 := maxdeviceword; end; state := neutralstate; goto select; illegal: ; comment *************** ; alarm(<:out of sequence:>); \f <* bbj 9 9 76 special actions catupdate ...23... *> comment the following contains the different special actions to be taken with the different options, called by linetype 5 and linetype 6... notice: some of the action require a certain linetype ***************************************************** ; action1: ; comment *************** ; comment joboptions which consist of <keyword> <int parameter> ; comment acco, area, buf, cbuf, core, inte, key, outp, moun, wait, size, stat, susp, tape, prio, link; output(trans, maxlength); valueofpar:=trans.int1 := line(p(1)); goto print_line; action2: ; comment *************** ; comment devi; if kind(p(1)) = 6 then begin comment text parameter; nameptr := p(1) * 2 + 2; comment point at device name; name := line.nameptr shift (-16) shift 16; comment extract the first four letters of device name; for i := 2 step 1 until 5 do if devicename(i) = name and devicenumber(i) > 0 then goto device_found; if name = long <:no:> then begin i := 50; comment devicebit out of range...; if linetype = 5 then deviceword := 0 else maxdeviceword := -1; end else alarm(<:device unknown:>); end else begin comment integer parameter; for i := no_of_devices step -1 until 4 do if line(p(1)) = devicenumber(i) then goto device_found; alarm(<:device unknown:>); end; device_found: if linetype = 5 then begin if deviceword shift (-47+i) extract 1 = 0 then deviceword := deviceword + (extend 1) shift (47-i); device := true; end else begin if maxdeviceword shift (-47+i) extract 1 = 1 then maxdeviceword := maxdeviceword - (extend 1) shift (47-i); maxdevice := true; end; goto print_line; \f <* bbj 9 9 76 special actions catupdate ...24... *> action3: ; comment *************** ; comment late; output(trans, maxlength); valueofpar:=trans.int1 := extend 0 + ((line(p(1)) * 60 + (if kind(p(2))=2 then line(p(2)) else 0)) * (extend 600000)) shift (-13); goto print_line; action4: ; comment *************** ; comment priv; if linetype <> 5 then alarm(<:max value not allowed:>); output(trans, maxlength); i:=line(p(1)); if i>9 or i<=0 then alarm(<:privilege illegal:>); trans.int1:=case i of (4081, 4080, 4064, 4032, 3968, 3840, 3584, 3072, 2048); goto print_line; action5: ; comment *************** ; comment prog; if linetype <> 5 then alarm(<:max value not allowed:>); output(trans, maxlength); nameptr := p(1) * 2 + 2; comment point at programname; trans.long1 := line.nameptr; nameptr := nameptr + 4; trans.long2 := if kind(p(1) + 2) = 6 then line.nameptr shift (-8) shift 8 else extend 0; goto print_line; action6: ; comment *************** ; comment time; output(trans, maxlength); j := 0; comment compute time from up to three params; for i := 1 step 1 until 3 do if kind(p(i)) <> 2 then i := 3 else j := j * 60 + line(p(i)); valueofpar:=trans.int1 := ((extend 10000) * j) shift (-13); goto print_line; \f <* bbj 9 9 76 special actions catupdate ...25... *> action7: ; comment *************** ; comment perm; if linetype <> 5 then alarm(<:max value not allowed:>); nameptr := p(1) * 2 + 2; comment point at device name; name := line.nameptr; if name = long <:drum:> then rectypelgth := 46 shift 12 add 4 else if name <> long <:disc:> then goto special; output(trans, maxlength); trans.int1 := line(p(3)) shift 12 + line(p(2)); goto print_line; special: rectypelgth := 48 shift 12 add 12; output(trans, maxlength); trans.long1 := line.nameptr; nameptr := nameptr + 4; trans.long2 := if kind(p(1) + 2) <> 6 then extend 0 else line.nameptr shift (-8) shift 8; trans.int5 := line(p(3)) shift 12 + line(p(2)); goto print_line; action8: ; comment *************** ; comment temp; if linetype <> 5 then alarm(<:max value not allowed:>); nameptr := p(1) * 2 + 2; comment point at devicename; name := line.nameptr; if name = long <:disc:> then rectypelgth := 38 shift 12 add 4 else if name <> long <:drum:> then alarm(<:temp not allowed on specified device:>); output(trans, maxlength); trans.int1 := line(p(2)) + (if kind(p(3)) = 2 then line(p(3)) shift 12 else 0); goto print_line; action9: ; comment *************** ; comment onli , pres or mini; nameptr := p(1) * 2 + 2; comment point at answer; name := line.nameptr; if name = long <:no:> then i := 0 else if name = long <:yes:> then i := 1 else alarm(<:illegal parameter:>); output(trans, maxlength); trans.int1 := i; goto print_line; \f <* bbj 9 9 76 end of input catupdate ...26... *> initsort: ; comment **************** ; comment now all input has been processed, and has been changed into transaction records; rectypelgth := 0 shift 12 add 12; comment produce a end-catalog-record; projno := (-1) shift (-1); username1 := username2 := 0; updateinf := 0; output(trans, maxlength); output(vartrans, varlength); no_of_trans := no_of_trans - 1; comment compensate the counting; no_of_vartrans := no_of_vartrans + 1; close(in, true); close(trans, true); close(vartrans, true); end; <* end of input *> \f <* bbj 9 9 76 sorting of records catupdate ...27... *> begin comment sorting block; procedure discsort(filnavn,læ,antalindiv,segmprblok,ngl,levls); value segmprblok; string filnavn; integer læ,antalindiv,segmprblok,levls; integer array ngl; begin integer fysisksubbloklængde, fysiskbloklængde, b; integer array ia(1:20); array ra(1:2); fysisksubbloklængde := 512 * segmprblok; b:= (system(2,b,ra)-8*512)//(2*fysisksubbloklængde); fysiskbloklængde := b * fysisksubbloklængde; segmprblok := b * segmprblok; comment iiff updatest then write(out, <:<10>antalindiv = :>, antalindiv); begin integer diff, fa, indivlæ2, logiskbloklængde, logisksubbloklængde, nedbasis, nedplads, nedslut, opbasis, opplads, opslut, slut2, start2, subblokstart, transporter; long array field m, ned, op; integer array nuvblok(0:1); zone z(fysiskbloklængde//2,1,blproc); long array mid, nøgle(1:levls); long r; long field i; integer j, levels, level; integer field indivlæ; procedure blproc(z,s,b); zone z; integer s, b; if s extract 19 < 1 shift 18 or ia(4)<>5 shift 12 then stderror(z,s,b); procedure io(plads,operation); integer plads, operation; begin b:=nuvblok(plads)*segmprblok; if b>=0 then begin ia(4):= operation shift 12; ia(7):= b; ia(5):= b:= fa + plads*fysiskbloklængde; ia(6):= b + fysiskbloklængde - 2; setshare(z,ia,1); monitor(16,z,1,ia); check(z); end end io; \f <* bbj 9 9 76 quicksort catupdate ...28... *> procedure quicksort(start,slut,enblok); value start, slut, enblok; integer start, slut; boolean enblok; begin for m:=(start+slut)//indivlæ2*indivlæ while start<slut-indivlæ2 do begin op:= start-opbasis; ned:= slut-nedbasis; if enblok then m:=m-opbasis else begin transporter:=0; transport(m,0,opplads,nedplads); nedslut:=ned; opslut:=op; end; for level:= 1 step 1 until levels do mid(level):= z.m(nøgle(level)); søgned: ned:= ned-indivlæ; if ned < nedslut then begin transport(ned,nedbasis,nedplads,opplads); nedslut:= subblokstart; end; for level:= 1 step 1 until levels do if z.ned(nøgle(level)) > mid(level) then goto søgned else if z.ned(nøgle(level)) < mid(level) then level:= levels; søgop: op:= op+indivlæ; if op >= opslut then begin transport(op,opbasis,opplads,nedplads); opslut:= subblokstart + logisksubbloklængde; if transporter=3 then enblok:= nedslut=subblokstart; end; for level:= 1 step 1 until levels do if z.op(nøgle(level)) < mid(level) then goto søgop else if z.op(nøgle(level)) > mid(level) then level:= levels; if op+opbasis < ned+nedbasis then begin for i:=4 step 4 until indivlæ do begin r:=z.op.i; z.op.i:=z.ned.i; z.ned.i:=r end; if indivlæ extract 2 = 2 then begin j:=z.op.indivlæ; z.op.indivlæ:=z.ned.indivlæ; z.ned.indivlæ:=j end; goto søgned; end; slut2:= op+opbasis; start2:= start; start:= ned+nedbasis; if slut-start < slut2-start2 then begin i:=slut; slut:=slut2; slut2:=i; i:=start; start:=start2; start2:=i; end; if start2<slut2-indivlæ2 then quicksort(start2,slut2,enblok); end for m; end quicksort; \f \f <* bbj 9 9 76 transport catupdate ...29... *> procedure transport(fysisk,basis,plads,andenplads); integer fysisk, basis, plads, andenplads; begin integer logisk, blok, blokrel, subbloknr, blokbasis; logisk:= fysisk+basis; blok:= logisk//logiskbloklængde; blokrel:= logisk mod logiskbloklængde; if blok = nuvblok(0) then plads := 0 else if blok = nuvblok(1) then plads := 1 else begin plads := 1-andenplads; io(plads,5); nuvblok(plads):= blok; io(plads,3); end; subbloknr := blokrel//logisksubbloklængde; blokbasis := plads * fysiskbloklængde; fysisk := blokrel + subbloknr * diff + blokbasis; subblokstart := subbloknr * fysisksubbloklængde + blokbasis; basis := logisk - fysisk; transporter := transporter + 1; end transport; open(z,4,filnavn,1 shift 18); close(z,false); getzone(z,ia); fa:=ia(19)+1; getshare(z,ia,1); indivlæ:= læ; indivlæ2:= 2*indivlæ; levels:= levls; for level:= 1 step 1 until levels do nøgle(level):= ngl(level); diff:= fysisksubbloklængde mod indivlæ; logisksubbloklængde := fysisksubbloklængde - diff; logiskbloklængde := b * logisksubbloklængde; nuvblok(0) := nuvblok(1) := -1; opbasis:= nedbasis:= nedplads:= 0; quicksort(-indivlæ, indivlæ*antalindiv, false); io(0,5); io(1,5); end zone blok; end disksort; integer array keyfield(1:6); integer i; for i:= 1 step 1 until 6 do keyfield(i):= case i of(1,2,3,4,5,6); i:= 1; discsort(string transname(increase(i)), maxlength, no_of_trans, 1, keyfield, 6); i:= 1; discsort(string vartransname(increase(i)), varlength, no_of_vartrans, 1, keyfield, 3); end sorting block; \f \f <* bbj 9 9 76 declarations catupdate ...30... *> begin integer projlower, projupper, lowerint, upperint, minimum, maximum, nextnew, nextold, level, copytype, firstsegm, projsegm, projrel, projstart, userstart, nil; long tproj, tuser1, tuser2, ttype, cproj, cuser1, cuser2, ctype, ckit1, ckit2, width, catno, transno; boolean absint, warning, delete, nodelete, create, after_delete, firsttime, bool, record_in_inbuf, newproj, firstproj, projlist, userlist; integer field proj, cupper, clower, cstart, cwidth, cjobs, maxlower, maxupper, ptr, oldptr, firstfree, i, j, if2, if12, basis; long field kitname1, kitname2, username1, username2, lg6, lg10; integer array xinf(1:2), intervals(1:3*intervaltable_size), special_action(0:max_record_type//2); long array comp(1:2,1:4); boolean array change(0:max_record_type//2); integer array field old, new, rec, cat, upper, lower; zone trans, vartrans, oldcat, newcat(128, 1, stderror); \f <* bbj 9 9 76 proc initialize catupdate ...31... *> procedure initialize(start, project, lowint, upint); value project, lowint, upint; integer start, lowint, upint; boolean project; comment the procedure initializes the intervaltable, and returns the start-address of the list in ..start..; begin integer lowerint, upperint, segm; integer field minptr, stepptr, searchptr; comment iiff updatest then write(out, <:<10>initialize :>, if project then <:proj:> else <:user:>, lowint, upint); if firstfree > intervaltable_size then interval_alarm; start := oldptr := firstfree; firstfree := firstfree + 6; comment initialize list-head, containing top- and base-interval of the ..owner.. of the list (i.e. the surrounding interval to be obeyed); intervals.lower.oldptr := upint + 1; intervals.upper.oldptr := lowint - 1; intervals.oldptr := nil; comment notice the funny exchange of lower- and upper...; if newproj or firstproj then goto exit; comment i.e. there are no proper records in oldcat; comment the oldcat is searched, extracting the information concerning the intervals of all projects (or all users belonging to the current project); getposition(oldcat, 0, segm); setposition(oldcat, 0, if project then firstsegm else projsegm); cat := if project then 0 else projrel; \f <* bbj 9 9 76 proc initialize catupdate ...32... *> next_block: inrec6(oldcat, 512); for i := oldcat.cat.if2 extract 12 + cat while oldcat.cat.if2 <> 0 do begin if oldcat.cat.if2 < 2 shift 12 then begin comment project record; if -, project or oldcat.cat.proj = maximum then goto updated; if firstfree > intervaltable_size then interval_alarm; intervals.lower.firstfree := lowerint := oldcat.cat.clower; intervals.upper.firstfree := oldcat.cat.cupper; if lowerint <> minimum then firstfree := firstfree + 6; comment maintenance-project and account-project are not included in interval-list; end proj-record else if if project then false else oldcat.cat.if2 < 4 shift 12 then begin comment user-record (skipped if only extracting projects...); if firstfree > intervaltable_size then interval_alarm; intervals.lower.firstfree := lowerint := oldcat.cat.cstart; intervals.upper.firstfree := oldcat.cat.cwidth * oldcat.cat.cjobs + lowerint - 1; if lowerint <> minimum then firstfree := firstfree + 6; end user-record; cat := i; comment increase to next record...; end; cat := 0; goto next_block; \f <* bbj 9 9 76 proc initialize catupdate ...33... *> updated:; comment restore the oldcat-zone...; setposition(oldcat, 0, segm); inrec6(oldcat, 512); comment the intervals must be sorted: primary: lower interval ascending, sec.ary: upper interval descending; for stepptr := start+6 step 6 until firstfree-6 do begin minptr := stepptr; comment point at current winner; lowerint := intervals.lower.minptr; for searchptr := stepptr+6 step 6 until firstfree-6 do if if extend intervals.lower.searchptr < lowerint then true else intervals.lower.searchptr = lowerint and extend intervals.upper.searchptr < intervals.upper.minptr then begin minptr := searchptr; lowerint := intervals.lower.minptr; end; comment exchange the challenger and the winner; intervals.lower.minptr := intervals.lower.stepptr; intervals.lower.stepptr:= lowerint; upperint := intervals.upper.minptr; intervals.upper.minptr := intervals.upper.stepptr; intervals.upper.stepptr:= upperint; comment insert in list of intervals; intervals.oldptr := oldptr := stepptr; intervals.stepptr := nil; end sorting; exit: end initialize_procedure; \f <* bbj 9 9 76 proc getinterval catupdate ...34... *> procedure get_interval(start, lowint, upint); value start; integer start, lowint, upint; comment the procedure searches the interval-list, starting at start, until a hole with the width upint-lowint+1 is found. special actions are made with abs-intervals; begin long oldupper, maxupper, low; width := extend upint - lowint + 1; ptr := start; maxupper := intervals.upper.ptr; comment iiff updatest then write(out, <:<10>get interval :>, start, lowint, upint, intervals.upper.ptr, intervals.lower.ptr); if absint then begin if extend lowint <= intervals.upper.ptr or extend upint >= intervals.lower.ptr then update_alarm(<:illegal abs interval:>); end; rep: oldptr := ptr; oldupper := intervals.upper.oldptr; ptr := intervals.oldptr; if oldupper > maxupper then maxupper := oldupper; if ptr <> nil then begin low := intervals.lower.ptr; if absint then begin comment search until low has passed lowint...; if low < lowint then goto rep; comment if low has not yet passed upint then overlap...; if low <= upint then begin warning := true; update_alarm(<:overlapping intervals:>); end; comment search until the sorting demands are fulfilled...; if low = lowint and intervals.upper.ptr > upint then goto rep; end else begin comment search until a hole is found big enough...; if low - oldupper <= width then goto rep; end end ptr <> nil else ptr := start; comment notice: lower.start is top of legal interv.; \f <* bbj 9 9 76 proc getinterval catupdate ...35... *> comment now oldptr points at element just before, while intervals.lower.ptr contains the start of the next interval (used to chech ..no room..); if absint then oldupper := lowint - 1 else if intervals.lower.ptr - oldupper <= width then update_alarm(<:no room:>); if firstfree > intervaltable_size then interval_alarm; intervals.lower.firstfree := lowint := oldupper + 1; intervals.upper.firstfree := upint := oldupper + width; if maxupper >= lowint then begin warning := true; update_alarm(<:overlapping intervals:>); end; intervals.firstfree := intervals.oldptr; intervals.oldptr := firstfree; firstfree := firstfree + 6; end get_interval...; \f <* bbj 9 9 76 proc output catupdate ...36... *> procedure output(from, iaf); zone from; integer array field iaf; begin integer length; length := from.iaf.if2 extract 12; comment iiff updatest then write(out, <:<10>output :>, from.iaf.if2 shift (-12), length, nextnew); if nextnew+length > 510 then begin if leftside then outrec6(newcat, 512); nextnew := 0; end; new := nextnew; nextnew := nextnew + length; comment point at next record; for i := 2 step 2 until length do newcat.new.i := from.iaf.i; newcat.new.i := 0; comment insert a dummy zero (in case of block-change...); end output_procedure; procedure interval_alarm; begin write(out, <:***the catupdate program must be corrected and recompiled, with a greater intervaltable_size<10>:>); system(9, intervaltable_size//6, <:<10>size :>); end; procedure update_alarm(text); string text; begin write(out, <:projno= :>, <<dddddd>, tproj, <: user= :>); i := 1; write(out, false add 32, 13 - write(out, string( case increase(i) of (tuser1, tuser2))), <:*** :>,text,<: ***:>, <:<10><10> ; :>); if ttype=42 then printrec(vartrans.rec, tproj) else printrec(trans.rec , tproj); write(out, <:<10><10>:>); if warning then warning := false else goto next_trans; end; \f <* bbj 9 9 76 proc printrec catupdate ...37... *> procedure printrec(record, projno); integer array record; long projno; comment the procedure prints the current record in such a way, that it later may be used again as input for the program...; begin integer i, typ, type, length; long longwork; boolean newline; procedure slices(n); integer n; write(out, <<d>, record(n) shift 12 // 4096, <:,:>, record(n) // 4096); procedure claim(n); integer n; begin write(out, <: (slices, entries=) :>); slices(n); end; procedure restclaim(n); integer n; begin write(out, <: (restclaim= :>); slices(n); write(out, <:):>); end; procedure temp_or_perm(device, n); string device; integer n; begin write(out, <: 5 :>, if type < 40 then <:temp :> else <:perm :>, device); claim(n); end; long procedure name; name := case increase(i) of (record.username1, record.username2); long procedure longtext; longtext := long <::> add (if i < length then record(increase(i)+1) else 0) shift 24 add (if i < length then record(increase(i)+1) else 0); procedure standard(text); string text; write(out, <<ddd>, typ, <: :>, text, << d>, record(2)); \f <* bbj 9 9 76 proc printrec catupdate ...38... *> type := record(1) shift (-12); length := record(1) extract 12; typ := if type extract 1 = 0 then 5 else 6; i := 1; comment used in printing text a.o.; case type shift (-1) + 1 of begin comment type=0, project-record; begin write(out, <: 10 (new projno =):>, <<dddddd>, projno, <: 0:>); claim(6); restclaim(5); write(out, <: (interval=):>, record.clower, record.cupper); end; comment type=2, user-record; write(out, <: 11 (new user =) :>, string name, <: (projno =):>, projno, <: 0 (width,jobs,start =):>, record.cwidth, record.cjobs, record.cstart); comment type=4, priority and respite; write(out, <: 7 (priority, respite =):>, record(2), (extend record(3)) shift 13 // 10000); comment type=6, claims on private kits; begin write(out, <: 4 (private kit =) :>, string name); claim(7); restclaim(6); write(out, <: (slicelength =):>, if length = 14 then 8 else record(8)); end; comment type=8/9 , device-mask record; begin longwork := record.username1; if type extract 1 = 1 then longwork := -1 - longwork; comment ones-complement...; if longwork = 0 then write(out, <<ddd>, typ, <: device no:>) else begin newline := false; for i := 2 step 1 until 5 do if longwork shift (-47+i) extract 1 = 1 then begin write(out, newline, 1); newline := false add 10; write(out, <<ddd>, typ, <: device :>, string devicename(i)); end; for i := 6 step 1 until no_of_devices do if longwork shift (-47+i) extract 1 = 1 then begin write(out, newline, 1); newline := false add 10; write(out, <<ddd>, typ, <: device :>, devicenumber(i)); end; end; end; \f <* bbj 9 9 76 print rec types catupdate ...39... *> comment type=10/11; standard(<:acco:>); comment type=12/13; standard(<:area:>); comment type=14/15; standard(<:buf:>); comment type=16/17; standard(<:cbuf:>); comment type=18/19; standard(<:inte:>); comment type=20/21; standard(<:key:>); comment type=22/23; standard(<:moun:>); comment type=24/25; write(out, <<ddd>, typ, <: outp:>, << d>, record(2), <: (slices):>); comment type=26/27; standard(<:size:>); comment type=28/29; standard(<:stat:>); comment type=30/31; standard(<:tape:>); comment type=32/33; begin write(out, <<ddd>, typ, <: time:>); longwork := (extend record(2)) shift 13 // 10000; if longwork >= 3600 then write(out, longwork // 3600); if longwork >= 60 then write(out, longwork mod 3600 // 60); write(out, longwork mod 60); end; comment type=34; begin write(out, <: 9 (userpool):>); claim(5); restclaim(4); end; comment type=36, temp drum; temp_or_perm(<:drum:>, 2); comment type=38, temp disc; temp_or_perm(<:disc:>, 2); comment type=40, perm disc; temp_or_perm(<:disc:>, 2); comment type=42, username and address; write(out, <: 3 :>, string longtext); \f <* bbj 9 9 76 print rec types catupdate ...40... *> comment type=44, permanent resources on drum; begin write(out, <: 8 (permanent drum):>); claim(3); restclaim(2); end; comment type=46, perm drum; temp_or_perm(<:drum:>, 2); comment type=48, perm <private kit>; temp_or_perm(string name, 6); comment type=50/51 the latest finishing time for the job; begin longwork := (extend record(2)) shift 13 // 600000; write(out,<<ddd>, typ, <: late:>, longwork // 60, longwork mod 60); end; comment type=52, project id; write(out, <: 12 :>, string longtext); comment type=54; write(out, <: 5 program= :>, string name); comment type=56; standard(<:susp:>); comment type=58/59; write(out, <<ddd>, typ, <: onli:>, if record(2) = 0 then <: no:> else <: yes:>); comment type=60/61; standard(<:core:>); comment type=62/63; write(out,<<ddd>, typ, <: mini:>, if record(2) = 0 then <: no:> else <: yes:>); comment type=64/65; standard(<:prio:>); comment type=66/67; standard(<:wait:>); comment type=68/69; write(out, <<ddd>, typ, <: pres:>, if record(2) = 0 then <: no:> else <: yes:>); \f <* bbj 9 9 76 print rec types catupdate ...41... *> comment type=70; begin write(out,<<ddd>, typ,<: priv:>); longwork:=record(2); if longwork extract 1=1 then i:=1 else begin longwork:=longwork shift (-3); i:=2; for longwork:=longwork shift (-1) while longwork extract 1=0 do i:=i+1; end; write(out,i,<: (bit pattern: :>); longwork:=record(2); write(out,<< d>, longwork shift (-11) extract 1, longwork shift (-10) extract 1, longwork shift (-9) extract 1, longwork shift (-8) extract 1, longwork shift (-7) extract 1, longwork shift (-6) extract 1, longwork shift (-5) extract 1, longwork shift (-4) extract 1, longwork shift (-3) extract 1, longwork shift (-2) extract 1, longwork shift (-1) extract 1, longwork extract 1,<:):>); end; comment type=72 link ; standard(<:link:>); end case type...; write(out, <:;:>); end procedure printrec; \f <* bbj 9 9 76 initialization catupdate ...42... *> comment initialize field-variables; comment project record (type = 0); proj := 4; clower := 6; cupper := 8; comment user record (type = 2); username1 := 6; username2 := 10; cstart := 12; cwidth := 14; cjobs := 16; comment special bs-device record (type = 6); kitname1 := 6; kitname2 := 10; comment userpool record(type = 34); maxlower := 4; maxupper := 6; comment sorting fields in transactions; if2 := 2; comment projectnumber of transaction, rectype of usercat; lg6 := 6; comment username1 of transactions; lg10 := 10; comment username2 of transactions; if12 := 12; comment contains updateinf...; basis := 14; comment recordtype and -length of transactions; rec := basis-if2; comment interval-list; intervaltable_size := intervaltable_size * 6; userstart := firstfree := 2; upper := 2; lower := upper + 2; warning := false; comment std-variables; maximum := (-1) shift (-1); minimum := 1 shift 23 + 1; nil := -1; comment initialize update-tables; for i := 0 step 2 until max_record_type do begin change(i//2) := false add (if i=0 then (1 + 1 shift 4 + 1 shift 5) else if i=2 then 1 else if i=6 then (1 + 1 shift 5 + 1 shift 6) else if i=34 then (1 + 1 shift 3 + 1 shift 4) else if i=44 then (1 + 1 shift 1 + 1 shift 2) else if i=46 then (1 + 1 shift 1 ) else if i=48 then (1 + 1 shift 5 ) else 0 ); comment this means, that in f.ex. the record of type 6, updating is made by increasing the contents of word 5 (i.e. 1 shift 5) and word 6 in the usercat- record by the corresponding words in the trans- action-record. ***** only bs claims ***** (the bit 1 shift 0 indicates whether the record is to be updated or simply exchanged by a new record); special_action(i//2) := if i=0 then 1 else if i=2 then 2 else if i=6 or i=48 then 3 else if i=34 then 4 else 5 ; end initialize update-tables; \f <* bbj 9 9 76 mix catalogs catupdate ...43... *> if nooldcat then <* the parameter cat.yes is set *> begin comment no old usercat present, simulate end-record; oldcat.if2 := 0 shift 12 + 12; comment rectype of proj-record; oldcat.proj := maximum; comment projno of end-record; cproj := maximum; cuser1 := cuser2 := ctype := 0; firstsegm := std_usercat_index; old := 0; record_in_inbuf := true; end else begin open(oldcat, 4, <:usercat:>, 0); firstsegm := 0; for i:= inrec6(oldcat, 2), inrec6(oldcat, 2) while oldcat.if2 < 0 do firstsegm := firstsegm + 1; setposition(oldcat, 0, firstsegm); cproj := -1; nextold := 0; inrec6(oldcat, 512); record_in_inbuf := false; end; i := 1; open(trans, 4, string(transname(increase(i))), 0); i := 1; open(vartrans, 4, string(vartransname(increase(i))), 0); nextnew := 512; if leftside then begin i := 1; open(newcat, 4, string(newcatname(increase(i))), 0); setposition(newcat, 0, std_usercat_index); end; projlist := false; comment the interval-list of projs is not created yet; firstproj := true; firsttime := true; ttype := 0 ; comment serves to initialize the trans-zones...; \f <* bbj 9 9 76 mix catalogs catupdate ...44... *> next_trans: ; comment *************** ; comment select the next transaction from either the trans-zone or the vartrans-zone. initialize the merging variables; if first_time or ttype=42 then begin first_time := false; inrec6(vartrans, varlength); comp(1,1) := vartrans.if2; comment project number; comp(1,2) := vartrans.lg6; comment username...; comp(1,3) := vartrans.lg10; xinf(1) := vartrans.if12 extract 4; comment updateinf; comp(1,4) := vartrans.basis shift (-12); comment recordtype; end; if ttype <> 42 then begin inrec6(trans, maxlength); comp(2,1) := trans.if2; comment project number; comp(2,2) := trans.lg6; comment username...; comp(2,3) := trans.lg10; xinf(2) := trans.if12 extract 4; comment updateinf; comp(2,4) := trans.basis shift (-12); comment recordtype; end; i := 1; comment suppose vartrans wins...; for level := 1 step 1 until 4 do if comp(1,level) < comp(2,level) then goto winner else if comp(1,level) > comp(2,level) then level := 5; i := 2; comment vartrans lost the competition...; winner: ; comment ******; tproj := comp(i,1); comment project number; tuser1:= comp(i,2); comment username...; tuser2:= comp(i,3); comment .... ; ttype := comp(i,4); comment recordtype; absint:= xinf(i) extract 1 = 0; delete:= xinf(i) shift (-1) = 0; create:= xinf(i) shift (-1) = 1; nodelete := true; after_delete := false; comment no deleting is in progress...; comment iiff updatest then write(out, case i of (<:<10>var:>, <:<10>tr :>), tproj, ttype, xinf(i)); \f <* bbj 9 9 76 mix catalogs catupdate ...45... *> compare_start: ; comment *************** ; level := 1; comment start the comparison at project-level; compare: ; comment *************** ; comment proceed the comparison at the current level...; catno := case level of (cproj, cuser1, cuser2, ctype, ckit1, ckit2); <* current record-variables *> transno := case level of (tproj, tuser1, tuser2, ttype, trans.rec.kitname1, trans.rec.kitname2); <* record from trans or vartrans *> copytype := case level of (2, 4, 4, 1000, 1000, 1000); comment iiff updatest then write(out, <:<10>cat:>, level, catno, transno); if catno < transno then begin comment the current record is completely updated. copy the usercat, until a record with recordtype less than ..copytype.. is met; copy: if nodelete and record_in_inbuf then output(oldcat, old); if nextnew < 512 and print > 0 then begin comment print the current record...; if nodelete then begin printrec(newcat.new, cproj); if print extract 1 = 1 then write(out, <: --- updated ---:>); end else begin printrec(oldcat.old, cproj); write(out, <: --- deleted ---:>); end; write(out, <:<10>:>); print := print shift (-1) shift 1; comment remove the update-bit; end; for old := nextold while oldcat.old.if2 = 0 do begin nextold := 0; inrec6(oldcat, 512); end; nextold := oldcat.old.if2 extract 12 + old; comment step nextold up pointing at next record...; ctype := oldcat.old.if2 shift (-12); record_in_inbuf := true; if ctype >= copytype then goto copy; comment the present record is to be seperatly considered; \f <* bbj 9 9 76 mix catalogs catupdate ...46... *> if ctype < (case level of ( 0, 2, 2, 4, 4, 4)) then goto possibly_new_record; comment this means, that the next project-record or next user-record is met (i.e. a sort of end-situation has come up...); case level of begin level1: begin comment projectno was not ok, try this one; cproj := oldcat.old.proj; cuser1 := cuser2 := ctype := 0; firstproj := false; comment initialize interval-procedures...; getposition(oldcat, 0, projsegm); projrel := nextold; firstfree := userstart; projlower := oldcat.old.clower; projupper := oldcat.old.cupper; newproj := userlist := false; end level1; level2: begin comment project ok, user not ok, try this user; cuser1 := oldcat.old.username1; cuser2 := oldcat.old.username2; lowerint := oldcat.old.cstart; upperint := oldcat.old.cwidth * oldcat.old.cjobs + lowerint - 1; end; level3: begin comment second part of username not ok, try this user; level := 2; goto level2; end; level4: begin comment project and user ok, recordtype not ok. try this record; end; level5: begin comment first part of kitname in record concerning private kit is not ok, try this record; level := 4; end; level6: begin comment second part of kitname not ok, try this record; level := 4; end; end level_case; goto compare; comment i.e. test with the current level...; end catno<transno; if catno = transno then begin comment proceed the comparison in all levels...; level := level + 1; if level <= 4 then goto compare; comment at this point projectnumber, username and recordtype is ok; \f <* bbj 9 9 76 mix catalogs catupdate ...47... *> case special_action(ctype//2) of begin acti1: begin comment ctype = 0... project-record; if cproj = maximum then begin output(oldcat, old); comment end-record...; goto finisupdate; end; goto testcreate; end; acti2: begin comment ctype = 2... user-record; testcreate: if create then update_alarm(<:existing:>); if delete then begin if cuser1 = 0 then begin comment delete project until next proj-record; comment check proper interval...; if trans.rec.clower <> projlower or trans.rec.cupper <> projupper then update_alarm(<:delete wrong interval:>); tproj := tproj + 1; comment to skip rest of project; end else begin comment delete user...; comment check proper interval...; if lowerint <> trans.rec.cstart or upperint <> trans.rec.cwidth * trans.rec.cjobs + lowerint - 1 then update_alarm(<:delete wrong interval:>); tuser2 := tuser2 + 1; comment to skip rest of user...; end; comment the project (or user) is not removed from the internal list; start_delete: after_delete := true; comment i.e. remember the forgery...; nodelete := false; comment i.e. skip rest of proj or user; delete := false; print := print shift (-1) shift 1 add 1; goto compare_start; end delete-action; if after_delete then stop_delete: begin comment forget about the simulated transaction...; nodelete := true; ttype := ttype - 1; comment in case of deleting username-record...; goto next_trans; end; end action 2, delete user or project; \f <* bbj 9 9 76 mix catalogs catupdate ...48... *> acti3: begin comment special bs-devices, ctype = 6 or ctype = 48; comment proceed the comparison to check the devicename...; if record_in_inbuf then begin ckit1 := oldcat.old.kitname1; ckit2 := oldcat.old.kitname2; end else begin ckit1 := newcat.new.kitname1; ckit2 := newcat.new.kitname2; end; if level < 7 then goto compare; if delete then begin trans.rec.kitname2 := trans.rec.kitname2 + 1; goto start_delete; end; end action 3; acti4: begin comment ctype = 34, userpool record; if delete then update_alarm(<:delete not allowed:>); end; acti5: begin comment other records, no action to be done...; if delete then begin comment skip record...; ttype := ttype + 1; goto start_delete; end; end; end special_action_case; comment at this point the proper record is found update it...; \f <* bbj 9 9 76 mix catalogs catupdate ...49... *> bool := change(ctype//2); if bool then begin comment the variable bool contains information about which elements in the record to update; if record_in_inbuf then output(oldcat, old); for i := -1 step -1 until -11 do if bool shift i then begin j:=newcat.new(1-i) + trans.rec(1-i); if j<0 or j shift 12 < 0 then begin comment claims would get negative; warning:=true; update_alarm(<:illegal claims:>); end else newcat.new(1-i):=j; end; end else begin comment forget about the old version of the record...; if -, record_in_inbuf then nextnew := new; new_record: if ttype = 42 then output(vartrans, rec) else output(trans , rec); end; ctype := ttype; record_in_inbuf := false; print := print shift (-1) shift 1 add 1; comment indicate the updating; goto next_trans; end catno = transno; \f <* bbj 9 9 76 mix catalogs catupdate ...50... *> comment catno > transno; possibly_new_record: nextold := old; comment regret input, i.e. repeat next time...; record_in_inbuf := false; if afterdelete then goto stop_delete; case special_action(ttype//2) of begin act1: begin comment ttype = 0, new project; if -, create then update_alarm(<:project unknown:>); firstfree := userstart; if -, projlist then initialize(projstart, true, minimum+2, maximum-2); projlist := true; userlist := false; newproj := true; comment the intervals of the project must be inserted in the interval-list (except the maintenance-proj and the account-project); if trans.rec.clower <> minimum then get_interval(projstart, trans.rec.clower, trans.rec.cupper); userstart := firstfree; projlower := trans.rec.clower; projupper := trans.rec.cupper; cproj := tproj; cuser1 := cuser2 := ctype := 0; end action 1; act2: begin comment ttype = 2, new user; if level = 1 then update_alarm(<:project unknown:>); if -, create then update_alarm(<:user unknown:>); if -, userlist then initialize(userstart, false, projlower, projupper); userlist := true; comment the intervals of the user must be inserted in the interval list; lowerint:= trans.rec.cstart; upperint := trans.rec.cwidth * trans.rec.cjobs + lowerint - 1; get_interval(userstart, lowerint, upperint); trans.rec.cstart := lowerint; cuser1 := tuser1; cuser2 := tuser2; end action 2; act3: begin comment special bs-devices, ttype = 6; goto act5; end; act4: begin comment userpool record, ttype = 34; if level < 4 then goto act5; trans.rec.maxlower:= lowerint; trans.rec.maxupper:= upperint; end; act5: begin comment other records; if level < 4 then update_alarm(<:out of sequence:>); end; end special-action_case with new record...; if delete then updatealarm(<:record unknown:>); bool:=change(ttype//2); if bool then for i:=-1 step -1 until -11 do if bool shift i then begin if trans.rec(1-i)<0 or trans.rec(1-i) shift 12 < 0 then update_alarm(<:illegal claims:>); end; goto new_record; finis_update: ; comment ****************; if print shift(-3) extract 1=1 then write(out,<:-1 ; end of catalog<10>:>); close(vartrans, true); monitor(48) remove entry:(vartrans, 0, xinf); close(trans, true); monitor(48) remove entry:(trans, 0, xinf); close(oldcat, true); close(newcat, false); end update_block; end device-number block; \f <* bbj 9 9 76 index segment catupdate ...51... *> if leftside then begin comment update the index segments...; zone index(128, 1, stderror), newcat(128, 1, stderror); integer array entr, slicelength(1:max_no_of_disckits); long array kittable(2:2*max_no_of_disckits+1); integer array field new; integer field if2, proj, slicelgth, disc_entr, priv_entr, userdisc_entr, drum_entr; long field kit1, kit2, user1, user2; integer i, j, projno, type, entries, max, maxindex, no_of_disckits, kitcount; long name1, name2; procedure warn(text); string text; begin integer i; write(out, <:projno= :>, <<dddddd>, projno, <: user= :>); i := 1; write(out, false add 32, 13 - write(out, string (case increase(i) of (name1, name2))), text, <:<10>:>); end; i := 1; open(index , 4, string newcatname(increase(i)), 0); i := 1; open(newcat, 4, string newcatname(increase(i)), 0); setposition(newcat, 0, std_usercat_index); if2 := 2; proj := 4; disc_entr := 12; priv_entr := 14; userdisc_entr := 10; drum_entr := 6; kit1 := 6; kit2 := 10; slicelgth:= 16; user1 := 6; user2 := 10; projno := -1; for i := 1 step 1 until std_usercat_index do begin outrec6(index, 2); index.if2 := projno; end; comment scan the new usercat and count the maximum-number of pre-promissed entries; entries := 0; no_of_disckits := 0; next_block: inrec6(newcat, 512); index.if2 := projno; new := 0; outrec6(index, 2); \f <* bbj 9 9 76 count entries catupdate ...52... *> next_record: type := newcat.new.if2 shift (-12); if type < 2 then begin comment project-record or end-of-segment; if newcat.new.if2 = 0 then goto next_block; projno := newcat.new.proj; if projno = (-1) shift (-1) then goto finished; entries := newcat.new.disc_entr shift (-12) + entries; kitcount := 0; name1 := name2 := long <::>; end else if type < 4 then begin comment user-record; kitcount := 0; name1 := newcat.new.user1; name2 := newcat.new.user2; end else if type = 6 then begin comment private disckit, search kitname in kittable; for i := 2 step 2 until no_of_disckits do if if newcat.new.kit1 <> kittable(i) then false else newcat.new.kit2 = kittable(i+1) then goto found; comment kitname was not in kittable, include it now...; if i > 2* max_no_of_disckits then begin warn(<::>); system(9, i//2, <:<10>disckits:>); end; no_of_disckits := i; kittable(i) := newcat.new.kit1; kittable(i+1) := newcat.new.kit2; slicelength(i//2) := newcat.new.slicelgth; entr(i//2) := 0; found: kitcount := kitcount + 1; if kitcount = no_of_privkits + 1 then warn(<:too many privkits:>); entr(i//2) := entr(i//2) + newcat.new.priv_entr shift (-12); if slicelength(i//2) <> newcat.new.slicelgth then warn(<:different slice-length on same kit:>); slicelength(i//2) := newcat.new.slicelgth; end type=6 else if type = 34 then begin comment userpool-record; entries := newcat.new.userdisc_entr shift (-12) + entries; end else if type = 44 then begin comment permanent drum-record; entries := newcat.new.drum_entr shift (-12) + entries; end; new := newcat.new.if2 extract 12 + new; goto next_record; \f <* bbj 9 9 76 private kits catupdate ...53... *> finished: getposition(index, 0, new); if new >= std_usercat_index then write(out, <:<10>***std_usercat_index too small***<10>:>); index.if2 := projno; for i := 1 step 1 until no_of_priv_discdrives do begin max := 0; maxindex := 1; for j := no_of_disckits//2 step -1 until 1 do if entr(j) > max then begin max := entr(j); maxindex := j; end; entries := entries + max; entr(maxindex) := 0; comment i.e. clear in the kittable...; end; setposition(index, 0, 0); swoprec6(index, 2); index.if2 := - entries; close(index, true); close(newcat,true); end index-update block; end ▶EOF◀