105a755439d4c846345933270ad6da24f5b455f0
1 (* Copyright (C) DooM 2D:Forever Developers
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *)
16 {$INCLUDE a_modes.inc}
19 interface
21 uses
22 Classes,
26 // ////////////////////////////////////////////////////////////////////////// //
27 type
37 // this is base type for all scalars (and arrays)
39 public
40 type
41 TType = (TBool, TChar, TByte, TUByte, TShort, TUShort, TInt, TUInt, TString, TPoint, TSize, TList, TTrigData);
42 // TPoint: pair of Integers
43 // TSize: pair of UShorts
44 // TList: actually, array of records
45 // TTrigData: array of mMaxDim bytes, but internally a record (mRecRef)
46 // arrays of chars are pascal shortstrings (with counter in the first byte)
48 private
49 type
52 private
74 mAsMonsterId: Boolean; // special hack for triggers: monster record number+1 in binary (so 0 means "none")
75 // default value
82 mEBSType: TObject; // either TDynRecord or TDynEBS; nil means "simple type"; nil for `TTrigData` too
84 // for binary parser
87 private
92 procedure parseDefaultValue (); // parse `mDefUnparsed` to `mDefSVal`, `mDefIVal`, `mDefIVal2`, `mDefRecRef`
99 public
117 // won't work for lists
122 public
135 //property list: TDynRecList read mRVal; // for list
146 // "value" header record contains TList fields, with name equal to record type
148 private
158 mHeaderRec: TDynRecord; // for "value" records this is header record with data, for "type" records this is header type record
160 private
170 protected
175 public
193 // find field with `TriggerType` type
196 // number of records of the given instance
199 public
214 private
223 private
232 public
239 // return empty string if not found
242 public
251 public
256 private
261 public
271 // creates new header record
274 // creates new header record
277 public
282 {$IF DEFINED(D2D_DYNREC_PROFILER)}
284 {$ENDIF}
287 implementation
289 uses
290 SysUtils, e_log
294 // ////////////////////////////////////////////////////////////////////////// //
298 // ////////////////////////////////////////////////////////////////////////// //
300 begin
308 begin
316 begin
323 begin
330 begin
366 var
368 begin
379 begin
383 begin
414 // won't work for lists
416 begin
434 begin
444 var
446 begin
448 try
450 finally
457 var
463 begin
465 begin
470 end
471 else
472 begin
478 try
485 finally
497 // default value should be parsed
499 begin
502 begin
504 raise Exception.Create(Format('field ''%s'' in record ''%s'' of record type ''%s'' is not set', [mName, mOwner.mId, mOwner.mName]));
514 // default value should be parsed
516 begin
529 begin
535 begin
536 if (mRVal <> nil) and (idx >= 0) and (idx < mRVal.count) then result := mRVal[idx] else result := nil;
541 begin
562 begin
571 TEBS.TBitSet: begin result += ' bitset '; if mBitSetUnique then result += 'unique '; result += mEBSTypeName; end;
576 begin
577 if (mType = TType.TPoint) then begin if (mAsT) then result += ' as txy' else result += ' as xy'; end
578 else if (mType = TType.TSize) then begin if (mAsT) then result += ' as twh' else result += ' as wh'; end;
586 begin
590 TType.TChar: if (mMaxDim > 0) then result += formatstrf('Char%d;', [mMaxDim]) else result += 'Char;';
614 var
632 begin
663 begin
665 if (lmaxdim < 1) then raise Exception.Create(Format('invalid field ''%s'' array size', [fldname]));
667 end;
670 begin
672 begin
673 if (fldofs >= 0) then raise Exception.Create(Format('duplicate field ''%s'' offset', [fldname]));
676 continue;
680 begin
687 continue;
688 end;
691 begin
693 if (Length(fldrecname) <> 0) then raise Exception.Create(Format('field ''%s'' already typed as ''%s''', [fldname, fldrecname]));
695 continue;
699 begin
701 if (Length(fldrecname) <> 0) then raise Exception.Create(Format('field ''%s'' already typed as ''%s''', [fldname, fldrecname]));
704 continue;
708 begin
709 if hasdefStr or hasdefInt or hasdefId then raise Exception.Create(Format('field ''%s'' has duplicate default', [fldname]));
712 begin
717 begin
722 begin
726 else
729 continue;
733 begin
735 continue;
739 begin
741 continue;
744 if (pr.tokType <> pr.TTId) then raise Exception.Create(Format('field ''%s'' has something unexpected in definition', [fldname]));
746 if (Length(fldrecname) <> 0) then raise Exception.Create(Format('field ''%s'' already typed as ''%s''', [fldname, fldrecname]));
753 // create field
768 else raise Exception.Create(Format('field ''%s'' has invalid type ''%s''', [fldname, fldtype]));
770 if (lmaxdim > 0) and (mType <> TType.TChar) and (mType <> TType.TTrigData) then raise Exception.Create(Format('field ''%s'' of type ''%s'' cannot be array', [fldname, fldtype]));
772 begin
773 if (lmaxdim < 1) then raise Exception.Create(Format('field ''%s'' of type ''%s'' cannot be array', [fldname, fldtype]));
774 if (Length(fldrecname) > 0) then raise Exception.Create(Format('field ''%s'' of type ''%s'' cannot have another type', [fldname, fldtype]));
795 end;
799 var
805 begin
809 begin
811 begin
812 // this must be triggerdata
814 begin
815 raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
817 // write triggerdata
819 if (buf = nil) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
820 try
823 begin
828 finally
832 exit;
834 // record reference
842 else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
844 // find record number
846 begin
848 if (f < 0) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' not found in record list', [mEBSTypeName, mName]));
850 if (f > maxv) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' has too big index', [mEBSTypeName, mName]));
851 end
852 else
853 begin
860 else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
862 exit;
871 begin
873 begin
875 end
876 else
877 begin
880 exit;
883 begin
884 if (mMaxDim = 0) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
886 begin
887 if (Length(mSVal) <> 1) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
889 end
890 else
891 begin
892 if (Length(mSVal) > mMaxDim) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
897 exit;
901 begin
902 // triggerdata array was processed earlier
903 if (mMaxDim >= 0) then Exception.Create(Format('byte array in field ''%s'' cannot be written', [mName]));
905 exit;
909 begin
910 if (mMaxDim >= 0) then raise Exception.Create(Format('short array in field ''%s'' cannot be written', [mName]));
912 exit;
916 begin
917 if (mMaxDim >= 0) then raise Exception.Create(Format('int array in field ''%s'' cannot be written', [mName]));
919 exit;
922 begin
926 begin
927 if (mMaxDim >= 0) then raise Exception.Create(Format('pos/size array in field ''%s'' cannot be written', [mName]));
930 exit;
933 begin
934 if (mMaxDim >= 0) then raise Exception.Create(Format('pos/size array in field ''%s'' cannot be written', [mName]));
937 exit;
940 begin
942 exit;
945 begin
947 exit;
955 var
959 begin
965 begin
967 begin
969 end
971 begin
973 end
974 else
975 begin
979 exit;
982 begin
983 //def := mOwner.mOwner;
984 //es := def.findEBSType(mEBSTypeName);
987 if (es = nil) or (not es.mIsEnum) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
989 begin
991 begin
994 exit;
997 raise Exception.Create(Format('value %d in record enum type ''%s'' for field ''%s'' not found', [mIVal, mEBSTypeName, mName]));
1000 begin
1001 //def := mOwner.mOwner;
1002 //es := def.findEBSType(mEBSTypeName);
1005 if (es = nil) or es.mIsEnum then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1006 // none?
1008 begin
1010 begin
1012 begin
1015 exit;
1018 raise Exception.Create(Format('value %d in record bitset type ''%s'' for field ''%s'' not found', [0, mEBSTypeName, mName]));
1020 // not none
1024 begin
1026 begin
1029 begin
1031 begin
1035 break;
1038 if not found then raise Exception.Create(Format('value %d in record bitset type ''%s'' for field ''%s'' not found', [mask, mEBSTypeName, mName]));
1043 exit;
1050 begin
1052 exit;
1055 begin
1056 if (mMaxDim = 0) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
1059 exit;
1067 begin
1069 exit;
1072 begin
1075 exit;
1079 begin
1081 exit;
1084 begin
1086 exit;
1089 begin
1091 exit;
1099 var
1106 begin
1110 begin
1111 // this must be triggerdata
1113 begin
1116 // find trigger definition
1118 if (tfld = nil) then raise Exception.Create(Format('triggerdata value for field ''%s'' in record ''%s'' without TriggerType field', [mName, rec.mName]));
1120 if (rc = nil) then raise Exception.Create(Format('triggerdata definition for field ''%s'' in record ''%s'' with type ''%s'' not found', [mName, rec.mName, tfld.mSVal]));
1123 try
1127 finally
1131 exit;
1132 end
1133 else
1134 begin
1135 // not a trigger data
1143 else raise Exception.Create(Format('invalid non-numeric type ''%s'' for field ''%s'' of record ''%s''', [getTypeName(mType), mName, mEBSTypeName]));
1149 exit;
1153 begin
1162 else raise Exception.Create(Format('invalid non-numeric type ''%s'' for field ''%s'' of record ''%s''', [getTypeName(mType), mName, mEBSTypeName]));
1166 if (es = nil) or (es.mIsEnum <> (mEBS = TEBS.TEnum)) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1168 // build enum/bitfield values
1170 begin
1172 if (Length(mSVal) = 0) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' has invalid value %d', [mEBSTypeName, mName, mIVal]));
1173 end
1174 else
1175 begin
1176 // special for 'none'
1178 begin
1180 if (Length(mSVal) = 0) then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' has invalid value %d', [mEBSTypeName, mName, mIVal]));
1181 end
1182 else
1183 begin
1187 begin
1189 begin
1191 if (Length(s) = 0) then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' has invalid value %d', [mEBSTypeName, mName, mask]));
1199 //writeln('ebs <', es.mName, '>: ', mSVal);
1201 exit;
1208 begin
1214 exit;
1217 begin
1219 begin
1221 end
1222 else
1223 begin
1226 try
1231 begin
1236 finally
1241 exit;
1250 begin
1252 exit;
1255 begin
1259 exit;
1262 begin
1266 exit;
1269 begin
1271 exit;
1274 begin
1276 exit;
1287 begin
1289 if (mIVal < min) or (mIVal > max) then raise Exception.Create(Format('invalid %s value for field ''%s''', [getTypeName(mType), mName]));
1293 var
1299 begin
1300 // if this field should contain struct, convert type and parse struct
1304 begin
1305 // ugly hack. sorry.
1307 begin
1310 begin
1311 // '{}'
1314 end
1315 else
1316 begin
1318 // find trigger definition
1320 if (tfld = nil) then raise Exception.Create(Format('triggerdata value for field ''%s'' in record ''%s'' without ''type'' field', [mName, rec.mName]));
1322 if (rc = nil) then raise Exception.Create(Format('triggerdata definition for field ''%s'' in record ''%s'' with type ''%s'' not found', [mName, rec.mName, tfld.mSVal]));
1325 //writeln(rc.definition);
1326 try
1330 finally
1336 exit;
1338 // other record types
1340 begin
1342 begin
1344 end
1345 else
1346 begin
1348 if (rec = nil) then raise Exception.Create(Format('record ''%s'' (%s) value for field ''%s'' not found', [pr.tokStr, mEBSTypeName, mName]));
1354 exit;
1355 end
1357 begin
1358 //rec := mOwner.mOwner.findRecType(mEBSTypeName); // find in mapdef
1361 if (rec = nil) then raise Exception.Create(Format('record type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1369 exit;
1374 begin
1375 //es := mOwner.mOwner.findEBSType(mEBSTypeName); // find in mapdef
1378 if (es = nil) or (not es.mIsEnum) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1380 if not es.has[tk] then raise Exception.Create(Format('record enum value ''%s'' of type ''%s'' for field ''%s'' not found', [tk, mEBSTypeName, mName]));
1383 //writeln('ENUM ', mEBSName, '; element <', mSVal, '> with value ', mIVal);
1386 exit;
1389 begin
1390 //es := mOwner.mOwner.findEBSType(mEBSTypeName); // find in mapdef
1393 if (es = nil) or es.mIsEnum then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1396 begin
1398 if not es.has[tk] then raise Exception.Create(Format('record bitset value ''%s'' of type ''%s'' for field ''%s'' not found', [tk, mEBSTypeName, mName]));
1402 if mBitSetUnique then raise Exception.Create(Format('record bitset of type ''%s'' for field ''%s'' expects only one value', [tk, mEBSTypeName, mName]));
1403 //pr.expectDelim('|');
1408 exit;
1415 begin
1421 exit;
1424 begin
1425 if (mMaxDim = 0) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
1428 begin
1429 // single char
1430 if (Length(mSVal) <> 1) then raise Exception.Create(Format('invalid string size for field ''%s''', [mName]));
1433 end
1434 else
1435 begin
1436 // string
1437 if (Length(mSVal) > mMaxDim) then raise Exception.Create(Format('invalid string size for field ''%s''', [mName]));
1441 exit;
1444 begin
1447 exit;
1450 begin
1453 exit;
1456 begin
1459 exit;
1462 begin
1465 exit;
1468 begin
1471 exit;
1474 begin
1477 exit;
1480 begin
1484 exit;
1488 begin
1492 begin
1493 if (mIVal < 0) or (mIVal > 32767) then raise Exception.Create(Format('invalid %s value for field ''%s''', [getTypeName(mType), mName]));
1497 begin
1498 if (mIVal2 < 0) or (mIVal2 > 32767) then raise Exception.Create(Format('invalid %s value for field ''%s''', [getTypeName(mType), mName]));
1503 exit;
1506 begin
1508 exit;
1511 begin
1513 exit;
1521 // ////////////////////////////////////////////////////////////////////////// //
1523 begin
1524 if (pr = nil) then raise Exception.Create('cannot create record type without type definition');
1538 begin
1549 begin
1560 begin
1563 begin
1572 begin
1578 var
1580 begin
1587 begin
1593 var
1595 begin
1603 var
1606 begin
1614 begin
1627 var
1629 //rec: TDynRecord;
1631 begin
1634 // find record data
1637 if (fld.mType <> fld.TType.TList) then raise Exception.Create(Format('cannot get record of type ''%s'' due to name conflict with ordinary field', [atypename]));
1638 // find by id
1640 begin
1641 {
1642 for rec in fld.mRVal do
1643 begin
1644 if StrEqu(rec.mId, aid) then begin result := rec; exit; end;
1645 end;
1646 }
1649 // alas
1653 function TDynRecord.findRecordNumByType (const atypename: AnsiString; rc: TDynRecord): Integer;
1654 var
1657 begin
1659 // find record data
1662 if (fld.mType <> fld.TType.TList) then raise Exception.Create(Format('cannot get record of type ''%s'' due to name conflict with ordinary field', [atypename]));
1663 // find by ref
1665 begin
1667 begin
1671 // alas
1676 var
1678 begin
1679 // find record data
1682 begin
1683 // first record
1688 if (fld.mType <> fld.TType.TList) then raise Exception.Create(Format('cannot append record of type ''%s'' due to name conflict with ordinary field', [atypename]));
1689 // append
1691 begin
1701 var
1703 begin
1709 begin
1717 var
1720 begin
1722 begin
1733 // number of records of the given instance
1735 var
1737 begin
1745 var
1748 begin
1750 begin
1753 begin
1755 begin
1759 if isForTrig[tdn] then raise Exception.Create(Format('duplicate trigdata ''%s'' trigtype ''%s''', [mName, tdn]));
1763 end
1764 else
1765 begin
1771 end
1772 else
1773 begin
1778 begin
1781 begin
1782 if (mSize > 0) then raise Exception.Create(Format('duplicate `size` in record ''%s''', [mName]));
1784 if (mSize < 1) then raise Exception.Create(Format('invalid record ''%s'' size: %d', [mName, mSize]));
1786 continue;
1789 begin
1790 if (mBinBlock >= 0) then raise Exception.Create(Format('duplicate `binblock` in record ''%s''', [mName]));
1792 if (mBinBlock < 1) then raise Exception.Create(Format('invalid record ''%s'' binblock: %d', [mName, mBinBlock]));
1793 continue;
1799 // load fields
1801 begin
1803 if hasByName(fld.name) then begin fld.Free(); raise Exception.Create(Format('duplicate field ''%s''', [fld.name])); end;
1804 // append
1807 // done with field
1814 var
1816 begin
1818 begin
1821 end
1822 else
1823 begin
1824 // record
1828 begin
1838 var
1840 begin
1842 begin
1843 // trigger data
1846 begin
1849 begin
1854 end
1855 else
1856 begin
1859 end
1860 else
1861 begin
1862 // record
1869 begin
1879 var
1891 var
1894 begin
1895 //writeln('*** rec: ', rec.mName, '.', rec.mId, ' (', rec.mFields.count, ')');
1897 begin
1899 begin
1901 continue;
1907 begin
1908 e_LogWritefln('record of type ''%s'' with id ''%s'' links to inexistant record of type ''%s'' with id ''%s''', [rec.mName, rec.mId, fld.mEBSTypeName, fld.mRecRefId], MSG_WARNING);
1909 //raise Exception.Create(Format('record of type ''%s'' with id ''%s'' links to inexistant record of type ''%s'' with id ''%s''', [rec.mName, rec.mId, fld.mEBSTypeName, fld.mRecRefId]));
1911 //writeln(' ', rec.mName, '.', rec.mId, ':', fld.mName, ' -> ', rt.mName, '.', rt.mId, ' (', fld.mEBSTypeName, '.', fld.mRecRefId, ')');
1917 begin
1918 //writeln(' ', fld.mName);
1923 begin
1926 try
1928 begin
1929 // parse map file as sequence of blocks
1933 // parse blocks
1935 begin
1941 if (bsize < 0) or (bsize > $1fffffff) then raise Exception.Create(Format('block of type %d has invalid size %d', [btype, bsize]));
1942 if loaded[btype] then raise Exception.Create(Format('block of type %d already loaded', [btype]));
1944 // find record type for this block
1947 if (rect = nil) then raise Exception.Create(Format('block of type %d has no corresponding record', [btype]));
1948 //writeln('found type ''', rec.mName, ''' for block type ', btype);
1949 if (rec.mSize = 0) or ((bsize mod rec.mSize) <> 0) then raise Exception.Create(Format('block of type %d has invalid number of records', [btype]));
1950 // header?
1952 begin
1953 if (bsize <> mSize) then raise Exception.Create(Format('header block of type %d has invalid number of records', [btype]));
1958 end
1959 else
1960 begin
1961 // create list for this type
1966 begin
1970 begin
1978 //writeln('parsed ''', rec.mId, '''...');
1984 //st.position := st.position+bsize;
1986 // link fields
1988 begin
1992 exit;
1995 // read fields
1997 if (mSize < 1) then raise Exception.Create(Format('cannot read record of type ''%s'' with unknown size', [mName]));
2001 begin
2004 if (fld.mBinOfs >= st.size) then raise Exception.Create(Format('record of type ''%s'' has invalid field ''%s''', [fld.mName]));
2006 //writeln('parsing ''', mName, '.', fld.mName, '''...');
2009 finally
2016 procedure TDynRecord.writeBinTo (st: TStream; trigbufsz: Integer=-1; onlyFields: Boolean=false);
2017 var
2023 //f, c: Integer;
2026 begin
2028 begin
2029 if (mBinBlock < 1) then raise Exception.Create('cannot write binary record without block number');
2032 end
2033 else
2034 begin
2037 try
2042 // write normal fields
2044 begin
2045 // record list?
2049 if (fld.mBinOfs >= bufsz) then raise Exception.Create('binary value offset is outside of the buffer');
2051 //writeln('writing field <', fld.mName, '>');
2055 // write block with normal fields
2057 begin
2058 //writeln('writing header...');
2059 // signature and version
2070 // write other blocks, if any
2072 begin
2073 // calculate blkmax
2076 begin
2077 // record list?
2079 begin
2087 // write blocks
2089 begin
2093 begin
2094 // record list?
2096 begin
2105 // flush block
2107 begin
2118 // write end marker
2123 finally
2131 var
2134 begin
2136 begin
2143 try
2145 begin
2146 // record list?
2148 begin
2151 begin
2153 begin
2159 continue;
2166 finally
2174 {$IF DEFINED(D2D_DYNREC_PROFILER)}
2175 var
2186 begin
2188 writeln('record cloning: ', profCloneRec div 1000, '.', profCloneRec mod 1000, ' milliseconds');
2189 writeln('findRecType : ', profFindRecType div 1000, '.', profFindRecType mod 1000, ' milliseconds');
2190 writeln('field[] : ', profFieldSearching div 1000, '.', profFieldSearching mod 1000, ' milliseconds');
2191 writeln('list dup check: ', profListDupChecking div 1000, '.', profListDupChecking mod 1000, ' milliseconds');
2192 writeln('addRecByType : ', profAddRecByType div 1000, '.', profAddRecByType mod 1000, ' milliseconds');
2193 writeln('field valparse: ', profFieldValParsing div 1000, '.', profFieldValParsing mod 1000, ' milliseconds');
2194 writeln('fix defaults : ', profFixDefaults div 1000, '.', profFixDefaults mod 1000, ' milliseconds');
2195 writeln('recvalparse : ', profRecValParse div 1000, '.', profRecValParse mod 1000, ' milliseconds');
2197 {$ENDIF}
2201 var
2205 {$IF DEFINED(D2D_DYNREC_PROFILER)}
2207 {$ENDIF}
2208 begin
2209 if (mOwner = nil) then raise Exception.Create(Format('can''t parse record ''%s'' value without owner', [mName]));
2213 // not a header?
2215 begin
2216 // id?
2218 end
2219 else
2220 begin
2224 //writeln('parsing record <', mName, '>');
2227 begin
2229 //writeln('<', mName, '.', pr.tokStr, '>');
2231 // records
2233 begin
2234 // add records with this type (if any)
2239 begin
2244 try
2248 begin
2253 begin
2255 //idtmp := trc.mName+':'+rec.mId;
2256 //if ids.put(idtmp, 1) then raise Exception.Create(Format('duplicate thing ''%s'' in record ''%s''', [fld.mName, mName]));
2257 if fld.mRHash.has(rec.mId) then raise Exception.Create(Format('duplicate thing ''%s'' in record ''%s''', [fld.mName, mName]));
2265 finally
2268 continue;
2272 // fields
2277 begin
2278 if fld.defined then raise Exception.Create(Format('duplicate field ''%s'' in record ''%s''', [fld.mName, mName]));
2279 if fld.internal then raise Exception.Create(Format('internal field ''%s'' in record ''%s''', [fld.mName, mName]));
2284 continue;
2287 // something is wrong
2291 // fix field defaults
2295 //writeln('done parsing record <', mName, '>');
2296 //{$IF DEFINED(D2D_DYNREC_PROFILER)}writeln('stall: ', curTimeMicro()-stall);{$ENDIF}
2301 // ////////////////////////////////////////////////////////////////////////// //
2303 begin
2310 begin
2317 begin
2328 begin
2331 begin
2340 begin
2346 var
2348 begin
2355 var
2357 begin
2361 // fields
2364 begin
2368 begin
2372 end
2373 else
2374 begin
2379 // max field
2386 var
2388 begin
2390 // fields
2392 begin
2399 var
2401 begin
2403 begin
2411 var
2417 begin
2426 begin
2429 begin
2430 if StrEqu(mIds[f], idname) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
2432 if StrEqu(mMaxName, idname) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
2436 // has value?
2438 begin
2440 begin
2441 if (Length(mMaxName) > 0) then raise Exception.Create(Format('duplicate max field ''%s'' in enum/bitset ''%s''', [idname, mName]));
2444 end
2445 else
2446 begin
2452 // append it?
2454 begin
2455 // fix maxvalue
2457 begin
2464 // next cv
2466 begin
2475 // add max field
2477 begin
2486 // ////////////////////////////////////////////////////////////////////////// //
2488 begin
2497 var
2500 begin
2515 begin
2522 var
2524 begin
2526 begin
2534 var
2536 begin
2538 begin
2546 var
2548 begin
2550 begin
2558 var
2563 // setup header links and type links
2565 var
2567 begin
2570 begin
2575 begin
2577 if (fld.mEBSType = nil) then raise Exception.Create(Format('field ''%s'' of type ''%s'' has no correcponding record definition', [fld.mName, fld.mEBSTypeName]));
2581 begin
2583 if (fld.mEBSType = nil) then raise Exception.Create(Format('field ''%s'' of type ''%s'' has no correcponding enum/bitset', [fld.mName, fld.mEBSTypeName]));
2584 if ((fld.mEBS = TDynField.TEBS.TEnum) <> (fld.mEBSType as TDynEBS).mIsEnum) then raise Exception.Create(Format('field ''%s'' of type ''%s'' enum/bitset type conflict', [fld.mName, fld.mEBSTypeName]));
2590 // setup default values
2592 var
2594 begin
2598 begin
2601 begin
2606 begin
2609 begin
2615 //writeln(eb.definition); writeln;
2616 continue;
2620 begin
2623 begin
2625 begin
2632 //writeln(dr.definition); writeln;
2633 continue;
2637 //writeln(dr.definition); writeln;
2638 if (findRecType(rec.name) <> nil) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
2639 if (hdr <> nil) and StrEqu(rec.name, hdr.name) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
2642 begin
2643 if (hdr <> nil) then begin rec.Free(); raise Exception.Create(Format('duplicate header record ''%s'' (previous is ''%s'')', [rec.name, hdr.name])); end;
2645 end
2646 else
2647 begin
2652 // put header record to top
2658 // setup header links and type links
2662 // setup default values
2668 // ////////////////////////////////////////////////////////////////////////// //
2670 var
2672 begin
2674 try
2681 finally
2688 var
2690 begin
2692 try
2698 finally
2705 var
2711 begin
2713 result += '// ////////////////////////////////////////////////////////////////////////// //'#10;
2716 result += #10#10'// ////////////////////////////////////////////////////////////////////////// //'#10;
2719 begin
2724 result += #10#10'// ////////////////////////////////////////////////////////////////////////// //'#10;
2730 begin
2734 begin
2740 begin