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
73 mAsMonsterId: Boolean; // special hack for triggers: monster record number+1 in binary (so 0 means "none")
74 // default value
81 mEBSType: TObject; // either TDynRecord or TDynEBS; nil means "simple type"; nil for `TTrigData` too
83 // for binary parser
86 private
91 procedure parseDefaultValue (); // parse `mDefUnparsed` to `mDefSVal`, `mDefIVal`, `mDefIVal2`, `mDefRecRef`
95 public
113 // won't work for lists
118 public
140 // "value" header record contains TList fields, with name equal to record type
142 private
152 mHeaderRec: TDynRecord; // for "value" records this is header record with data, for "type" records this is header type record
154 private
164 protected
169 public
187 // find field with `TriggerType` type
190 // number of records of the given instance
193 public
208 private
217 private
226 public
233 // return empty string if not found
236 public
245 public
250 private
255 public
265 // creates new header record
268 // creates new header record
271 public
276 {$IF DEFINED(D2D_DYNREC_PROFILER)}
278 {$ENDIF}
281 implementation
283 uses
288 // ////////////////////////////////////////////////////////////////////////// //
292 // ////////////////////////////////////////////////////////////////////////// //
294 begin
305 begin
312 begin
319 begin
354 var
356 begin
367 begin
370 end
371 else
372 begin
400 // won't work for lists
402 begin
420 begin
430 var
432 begin
434 try
436 finally
443 var
449 begin
451 begin
456 end
457 else
458 begin
464 try
471 finally
483 // default value should be parsed
485 begin
488 begin
490 raise Exception.Create(Format('field ''%s'' in record ''%s'' of record type ''%s'' is not set', [mName, mOwner.mId, mOwner.mName]));
500 // default value should be parsed
502 begin
515 begin
536 begin
545 TEBS.TBitSet: begin result += ' bitset '; if mBitSetUnique then result += 'unique '; result += mEBSTypeName; end;
550 begin
551 if (mType = TType.TPoint) then begin if (mAsT) then result += ' as txy' else result += ' as xy'; end
552 else if (mType = TType.TSize) then begin if (mAsT) then result += ' as twh' else result += ' as wh'; end;
560 begin
564 TType.TChar: if (mMaxDim > 0) then result += formatstrf('Char%d;', [mMaxDim]) else result += 'Char;';
588 var
606 begin
637 begin
639 if (lmaxdim < 1) then raise Exception.Create(Format('invalid field ''%s'' array size', [fldname]));
641 end;
644 begin
646 begin
647 if (fldofs >= 0) then raise Exception.Create(Format('duplicate field ''%s'' offset', [fldname]));
650 continue;
654 begin
661 continue;
662 end;
665 begin
667 if (Length(fldrecname) <> 0) then raise Exception.Create(Format('field ''%s'' already typed as ''%s''', [fldname, fldrecname]));
669 continue;
673 begin
675 if (Length(fldrecname) <> 0) then raise Exception.Create(Format('field ''%s'' already typed as ''%s''', [fldname, fldrecname]));
678 continue;
682 begin
683 if hasdefStr or hasdefInt or hasdefId then raise Exception.Create(Format('field ''%s'' has duplicate default', [fldname]));
686 begin
691 begin
696 begin
700 else
703 continue;
707 begin
709 continue;
713 begin
715 continue;
718 if (pr.tokType <> pr.TTId) then raise Exception.Create(Format('field ''%s'' has something unexpected in definition', [fldname]));
720 if (Length(fldrecname) <> 0) then raise Exception.Create(Format('field ''%s'' already typed as ''%s''', [fldname, fldrecname]));
727 // create field
742 else raise Exception.Create(Format('field ''%s'' has invalid type ''%s''', [fldname, fldtype]));
744 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]));
746 begin
747 if (lmaxdim < 1) then raise Exception.Create(Format('field ''%s'' of type ''%s'' cannot be array', [fldname, fldtype]));
748 if (Length(fldrecname) > 0) then raise Exception.Create(Format('field ''%s'' of type ''%s'' cannot have another type', [fldname, fldtype]));
769 end;
773 var
779 begin
783 begin
785 begin
786 // this must be triggerdata
788 begin
789 raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
791 // write triggerdata
793 if (buf = nil) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
794 try
797 begin
802 finally
806 exit;
808 // record reference
816 else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
818 // find record number
820 begin
822 if (f < 0) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' not found in record list', [mEBSTypeName, mName]));
824 if (f > maxv) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' has too big index', [mEBSTypeName, mName]));
825 end
826 else
827 begin
834 else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
836 exit;
845 begin
847 begin
849 end
850 else
851 begin
854 exit;
857 begin
858 if (mMaxDim = 0) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
860 begin
861 if (Length(mSVal) <> 1) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
863 end
864 else
865 begin
866 if (Length(mSVal) > mMaxDim) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
871 exit;
875 begin
876 // triggerdata array was processed earlier
877 if (mMaxDim >= 0) then Exception.Create(Format('byte array in field ''%s'' cannot be written', [mName]));
879 exit;
883 begin
884 if (mMaxDim >= 0) then raise Exception.Create(Format('short array in field ''%s'' cannot be written', [mName]));
886 exit;
890 begin
891 if (mMaxDim >= 0) then raise Exception.Create(Format('int array in field ''%s'' cannot be written', [mName]));
893 exit;
896 begin
900 begin
901 if (mMaxDim >= 0) then raise Exception.Create(Format('pos/size array in field ''%s'' cannot be written', [mName]));
904 exit;
907 begin
908 if (mMaxDim >= 0) then raise Exception.Create(Format('pos/size array in field ''%s'' cannot be written', [mName]));
911 exit;
914 begin
916 exit;
919 begin
921 exit;
929 var
933 begin
939 begin
941 begin
943 end
945 begin
947 end
948 else
949 begin
953 exit;
956 begin
957 //def := mOwner.mOwner;
958 //es := def.findEBSType(mEBSTypeName);
961 if (es = nil) or (not es.mIsEnum) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
963 begin
965 begin
968 exit;
971 raise Exception.Create(Format('value %d in record enum type ''%s'' for field ''%s'' not found', [mIVal, mEBSTypeName, mName]));
974 begin
975 //def := mOwner.mOwner;
976 //es := def.findEBSType(mEBSTypeName);
979 if (es = nil) or es.mIsEnum then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
980 // none?
982 begin
984 begin
986 begin
989 exit;
992 raise Exception.Create(Format('value %d in record bitset type ''%s'' for field ''%s'' not found', [0, mEBSTypeName, mName]));
994 // not none
998 begin
1000 begin
1003 begin
1005 begin
1009 break;
1012 if not found then raise Exception.Create(Format('value %d in record bitset type ''%s'' for field ''%s'' not found', [mask, mEBSTypeName, mName]));
1017 exit;
1024 begin
1026 exit;
1029 begin
1030 if (mMaxDim = 0) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
1033 exit;
1041 begin
1043 exit;
1046 begin
1049 exit;
1053 begin
1055 exit;
1058 begin
1060 exit;
1063 begin
1065 exit;
1073 var
1080 begin
1084 begin
1085 // this must be triggerdata
1087 begin
1090 // find trigger definition
1092 if (tfld = nil) then raise Exception.Create(Format('triggerdata value for field ''%s'' in record ''%s'' without TriggerType field', [mName, rec.mName]));
1094 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]));
1097 try
1101 finally
1105 exit;
1106 end
1107 else
1108 begin
1109 // not a trigger data
1117 else raise Exception.Create(Format('invalid non-numeric type ''%s'' for field ''%s'' of record ''%s''', [getTypeName(mType), mName, mEBSTypeName]));
1123 exit;
1127 begin
1136 else raise Exception.Create(Format('invalid non-numeric type ''%s'' for field ''%s'' of record ''%s''', [getTypeName(mType), mName, mEBSTypeName]));
1140 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]));
1142 // build enum/bitfield values
1144 begin
1146 if (Length(mSVal) = 0) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' has invalid value %d', [mEBSTypeName, mName, mIVal]));
1147 end
1148 else
1149 begin
1150 // special for 'none'
1152 begin
1154 if (Length(mSVal) = 0) then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' has invalid value %d', [mEBSTypeName, mName, mIVal]));
1155 end
1156 else
1157 begin
1161 begin
1163 begin
1165 if (Length(s) = 0) then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' has invalid value %d', [mEBSTypeName, mName, mask]));
1173 //writeln('ebs <', es.mName, '>: ', mSVal);
1175 exit;
1182 begin
1188 exit;
1191 begin
1193 begin
1195 end
1196 else
1197 begin
1200 try
1205 begin
1210 finally
1215 exit;
1224 begin
1226 exit;
1229 begin
1233 exit;
1236 begin
1240 exit;
1243 begin
1245 exit;
1248 begin
1250 exit;
1261 begin
1263 if (mIVal < min) or (mIVal > max) then raise Exception.Create(Format('invalid %s value for field ''%s''', [getTypeName(mType), mName]));
1267 var
1273 begin
1274 // if this field should contain struct, convert type and parse struct
1278 begin
1279 // ugly hack. sorry.
1281 begin
1284 begin
1285 // '{}'
1288 end
1289 else
1290 begin
1292 // find trigger definition
1294 if (tfld = nil) then raise Exception.Create(Format('triggerdata value for field ''%s'' in record ''%s'' without ''type'' field', [mName, rec.mName]));
1296 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]));
1299 //writeln(rc.definition);
1300 try
1304 finally
1310 exit;
1312 // other record types
1314 begin
1316 begin
1318 end
1319 else
1320 begin
1322 if (rec = nil) then raise Exception.Create(Format('record ''%s'' (%s) value for field ''%s'' not found', [pr.tokStr, mEBSTypeName, mName]));
1328 exit;
1329 end
1331 begin
1332 //rec := mOwner.mOwner.findRecType(mEBSTypeName); // find in mapdef
1335 if (rec = nil) then raise Exception.Create(Format('record type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1343 exit;
1348 begin
1349 //es := mOwner.mOwner.findEBSType(mEBSTypeName); // find in mapdef
1352 if (es = nil) or (not es.mIsEnum) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1354 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]));
1357 //writeln('ENUM ', mEBSName, '; element <', mSVal, '> with value ', mIVal);
1360 exit;
1363 begin
1364 //es := mOwner.mOwner.findEBSType(mEBSTypeName); // find in mapdef
1367 if (es = nil) or es.mIsEnum then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1370 begin
1372 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]));
1376 if mBitSetUnique then raise Exception.Create(Format('record bitset of type ''%s'' for field ''%s'' expects only one value', [tk, mEBSTypeName, mName]));
1377 //pr.expectDelim('|');
1382 exit;
1389 begin
1395 exit;
1398 begin
1399 if (mMaxDim = 0) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
1402 begin
1403 // single char
1404 if (Length(mSVal) <> 1) then raise Exception.Create(Format('invalid string size for field ''%s''', [mName]));
1407 end
1408 else
1409 begin
1410 // string
1411 if (Length(mSVal) > mMaxDim) then raise Exception.Create(Format('invalid string size for field ''%s''', [mName]));
1415 exit;
1418 begin
1421 exit;
1424 begin
1427 exit;
1430 begin
1433 exit;
1436 begin
1439 exit;
1442 begin
1445 exit;
1448 begin
1451 exit;
1454 begin
1458 exit;
1462 begin
1466 begin
1467 if (mIVal < 0) or (mIVal > 32767) then raise Exception.Create(Format('invalid %s value for field ''%s''', [getTypeName(mType), mName]));
1471 begin
1472 if (mIVal2 < 0) or (mIVal2 > 32767) then raise Exception.Create(Format('invalid %s value for field ''%s''', [getTypeName(mType), mName]));
1477 exit;
1480 begin
1482 exit;
1485 begin
1487 exit;
1495 // ////////////////////////////////////////////////////////////////////////// //
1497 begin
1498 if (pr = nil) then raise Exception.Create('cannot create record type without type definition');
1512 begin
1523 begin
1534 begin
1537 begin
1546 begin
1552 var
1554 begin
1561 begin
1567 var
1569 begin
1577 var
1580 begin
1588 begin
1601 var
1604 begin
1607 // find record data
1610 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]));
1611 // find by id
1613 begin
1615 begin
1619 // alas
1623 function TDynRecord.findRecordNumByType (const atypename: AnsiString; rc: TDynRecord): Integer;
1624 var
1627 begin
1629 // find record data
1632 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]));
1633 // find by ref
1635 begin
1637 begin
1641 // alas
1646 var
1648 begin
1649 // find record data
1652 begin
1653 // first record
1658 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]));
1659 // append
1666 var
1668 begin
1674 begin
1682 var
1685 begin
1687 begin
1698 // number of records of the given instance
1700 var
1702 begin
1710 var
1713 begin
1715 begin
1718 begin
1720 begin
1724 if isForTrig[tdn] then raise Exception.Create(Format('duplicate trigdata ''%s'' trigtype ''%s''', [mName, tdn]));
1728 end
1729 else
1730 begin
1736 end
1737 else
1738 begin
1743 begin
1746 begin
1747 if (mSize > 0) then raise Exception.Create(Format('duplicate `size` in record ''%s''', [mName]));
1749 if (mSize < 1) then raise Exception.Create(Format('invalid record ''%s'' size: %d', [mName, mSize]));
1751 continue;
1754 begin
1755 if (mBinBlock >= 0) then raise Exception.Create(Format('duplicate `binblock` in record ''%s''', [mName]));
1757 if (mBinBlock < 1) then raise Exception.Create(Format('invalid record ''%s'' binblock: %d', [mName, mBinBlock]));
1758 continue;
1764 // load fields
1766 begin
1768 if hasByName(fld.name) then begin fld.Free(); raise Exception.Create(Format('duplicate field ''%s''', [fld.name])); end;
1769 // append
1772 // done with field
1779 var
1781 begin
1783 begin
1786 end
1787 else
1788 begin
1789 // record
1793 begin
1803 var
1805 begin
1807 begin
1808 // trigger data
1811 begin
1814 begin
1819 end
1820 else
1821 begin
1824 end
1825 else
1826 begin
1827 // record
1834 begin
1844 var
1856 var
1859 begin
1860 //writeln('*** rec: ', rec.mName, '.', rec.mId, ' (', rec.mFields.count, ')');
1862 begin
1864 begin
1866 continue;
1872 begin
1873 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);
1874 //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]));
1876 //writeln(' ', rec.mName, '.', rec.mId, ':', fld.mName, ' -> ', rt.mName, '.', rt.mId, ' (', fld.mEBSTypeName, '.', fld.mRecRefId, ')');
1882 begin
1883 //writeln(' ', fld.mName);
1888 begin
1891 try
1893 begin
1894 // parse map file as sequence of blocks
1898 // parse blocks
1900 begin
1906 if (bsize < 0) or (bsize > $1fffffff) then raise Exception.Create(Format('block of type %d has invalid size %d', [btype, bsize]));
1907 if loaded[btype] then raise Exception.Create(Format('block of type %d already loaded', [btype]));
1909 // find record type for this block
1912 if (rect = nil) then raise Exception.Create(Format('block of type %d has no corresponding record', [btype]));
1913 //writeln('found type ''', rec.mName, ''' for block type ', btype);
1914 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]));
1915 // header?
1917 begin
1918 if (bsize <> mSize) then raise Exception.Create(Format('header block of type %d has invalid number of records', [btype]));
1923 end
1924 else
1925 begin
1926 // create list for this type
1931 begin
1935 begin
1942 //writeln('parsed ''', rec.mId, '''...');
1948 //st.position := st.position+bsize;
1950 // link fields
1952 begin
1956 exit;
1959 // read fields
1961 if (mSize < 1) then raise Exception.Create(Format('cannot read record of type ''%s'' with unknown size', [mName]));
1965 begin
1968 if (fld.mBinOfs >= st.size) then raise Exception.Create(Format('record of type ''%s'' has invalid field ''%s''', [fld.mName]));
1970 //writeln('parsing ''', mName, '.', fld.mName, '''...');
1973 finally
1980 procedure TDynRecord.writeBinTo (st: TStream; trigbufsz: Integer=-1; onlyFields: Boolean=false);
1981 var
1987 //f, c: Integer;
1990 begin
1992 begin
1993 if (mBinBlock < 1) then raise Exception.Create('cannot write binary record without block number');
1996 end
1997 else
1998 begin
2001 try
2006 // write normal fields
2008 begin
2009 // record list?
2013 if (fld.mBinOfs >= bufsz) then raise Exception.Create('binary value offset is outside of the buffer');
2015 //writeln('writing field <', fld.mName, '>');
2019 // write block with normal fields
2021 begin
2022 //writeln('writing header...');
2023 // signature and version
2034 // write other blocks, if any
2036 begin
2037 // calculate blkmax
2040 begin
2041 // record list?
2043 begin
2051 // write blocks
2053 begin
2057 begin
2058 // record list?
2060 begin
2069 // flush block
2071 begin
2082 // write end marker
2087 finally
2095 var
2098 begin
2100 begin
2107 try
2109 begin
2110 // record list?
2112 begin
2115 begin
2117 begin
2123 continue;
2130 finally
2138 {$IF DEFINED(D2D_DYNREC_PROFILER)}
2139 var
2150 begin
2152 writeln('record cloning: ', profCloneRec div 1000, '.', profCloneRec mod 1000, ' milliseconds');
2153 writeln('findRecType : ', profFindRecType div 1000, '.', profFindRecType mod 1000, ' milliseconds');
2154 writeln('field[] : ', profFieldSearching div 1000, '.', profFieldSearching mod 1000, ' milliseconds');
2155 writeln('list dup check: ', profListDupChecking div 1000, '.', profListDupChecking mod 1000, ' milliseconds');
2156 writeln('addRecByType : ', profAddRecByType div 1000, '.', profAddRecByType mod 1000, ' milliseconds');
2157 writeln('field valparse: ', profFieldValParsing div 1000, '.', profFieldValParsing mod 1000, ' milliseconds');
2158 writeln('fix defaults : ', profFixDefaults div 1000, '.', profFixDefaults mod 1000, ' milliseconds');
2159 writeln('recvalparse : ', profRecValParse div 1000, '.', profRecValParse mod 1000, ' milliseconds');
2161 {$ENDIF}
2165 var
2169 {$IF DEFINED(D2D_DYNREC_PROFILER)}
2171 {$ENDIF}
2174 begin
2175 if (mOwner = nil) then raise Exception.Create(Format('can''t parse record ''%s'' value without owner', [mName]));
2179 // not a header?
2181 begin
2182 // id?
2184 end
2185 else
2186 begin
2191 try
2192 //writeln('parsing record <', mName, '>');
2195 begin
2197 //writeln('<', mName, '.', pr.tokStr, '>');
2199 // records
2201 begin
2202 // add records with this type (if any)
2207 begin
2212 try
2216 begin
2220 {$iF FALSE}
2222 begin
2225 begin
2226 if (Length(rv.mId) > 0) and StrEqu(rv.mId, rec.mId) then raise Exception.Create(Format('duplicate thing ''%s'' in record ''%s''', [fld.mName, mName]));
2230 {$ELSE}
2232 begin
2235 if ids.put(idtmp, 1) then raise Exception.Create(Format('duplicate thing ''%s'' in record ''%s''', [fld.mName, mName]));
2238 {$ENDIF}
2244 finally
2247 continue;
2251 // fields
2256 begin
2257 if fld.defined then raise Exception.Create(Format('duplicate field ''%s'' in record ''%s''', [fld.mName, mName]));
2258 if fld.internal then raise Exception.Create(Format('internal field ''%s'' in record ''%s''', [fld.mName, mName]));
2263 continue;
2266 // something is wrong
2270 // fix field defaults
2274 //writeln('done parsing record <', mName, '>');
2275 //{$IF DEFINED(D2D_DYNREC_PROFILER)}writeln('stall: ', curTimeMicro()-stall);{$ENDIF}
2277 finally
2283 // ////////////////////////////////////////////////////////////////////////// //
2285 begin
2292 begin
2299 begin
2310 begin
2313 begin
2322 begin
2328 var
2330 begin
2337 var
2339 begin
2343 // fields
2346 begin
2350 begin
2354 end
2355 else
2356 begin
2361 // max field
2368 var
2370 begin
2372 // fields
2374 begin
2381 var
2383 begin
2385 begin
2393 var
2399 begin
2408 begin
2411 begin
2412 if StrEqu(mIds[f], idname) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
2414 if StrEqu(mMaxName, idname) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
2418 // has value?
2420 begin
2422 begin
2423 if (Length(mMaxName) > 0) then raise Exception.Create(Format('duplicate max field ''%s'' in enum/bitset ''%s''', [idname, mName]));
2426 end
2427 else
2428 begin
2434 // append it?
2436 begin
2437 // fix maxvalue
2439 begin
2446 // next cv
2448 begin
2457 // add max field
2459 begin
2468 // ////////////////////////////////////////////////////////////////////////// //
2470 begin
2479 var
2482 begin
2497 begin
2504 var
2506 begin
2508 begin
2516 var
2518 begin
2520 begin
2528 var
2530 begin
2532 begin
2540 var
2545 // setup header links and type links
2547 var
2549 begin
2552 begin
2557 begin
2559 if (fld.mEBSType = nil) then raise Exception.Create(Format('field ''%s'' of type ''%s'' has no correcponding record definition', [fld.mName, fld.mEBSTypeName]));
2563 begin
2565 if (fld.mEBSType = nil) then raise Exception.Create(Format('field ''%s'' of type ''%s'' has no correcponding enum/bitset', [fld.mName, fld.mEBSTypeName]));
2566 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]));
2572 // setup default values
2574 var
2576 begin
2580 begin
2583 begin
2588 begin
2591 begin
2597 //writeln(eb.definition); writeln;
2598 continue;
2602 begin
2605 begin
2607 begin
2614 //writeln(dr.definition); writeln;
2615 continue;
2619 //writeln(dr.definition); writeln;
2620 if (findRecType(rec.name) <> nil) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
2621 if (hdr <> nil) and StrEqu(rec.name, hdr.name) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
2624 begin
2625 if (hdr <> nil) then begin rec.Free(); raise Exception.Create(Format('duplicate header record ''%s'' (previous is ''%s'')', [rec.name, hdr.name])); end;
2627 end
2628 else
2629 begin
2634 // put header record to top
2640 // setup header links and type links
2644 // setup default values
2650 // ////////////////////////////////////////////////////////////////////////// //
2652 var
2654 begin
2656 try
2663 finally
2670 var
2672 begin
2674 try
2680 finally
2687 var
2693 begin
2695 result += '// ////////////////////////////////////////////////////////////////////////// //'#10;
2698 result += #10#10'// ////////////////////////////////////////////////////////////////////////// //'#10;
2701 begin
2706 result += #10#10'// ////////////////////////////////////////////////////////////////////////// //'#10;
2712 begin
2716 begin
2722 begin