Listing: 1 IMPLEMENTATION MODULE NdxUtils; 2 (* 3 * REPERTOIRE 4 * Release 1.6 5 * By Charles Bradford and Cole Brecheen 6 * (c) Copyright 1985-1992 PMI 7 * Green Bay, Wisconsin 8 * All rights reserved 9 * (414) 468-6040 10 * 11 * $Header: D:/logfiles/mods/ndxutils.mov 1.7 10 Mar 1991 15:30:56 coleb $ 12 * 13 *) 14 15 16 (*EntryDiag: 17 IMPORT Diagnostics; 18 :EntryDiag*) 19 20 (* 21 IMPORT BuildLst; 22 *) 23 IMPORT EnvironUtils; 24 IMPORT ErrorManager; 25 IMPORT ErrorNames; 26 IMPORT HandleIO; 27 IMPORT GenLists; 28 IMPORT ListUtils; 29 IMPORT LowLevel; 30 IMPORT M2Strings; 31 IMPORT NdxBones; 32 IMPORT NdxFiles; 33 FROM NdxTypes IMPORT NdxElement; 34 IMPORT NdxTypes; ***** ^ duplicate identifier 35 IMPORT Numbers; 36 IMPORT NumTypes; 37 IMPORT PosUtils; 38 IMPORT StrConv; 39 IMPORT StrEdit; 40 IMPORT StringIO; 41 IMPORT SYSTEM; 42 IMPORT VStorage; 43 44 VAR 45 Initialized : BOOLEAN; 46 47 48 PROCEDURE CopyMatchingFields( NdxF1: NdxTypes.NdxFileType; VAR ***** ^ not supported yet 49 NdxF2: NdxTypes.NdxFileType; RecName: ARRAY OF CHAR; ***** ^ not supported yet ***** ^ not supported yet 50 MatchingFields: GenLists.GenList ); ***** ^ not supported yet 51 VAR 52 spot, TypeCode: CARDINAL; 53 FieldName1, FieldName2: ARRAY [0..79] OF CHAR; ***** ^ not supported yet ***** ^ not supported yet 54 BufElement: ARRAY [0..1023] OF CHAR; ***** ^ not supported yet ***** ^ not supported yet 55 TmpList1, TmpList2: GenLists.GenList; ***** ^ not supported yet 56 57 PROCEDURE GetPair( index: CARDINAL; TheList: GenLists.GenList; ***** ^ not supported yet 58 VAR s1, s2: ARRAY OF CHAR ); ***** ^ not supported yet 59 VAR 60 eqspot, TypeCode: CARDINAL; 61 BEGIN 62 GenLists.GetElmt( TheList, index, s1, TypeCode ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 63 eqspot := PosUtils.Pos( '=', s1 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 64 IF eqspot < HIGH(s1) THEN ***** ^ undeclared identifier ***** ^ not supported yet 65 M2Strings.Copy( s1, eqspot + 1, (M2Strings.Length(s1) - eqspot) - 1, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 66 s2 ); ***** ^ not supported yet 67 M2Strings.Delete( s1, eqspot, M2Strings.Length(s1) - eqspot ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 68 ELSE 69 StrEdit.SetLength( s1, 0 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 70 StrEdit.SetLength( s2, 0 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 71 END; 72 END GetPair; ***** ^ not supported yet 73 74 BEGIN (* CopyMatchingFields *) 75 spot := 1; 76 GetPair( spot, MatchingFields, FieldName1, FieldName2 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 77 WHILE spot <= GenLists.ListLength( MatchingFields ) DO ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 78 IF (M2Strings.Length(FieldName1) > 0) AND ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 79 (M2Strings.Length(FieldName2) > 0) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 80 IF NdxFiles.GetField( NdxF1, RecName, FieldName1, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 81 TypeCode, BufElement ) THEN ***** ^ not supported yet 82 IF TypeCode # GenLists.ListCode THEN ***** ^ not supported yet ***** ^ not supported yet 83 IF NOT NdxFiles.PutField( NdxF2, RecName, FieldName2, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 84 TypeCode, BufElement ) THEN ***** ^ not supported yet 85 (* You could do something here to account 86 for fields that do not exist in the 87 destination structure *) 88 END; 89 ELSE 90 (* copy lists before insertion *) 91 IF NdxFiles.GetField( NdxF1, RecName, FieldName1, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 92 TypeCode, TmpList1 ) THEN ***** ^ not supported yet 93 GenLists.CopyList( TmpList1, TmpList2 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 94 IF NOT NdxFiles.PutField( NdxF2, RecName, FieldName2, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 95 TypeCode, TmpList2 ) THEN ***** ^ not supported yet 96 (* You could do something here to account 97 for fields that do not exist in the 98 destination structure *) 99 END; 100 END; 101 END; 102 END; 103 END; 104 INC( spot ); ***** ^ undeclared identifier ***** ^ not supported yet 105 IF spot <= GenLists.ListLength(MatchingFields) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 106 GetPair( spot, MatchingFields, FieldName1, FieldName2 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 107 END; 108 END; 109 IF NOT NdxFiles.WriteRecord( NdxF2, RecName ) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 110 (* You could do something here to account for records 111 that could not be read from source file, so none of 112 the GetFields above succeeded *) 113 END; 114 END CopyMatchingFields; ***** ^ not supported yet 115 116 117 PROCEDURE CopyRecord( RecName: ARRAY OF CHAR; SourceFile, DestFile: ***** ^ not supported yet 118 NdxTypes.NdxFileType ): BOOLEAN; ***** ^ not supported yet 119 VAR 120 TypeCode: CARDINAL; 121 TmpList1, TmpList2: GenLists.GenList; ***** ^ not supported yet 122 BEGIN 123 IF NdxFiles.GetField( SourceFile, RecName, 'RECORD', TypeCode, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 124 TmpList1 ) THEN ***** ^ not supported yet 125 IF TypeCode = GenLists.ListCode THEN ***** ^ not supported yet ***** ^ not supported yet 126 GenLists.CopyList( TmpList1, TmpList2 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 127 IF NdxFiles.PutField( DestFile, RecName, 'RECORD', TypeCode, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 128 TmpList2 ) THEN ***** ^ not supported yet 129 IF NdxFiles.WriteRecord( DestFile, RecName ) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 130 RETURN TRUE; 131 END; 132 END; 133 END; 134 END; 135 RETURN FALSE; 136 END CopyRecord; ***** ^ not supported yet 137 138 139 PROCEDURE TransferRecord( RecName: ARRAY OF CHAR; SourceFile, DestFile: ***** ^ not supported yet 140 NdxTypes.NdxFileType ): BOOLEAN; ***** ^ not supported yet 141 VAR 142 TypeCode: CARDINAL; 143 TmpList1, TmpList2: GenLists.GenList; ***** ^ not supported yet 144 BEGIN 145 IF NdxFiles.GetField( SourceFile, RecName, 'RECORD', TypeCode, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 146 TmpList1 ) THEN ***** ^ not supported yet 147 IF TypeCode = GenLists.ListCode THEN ***** ^ not supported yet ***** ^ not supported yet 148 GenLists.CopyList( TmpList1, TmpList2 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 149 IF NdxFiles.PutField( DestFile, RecName, 'RECORD', TypeCode, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 150 TmpList2 ) THEN ***** ^ not supported yet 151 IF NdxFiles.WriteRecord( DestFile, RecName ) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 152 IF NdxFiles.DeleteRecord( SourceFile, RecName ) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 153 RETURN TRUE; 154 END; 155 END; 156 END; 157 END; 158 END; 159 RETURN FALSE; 160 END TransferRecord; ***** ^ not supported yet 161 162 163 PROCEDURE ExportToFile( NdxFile: NdxTypes.NdxFileType; RecNameList: ***** ^ not supported yet 164 GenLists.GenList; fhandle: CARDINAL ); ***** ^ not supported yet 165 (* exports records to a plain ascii file *) 166 VAR 167 lngth, cnt, TypeCode: CARDINAL; 168 TmpStr: NdxTypes.RecNameStr; ***** ^ not supported yet 169 TmpList: GenLists.GenList; ***** ^ not supported yet 170 SearchingAll: BOOLEAN; 171 TmpNdxRec: NdxTypes.NdxElement; ***** ^ not supported yet 172 BEGIN 173 lngth := GenLists.ListLength( RecNameList ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 174 IF lngth = 0 THEN 175 SearchingAll := TRUE; 176 lngth := GenLists.ListLength( NdxFile^.Ndx ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 177 ELSE 178 SearchingAll := FALSE; 179 END; 180 FOR cnt := 1 TO lngth DO 181 IF SearchingAll THEN 182 GenLists.GetElmt( NdxFile^.Ndx, cnt, TmpNdxRec, TypeCode ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 183 StrEdit.AssignStr( TmpNdxRec.RecName, TmpStr ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 184 ELSE 185 GenLists.GetElmt( RecNameList, cnt, TmpStr, TypeCode ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 186 (*Put the cnt'th record name in TmpStr.*) 187 END; 188 IF (M2Strings.Length( TmpStr ) > 0) AND ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 189 (0 # M2Strings.CompareStr( TmpStr, (*BuildLst.ListStorageRec*) ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 190 'qQqQqQqQ' )) THEN ***** ^ not supported yet 191 (*Next, get the entire record.*) 192 IF NOT NdxFiles.GetField( NdxFile, TmpStr, 'RECORD', TypeCode, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 193 TmpList ) THEN ***** ^ not supported yet 194 StringIO.WriteStr( fhandle, TmpStr ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 195 StringIO.WriteEol( fhandle, ' is not a record in this file.' ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 196 END; 197 (*We are assuming TypeCode will always = ListCode here.*) 198 ListUtils.PrintList( fhandle, TmpList, 0, ',' ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 199 END; 200 END; 201 END ExportToFile; ***** ^ not supported yet 202 203 204 PROCEDURE SizeInfo( VAR NdxFile: NdxTypes.NdxFileType; VAR TotlSize, ***** ^ not supported yet 205 GbgSize: LONGINT; VAR PctUsed, NumDataRecs, NumGbgRecs: 206 CARDINAL); 207 VAR 208 CardTotalRecs: CARDINAL; 209 long2, long1, NdxElemSize, LongTotalRecs : LONGINT; 210 (*We use these temporary variables to avoid bugs in 211 Logitech's v3.03 compiler.*) 212 BEGIN 213 GarbageSize( NdxFile^.Ndx, GbgSize, NumDataRecs, NumGbgRecs); ***** ^ undeclared identifier ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 214 (* returns total size of garbage data and number of records *) 215 CardTotalRecs := NumDataRecs + NumGbgRecs; 216 NdxElemSize := Numbers.Lc( SYSTEM.TSIZE(NdxElement)); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 217 LongTotalRecs := Numbers.Lc( CardTotalRecs); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 218 long1 := (NdxElemSize * LongTotalRecs); 219 TotlSize := NdxFile^.NdxFilePtr + long1; ***** ^ not supported yet ***** ^ not supported yet 220 INC( TotlSize, 6 ); ***** ^ undeclared identifier ***** ^ not supported yet 221 long2 := Numbers.Lc( NumGbgRecs); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 222 long1 := (NdxElemSize * long2); 223 GbgSize := GbgSize + long1; 224 (* add size of garbage index entries to garbage size of data *) 225 long1 := GbgSize * Numbers.Lc( 100); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 226 long2 := long1 DIV TotlSize; 227 PctUsed := 100 - Numbers.C( long2); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 228 END SizeInfo; ***** ^ not supported yet 229 230 231 PROCEDURE GetRecName( NdxFile: NdxTypes.NdxFileType; Which: CARDINAL; ***** ^ not supported yet 232 VAR RecName: ARRAY OF CHAR ): BOOLEAN; ***** ^ not supported yet 233 (* returns name of Which'th ndx element, or FALSE if not found *) 234 VAR 235 NdxEl : NdxTypes.NdxElement; ***** ^ not supported yet 236 TheType: CARDINAL; 237 BEGIN 238 NdxTypes.CheckInit( NdxFile); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 239 IF GenLists.ListLength( NdxFile^.Ndx) < Which THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 240 RETURN FALSE; 241 END; 242 GenLists.GetElmt( NdxFile^.Ndx, Which, NdxEl, TheType); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 243 StrEdit.AssignStr( NdxEl.RecName, RecName); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 244 RETURN M2Strings.Length(RecName) # 0; ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 245 (* Return FALSE if index entry is marked as garbage *) 246 END GetRecName; ***** ^ not supported yet 247 248 249 PROCEDURE GetRecNames( NdxFile: NdxTypes.NdxFileType; ***** ^ not supported yet 250 VAR NameList: GenLists.GenList ); ***** ^ not supported yet 251 VAR 252 TmpElmt: NdxTypes.NdxElement; ***** ^ not supported yet 253 lngth, cnt, TypeCode : CARDINAL; 254 BEGIN 255 GenLists.NewList( NameList ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 256 lngth := GenLists.ListLength( NdxFile^.Ndx ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 257 FOR cnt := 1 TO lngth DO 258 GenLists.GetElmt( NdxFile^.Ndx, cnt, TmpElmt, TypeCode ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 259 StrEdit.CrunchBlanks( TmpElmt.RecName ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 260 IF (NOT PosUtils.Equal(TmpElmt.RecName, 'qQqQqQqQ' ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 261 (*BuildLst.ListStorageRec*)) ) 262 AND (M2Strings.Length( TmpElmt.RecName ) > 0) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 263 GenLists.ListInsert( TmpElmt.RecName, GenLists.StrCode, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 264 NameList, 65535 ); ***** ^ not supported yet ***** ^ not supported yet 265 END; 266 END; 267 END GetRecNames; ***** ^ not supported yet 268 269 270 PROCEDURE GarbageSize( VAR TheNdx: GenLists.GenList; VAR GbgSize: ***** ^ not supported yet 271 LONGINT; VAR NumDataRecs, NumGbgRecs: CARDINAL); 272 VAR 273 cnt, dum: CARDINAL; 274 TheElmt: NdxTypes.NdxElement; ***** ^ not supported yet 275 long1: LONGINT; 276 BEGIN 277 GbgSize := NumTypes.L0; ***** ^ not supported yet ***** ^ not supported yet 278 NumGbgRecs := 0; 279 NumDataRecs := GenLists.ListLength( TheNdx); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 280 FOR cnt := 1 TO NumDataRecs DO 281 GenLists.GetElmt( TheNdx, cnt, TheElmt, dum); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 282 IF TheElmt.UsedChars < TheElmt.Allocated THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 283 (* for every record with any gargbage in it *) 284 dum := TheElmt.Allocated - TheElmt.UsedChars; ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 285 (*We do this in steps because of bugs in Logitech's 286 v3.03 LONGINTs.*) 287 long1 := Numbers.Lc(dum); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 288 GbgSize := GbgSize + long1; 289 IF TheElmt.UsedChars = 0 THEN ***** ^ not supported yet ***** ^ not supported yet 290 INC( NumGbgRecs); ***** ^ undeclared identifier ***** ^ not supported yet 291 END; 292 END; 293 END; 294 DEC( NumDataRecs, NumGbgRecs); ***** ^ undeclared identifier ***** ^ not supported yet 295 END GarbageSize; ***** ^ not supported yet 296 297 PROCEDURE ByFilePos(adr1: SYSTEM.ADDRESS; size1: CARDINAL; ***** ^ not supported yet 298 adr2: SYSTEM.ADDRESS; size2: CARDINAL): INTEGER; ***** ^ not supported yet 299 (*We pass this procedure to the procedure variable parameter 300 of SortList to make it sort the Ndx according to position 301 of the record in the file. Used only in CrunchNdxFile, 302 but we can't make it local to that procedure because of 303 an implementation restriction in Logitech's handling of 304 procedure variables.*) 305 VAR 306 tmpsize: CARDINAL; 307 tmp1, tmp2: NdxTypes.NdxElement; ***** ^ not supported yet 308 BEGIN 309 tmpsize := SYSTEM.TSIZE( NdxElement ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 310 LowLevel.Move( adr1, SYSTEM.ADR(tmp1), tmpsize ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 311 LowLevel.Move( adr2, SYSTEM.ADR(tmp2), tmpsize ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 312 IF tmp1.FilePos > tmp2.FilePos THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 313 RETURN 1; 314 ELSIF tmp1.FilePos < tmp2.FilePos THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 315 RETURN -1; 316 ELSE 317 RETURN 0; 318 END; 319 END ByFilePos; ***** ^ not supported yet 320 321 PROCEDURE ByFileName( adr1: SYSTEM.ADDRESS; size1: CARDINAL; adr2: ***** ^ not supported yet 322 SYSTEM.ADDRESS; size2: CARDINAL ): INTEGER; ***** ^ not supported yet 323 (*We pass this procedure to the procedure variable parameter 324 of SortList to make it restore the Ndx to reverse 325 alphabetical order.*) 326 VAR 327 tmpsize: CARDINAL; 328 tmp1, tmp2: NdxTypes.NdxElement; ***** ^ not supported yet 329 BEGIN 330 tmpsize := SYSTEM.TSIZE(NdxElement); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 331 LowLevel.Move( adr1, SYSTEM.ADR(tmp1), tmpsize ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 332 LowLevel.Move( adr2, SYSTEM.ADR(tmp2), tmpsize ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 333 RETURN - M2Strings.CompareStr( tmp1.RecName, tmp2.RecName ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 334 END ByFileName; ***** ^ not supported yet 335 336 PROCEDURE CrunchNdxFile( VAR NdxFile: NdxTypes.NdxFileType ); ***** ^ not supported yet 337 (*Copies the file over itself.*) 338 339 PROCEDURE MoveFileData( TheHandle: CARDINAL; 340 FromSpot, ToSpot: LONGINT; HowMuch: CARDINAL); 341 VAR 342 BytesCopied, BufSize, ChunkSize : CARDINAL; 343 bufadr: SYSTEM.ADDRESS; ***** ^ not supported yet 344 SavedMessage: CARDINAL; 345 TmpL : LONGINT; 346 BEGIN 347 BytesCopied := 0; 348 IF VStorage.DosAvail( HowMuch ) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 349 BufSize := HowMuch; 350 ELSE 351 BufSize := EnvironUtils.MemAvail( 1000 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 352 (*Guesses the amount of memory available to within 1000 353 bytes.*) 354 END; 355 VStorage.DosAlloc( bufadr, BufSize ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 356 REPEAT 357 IF (HowMuch - BytesCopied) > BufSize THEN 358 ChunkSize := BufSize; 359 ELSE 360 ChunkSize := HowMuch - BytesCopied; 361 END; 362 TmpL := FromSpot + Numbers.Lc( BytesCopied); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 363 (*Necessary because of bugs in Logitech's LONGINT 364 arithmetic that have persisted into v3.03.*) 365 HandleIO.SetFilePtr( TheHandle, HandleIO.FromStart, TmpL ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 366 SavedMessage := HandleIO.BlockRead( TheHandle, bufadr, ChunkSize ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 367 CASE SavedMessage OF 368 StringIO.NoError, StringIO.PartialRead, StringIO.EndOfFile: ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 369 (*Do nothing.*); 370 ELSE 371 StringIO.PrintMessage( SavedMessage ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 372 (*Explains the error and aborts the program.*) 373 END; 374 TmpL := ToSpot + Numbers.Lc(BytesCopied); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 375 HandleIO.SetFilePtr( TheHandle, HandleIO.FromStart, TmpL ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 376 SavedMessage := HandleIO.BlockWrite( TheHandle, bufadr, ChunkSize ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 377 CASE SavedMessage OF 378 StringIO.NoError, StringIO.PartialRead, StringIO.EndOfFile: ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 379 (*Do nothing.*); 380 ELSE 381 StringIO.PrintMessage( SavedMessage ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 382 (*Explains the error and aborts the program.*) 383 END; 384 INC( BytesCopied, ChunkSize ); ***** ^ undeclared identifier ***** ^ not supported yet 385 UNTIL BytesCopied = HowMuch; 386 VStorage.DosDealloc( bufadr, BufSize ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 387 END MoveFileData; ***** ^ not supported yet 388 389 VAR 390 WritingSpot: LONGINT; 391 RecordCnt, TypeCode : CARDINAL; 392 TmpElmt: NdxTypes.NdxElement; ***** ^ not supported yet 393 ListReplaceNeeded : BOOLEAN; 394 395 BEGIN 396 (*CrunchNdxFile*) 397 NdxTypes.CheckInit( NdxFile ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 398 IF GenLists.ListLength( NdxFile^.Ndx ) = 0 THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 399 (*empty file*) 400 RETURN; 401 END; 402 403 HandleIO.UpdateDisk( NdxFile^.handle ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 404 GenLists.SortList( NdxFile^.Ndx, ByFilePos ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 405 RecordCnt := 1; 406 GenLists.GetElmt(NdxFile^.Ndx, RecordCnt, TmpElmt, TypeCode); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 407 WritingSpot := TmpElmt.FilePos; ***** ^ not supported yet ***** ^ not supported yet 408 (*Skip the structure record.*) 409 ListReplaceNeeded := FALSE; 410 WHILE RecordCnt <= GenLists.ListLength(NdxFile^.Ndx) DO ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 411 (* We look at every element in the Ndx. *) 412 GenLists.GetElmt(NdxFile^.Ndx, RecordCnt, TmpElmt, TypeCode); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 413 IF (M2Strings.Length(TmpElmt.RecName) > 0) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 414 IF TmpElmt.FilePos > WritingSpot THEN ***** ^ not supported yet ***** ^ not supported yet 415 (* If the record starts farther into the file than we think it's 416 supposed to start. *) 417 MoveFileData( NdxFile^.handle, TmpElmt.FilePos, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 418 WritingSpot, TmpElmt.UsedChars ); ***** ^ not supported yet ***** ^ not supported yet 419 (* In NdxFile^.handle, move TmpElmt.UsedChars from TmpElmt.FilePos 420 to WritingSpot. *) 421 TmpElmt.FilePos := WritingSpot; ***** ^ not supported yet ***** ^ not supported yet 422 NdxFile^.UpdateNeeded := TRUE; ***** ^ not supported yet ***** ^ not supported yet 423 ListReplaceNeeded := TRUE; 424 ELSIF TmpElmt.Allocated > TmpElmt.UsedChars THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 425 (* We know that the amount of space allocated to this record is 426 going to be reduced in the next loop, so we go ahead and update 427 its entry in the Ndx. *) 428 ListReplaceNeeded := TRUE; 429 END; 430 IF ListReplaceNeeded THEN 431 TmpElmt.Allocated := TmpElmt.UsedChars; ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 432 GenLists.ListReplace(TmpElmt, TypeCode, NdxFile^.Ndx, RecordCnt); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 433 ListReplaceNeeded := FALSE; 434 END; 435 WritingSpot := WritingSpot + Numbers.Lc( TmpElmt.UsedChars ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 436 (* Since we increment WritingSpot by TmpElmt.UsedChars instead of by 437 TmpElmt.Allocated, when we look at the next record, its FilePos 438 will be greater than WritingSpot, so we will crunch out small bits 439 of garbage at the ends of records. *) 440 INC( RecordCnt ); ***** ^ undeclared identifier ***** ^ not supported yet 441 ELSE 442 (* The length of the RecName is 0, so we know it's a garbage record.*) 443 GenLists.ListDelete( NdxFile^.Ndx, RecordCnt, 1 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 444 NdxFile^.UpdateNeeded := TRUE; ***** ^ not supported yet ***** ^ not supported yet 445 END; 446 END; (*WHILE*) 447 NdxFile^.NdxFilePtr := WritingSpot; ***** ^ not supported yet ***** ^ not supported yet 448 (*Sets the position of the NdxMarker.*) 449 IF GenLists.ListLength( NdxFile^.Ndx ) > 0 THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 450 GenLists.SortList( NdxFile^.Ndx, ByFileName ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 451 (*Put the Ndx list back into reverse alphabetical order.*) 452 END; 453 IF NdxFile^.UpdateNeeded THEN ***** ^ not supported yet ***** ^ not supported yet 454 NdxFiles.WriteNdx( NdxFile ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 455 END; 456 END CrunchNdxFile; ***** ^ not supported yet 457 458 459 PROCEDURE RebuildNdx( VAR NdxFile: NdxTypes.NdxFileType ); ***** ^ not supported yet 460 (*Scans a file for record separators and builds a new linked 461 list of record names, record sizes, and file offsets, then 462 writes the list to the file, beginning at the last byte of 463 the last record in the file. Used to repair damaged 464 NdxFiles. *) 465 CONST 466 DuplicateNameMessage = 467 'Duplicate RecName found. Will try to make it unique'; ***** ^ not supported yet 468 IrreparableMsg = 'NdxFile may be irreparably damaged'; ***** ^ not supported yet 469 470 VAR 471 RecFound, FileEndReached, NdxMarkFound, Garbage, FirstChar: 472 BOOLEAN; 473 bufch: CHAR; 474 L4, ThisEndSpot, FileSize, BytesToRead, LastSpot, FileSpot: LONGINT; 475 NdxElemSize, NestingLevel, cnt, BufSize, BufSpot, ZeroRecSize, 476 ChunkSize, memory: CARDINAL; 477 buf: LowLevel.Address8086; ***** ^ not supported yet 478 OldNdxElmt, NewNdxElmt: NdxTypes.NdxElement; ***** ^ not supported yet 479 TmpRecName: NdxTypes.RecNameStr; ***** ^ not supported yet 480 TmpStr: ARRAY [0..127] OF CHAR; ***** ^ not supported yet ***** ^ not supported yet 481 482 PROCEDURE MakeUniqueName( InStr: ARRAY OF CHAR; ***** ^ not supported yet 483 VAR OutStr: ARRAY OF CHAR); ***** ^ not supported yet 484 VAR 485 dumc: CARDINAL; 486 TimeStr: ARRAY [0..30] OF CHAR; ***** ^ not supported yet ***** ^ not supported yet 487 BEGIN 488 StrEdit.AssignStr( InStr, OutStr ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 489 EnvironUtils.GetTime(dumc,dumc,dumc,dumc, TimeStr); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 490 StrEdit.DeleteChar( ':', TimeStr ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 491 StrEdit.DeleteChar( ' ', TimeStr ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 492 IF M2Strings.Length(OutStr) < (HIGH(OutStr) - 1) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ undeclared identifier ***** ^ not supported yet 493 M2Strings.Delete( TimeStr, 1, M2Strings.Length(TimeStr) - 2 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 494 StrEdit.Append( OutStr, TimeStr ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 495 ELSE 496 StrEdit.AssignStr( TimeStr, OutStr ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 497 END; 498 END MakeUniqueName; ***** ^ not supported yet 499 500 PROCEDURE NextChar(): CHAR; 501 VAR 502 tmpch: CHAR; 503 SavedMessage: CARDINAL; 504 BEGIN 505 IF FirstChar THEN 506 (*We only want to allocate our buffer on the first 507 call.*) 508 FirstChar := FALSE; 509 FileSpot := NumTypes.L0; ***** ^ not supported yet ***** ^ not supported yet 510 (*FileSpot tracks our position in the file.*) 511 BytesToRead := FileSize; 512 IF BytesToRead > Numbers.Lc( 65000) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 513 (*We make it a little less than 64K because the Storage 514 module can't really allocate a full 64K block.*) 515 BufSize := 65000; 516 ELSE 517 BufSize := Numbers.C( BytesToRead ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 518 END; 519 memory := EnvironUtils.MemAvail( 5000 ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 520 (*Guess the amount of memory available, to within 5000 521 bytes.*) 522 IF memory < BufSize THEN 523 BufSize := memory; 524 END; 525 VStorage.DosAlloc( buf.a, BufSize ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 526 BufSpot := BufSize; 527 (*We do this so that we'll begin by doing a BlockRead, 528 just as we would if we'd reached the end of a buffer.*) 529 ChunkSize := BufSize; 530 END; 531 IF BytesToRead = NumTypes.L0 THEN ***** ^ not supported yet ***** ^ not supported yet 532 FileEndReached := TRUE; 533 RETURN 0C; 534 END; 535 IF (BufSpot >= ChunkSize) THEN 536 IF BytesToRead < Numbers.Lc( BufSize) THEN ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 537 (*If we have fewer bytes to read than will fit in the 538 buffer.*) 539 ChunkSize := Numbers.C( BytesToRead ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 540 END; 541 HandleIO.SetFilePtr( NdxFile^.handle, HandleIO.FromStart, FileSpot ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 542 SavedMessage := HandleIO.BlockRead( NdxFile^.handle, buf.a, ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 543 ChunkSize ); ***** ^ not supported yet 544 (*This is where we actually load the buffer.*) 545 IF (SavedMessage # StringIO.NoError) ***** ^ not supported yet ***** ^ not supported yet 546 AND 547 (SavedMessage # StringIO.PartialRead) ***** ^ not supported yet ***** ^ not supported yet 548 AND 549 (SavedMessage # StringIO.EndOfFile) THEN ***** ^ not supported yet ***** ^ not supported yet 550 StringIO.PrintMessage( SavedMessage ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 551 END; 552 BufSpot := 0; 553 END; 554 tmpch := LowLevel.PeekByte( buf.seg, buf.off + BufSpot ); ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet ***** ^ not supported yet 555 INC( BufSpot ); ***** ^ undeclared identifier ***** ^ not supported yet 556 INC( FileSpot ); ***** ^ undeclared identifier ***** ^ not supported yet 557 DEC( BytesToRead ); ***** ^ undeclared identifier ***** ^ not supported yet 558 IF BytesToRead = NumTypes.L0 THEN ***** ^ not supported yet ***** ^ not supported yet 559 FileEndReached := TRUE; 560 END; 561 RETURN tmpch; 562 END NextChar; ***** ^ not supported yet 563 564 PROCEDURE NextCard(): CARDINAL; 565 VAR 566 conv : RECORD 567 (*Used in swap and BytesToWord.*) 568 CASE : BOOLEAN OF ***** ^ not supported yet ***** ^ 'POINTER' expected 569 TRUE : 570 x : CARDINAL; 571 | FALSE : 572 a, b : CHAR; 573 END; 574 END; 575 BEGIN 576 conv.a := NextChar(); 577 conv.b := NextChar(); 578 RETURN conv.x; 579 END NextCard; 580 581 582 PROCEDURE NdxEntryInsert( TmpElmt: NdxTypes.NdxElement; 583 VAR NdxFile: NdxTypes.NdxFileType ): BOOLEAN; 584 VAR 585 dummylong: LONGINT; 586 TheElmt, dummycard: CARDINAL; 587 BEGIN 588 IF NOT NdxBones.FindRecord( NdxFile, TmpElmt.RecName, dummylong, 589 dummycard, TheElmt) THEN 590 (*The FindRecord returns the alphabetically correct 591 insertion point, TheElmt.*) 592 GenLists.ListInsert( TmpElmt, NdxTypes.NdxTypeCode, NdxFile^.Ndx, 593 TheElmt); 594 RETURN TRUE; 595 ELSE 596 RETURN FALSE; 597 END; 598 END NdxEntryInsert; 599 600 601 PROCEDURE SetName( RecName: ARRAY OF CHAR; 602 VAR OldNdxElmt: NdxTypes.NdxElement ); 603 BEGIN 604 IF OldNdxElmt.FilePos = NumTypes.L0 THEN 605 (* This makes sure that we don't try to set the name of 606 the last record while we're processing the first 607 record in the file.*) 608 RETURN; 609 END; 610 StrEdit.AssignStr( RecName, OldNdxElmt.RecName ); 611 IF M2Strings.Length( RecName ) > 0 THEN 612 WHILE NOT NdxEntryInsert(OldNdxElmt, NdxFile ) DO 613 StrEdit.AssignStr( DuplicateNameMessage, TmpStr ); 614 M2Strings.Insert( ': ', TmpStr, 0 ); 615 M2Strings.Insert( RecName, TmpStr, 0 ); 616 ErrorManager.WARN( TmpStr ); 617 MakeUniqueName(OldNdxElmt.RecName, OldNdxElmt.RecName); 618 StrEdit.AssignStr( OldNdxElmt.RecName, TmpStr ); 619 M2Strings.Insert( 'Trying "', TmpStr, 0 ); 620 StrEdit.Append( TmpStr, '". Please note new name' ); 621 ErrorManager.WARN( TmpStr ); 622 END; 623 ELSE 624 GenLists.ListInsert(OldNdxElmt, 625 NdxTypes.NdxTypeCode, NdxFile^.Ndx, 65535); 626 (*appends OldNdxElmt to end of Ndx*) 627 END; 628 END SetName; 629 630 PROCEDURE SkipToNext(); 631 (* When something goes wrong in a record, we call this to try 632 to skip ahead to the next thing that looks like the start 633 of a record. It's not foolproof, but it ought to work 634 most of the time.*) 635 BEGIN 636 StringIO.WriteEol( StringIO.outp, 'Skipping over this data:' ); 637 LOOP 638 bufch := NextChar(); 639 StringIO.WriteStr( StringIO.outp, bufch ); 640 IF (bufch = NdxBones.CodeChar) THEN 641 bufch := NextChar(); 642 IF bufch = NdxBones.NdxMarker[1] THEN 643 NdxMarkFound := TRUE; 644 EXIT; 645 END; 646 IF (bufch = NdxBones.StartSep[1]) AND 647 (NextCard() = GenLists.ListCode) AND 648 (NextChar() = NdxBones.CodeChar) AND 649 (NextChar() = NdxBones.StartSep[1]) AND 650 (NextCard() = GenLists.StrCode) THEN 651 bufch := NextChar(); 652 IF (bufch = 'O') OR (bufch = 'G') THEN 653 NestingLevel := 2; 654 RecFound := TRUE; 655 EXIT; 656 END; 657 END; 658 END; 659 END; 660 END SkipToNext; 661 662 PROCEDURE TruncateChosen(): BOOLEAN; 663 VAR 664 tmp: ARRAY [0..15] OF CHAR; 665 BEGIN 666 StringIO.WriteEol( StringIO.outp, '' ); 667 StringIO.WriteStr( StringIO.outp, 668 'Do you want to truncate the file here? ' ); 669 StringIO.ReadStr( StringIO.inp, tmp ); 670 IF CAP(tmp[0]) = 'Y' THEN 671 NdxMarkFound := TRUE; 672 RETURN TRUE; 673 ELSE 674 RETURN FALSE; 675 END; 676 END TruncateChosen; 677 678 PROCEDURE MarkBad( VAR RecName: ARRAY OF CHAR ); 679 VAR 680 TmpStr: ARRAY [0..79] OF CHAR; 681 BEGIN 682 StrConv.LongIntegerToStr( FileSpot, 0, TmpStr ); 683 StrEdit.Append( TmpStr, 684 '= file offset. This record has been corrupted: "' ); 685 StrEdit.Append( TmpStr, RecName ); 686 StrEdit.Append( TmpStr, '"' ); 687 ErrorManager.WARN( TmpStr ); 688 StrEdit.SetLength( RecName, 0 ); 689 END MarkBad; 690 691 BEGIN 692 (*RebuildNdx*) 693 NdxElemSize := SYSTEM.TSIZE(NdxElement); 694 (*This gets us around a bug in the beta copy of v3.0.*) 695 GenLists.NewList( NdxFile^.Ndx ); 696 (*Initialize the list in preparation for rebuilding it; we 697 assume it hasn't yet been initialized.*) 698 FileSize := HandleIO.FileLength( NdxFile^.handle ); 699 HandleIO.SetFilePtr( NdxFile^.handle, HandleIO.FromStart, NumTypes.L0 ); 700 LowLevel.Fill( SYSTEM.ADR(OldNdxElmt), NdxElemSize, 0C ); 701 LowLevel.Fill( SYSTEM.ADR(NewNdxElmt), NdxElemSize, 0C ); 702 StrEdit.SetLength( TmpRecName, 0 ); 703 NdxMarkFound := FALSE; 704 FileEndReached := FALSE; 705 FirstChar := TRUE; 706 ZeroRecSize := NextCard(); 707 (*BufSpot should now be 2, because the byte at offset 2--the 708 3rd byte--is the next one to be read.*) 709 IF (FileSize < NumTypes.L65535) AND 710 (ZeroRecSize > Numbers.C( FileSize)) THEN 711 ErrorManager.WARN( IrreparableMsg ); 712 END; 713 FOR cnt := 1 TO ZeroRecSize DO 714 (*Skip the zero record because it just contains the 715 structure.*) 716 bufch := NextChar(); 717 END; 718 NestingLevel := 1; 719 RecFound := FALSE; 720 LastSpot := NumTypes.L0; 721 ThisEndSpot := NumTypes.L0; 722 WHILE (NOT FileEndReached) AND (NOT NdxMarkFound) DO 723 (*Find the next CodeChar.*) 724 bufch := NextChar(); 725 726 IF bufch = NdxBones.CodeChar THEN 727 bufch := NextChar(); 728 (*find out what kind of separator this is*) 729 IF bufch = NdxBones.StartSep[1] THEN 730 INC( NestingLevel ); 731 bufch := NextChar(); 732 bufch := NextChar(); 733 (*Skip over the type code.*) 734 IF NestingLevel = 2 THEN 735 RecFound := TRUE; 736 END; 737 ELSIF bufch = NdxBones.EndSep[1] THEN 738 DEC( NestingLevel ); 739 IF NestingLevel = 1 THEN 740 ThisEndSpot := FileSpot; 741 ELSIF NestingLevel = 0 THEN 742 (*If NestingLevel gets back to 0 before we find the 743 NdxMarker, we're done for.*) 744 ErrorManager.WARN( IrreparableMsg ); 745 MarkBad( TmpRecName ); 746 IF NOT TruncateChosen() THEN 747 SkipToNext(); 748 END; 749 ThisEndSpot := FileSpot; 750 END; 751 ELSIF bufch = NdxBones.NdxMarker[1] THEN 752 ThisEndSpot := FileSpot; 753 NdxMarkFound := TRUE; 754 ELSIF bufch = NdxBones.CodedStr[1] THEN 755 (* This means there was a CodeChar embedded in the 756 user's data. We just skip it. It will be decoded 757 when it's read.*) 758 ELSE 759 StrConv.LongIntegerToStr( FileSpot, 0, TmpStr ); 760 M2Strings.Insert( '" ": illegal character at ', TmpStr, 0 ); 761 TmpStr[1] := bufch; 762 ErrorManager.WARN( TmpStr ); 763 MarkBad( TmpRecName ); 764 IF NOT TruncateChosen() THEN 765 SkipToNext(); 766 END; 767 END; 768 END; 769 770 IF (NOT NdxMarkFound) AND RecFound THEN 771 RecFound := FALSE; 772 (*We've just read the next record StartSep.*) 773 LowLevel.Fill( SYSTEM.ADR(OldNdxElmt), NdxElemSize, 0C ); 774 OldNdxElmt.FilePos := LastSpot; 775 (* position saved when last start sep was found *) 776 OldNdxElmt.Allocated := Numbers.C( FileSpot - LastSpot); 777 DEC( OldNdxElmt.Allocated, 4 ); 778 (* position when this rec startsep found minus 779 position saved when last rec start sep was found *) 780 IF M2Strings.Length(TmpRecName) > 0 THEN 781 OldNdxElmt.UsedChars := Numbers.C( ThisEndSpot - LastSpot ); 782 (*position when this rec endsep found minus 783 position saved when last rec start sep was found *) 784 ELSE 785 OldNdxElmt.UsedChars := 0; 786 END; 787 L4 := Numbers.Lc( 4); 788 (*We do this to avoid a bug in Logitech's v3.0 789 LONGINTs.*) 790 LastSpot := FileSpot - L4; 791 792 SetName( TmpRecName, OldNdxElmt ); 793 794 bufch := NextChar(); bufch := NextChar(); 795 (*Skip over the StartSep that starts the record name.*) 796 bufch := NextChar(); bufch := NextChar(); 797 (*Skip over the record name type code.*) 798 StrEdit.SetLength(TmpRecName, 0); 799 bufch := NextChar(); 800 Garbage := bufch = 'G'; 801 LOOP 802 (*This is where we get the record name, we keep it in 803 TmpRecName until we get to the start of the next 804 record or to the NdxMarker. SetName then assigns 805 TmpRecName to the RecName field of OldNdxElmt, taking 806 care of any duplication of names.*) 807 bufch := NextChar(); 808 IF FileEndReached THEN 809 EXIT; 810 END; 811 IF bufch = NdxBones.CodeChar THEN 812 bufch := NextChar(); 813 IF bufch = NdxBones.EndSep[1] THEN 814 IF Garbage THEN 815 StrEdit.SetLength( TmpRecName, 0 ); 816 END; 817 EXIT; 818 END; 819 ELSE 820 StrEdit.Append( TmpRecName, bufch ); 821 END; 822 END; 823 StrEdit.CrunchBlanks( TmpRecName ); 824 ELSIF NdxMarkFound THEN 825 LowLevel.Fill( SYSTEM.ADR(OldNdxElmt), NdxElemSize, 0C ); 826 OldNdxElmt.FilePos := LastSpot; 827 (* position saved when last start sep was found *) 828 OldNdxElmt.Allocated := Numbers.C( FileSpot - LastSpot); 829 DEC( OldNdxElmt.Allocated, 2 ); 830 (* position when this rec startsep found minus 831 position saved when last rec start sep was found *) 832 IF M2Strings.Length( TmpRecName ) > 0 THEN 833 OldNdxElmt.UsedChars := Numbers.C( ThisEndSpot - LastSpot); 834 (*position when this rec endsep found minus 835 position saved when last rec start sep was found *) 836 ELSE 837 OldNdxElmt.UsedChars := 0; 838 END; 839 NdxFile^.NdxFilePtr := FileSpot - NumTypes.L2; 840 SetName( TmpRecName, OldNdxElmt ); 841 END; 842 END;(*WHILE (NOT FileEndReached) AND (NOT NdxMarkFound)*) 843 844 IF (NOT NdxMarkFound) THEN 845 IF LastSpot = NumTypes.L0 THEN 846 ErrorNames.WarningName('NotNdx'); 847 ELSE 848 NdxFile^.NdxFilePtr := LastSpot; 849 END; 850 END; 851 852 VStorage.DosDealloc( buf.a, BufSize ); 853 NdxFile^.BufSizeNow := 0; 854 NdxFiles.WriteNdx( NdxFile ); 855 END RebuildNdx; 856 857 PROCEDURE AllowRebuild( VAR NdxFile: NdxTypes.NdxFileType ); 858 BEGIN 859 ErrorManager.WARN( 'Damaged file. Will attempt to rebuild it' ); 860 RebuildNdx( NdxFile ); 861 END AllowRebuild; 862 863 864 PROCEDURE Init(); 865 BEGIN 866 IF Initialized THEN 867 RETURN; 868 ELSE 869 Initialized := TRUE; 870 END; 871 (*EntryDiag: 872 Diagnostics.Init(); 873 :EntryDiag*) 874 875 EnvironUtils.Init(); 876 ErrorManager.Init(); 877 ErrorNames.Init(); 878 HandleIO.Init(); 879 GenLists.Init(); 880 ListUtils.Init(); 881 LowLevel.Init(); 882 M2Strings.Init(); 883 NdxBones.Init(); 884 NdxFiles.Init(); 885 NdxTypes.Init(); 886 Numbers.Init(); 887 NumTypes.Init(); 888 PosUtils.Init(); 889 StrConv.Init(); 890 StrEdit.Init(); 891 StringIO.Init(); 892 VStorage.Init(); 893 (*EntryDiag: 894 Diagnostics.diagS( 'Entering NdxUtils', '' ); 895 :EntryDiag*) 896 NdxBones.RebuildProc := AllowRebuild; 897 (*EntryDiag: 898 Diagnostics.diagS( 'Exiting NdxUtils', '' ); 899 :EntryDiag*) 900 END Init; 901 902 903 BEGIN 904 Initialized := FALSE; 905 Init(); 906 END NdxUtils. 654 errors