1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1999
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
59 #include "morkParser.h"
63 #include "morkBuilder.h"
71 #include "morkStore.h"
75 #include "morkTable.h"
90 #ifndef _MORKATOMSPACE_
91 #include "morkAtomSpace.h"
94 #ifndef _MORKROWSPACE_
95 #include "morkRowSpace.h"
98 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789
100 // ````` ````` ````` ````` `````
101 // { ===== begin morkNode interface =====
103 /*public virtual*/ void
104 morkBuilder::CloseMorkNode(morkEnv
* ev
) // CloseBuilder() only if open
106 if ( this->IsOpenNode() )
109 this->CloseBuilder(ev
);
115 morkBuilder::~morkBuilder() // assert CloseBuilder() executed earlier
117 MORK_ASSERT(mBuilder_Store
==0);
118 MORK_ASSERT(mBuilder_Row
==0);
119 MORK_ASSERT(mBuilder_Table
==0);
120 MORK_ASSERT(mBuilder_Cell
==0);
121 MORK_ASSERT(mBuilder_RowSpace
==0);
122 MORK_ASSERT(mBuilder_AtomSpace
==0);
126 morkBuilder::morkBuilder(morkEnv
* ev
,
127 const morkUsage
& inUsage
, nsIMdbHeap
* ioHeap
,
128 morkStream
* ioStream
, mdb_count inBytesPerParseSegment
,
129 nsIMdbHeap
* ioSlotHeap
, morkStore
* ioStore
)
131 : morkParser(ev
, inUsage
, ioHeap
, ioStream
,
132 inBytesPerParseSegment
, ioSlotHeap
)
134 , mBuilder_Store( 0 )
136 , mBuilder_Table( 0 )
140 , mBuilder_RowSpace( 0 )
141 , mBuilder_AtomSpace( 0 )
143 , mBuilder_OidAtomSpace( 0 )
144 , mBuilder_ScopeAtomSpace( 0 )
146 , mBuilder_PortForm( 0 )
147 , mBuilder_PortRowScope( (mork_scope
) 'r' )
148 , mBuilder_PortAtomScope( (mork_scope
) 'v' )
150 , mBuilder_TableForm( 0 )
151 , mBuilder_TableRowScope( (mork_scope
) 'r' )
152 , mBuilder_TableAtomScope( (mork_scope
) 'v' )
153 , mBuilder_TableKind( 0 )
155 , mBuilder_TablePriority( morkPriority_kLo
)
156 , mBuilder_TableIsUnique( morkBool_kFalse
)
157 , mBuilder_TableIsVerbose( morkBool_kFalse
)
158 , mBuilder_TablePadByte( 0 )
160 , mBuilder_RowForm( 0 )
161 , mBuilder_RowRowScope( (mork_scope
) 'r' )
162 , mBuilder_RowAtomScope( (mork_scope
) 'v' )
164 , mBuilder_CellForm( 0 )
165 , mBuilder_CellAtomScope( (mork_scope
) 'v' )
167 , mBuilder_DictForm( 0 )
168 , mBuilder_DictAtomScope( (mork_scope
) 'v' )
170 , mBuilder_MetaTokenSlot( 0 )
172 , mBuilder_DoCutRow( morkBool_kFalse
)
173 , mBuilder_DoCutCell( morkBool_kFalse
)
174 , mBuilder_CellsVecFill( 0 )
180 morkStore::SlotWeakStore(ioStore
, ev
, &mBuilder_Store
);
182 mNode_Derived
= morkDerived_kBuilder
;
185 ev
->NilPointerError();
190 /*public non-poly*/ void
191 morkBuilder::CloseBuilder(morkEnv
* ev
) // called by CloseMorkNode();
195 if ( this->IsNode() )
199 mBuilder_MetaTokenSlot
= 0;
201 morkTable::SlotStrongTable((morkTable
*) 0, ev
, &mBuilder_Table
);
202 morkStore::SlotWeakStore((morkStore
*) 0, ev
, &mBuilder_Store
);
204 morkRowSpace::SlotStrongRowSpace((morkRowSpace
*) 0, ev
,
207 morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace
*) 0, ev
,
208 &mBuilder_AtomSpace
);
210 morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace
*) 0, ev
,
211 &mBuilder_OidAtomSpace
);
213 morkAtomSpace::SlotStrongAtomSpace((morkAtomSpace
*) 0, ev
,
214 &mBuilder_ScopeAtomSpace
);
215 this->CloseParser(ev
);
219 this->NonNodeError(ev
);
222 ev
->NilPointerError();
225 // } ===== end morkNode methods =====
226 // ````` ````` ````` ````` `````
229 morkBuilder::NonBuilderTypeError(morkEnv
* ev
)
231 ev
->NewError("non morkBuilder");
235 morkBuilder::NilBuilderCellError(morkEnv
* ev
)
237 ev
->NewError("nil mBuilder_Cell");
241 morkBuilder::NilBuilderRowError(morkEnv
* ev
)
243 ev
->NewError("nil mBuilder_Row");
247 morkBuilder::NilBuilderTableError(morkEnv
* ev
)
249 ev
->NewError("nil mBuilder_Table");
253 morkBuilder::NonColumnSpaceScopeError(morkEnv
* ev
)
255 ev
->NewError("column space != 'c'");
259 morkBuilder::LogGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
,
262 MORK_USED_2(inGlitch
,inKind
);
263 ev
->NewWarning("parsing glitch");
267 morkBuilder::MidToYarn(morkEnv
* ev
,
268 const morkMid
& inMid
, // typically an alias to concat with strings
270 // The parser might ask that some aliases be turned into yarns, so they
271 // can be concatenated into longer blobs under some circumstances. This
272 // is an alternative to using a long and complex callback for many parts
273 // for a single cell value.
275 mBuilder_Store
->MidToYarn(ev
, inMid
, outYarn
);
279 morkBuilder::OnNewPort(morkEnv
* ev
, const morkPlace
& inPlace
)
280 // mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
281 // mp:PortItem ::= mp:Content | mp:Group | OnPortGlitch
282 // mp:Content ::= mp:PortRow | mp:Dict | mp:Table | mp:Row
284 MORK_USED_2(ev
,inPlace
);
285 // mParser_InPort = morkBool_kTrue;
286 mBuilder_PortForm
= 0;
287 mBuilder_PortRowScope
= (mork_scope
) 'r';
288 mBuilder_PortAtomScope
= (mork_scope
) 'v';
292 morkBuilder::OnPortGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
)
294 this->LogGlitch(ev
, inGlitch
, "port");
298 morkBuilder::OnPortEnd(morkEnv
* ev
, const morkSpan
& inSpan
)
299 // mp:Start ::= OnNewPort mp:PortItem* OnPortEnd
301 MORK_USED_2(ev
,inSpan
);
302 // ev->StubMethodOnlyError();
304 // mParser_InPort = morkBool_kFalse;
308 morkBuilder::OnNewGroup(morkEnv
* ev
, const morkPlace
& inPlace
, mork_gid inGid
)
310 MORK_USED_1(inPlace
);
311 // mParser_InGroup = morkBool_kTrue;
312 mork_pos startPos
= inPlace
.mPlace_Pos
;
314 morkStore
* store
= mBuilder_Store
;
317 if ( inGid
>= store
->mStore_CommitGroupIdentity
)
318 store
->mStore_CommitGroupIdentity
= inGid
+ 1;
320 if ( !store
->mStore_FirstCommitGroupPos
)
321 store
->mStore_FirstCommitGroupPos
= startPos
;
322 else if ( !store
->mStore_SecondCommitGroupPos
)
323 store
->mStore_SecondCommitGroupPos
= startPos
;
328 morkBuilder::OnGroupGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
)
330 this->LogGlitch(ev
, inGlitch
, "group");
334 morkBuilder::OnGroupCommitEnd(morkEnv
* ev
, const morkSpan
& inSpan
)
336 MORK_USED_2(ev
,inSpan
);
337 // mParser_InGroup = morkBool_kFalse;
338 // ev->StubMethodOnlyError();
342 morkBuilder::OnGroupAbortEnd(morkEnv
* ev
, const morkSpan
& inSpan
)
345 // mParser_InGroup = morkBool_kFalse;
346 ev
->StubMethodOnlyError();
350 morkBuilder::OnNewPortRow(morkEnv
* ev
, const morkPlace
& inPlace
,
351 const morkMid
& inMid
, mork_change inChange
)
353 MORK_USED_3(inMid
,inPlace
,inChange
);
354 // mParser_InPortRow = morkBool_kTrue;
355 ev
->StubMethodOnlyError();
359 morkBuilder::OnPortRowGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
)
361 this->LogGlitch(ev
, inGlitch
, "port row");
365 morkBuilder::OnPortRowEnd(morkEnv
* ev
, const morkSpan
& inSpan
)
368 // mParser_InPortRow = morkBool_kFalse;
369 ev
->StubMethodOnlyError();
373 morkBuilder::OnNewTable(morkEnv
* ev
, const morkPlace
& inPlace
,
374 const morkMid
& inMid
, mork_bool inCutAllRows
)
375 // mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
376 // mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch
377 // mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd
378 // mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
379 // mp:MetaItem ::= mp:Cell | OnMetaGlitch
381 MORK_USED_1(inPlace
);
382 // mParser_InTable = morkBool_kTrue;
383 mBuilder_TableForm
= mBuilder_PortForm
;
384 mBuilder_TableRowScope
= mBuilder_PortRowScope
;
385 mBuilder_TableAtomScope
= mBuilder_PortAtomScope
;
386 mBuilder_TableKind
= morkStore_kNoneToken
;
388 mBuilder_TablePriority
= morkPriority_kLo
;
389 mBuilder_TableIsUnique
= morkBool_kFalse
;
390 mBuilder_TableIsVerbose
= morkBool_kFalse
;
392 morkTable
* table
= mBuilder_Store
->MidToTable(ev
, inMid
);
393 morkTable::SlotStrongTable(table
, ev
, &mBuilder_Table
);
396 if ( table
->mTable_RowSpace
)
397 mBuilder_TableRowScope
= table
->mTable_RowSpace
->SpaceScope();
400 table
->CutAllRows(ev
);
405 morkBuilder::OnTableGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
)
407 this->LogGlitch(ev
, inGlitch
, "table");
411 morkBuilder::OnTableEnd(morkEnv
* ev
, const morkSpan
& inSpan
)
412 // mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
415 // mParser_InTable = morkBool_kFalse;
416 if ( mBuilder_Table
)
418 mBuilder_Table
->mTable_Priority
= mBuilder_TablePriority
;
420 if ( mBuilder_TableIsUnique
)
421 mBuilder_Table
->SetTableUnique();
423 if ( mBuilder_TableIsVerbose
)
424 mBuilder_Table
->SetTableVerbose();
426 morkTable::SlotStrongTable((morkTable
*) 0, ev
, &mBuilder_Table
);
429 this->NilBuilderTableError(ev
);
435 mBuilder_TablePriority
= morkPriority_kLo
;
436 mBuilder_TableIsUnique
= morkBool_kFalse
;
437 mBuilder_TableIsVerbose
= morkBool_kFalse
;
439 if ( mBuilder_TableKind
== morkStore_kNoneToken
)
440 ev
->NewError("missing table kind");
442 mBuilder_CellAtomScope
= mBuilder_RowAtomScope
=
443 mBuilder_TableAtomScope
= mBuilder_PortAtomScope
;
445 mBuilder_DoCutCell
= morkBool_kFalse
;
446 mBuilder_DoCutRow
= morkBool_kFalse
;
450 morkBuilder::OnNewMeta(morkEnv
* ev
, const morkPlace
& inPlace
)
451 // mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
452 // mp:MetaItem ::= mp:Cell | OnMetaGlitch
453 // mp:Cell ::= OnMinusCell? OnNewCell mp:CellItem? OnCellEnd
454 // mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
455 // mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
457 MORK_USED_2(ev
,inPlace
);
458 // mParser_InMeta = morkBool_kTrue;
463 morkBuilder::OnMetaGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
)
465 this->LogGlitch(ev
, inGlitch
, "meta");
469 morkBuilder::OnMetaEnd(morkEnv
* ev
, const morkSpan
& inSpan
)
470 // mp:Meta ::= OnNewMeta mp:MetaItem* OnMetaEnd
472 MORK_USED_2(ev
,inSpan
);
473 // mParser_InMeta = morkBool_kFalse;
477 morkBuilder::OnMinusRow(morkEnv
* ev
)
480 mBuilder_DoCutRow
= morkBool_kTrue
;
484 morkBuilder::OnNewRow(morkEnv
* ev
, const morkPlace
& inPlace
,
485 const morkMid
& inMid
, mork_bool inCutAllCols
)
486 // mp:Table ::= OnNewTable mp:TableItem* OnTableEnd
487 // mp:TableItem ::= mp:Row | mp:MetaTable | OnTableGlitch
488 // mp:MetaTable ::= OnNewMeta mp:MetaItem* mp:Row OnMetaEnd
489 // mp:Row ::= OnMinusRow? OnNewRow mp:RowItem* OnRowEnd
490 // mp:RowItem ::= mp:Cell | mp:Meta | OnRowGlitch
491 // mp:Cell ::= OnMinusCell? OnNewCell mp:CellItem? OnCellEnd
492 // mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
493 // mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
495 MORK_USED_1(inPlace
);
496 // mParser_InRow = morkBool_kTrue;
498 mBuilder_CellForm
= mBuilder_RowForm
= mBuilder_TableForm
;
499 mBuilder_CellAtomScope
= mBuilder_RowAtomScope
= mBuilder_TableAtomScope
;
500 mBuilder_RowRowScope
= mBuilder_TableRowScope
;
501 morkStore
* store
= mBuilder_Store
;
503 if ( !inMid
.mMid_Buf
&& !inMid
.mMid_Oid
.mOid_Scope
)
506 mid
.mMid_Oid
.mOid_Scope
= mBuilder_RowRowScope
;
507 mBuilder_Row
= store
->MidToRow(ev
, mid
);
511 mBuilder_Row
= store
->MidToRow(ev
, inMid
);
513 morkRow
* row
= mBuilder_Row
;
514 if ( row
&& inCutAllCols
)
516 row
->CutAllColumns(ev
);
519 morkTable
* table
= mBuilder_Table
;
524 if ( mParser_InMeta
)
526 morkRow
* metaRow
= table
->mTable_MetaRow
;
529 table
->mTable_MetaRow
= row
;
530 table
->mTable_MetaRowOid
= row
->mRow_Oid
;
531 row
->AddRowGcUse(ev
);
533 else if ( metaRow
!= row
) // not identical?
534 ev
->NewError("duplicate table meta row");
538 if ( mBuilder_DoCutRow
)
539 table
->CutRow(ev
, row
);
541 table
->AddRow(ev
, row
);
545 // else // it is now okay to have rows outside a table:
546 // this->NilBuilderTableError(ev);
548 mBuilder_DoCutRow
= morkBool_kFalse
;
552 morkBuilder::OnRowPos(morkEnv
* ev
, mork_pos inRowPos
)
554 if ( mBuilder_Row
&& mBuilder_Table
&& !mParser_InMeta
)
556 mork_pos hintFromPos
= 0; // best hint when we don't know position
557 mBuilder_Table
->MoveRow(ev
, mBuilder_Row
, hintFromPos
, inRowPos
);
562 morkBuilder::OnRowGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
)
564 this->LogGlitch(ev
, inGlitch
, "row");
568 morkBuilder::FlushBuilderCells(morkEnv
* ev
)
572 morkPool
* pool
= mBuilder_Store
->StorePool();
573 morkCell
* cells
= mBuilder_CellsVec
;
574 mork_fill fill
= mBuilder_CellsVecFill
;
575 mBuilder_Row
->TakeCells(ev
, cells
, fill
, mBuilder_Store
);
577 morkCell
* end
= cells
+ fill
;
578 --cells
; // prepare for preincrement
579 while ( ++cells
< end
)
581 if ( cells
->mCell_Atom
)
582 cells
->SetAtom(ev
, (morkAtom
*) 0, pool
);
584 mBuilder_CellsVecFill
= 0;
587 this->NilBuilderRowError(ev
);
591 morkBuilder::OnRowEnd(morkEnv
* ev
, const morkSpan
& inSpan
)
592 // mp:Row ::= OnMinusRow? OnNewRow mp:RowItem* OnRowEnd
595 // mParser_InRow = morkBool_kFalse;
598 this->FlushBuilderCells(ev
);
601 this->NilBuilderRowError(ev
);
606 mBuilder_DoCutCell
= morkBool_kFalse
;
607 mBuilder_DoCutRow
= morkBool_kFalse
;
611 morkBuilder::OnNewDict(morkEnv
* ev
, const morkPlace
& inPlace
)
612 // mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
613 // mp:DictItem ::= OnAlias | OnAliasGlitch | mp:Meta | OnDictGlitch
615 MORK_USED_2(ev
,inPlace
);
616 // mParser_InDict = morkBool_kTrue;
618 mBuilder_CellForm
= mBuilder_DictForm
= mBuilder_PortForm
;
619 mBuilder_CellAtomScope
= mBuilder_DictAtomScope
= mBuilder_PortAtomScope
;
623 morkBuilder::OnDictGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
)
625 this->LogGlitch(ev
, inGlitch
, "dict");
629 morkBuilder::OnDictEnd(morkEnv
* ev
, const morkSpan
& inSpan
)
630 // mp:Dict ::= OnNewDict mp:DictItem* OnDictEnd
632 MORK_USED_2(ev
,inSpan
);
633 // mParser_InDict = morkBool_kFalse;
635 mBuilder_DictForm
= 0;
636 mBuilder_DictAtomScope
= 0;
640 morkBuilder::OnAlias(morkEnv
* ev
, const morkSpan
& inSpan
,
641 const morkMid
& inMid
)
644 if ( mParser_InDict
)
646 morkMid mid
= inMid
; // local copy for modification
647 mid
.mMid_Oid
.mOid_Scope
= mBuilder_DictAtomScope
;
648 mBuilder_Store
->AddAlias(ev
, mid
, mBuilder_DictForm
);
651 ev
->NewError("alias not in dict");
655 morkBuilder::OnAliasGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
)
657 this->LogGlitch(ev
, inGlitch
, "alias");
662 morkBuilder::AddBuilderCell(morkEnv
* ev
,
663 const morkMid
& inMid
, mork_change inChange
)
665 morkCell
* outCell
= 0;
666 mork_column column
= inMid
.mMid_Oid
.mOid_Id
;
670 if ( mBuilder_CellsVecFill
>= morkBuilder_kCellsVecSize
)
671 this->FlushBuilderCells(ev
);
674 if ( mBuilder_CellsVecFill
< morkBuilder_kCellsVecSize
)
676 mork_fill indx
= mBuilder_CellsVecFill
++;
677 outCell
= mBuilder_CellsVec
+ indx
;
678 outCell
->SetColumnAndChange(column
, inChange
);
679 outCell
->mCell_Atom
= 0;
682 ev
->NewError("out of builder cells");
689 morkBuilder::OnMinusCell(morkEnv
* ev
)
692 mBuilder_DoCutCell
= morkBool_kTrue
;
696 morkBuilder::OnNewCell(morkEnv
* ev
, const morkPlace
& inPlace
,
697 const morkMid
* inMid
, const morkBuf
* inBuf
)
698 // Exactly one of inMid and inBuf is nil, and the other is non-nil.
699 // When hex ID syntax is used for a column, then inMid is not nil, and
700 // when a naked string names a column, then inBuf is not nil.
702 // mp:Cell ::= OnMinusCell? OnNewCell mp:CellItem? OnCellEnd
703 // mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
704 // mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
706 MORK_USED_1(inPlace
);
707 // mParser_InCell = morkBool_kTrue;
709 mork_change cellChange
= ( mBuilder_DoCutCell
)?
710 morkChange_kCut
: morkChange_kAdd
;
712 mBuilder_DoCutCell
= morkBool_kFalse
;
714 mBuilder_CellAtomScope
= mBuilder_RowAtomScope
;
716 mBuilder_Cell
= 0; // nil until determined for a row
717 morkStore
* store
= mBuilder_Store
;
718 mork_scope scope
= morkStore_kColumnSpaceScope
;
719 morkMid tempMid
; // space for local and modifiable cell mid
720 morkMid
* cellMid
= &tempMid
; // default to local if inMid==0
722 if ( inMid
) // mid parameter is actually provided?
724 *cellMid
= *inMid
; // bitwise copy for modifiable local mid
726 if ( !cellMid
->mMid_Oid
.mOid_Scope
)
728 if ( cellMid
->mMid_Buf
)
730 scope
= store
->BufToToken(ev
, cellMid
->mMid_Buf
);
731 cellMid
->mMid_Buf
= 0; // don't do scope lookup again
732 ev
->NewWarning("column mids need column scope");
734 cellMid
->mMid_Oid
.mOid_Scope
= scope
;
737 else if ( inBuf
) // buf points to naked column string name?
740 cellMid
->mMid_Oid
.mOid_Id
= store
->BufToToken(ev
, inBuf
);
741 cellMid
->mMid_Oid
.mOid_Scope
= scope
; // kColumnSpaceScope
744 ev
->NilPointerError(); // either inMid or inBuf must be non-nil
746 mork_column column
= cellMid
->mMid_Oid
.mOid_Id
;
748 if ( mBuilder_Row
&& ev
->Good() ) // this cell must be inside a row
750 // mBuilder_Cell = this->AddBuilderCell(ev, *cellMid, cellChange);
752 if ( mBuilder_CellsVecFill
>= morkBuilder_kCellsVecSize
)
753 this->FlushBuilderCells(ev
);
756 if ( mBuilder_CellsVecFill
< morkBuilder_kCellsVecSize
)
758 mork_fill ix
= mBuilder_CellsVecFill
++;
759 morkCell
* cell
= mBuilder_CellsVec
+ ix
;
760 cell
->SetColumnAndChange(column
, cellChange
);
762 cell
->mCell_Atom
= 0;
763 mBuilder_Cell
= cell
;
766 ev
->NewError("out of builder cells");
770 else if ( mParser_InMeta
&& ev
->Good() ) // cell is in metainfo structure?
772 if ( scope
== morkStore_kColumnSpaceScope
)
774 if ( mParser_InTable
) // metainfo for table?
776 if ( column
== morkStore_kKindColumn
)
777 mBuilder_MetaTokenSlot
= &mBuilder_TableKind
;
778 else if ( column
== morkStore_kStatusColumn
)
779 mBuilder_MetaTokenSlot
= &mBuilder_TableStatus
;
780 else if ( column
== morkStore_kRowScopeColumn
)
781 mBuilder_MetaTokenSlot
= &mBuilder_TableRowScope
;
782 else if ( column
== morkStore_kAtomScopeColumn
)
783 mBuilder_MetaTokenSlot
= &mBuilder_TableAtomScope
;
784 else if ( column
== morkStore_kFormColumn
)
785 mBuilder_MetaTokenSlot
= &mBuilder_TableForm
;
787 else if ( mParser_InDict
) // metainfo for dict?
789 if ( column
== morkStore_kAtomScopeColumn
)
790 mBuilder_MetaTokenSlot
= &mBuilder_DictAtomScope
;
791 else if ( column
== morkStore_kFormColumn
)
792 mBuilder_MetaTokenSlot
= &mBuilder_DictForm
;
794 else if ( mParser_InRow
) // metainfo for row?
796 if ( column
== morkStore_kAtomScopeColumn
)
797 mBuilder_MetaTokenSlot
= &mBuilder_RowAtomScope
;
798 else if ( column
== morkStore_kRowScopeColumn
)
799 mBuilder_MetaTokenSlot
= &mBuilder_RowRowScope
;
800 else if ( column
== morkStore_kFormColumn
)
801 mBuilder_MetaTokenSlot
= &mBuilder_RowForm
;
805 ev
->NewWarning("expected column scope");
810 morkBuilder::OnCellGlitch(morkEnv
* ev
, const morkGlitch
& inGlitch
)
812 this->LogGlitch(ev
, inGlitch
, "cell");
816 morkBuilder::OnCellForm(morkEnv
* ev
, mork_cscode inCharsetFormat
)
818 morkCell
* cell
= mBuilder_Cell
;
821 mBuilder_CellForm
= inCharsetFormat
;
824 this->NilBuilderCellError(ev
);
828 morkBuilder::OnCellEnd(morkEnv
* ev
, const morkSpan
& inSpan
)
829 // mp:Cell ::= OnMinusCell? OnNewCell mp:CellItem? OnCellEnd
831 MORK_USED_2(ev
,inSpan
);
832 // mParser_InCell = morkBool_kFalse;
834 mBuilder_MetaTokenSlot
= 0;
835 mBuilder_CellAtomScope
= mBuilder_RowAtomScope
;
839 morkBuilder::OnValue(morkEnv
* ev
, const morkSpan
& inSpan
,
840 const morkBuf
& inBuf
)
841 // mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
842 // mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
845 morkStore
* store
= mBuilder_Store
;
846 morkCell
* cell
= mBuilder_Cell
;
850 yarn
.mYarn_Buf
= inBuf
.mBuf_Body
;
851 yarn
.mYarn_Fill
= yarn
.mYarn_Size
= inBuf
.mBuf_Fill
;
853 yarn
.mYarn_Form
= mBuilder_CellForm
;
855 morkAtom
* atom
= store
->YarnToAtom(ev
, &yarn
, PR_TRUE
/* create */);
856 cell
->SetAtom(ev
, atom
, store
->StorePool());
858 else if ( mParser_InMeta
)
860 mork_token
* metaSlot
= mBuilder_MetaTokenSlot
;
863 if ( metaSlot
== &mBuilder_TableStatus
) // table status?
865 if ( mParser_InTable
&& mBuilder_Table
)
867 const char* body
= (const char*) inBuf
.mBuf_Body
;
868 mork_fill bufFill
= inBuf
.mBuf_Fill
;
869 if ( body
&& bufFill
)
871 const char* bodyEnd
= body
+ bufFill
;
872 while ( body
< bodyEnd
)
887 mBuilder_TablePriority
= (mork_priority
) ( c
- '0' );
892 mBuilder_TableIsUnique
= morkBool_kTrue
;
897 mBuilder_TableIsVerbose
= morkBool_kTrue
;
906 mork_token token
= store
->BufToToken(ev
, &inBuf
);
910 if ( metaSlot
== &mBuilder_TableKind
) // table kind?
912 if ( mParser_InTable
&& mBuilder_Table
)
913 mBuilder_Table
->mTable_Kind
= token
;
920 this->NilBuilderCellError(ev
);
924 morkBuilder::OnValueMid(morkEnv
* ev
, const morkSpan
& inSpan
,
925 const morkMid
& inMid
)
926 // mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
927 // mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
930 morkStore
* store
= mBuilder_Store
;
931 morkCell
* cell
= mBuilder_Cell
;
933 morkMid valMid
; // local mid for modifications
934 mdbOid
* valOid
= &valMid
.mMid_Oid
; // ref to oid inside mid
935 *valOid
= inMid
.mMid_Oid
; // bitwise copy inMid's oid
937 if ( inMid
.mMid_Buf
)
939 if ( !valOid
->mOid_Scope
)
940 store
->MidToOid(ev
, inMid
, valOid
);
942 else if ( !valOid
->mOid_Scope
)
943 valOid
->mOid_Scope
= mBuilder_CellAtomScope
;
947 morkBookAtom
* atom
= store
->MidToAtom(ev
, valMid
);
949 cell
->SetAtom(ev
, atom
, store
->StorePool());
951 ev
->NewError("undefined cell value alias");
953 else if ( mParser_InMeta
)
955 mork_token
* metaSlot
= mBuilder_MetaTokenSlot
;
958 mork_scope valScope
= valOid
->mOid_Scope
;
959 if ( !valScope
|| valScope
== morkStore_kColumnSpaceScope
)
961 if ( ev
->Good() && valMid
.HasSomeId() )
963 *metaSlot
= valOid
->mOid_Id
;
964 if ( metaSlot
== &mBuilder_TableKind
) // table kind?
966 if ( mParser_InTable
&& mBuilder_Table
)
968 mBuilder_Table
->mTable_Kind
= valOid
->mOid_Id
;
971 ev
->NewWarning("mBuilder_TableKind not in table");
973 else if ( metaSlot
== &mBuilder_TableStatus
) // table status?
975 if ( mParser_InTable
&& mBuilder_Table
)
980 ev
->NewWarning("mBuilder_TableStatus not in table");
985 this->NonColumnSpaceScopeError(ev
);
989 this->NilBuilderCellError(ev
);
993 morkBuilder::OnRowMid(morkEnv
* ev
, const morkSpan
& inSpan
,
994 const morkMid
& inMid
)
995 // mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
996 // mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
999 morkStore
* store
= mBuilder_Store
;
1000 morkCell
* cell
= mBuilder_Cell
;
1003 mdbOid rowOid
= inMid
.mMid_Oid
;
1004 if ( inMid
.mMid_Buf
)
1006 if ( !rowOid
.mOid_Scope
)
1007 store
->MidToOid(ev
, inMid
, &rowOid
);
1009 else if ( !rowOid
.mOid_Scope
)
1010 rowOid
.mOid_Scope
= mBuilder_RowRowScope
;
1014 morkPool
* pool
= store
->StorePool();
1015 morkAtom
* atom
= pool
->NewRowOidAtom(ev
, rowOid
, &store
->mStore_Zone
);
1018 cell
->SetAtom(ev
, atom
, pool
);
1019 morkRow
* row
= store
->OidToRow(ev
, &rowOid
);
1020 if ( row
) // found or created such a row?
1021 row
->AddRowGcUse(ev
);
1026 this->NilBuilderCellError(ev
);
1030 morkBuilder::OnTableMid(morkEnv
* ev
, const morkSpan
& inSpan
,
1031 const morkMid
& inMid
)
1032 // mp:CellItem ::= mp:Slot | OnCellForm | OnCellGlitch
1033 // mp:Slot ::= OnValue | OnValueMid | OnRowMid | OnTableMid
1035 MORK_USED_1(inSpan
);
1036 morkStore
* store
= mBuilder_Store
;
1037 morkCell
* cell
= mBuilder_Cell
;
1040 mdbOid tableOid
= inMid
.mMid_Oid
;
1041 if ( inMid
.mMid_Buf
)
1043 if ( !tableOid
.mOid_Scope
)
1044 store
->MidToOid(ev
, inMid
, &tableOid
);
1046 else if ( !tableOid
.mOid_Scope
)
1047 tableOid
.mOid_Scope
= mBuilder_RowRowScope
;
1051 morkPool
* pool
= store
->StorePool();
1052 morkAtom
* atom
= pool
->NewTableOidAtom(ev
, tableOid
, &store
->mStore_Zone
);
1055 cell
->SetAtom(ev
, atom
, pool
);
1056 morkTable
* table
= store
->OidToTable(ev
, &tableOid
,
1057 /*optionalMetaRowOid*/ (mdbOid
*) 0);
1058 if ( table
) // found or created such a table?
1059 table
->AddTableGcUse(ev
);
1064 this->NilBuilderCellError(ev
);
1068 //3456789_123456789_123456789_123456789_123456789_123456789_123456789_123456789