c6897578d7d6334e3f9f71f964e64753013b6338
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)
51 private
52 type
55 private
76 // default value
83 mEBSType: TObject; // either TDynRecord or TDynEBS; nil means "simple type"; nil for `TTrigData` too
85 // for binary parser
88 private
93 procedure parseDefaultValue (); // parse `mDefUnparsed` to `mDefSVal`, `mDefIVal`, `mDefIVal2`, `mDefRecRef`
97 public
114 // won't work for lists
119 public
127 //property list: TDynRecordArray read mRVal write mRVal;
144 // "value" header record contains TList fields, with name equal to record type
146 private
156 mHeaderRec: TDynRecord; // for "value" records this is header record with data, for "type" records this is header type record
158 private
168 protected
173 public
190 // find field with `TriggerType` type
193 public
207 private
216 private
225 public
231 // return empty string if not found
234 public
243 public
248 private
253 public
261 // creates new header record
264 // creates new header record
267 public
272 implementation
274 uses
275 SysUtils;
278 // ////////////////////////////////////////////////////////////////////////// //
280 begin
291 begin
298 begin
305 begin
339 var
341 begin
352 begin
355 end
356 else
357 begin
384 // won't work for lists
386 begin
404 begin
414 var
416 begin
418 try
420 finally
427 var
433 begin
435 begin
440 end
441 else
442 begin
448 try
455 finally
467 // default value should be parsed
469 begin
472 begin
474 raise Exception.Create(Format('field ''%s'' in record ''%s'' of record type ''%s'' is not set', [mName, mOwner.mId, mOwner.mName]));
484 // default value should be parsed
486 begin
499 begin
520 begin
529 TEBS.TBitSet: begin result += ' bitset '; if mBitSetUnique then result += 'unique '; result += mEBSTypeName; end;
533 begin
534 if (mType = TType.TPoint) then begin if (mAsT) then result += ' as txy' else result += ' as xy'; end
535 else if (mType = TType.TSize) then begin if (mAsT) then result += ' as twh' else result += ' as wh'; end;
543 var
560 begin
581 // field name
584 // field type
588 // fixed-size array?
590 begin
592 if (lmaxdim < 1) then raise Exception.Create(Format('invalid field ''%s'' array size', [fldname]));
597 begin
599 begin
600 if (fldofs >= 0) then raise Exception.Create(Format('duplicate field ''%s'' offset', [fldname]));
603 continue;
607 begin
613 continue;
617 begin
619 if (Length(fldrecname) <> 0) then raise Exception.Create(Format('field ''%s'' already typed as ''%s''', [fldname, fldrecname]));
621 continue;
625 begin
627 if (Length(fldrecname) <> 0) then raise Exception.Create(Format('field ''%s'' already typed as ''%s''', [fldname, fldrecname]));
630 continue;
634 begin
635 if hasdefStr or hasdefInt or hasdefId then raise Exception.Create(Format('field ''%s'' has duplicate default', [fldname]));
638 begin
643 begin
648 begin
652 else
655 continue;
659 begin
661 continue;
665 begin
667 continue;
670 if (pr.tokType <> pr.TTId) then raise Exception.Create(Format('field ''%s'' has something unexpected in definition', [fldname]));
672 if (Length(fldrecname) <> 0) then raise Exception.Create(Format('field ''%s'' already typed as ''%s''', [fldname, fldrecname]));
679 // create field
694 else raise Exception.Create(Format('field ''%s'' has invalid type ''%s''', [fldname, fldtype]));
696 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]));
698 begin
699 if (lmaxdim < 1) then raise Exception.Create(Format('field ''%s'' of type ''%s'' cannot be array', [fldname, fldtype]));
700 if (Length(fldrecname) > 0) then raise Exception.Create(Format('field ''%s'' of type ''%s'' cannot have another type', [fldname, fldtype]));
724 var
730 begin
734 begin
736 begin
737 // this must be triggerdata
739 begin
740 raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
742 // write triggerdata
744 if (buf = nil) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
745 try
748 begin
753 finally
757 exit;
759 // record reference
761 begin
762 // no ref, write -1
767 else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
769 exit;
778 else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
780 // find record number
782 if (f < 0) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' not found in record list', [mEBSTypeName, mName]));
783 if (f > maxv) then raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' has too big index', [mEBSTypeName, mName]));
788 else raise Exception.Create(Format('record reference type ''%s'' in field ''%s'' cannot be written', [mEBSTypeName, mName]));
790 exit;
799 begin
801 begin
803 end
804 else
805 begin
808 exit;
811 begin
812 if (mMaxDim = 0) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
814 begin
815 if (Length(mSVal) <> 1) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
817 end
818 else
819 begin
820 if (Length(mSVal) > mMaxDim) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
825 exit;
829 begin
830 // triggerdata array was processed earlier
831 if (mMaxDim >= 0) then Exception.Create(Format('byte array in field ''%s'' cannot be written', [mName]));
833 exit;
837 begin
838 if (mMaxDim >= 0) then raise Exception.Create(Format('short array in field ''%s'' cannot be written', [mName]));
840 exit;
844 begin
845 if (mMaxDim >= 0) then raise Exception.Create(Format('int array in field ''%s'' cannot be written', [mName]));
847 exit;
850 begin
854 begin
855 if (mMaxDim >= 0) then raise Exception.Create(Format('pos/size array in field ''%s'' cannot be written', [mName]));
858 exit;
861 begin
862 if (mMaxDim >= 0) then raise Exception.Create(Format('pos/size array in field ''%s'' cannot be written', [mName]));
865 exit;
868 begin
870 exit;
873 begin
875 exit;
883 var
887 begin
893 begin
895 begin
897 end
899 begin
901 end
902 else
903 begin
907 exit;
910 begin
911 //def := mOwner.mOwner;
912 //es := def.findEBSType(mEBSTypeName);
915 if (es = nil) or (not es.mIsEnum) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
917 begin
919 begin
922 exit;
925 raise Exception.Create(Format('value %d in record enum type ''%s'' for field ''%s'' not found', [mIVal, mEBSTypeName, mName]));
928 begin
929 //def := mOwner.mOwner;
930 //es := def.findEBSType(mEBSTypeName);
933 if (es = nil) or es.mIsEnum then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
934 // none?
936 begin
938 begin
940 begin
943 exit;
946 raise Exception.Create(Format('value %d in record bitset type ''%s'' for field ''%s'' not found', [0, mEBSTypeName, mName]));
948 // not none
952 begin
954 begin
957 begin
959 begin
963 break;
966 if not found then raise Exception.Create(Format('value %d in record bitset type ''%s'' for field ''%s'' not found', [mask, mEBSTypeName, mName]));
971 exit;
978 begin
980 exit;
983 begin
984 if (mMaxDim = 0) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
987 exit;
995 begin
997 exit;
1000 begin
1003 exit;
1007 begin
1009 exit;
1012 begin
1014 exit;
1017 begin
1019 exit;
1027 var
1034 begin
1038 begin
1039 // this must be triggerdata
1041 begin
1044 // find trigger definition
1046 if (tfld = nil) then raise Exception.Create(Format('triggerdata value for field ''%s'' in record ''%s'' without TriggerType field', [mName, rec.mName]));
1048 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]));
1051 try
1055 finally
1059 exit;
1060 end
1061 else
1062 begin
1063 // not a trigger data
1071 else raise Exception.Create(Format('invalid non-numeric type ''%s'' for field ''%s'' of record ''%s''', [getTypeName(mType), mName, mEBSTypeName]));
1076 exit;
1080 begin
1089 else raise Exception.Create(Format('invalid non-numeric type ''%s'' for field ''%s'' of record ''%s''', [getTypeName(mType), mName, mEBSTypeName]));
1093 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]));
1095 // build enum/bitfield values
1097 begin
1099 if (Length(mSVal) = 0) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' has invalid value %d', [mEBSTypeName, mName, mIVal]));
1100 end
1101 else
1102 begin
1103 // special for 'none'
1105 begin
1107 if (Length(mSVal) = 0) then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' has invalid value %d', [mEBSTypeName, mName, mIVal]));
1108 end
1109 else
1110 begin
1114 begin
1116 begin
1118 if (Length(s) = 0) then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' has invalid value %d', [mEBSTypeName, mName, mask]));
1126 //writeln('ebs <', es.mName, '>: ', mSVal);
1128 exit;
1135 begin
1141 exit;
1144 begin
1146 begin
1148 end
1149 else
1150 begin
1153 try
1158 begin
1163 finally
1168 exit;
1177 begin
1179 exit;
1182 begin
1186 exit;
1189 begin
1193 exit;
1196 begin
1198 exit;
1201 begin
1203 exit;
1214 begin
1216 if (mIVal < min) or (mIVal > max) then raise Exception.Create(Format('invalid %s value for field ''%s''', [getTypeName(mType), mName]));
1220 var
1225 begin
1226 // if this field should contain struct, convert type and parse struct
1230 begin
1231 // ugly hack. sorry.
1233 begin
1236 begin
1237 // '{}'
1240 end
1241 else
1242 begin
1244 // find trigger definition
1246 if (tfld = nil) then raise Exception.Create(Format('triggerdata value for field ''%s'' in record ''%s'' without ''type'' field', [mName, rec.mName]));
1248 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]));
1251 //writeln(rc.definition);
1252 try
1256 finally
1262 exit;
1264 // other record types
1266 begin
1268 begin
1270 end
1271 else
1272 begin
1274 if (rec = nil) then raise Exception.Create(Format('record ''%s'' (%s) value for field ''%s'' not found', [pr.tokStr, mEBSTypeName, mName]));
1280 exit;
1281 end
1283 begin
1284 //rec := mOwner.mOwner.findRecType(mEBSTypeName); // find in mapdef
1287 if (rec = nil) then raise Exception.Create(Format('record type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1295 exit;
1300 begin
1301 //es := mOwner.mOwner.findEBSType(mEBSTypeName); // find in mapdef
1304 if (es = nil) or (not es.mIsEnum) then raise Exception.Create(Format('record enum type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1306 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]));
1309 //writeln('ENUM ', mEBSName, '; element <', mSVal, '> with value ', mIVal);
1312 exit;
1315 begin
1316 //es := mOwner.mOwner.findEBSType(mEBSTypeName); // find in mapdef
1319 if (es = nil) or es.mIsEnum then raise Exception.Create(Format('record bitset type ''%s'' for field ''%s'' not found', [mEBSTypeName, mName]));
1322 begin
1324 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]));
1328 if mBitSetUnique then raise Exception.Create(Format('record bitset of type ''%s'' for field ''%s'' expects only one value', [tk, mEBSTypeName, mName]));
1329 //pr.expectDelim('|');
1334 exit;
1341 begin
1347 exit;
1350 begin
1351 if (mMaxDim = 0) then raise Exception.Create(Format('invalid string size definition for field ''%s''', [mName]));
1354 begin
1355 // single char
1356 if (Length(mSVal) <> 1) then raise Exception.Create(Format('invalid string size for field ''%s''', [mName]));
1359 end
1360 else
1361 begin
1362 // string
1363 if (Length(mSVal) > mMaxDim) then raise Exception.Create(Format('invalid string size for field ''%s''', [mName]));
1367 exit;
1370 begin
1373 exit;
1376 begin
1379 exit;
1382 begin
1385 exit;
1388 begin
1391 exit;
1394 begin
1397 exit;
1400 begin
1403 exit;
1406 begin
1410 exit;
1414 begin
1418 begin
1419 if (mIVal < 0) or (mIVal > 32767) then raise Exception.Create(Format('invalid %s value for field ''%s''', [getTypeName(mType), mName]));
1423 begin
1424 if (mIVal2 < 0) or (mIVal2 > 32767) then raise Exception.Create(Format('invalid %s value for field ''%s''', [getTypeName(mType), mName]));
1429 exit;
1432 begin
1434 exit;
1437 begin
1439 exit;
1447 // ////////////////////////////////////////////////////////////////////////// //
1449 begin
1450 if (pr = nil) then raise Exception.Create('cannot create record type without type definition');
1464 begin
1475 begin
1486 begin
1489 begin
1498 begin
1504 var
1506 begin
1513 begin
1519 var
1521 begin
1529 var
1532 begin
1540 begin
1553 var
1556 begin
1559 // find record data
1562 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]));
1563 // find by id
1565 begin
1567 begin
1571 // alas
1575 function TDynRecord.findRecordNumByType (const atypename: AnsiString; rc: TDynRecord): Integer;
1576 var
1579 begin
1581 // find record data
1584 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]));
1585 // find by ref
1587 begin
1589 begin
1593 // alas
1598 var
1600 begin
1601 // find record data
1604 begin
1605 // first record
1610 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]));
1611 // append
1618 var
1620 begin
1626 begin
1634 var
1637 begin
1639 begin
1651 var
1654 begin
1656 begin
1659 begin
1661 begin
1665 if isForTrig[tdn] then raise Exception.Create(Format('duplicate trigdata ''%s'' trigtype ''%s''', [mName, tdn]));
1669 end
1670 else
1671 begin
1677 end
1678 else
1679 begin
1684 begin
1687 begin
1688 if (mSize > 0) then raise Exception.Create(Format('duplicate `size` in record ''%s''', [mName]));
1690 if (mSize < 1) then raise Exception.Create(Format('invalid record ''%s'' size: %d', [mName, mSize]));
1692 continue;
1695 begin
1696 if (mBinBlock >= 0) then raise Exception.Create(Format('duplicate `binblock` in record ''%s''', [mName]));
1698 if (mBinBlock < 1) then raise Exception.Create(Format('invalid record ''%s'' binblock: %d', [mName, mBinBlock]));
1699 continue;
1705 // load fields
1707 begin
1709 if hasByName(fld.name) then begin fld.Free(); raise Exception.Create(Format('duplicate field ''%s''', [fld.name])); end;
1710 // append
1713 // done with field
1720 var
1722 begin
1724 begin
1725 // trigger data
1728 begin
1731 begin
1736 end
1737 else
1738 begin
1741 end
1742 else
1743 begin
1744 // record
1751 begin
1761 var
1773 var
1776 begin
1777 //writeln('*** rec: ', rec.mName, '.', rec.mId, ' (', rec.mFields.count, ')');
1779 begin
1781 begin
1783 continue;
1788 if (rt = nil) then raise Exception.Create(Format('record of type ''%s'' with id ''%s'' links to inexistant record of type ''%s'' with id ''%d''', [rec.mName, rec.mId, fld.mEBSTypeName, fld.mRecRefId]));
1789 //writeln(' ', rec.mName, '.', rec.mId, ':', fld.mName, ' -> ', rt.mName, '.', rt.mId, ' (', fld.mEBSTypeName, '.', fld.mRecRefId, ')');
1795 begin
1796 //writeln(' ', fld.mName);
1801 begin
1804 try
1806 begin
1807 // parse map file as sequence of blocks
1811 // parse blocks
1813 begin
1819 if (bsize < 0) or (bsize > $1fffffff) then raise Exception.Create(Format('block of type %d has invalid size %d', [btype, bsize]));
1820 if loaded[btype] then raise Exception.Create(Format('block of type %d already loaded', [btype]));
1822 // find record type for this block
1825 if (rect = nil) then raise Exception.Create(Format('block of type %d has no corresponding record', [btype]));
1827 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]));
1828 // header?
1830 begin
1831 if (bsize <> mSize) then raise Exception.Create(Format('header block of type %d has invalid number of records', [btype]));
1836 end
1837 else
1838 begin
1839 // create list for this type
1844 begin
1848 begin
1855 //writeln('parsed ''', rec.mId, '''...');
1861 //st.position := st.position+bsize;
1863 // link fields
1865 begin
1869 exit;
1872 // read fields
1874 if (mSize < 1) then raise Exception.Create(Format('cannot read record of type ''%s'' with unknown size', [mName]));
1878 begin
1881 if (fld.mBinOfs >= st.size) then raise Exception.Create(Format('record of type ''%s'' has invalid field ''%s''', [fld.mName]));
1883 //writeln('parsing ''', mName, '.', fld.mName, '''...');
1886 finally
1894 var
1900 //f, c: Integer;
1903 begin
1905 begin
1906 if (mBinBlock < 1) then raise Exception.Create('cannot write binary record without block number');
1909 end
1910 else
1911 begin
1914 try
1919 // write normal fields
1921 begin
1922 // record list?
1926 if (fld.mBinOfs >= bufsz) then raise Exception.Create('binary value offset is outside of the buffer');
1928 //writeln('writing field <', fld.mName, '>');
1932 // write block with normal fields
1934 begin
1935 //writeln('writing header...');
1936 // signature and version
1947 // write other blocks, if any
1949 begin
1950 // calculate blkmax
1953 begin
1954 // record list?
1956 begin
1964 // write blocks
1966 begin
1970 begin
1971 // record list?
1973 begin
1982 // flush block
1984 begin
1995 // write end marker
2000 finally
2008 var
2011 begin
2013 begin
2020 try
2022 begin
2023 // record list?
2025 begin
2028 begin
2030 begin
2036 continue;
2043 finally
2052 var
2055 begin
2056 if (mOwner = nil) then raise Exception.Create(Format('can''t parse record ''%s'' value without owner', [mName]));
2058 // not a header?
2060 begin
2061 // id?
2063 end
2064 else
2065 begin
2069 //writeln('parsing record <', mName, '>');
2072 begin
2074 //writeln('<', mName, '.', pr.tokStr, '>');
2076 // records
2078 begin
2079 // add records with this type (if any)
2082 begin
2085 try
2089 begin
2092 begin
2094 begin
2095 if (Length(rv.mId) > 0) and (CompareText(rv.mId, rec.mId) = 0) then raise Exception.Create(Format('duplicate thing ''%s'' in record ''%s''', [fld.mName, mName]));
2101 finally
2104 continue;
2108 // fields
2111 begin
2112 if fld.defined then raise Exception.Create(Format('duplicate field ''%s'' in record ''%s''', [fld.mName, mName]));
2113 if fld.internal then raise Exception.Create(Format('internal field ''%s'' in record ''%s''', [fld.mName, mName]));
2116 continue;
2119 // something is wrong
2123 // fix field defaults
2125 //writeln('done parsing record <', mName, '>');
2129 // ////////////////////////////////////////////////////////////////////////// //
2131 begin
2138 begin
2145 begin
2156 begin
2159 begin
2168 begin
2174 var
2176 begin
2183 var
2185 begin
2189 // fields
2192 begin
2196 begin
2200 end
2201 else
2202 begin
2207 // max field
2214 var
2216 begin
2218 begin
2226 var
2232 begin
2241 begin
2244 begin
2245 if (CompareText(mIds[f], idname) = 0) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
2247 if (CompareText(mMaxName, idname) = 0) then raise Exception.Create(Format('duplicate field ''%s'' in enum/bitset ''%s''', [idname, mName]));
2251 // has value?
2253 begin
2255 begin
2256 if (Length(mMaxName) > 0) then raise Exception.Create(Format('duplicate max field ''%s'' in enum/bitset ''%s''', [idname, mName]));
2259 end
2260 else
2261 begin
2267 // append it?
2269 begin
2270 // fix maxvalue
2272 begin
2279 // next cv
2281 begin
2290 // add max field
2292 begin
2301 // ////////////////////////////////////////////////////////////////////////// //
2303 begin
2312 var
2315 begin
2330 begin
2337 var
2339 begin
2341 begin
2349 var
2351 begin
2353 begin
2361 var
2363 begin
2365 begin
2373 var
2378 // setup header links and type links
2380 var
2382 begin
2385 begin
2390 begin
2392 if (fld.mEBSType = nil) then raise Exception.Create(Format('field ''%s'' of type ''%s'' has no correcponding record definition', [fld.mName, fld.mEBSTypeName]));
2396 begin
2398 if (fld.mEBSType = nil) then raise Exception.Create(Format('field ''%s'' of type ''%s'' has no correcponding enum/bitset', [fld.mName, fld.mEBSTypeName]));
2399 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]));
2405 // setup default values
2407 var
2409 begin
2413 begin
2416 begin
2421 begin
2424 begin
2430 //writeln(eb.definition); writeln;
2431 continue;
2435 begin
2438 begin
2440 begin
2447 //writeln(dr.definition); writeln;
2448 continue;
2452 //writeln(dr.definition); writeln;
2453 if (findRecType(rec.name) <> nil) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
2454 if (hdr <> nil) and (CompareText(rec.name, hdr.name) = 0) then begin rec.Free(); raise Exception.Create(Format('duplicate record ''%s''', [rec.name])); end;
2457 begin
2458 if (hdr <> nil) then begin rec.Free(); raise Exception.Create(Format('duplicate header record ''%s'' (previous is ''%s'')', [rec.name, hdr.name])); end;
2460 end
2461 else
2462 begin
2467 // put header record to top
2473 // setup header links and type links
2477 // setup default values
2483 // ////////////////////////////////////////////////////////////////////////// //
2485 var
2487 begin
2489 try
2497 begin
2506 var
2508 begin
2510 try
2517 begin