1 /*===========================================================================
2 *
3 * PUBLIC DOMAIN NOTICE
4 * National Center for Biotechnology Information
5 *
6 * This software/database is a "United States Government Work" under the
7 * terms of the United States Copyright Act. It was written as part of
8 * the author's official duties as a United States Government employee and
9 * thus cannot be copyrighted. This software/database is freely available
10 * to the public for use. The National Library of Medicine and the U.S.
11 * Government have not placed any restriction on its use or reproduction.
12 *
13 * Although all reasonable efforts have been taken to ensure the accuracy
14 * and reliability of the software and data, the NLM and the U.S.
15 * Government do not and cannot warrant the performance or results that
16 * may be obtained by using this software or data. The NLM and the U.S.
17 * Government disclaim all warranties, express or implied, including
18 * warranties of performance, merchantability or fitness for any particular
19 * purpose.
20 *
21 * Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26
27 #include <vdb/extern.h>
28
29 #include "schema-priv.h"
30 #include "schema-parse.h"
31 #include "schema-expr.h"
32 #include "schema-dump.h"
33
34 #include <klib/symbol.h>
35 #include <klib/symtab.h>
36 #include <klib/rc.h>
37 #include <sysalloc.h>
38
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <string.h>
42 #include <ctype.h>
43 #include <os-native.h>
44 #include <assert.h>
45
46
47 /*--------------------------------------------------------------------------
48 * SExpression
49 */
50 #if SLVL >= 1
SExpressionWhack(const SExpression * cself)51 void SExpressionWhack ( const SExpression *cself )
52 {
53 SExpression *self = ( SExpression* ) cself;
54 if ( self != NULL && atomic32_dec_and_test ( & self -> refcount ) )
55 {
56 switch ( self -> var )
57 {
58 case eTypeExpr:
59 {
60 STypeExpr *x = ( STypeExpr* ) self;
61 SExpressionWhack ( x -> dim );
62 break;
63 }
64 case eFuncExpr:
65 case eScriptExpr:
66 {
67 SFuncExpr *x = ( SFuncExpr* ) self;
68 VectorWhack ( & x -> schem, SExpressionVWhack, NULL );
69 VectorWhack ( & x -> pfact, SExpressionVWhack, NULL );
70 VectorWhack ( & x -> pfunc, SExpressionVWhack, NULL );
71 break;
72 }
73 case ePhysEncExpr:
74 {
75 SPhysEncExpr *x = ( SPhysEncExpr* ) self;
76 VectorWhack ( & x -> schem, SExpressionVWhack, NULL );
77 VectorWhack ( & x -> pfact, SExpressionVWhack, NULL );
78 break;
79 }
80 case eNegateExpr:
81 {
82 SUnaryExpr *x = ( SUnaryExpr* ) self;
83 SExpressionWhack ( x -> expr );
84 break;
85 }
86 case eCastExpr:
87 case eCondExpr:
88 {
89 SBinExpr *x = ( SBinExpr* ) self;
90 SExpressionWhack ( x -> left );
91 SExpressionWhack ( x -> right );
92 break;
93 }
94 case eVectorExpr:
95 {
96 SVectExpr *x = ( SVectExpr* ) self;
97 VectorWhack ( & x -> expr, SExpressionVWhack, NULL );
98 break;
99 }
100 case eMembExpr:
101 {
102 SMembExpr *x = ( SMembExpr* ) self;
103 SExpressionWhack ( x -> rowId );
104 break;
105 }
106 }
107
108 free ( self );
109 }
110 }
111
SExpressionVWhack(void * item,void * ignore)112 void CC SExpressionVWhack ( void *item, void *ignore )
113 {
114 SExpression *self = item;
115 SExpressionWhack ( self );
116 }
117 #endif
118
119 /* Mark
120 */
121 #if SLVL >= 1
SExpressionMark(void * item,void * data)122 void CC SExpressionMark ( void * item, void * data )
123 {
124 const SExpression * self = item;
125 const VSchema * schema = data;
126 if ( self != NULL ) switch ( self -> var )
127 {
128 case eTypeExpr:
129 STypeExprMark ( ( const STypeExpr* ) self, schema );
130 break;
131 case eConstExpr:
132 VSchemaTypeMark ( schema, ( ( const SConstExpr* ) self ) -> td . type_id );
133 break;
134 case eIndirectExpr:
135 case eParamExpr:
136 case eProdExpr:
137 case eFwdExpr:
138 case eFuncParamExpr:
139 case eColExpr:
140 case ePhysExpr:
141 SSymExprMark ( ( const SSymExpr* ) self, schema );
142 break;
143 case eFuncExpr:
144 case eScriptExpr:
145 SFuncExprMark ( ( const SFuncExpr* ) self, schema );
146 break;
147 case ePhysEncExpr:
148 SPhysEncExprMark ( ( const SPhysEncExpr* ) self, schema );
149 break;
150 case eNegateExpr:
151 SExpressionMark ( ( void * )( ( const SUnaryExpr* ) self ) -> expr, data );
152 break;
153 case eCastExpr:
154 case eCondExpr:
155 SExpressionMark ( ( void * )( ( const SBinExpr* ) self ) -> left, data );
156 SExpressionMark ( ( void * )( ( const SBinExpr* ) self ) -> right, data );
157 break;
158 case eVectorExpr:
159 VectorForEach ( & ( ( const SVectExpr* ) self ) -> expr, false,
160 SExpressionMark, data );
161 break;
162 case eMembExpr:
163 assert (false); //TODO SMembExprMark
164 break;
165 }
166 }
167 #endif
168
169 /* Dump
170 */
171 #if SLVL >= 1
SExpressionListDump(void * item,void * data)172 bool CC SExpressionListDump ( void *item, void *data )
173 {
174 SDumper *b = data;
175 const SExpression *self = ( const void* ) item;
176
177 SDumperSep ( b );
178 b -> rc = SExpressionDump ( self, b );
179 SDumperSepString ( b, SDumperMode ( b ) == sdmCompact ? "," : ", " );
180
181 return ( b -> rc != 0 ) ? true : false;
182 }
183
SExpressionBracketListDump(const Vector * expr,SDumper * b,const char * begin,const char * end)184 rc_t SExpressionBracketListDump ( const Vector *expr, SDumper *b,
185 const char *begin, const char *end )
186 {
187 SDumperSepString ( b, begin );
188 if ( VectorDoUntil ( expr, false, SExpressionListDump, b ) )
189 return b -> rc;
190 return SDumperPrint ( b, end );
191 }
192
193 static
STypeExprDump(const STypeExpr * self,SDumper * b)194 rc_t STypeExprDump ( const STypeExpr *self, SDumper *b )
195 {
196 rc_t rc;
197 if ( self -> fmt != NULL )
198 {
199 rc = SFormatDump ( self -> fmt, b );
200 if ( rc != 0 )
201 return rc;
202
203 if ( self -> dt == NULL && self -> ts == NULL && self -> id == NULL )
204 return 0;
205
206 rc = SDumperWrite ( b, "/", 1 );
207 if ( rc != 0 )
208 return rc;
209 }
210
211 if ( self -> dt != NULL )
212 rc = SDatatypeDump ( self -> dt, b );
213 else if ( self -> ts != NULL )
214 rc = STypesetDump ( self -> ts, b );
215 #if SLVL >= 3
216 else if ( self -> id != NULL )
217 rc = SIndirectTypeDump ( self -> id, b );
218 #endif
219 else
220 rc = SDumperWrite ( b, "NULL", 4 );
221
222 if ( rc == 0 )
223 {
224 if ( SDumperMode ( b ) == sdmCompact )
225 {
226 if ( self -> dim != NULL )
227 rc = SDumperPrint ( b, "[%E]", self -> dim );
228 else if ( self -> fd . td . dim == 0 )
229 rc = SDumperPrint ( b, "[*]" );
230 }
231 else
232 {
233 if ( self -> dim != NULL )
234 rc = SDumperPrint ( b, " [ %E ]", self -> dim );
235 else if ( self -> fd . td . dim == 0 )
236 rc = SDumperPrint ( b, " [ * ]" );
237 }
238 }
239
240 return rc;
241 }
242
243 static
SConstExprDump(const SConstExpr * self,SDumper * b)244 rc_t SConstExprDump ( const SConstExpr *self, SDumper *b )
245 {
246 rc_t rc = 0;
247 bool compact = SDumperMode ( b ) == sdmCompact ? true : false;
248 const SDatatype *dt = VSchemaFindTypeid ( b -> schema, self -> td . type_id );
249 uint32_t bits = dt -> size;
250 uint32_t i, dim = SDatatypeIntrinsicDim ( dt );
251 assert ( dim != 0 && ( bits % dim ) == 0 );
252 bits /= dim;
253 dim *= self -> td . dim;
254
255 /* open a vector expression */
256 if ( dt -> domain < ddAscii && dim > 1 )
257 {
258 rc = SDumperPrint ( b, compact ? "[" : "[ " );
259 if ( rc != 0 )
260 return rc;
261 }
262
263 SDumperSepString ( b, "" );
264
265 switch ( dt -> domain )
266 {
267 case ddBool:
268 for ( i = 0; i < dim; ++ i )
269 {
270 rc = SDumperPrint ( b, "\v%s", self -> u . b [ i ] ? "true" : "false" );
271 if ( rc != 0 )
272 return rc;
273 SDumperSepString ( b, compact ? "," : ", " );
274 }
275 break;
276 case ddUint:
277 switch ( bits )
278 {
279 case 8:
280 for ( i = 0; i < dim; ++ i )
281 {
282 rc = SDumperPrint ( b, "\v%u", self -> u . u8 [ i ] );
283 if ( rc != 0 )
284 return rc;
285 SDumperSepString ( b, compact ? "," : ", " );
286 }
287 break;
288 case 16:
289 for ( i = 0; i < dim; ++ i )
290 {
291 rc = SDumperPrint ( b, "\v%u", self -> u . u16 [ i ] );
292 if ( rc != 0 )
293 return rc;
294 SDumperSepString ( b, compact ? "," : ", " );
295 }
296 break;
297 case 32:
298 for ( i = 0; i < dim; ++ i )
299 {
300 rc = SDumperPrint ( b, "\v%u", self -> u . u32 [ i ] );
301 if ( rc != 0 )
302 return rc;
303 SDumperSepString ( b, compact ? "," : ", " );
304 }
305 break;
306 case 64:
307 for ( i = 0; i < dim; ++ i )
308 {
309 rc = SDumperPrint ( b, "\v%lu", self -> u . u64 [ i ] );
310 if ( rc != 0 )
311 return rc;
312 SDumperSepString ( b, compact ? "," : ", " );
313 }
314 break;
315 }
316 break;
317 case ddInt:
318 switch ( bits )
319 {
320 case 8:
321 for ( i = 0; i < dim; ++ i )
322 {
323 rc = SDumperPrint ( b, "\v%d", self -> u . i8 [ i ] );
324 if ( rc != 0 )
325 return rc;
326 SDumperSepString ( b, compact ? "," : ", " );
327 }
328 break;
329 case 16:
330 for ( i = 0; i < dim; ++ i )
331 {
332 rc = SDumperPrint ( b, "\v%d", self -> u . i16 [ i ] );
333 if ( rc != 0 )
334 return rc;
335 SDumperSepString ( b, compact ? "," : ", " );
336 }
337 break;
338 case 32:
339 for ( i = 0; i < dim; ++ i )
340 {
341 rc = SDumperPrint ( b, "\v%d", self -> u . i32 [ i ] );
342 if ( rc != 0 )
343 return rc;
344 SDumperSepString ( b, compact ? "," : ", " );
345 }
346 break;
347 case 64:
348 for ( i = 0; i < dim; ++ i )
349 {
350 rc = SDumperPrint ( b, "\v%ld", self -> u . i64 [ i ] );
351 if ( rc != 0 )
352 return rc;
353 SDumperSepString ( b, compact ? "," : ", " );
354 }
355 break;
356 }
357 break;
358 case ddFloat:
359 switch ( bits )
360 {
361 case 32:
362 for ( i = 0; i < dim; ++ i )
363 {
364 rc = SDumperPrint ( b, "\v%f", ( double ) self -> u . f32 [ i ] );
365 if ( rc != 0 )
366 return rc;
367 SDumperSepString ( b, compact ? "," : ", " );
368 }
369 break;
370 case 64:
371 for ( i = 0; i < dim; ++ i )
372 {
373 rc = SDumperPrint ( b, "\v%f", self -> u . f64 [ i ] );
374 if ( rc != 0 )
375 return rc;
376 SDumperSepString ( b, compact ? "," : ", " );
377 }
378 break;
379 }
380 break;
381 case ddAscii:
382 {
383 const char *end, *p;
384
385 rc = SDumperWrite ( b, "'", 1 );
386
387 do_ascii:
388 for ( p = self -> u . ascii, end = p + dim; rc == 0 && p < end; )
389 {
390 const char *start = p;
391 while ( p < end && isprint ( * p ) )
392 ++ p;
393 rc = SDumperWrite ( b, start, p - start );
394 if ( p == end )
395 break;
396
397 switch ( * p )
398 {
399 case '\n':
400 rc = SDumperWrite ( b, "\\n", 2 );
401 break;
402 case '\r':
403 rc = SDumperWrite ( b, "\\", 2 );
404 break;
405 case '\t':
406 rc = SDumperWrite ( b, "\\t", 2 );
407 break;
408 default:
409 rc = SDumperPrint ( b, "\\x%x%x", ( * ( uint8_t* ) p ) / 16, * p & 15 );
410 }
411 ++ p;
412 }
413 if ( rc == 0 )
414 rc = SDumperWrite ( b, "'", 1 );
415 return rc;
416 }
417 case ddUnicode:
418 {
419 rc = SDumperWrite ( b, "'", 1 );
420 if ( rc != 0 )
421 return rc;
422
423 if ( bits == 8 )
424 goto do_ascii;
425
426 for ( i = 0; i < dim; ++ i )
427 {
428 char buff [ 8 ];
429 uint32_t ch = ( bits == 16 ) ?
430 ( uint32_t ) self -> u . utf16 [ i ] :
431 self -> u . utf32 [ i ];
432
433 if ( ch >= 128 )
434 sprintf ( buff, "\\u%04x", ch );
435 else if ( isprint ( ( int ) ch ) )
436 buff [ 0 ] = ( char ) ch, buff [ 1 ] = 0;
437 else switch ( ch )
438 {
439 case '\n':
440 sprintf ( buff, "\\n" );
441 break;
442 case '\r':
443 sprintf ( buff, "\\r" );
444 break;
445 case '\t':
446 sprintf ( buff, "\\t" );
447 break;
448 default:
449 sprintf ( buff, "\\x%02x", ch );
450 }
451
452 rc = SDumperPrint ( b, buff );
453 if ( rc != 0 )
454 return rc;
455 }
456 if ( rc == 0 )
457 rc = SDumperWrite ( b, "'", 1 );
458 return rc;
459 }}
460
461 if ( rc == 0 && dim > 1 )
462 rc = SDumperPrint ( b, compact ? "]" : " ]" );
463
464 return rc;
465 }
466
467 #if SLVL >= 3
468 static
SFuncExprDump(const SFuncExpr * self,SDumper * b)469 rc_t SFuncExprDump ( const SFuncExpr *self, SDumper *b )
470 {
471 rc_t rc;
472 bool compact = SDumperMode ( b ) == sdmCompact ? true : false;
473
474 if ( VectorLength ( & self -> schem ) != 0 )
475 {
476 if ( compact )
477 rc = SExpressionBracketListDump ( & self -> schem, b, "<", ">" );
478 else
479 rc = SExpressionBracketListDump ( & self -> schem, b, "< ", " > " );
480 if ( rc != 0 )
481 return rc;
482 }
483
484 rc = SFunctionDump ( self -> func, b );
485 if ( rc != 0 )
486 return rc;
487
488 rc = SDumperVersion ( b, self -> version_requested ?
489 self -> version : self -> func -> version );
490 if ( rc != 0 )
491 return rc;
492
493 if ( VectorLength ( & self -> pfact ) != 0 )
494 {
495 if ( compact )
496 rc = SExpressionBracketListDump ( & self -> pfact, b, "<", ">" );
497 else
498 rc = SExpressionBracketListDump ( & self -> pfact, b, " < ", " >" );
499 if ( rc != 0 )
500 return rc;
501 }
502
503 if ( VectorLength ( & self -> pfunc ) == 0 )
504 rc = SDumperPrint ( b, compact ? "()" : " ()" );
505 else if ( compact )
506 rc = SExpressionBracketListDump ( & self -> pfunc, b, "(", ")" );
507 else
508 rc = SExpressionBracketListDump ( & self -> pfunc, b, " ( ", " )" );
509
510 return rc;
511 }
512 #endif
513
514 #if SLVL >= 7
515 static
SPhysEncExprDump(const SPhysEncExpr * self,SDumper * b)516 rc_t SPhysEncExprDump ( const SPhysEncExpr *self, SDumper *b )
517 {
518 rc_t rc;
519 bool compact = SDumperMode ( b ) == sdmCompact ? true : false;
520
521 if ( VectorLength ( & self -> schem ) != 0 )
522 {
523 if ( compact )
524 rc = SExpressionBracketListDump ( & self -> schem, b, "<", ">" );
525 else
526 rc = SExpressionBracketListDump ( & self -> schem, b, "< ", " > " );
527 if ( rc != 0 )
528 return rc;
529 }
530
531 rc = SPhysicalDump ( self -> phys, b );
532 if ( rc != 0 )
533 return rc;
534
535 if ( self -> version_requested )
536 rc = SDumperVersion ( b, self -> version );
537 else
538 rc = SDumperVersion ( b, self -> phys -> version );
539 if ( rc != 0 )
540 return rc;
541
542 if ( VectorLength ( & self -> pfact ) != 0 )
543 {
544 if ( compact )
545 rc = SExpressionBracketListDump ( & self -> pfact, b, "<", ">" );
546 else
547 rc = SExpressionBracketListDump ( & self -> pfact, b, " < ", " >" );
548 if ( rc != 0 )
549 return rc;
550 }
551
552 return rc;
553 }
554 #endif
555
SExpressionDump(const SExpression * self,SDumper * b)556 rc_t SExpressionDump ( const SExpression *self, SDumper *b )
557 {
558 bool compact = SDumperMode ( b ) == sdmCompact ? true : false;
559
560 if ( self == NULL )
561 return SDumperWrite ( b, "NULL", 4 );
562
563 switch ( self -> var )
564 {
565 case eTypeExpr:
566 return STypeExprDump ( ( const STypeExpr* ) self, b );
567 case eConstExpr:
568 return SConstExprDump ( ( const SConstExpr* ) self, b );
569 #if SLVL >= 3
570 case eIndirectExpr:
571 case eParamExpr:
572 case eProdExpr:
573 case eFwdExpr:
574 case eFuncParamExpr:
575 case eColExpr:
576 case ePhysExpr:
577 {
578 const SSymExpr *x = ( const SSymExpr* ) self;
579 if ( x -> alt )
580 return SDumperPrint ( b, "@%N", x -> _sym );
581 return KSymbolDump ( x -> _sym, b );
582 }
583 case eFuncExpr:
584 #if SLVL >= 4
585 case eScriptExpr:
586 #endif
587 return SFuncExprDump ( ( const SFuncExpr* ) self, b );
588 #endif
589 #if SLVL >= 7
590 case ePhysEncExpr:
591 return SPhysEncExprDump ( ( const SPhysEncExpr* ) self, b );
592 #endif
593 case eNegateExpr:
594 {
595 const SUnaryExpr *x = ( const SUnaryExpr* ) self;
596 return SDumperPrint ( b, "-%E", x -> expr );
597 }
598 case eCastExpr:
599 {
600 const SBinExpr *x = ( const SBinExpr* ) self;
601 return SDumperPrint ( b, compact ? "(%E)%E" : "( %E ) %E", x -> left, x -> right );
602 }
603 case eCondExpr:
604 {
605 const SBinExpr *x = ( const SBinExpr* ) self;
606 return SDumperPrint ( b, compact ? "%E|%E" : "%E | %E", x -> left, x -> right );
607 }
608 case eVectorExpr:
609 {
610 const SVectExpr *x = ( const SVectExpr* ) self;
611 if ( compact )
612 return SExpressionBracketListDump ( & x -> expr, b, "[", "]" );
613 return SExpressionBracketListDump ( & x -> expr, b, "[ ", " ]" );
614 }
615 case eMembExpr:
616 assert (false); //TODO: SMembExprDump
617 break;
618 }
619
620 return SDumperPrint ( b, "EXPR-UNKNOWN" );
621
622 }
623
SExpressionVDump(void * item,void * data)624 bool SExpressionVDump ( void *item, void *data )
625 {
626 SDumper *b = data;
627 const SExpression *self = ( const void* ) item;
628
629 b -> rc = SExpressionDump ( self, b );
630
631 return ( b -> rc != 0 ) ? true : false;
632 }
633 #endif /* SLVL >= 1 */
634
635
636 /*--------------------------------------------------------------------------
637 * STypeExpr
638 */
639
640 /* Mark
641 */
STypeExprMark(const STypeExpr * self,const VSchema * schema)642 void STypeExprMark ( const STypeExpr *self, const VSchema *schema )
643 {
644 if ( self -> fmt != NULL )
645 SFormatMark ( self -> fmt );
646 if ( self -> dt != NULL )
647 SDatatypeMark ( self -> dt );
648 if ( self -> ts != NULL )
649 STypesetMark ( self -> ts, schema );
650 if ( self -> dim )
651 SExpressionMark ( ( void * ) self -> dim, ( void * ) schema );
652 }
653
654
655 /*--------------------------------------------------------------------------
656 * SSymExpr
657 */
658
659 /* Make
660 * used when creating implicit expressions
661 */
SSymExprMake(const SExpression ** xp,const KSymbol * sym,uint32_t var)662 rc_t SSymExprMake ( const SExpression **xp, const KSymbol *sym, uint32_t var )
663 {
664 SSymExpr *x = malloc ( sizeof * x );
665 if ( x == NULL )
666 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
667
668 x -> dad . var = var;
669 atomic32_set ( & x -> dad . refcount, 1 );
670 x -> _sym = sym;
671 x -> alt = false;
672
673 * xp = & x -> dad;
674 return 0;
675 }
676
677 /* Mark
678 */
SSymExprMark(const SSymExpr * self,const VSchema * schema)679 void SSymExprMark ( const SSymExpr *self, const VSchema *schema )
680 {
681 switch ( self -> _sym -> type )
682 {
683 case eConstant:
684 SConstantMark ( self -> _sym -> u . obj );
685 break;
686 }
687 }
688
689
690 /*--------------------------------------------------------------------------
691 * SFuncExpr
692 */
693
694 /* Mark
695 */
SFuncExprMark(const SFuncExpr * self,const VSchema * schema)696 void SFuncExprMark ( const SFuncExpr *self, const VSchema *schema )
697 {
698 SFunctionMark ( ( void * )self -> func, ( void * )schema );
699 }
700
701
702 /*--------------------------------------------------------------------------
703 * SPhysEncExpr
704 */
705
706 /* ImplicitPhysEncExpr
707 * create expression object
708 */
VSchemaImplicitPhysEncExpr(VSchema * self,VTypedecl * td,const SExpression ** expr,const char * text,const char * ctx)709 rc_t VSchemaImplicitPhysEncExpr ( VSchema *self,
710 VTypedecl *td, const SExpression **expr, const char *text, const char *ctx )
711 {
712 KSymTable tbl;
713 rc_t rc = init_symtab ( & tbl, self );
714 if ( rc == 0 )
715 {
716 KToken t;
717 KTokenText tt;
718 KTokenSource src;
719
720 SchemaEnv env;
721 SchemaEnvInit ( & env, EXT_SCHEMA_LANG_VERSION );
722
723 KTokenTextInitCString ( & tt, text, ctx );
724 KTokenSourceInit ( & src, & tt );
725 next_token ( & tbl, & src, & t );
726
727 rc = phys_encoding_expr ( & tbl, & src, & t, & env, self, td, expr );
728
729 KSymTableWhack ( & tbl );
730 }
731 return rc;
732 }
733
734 /* Mark
735 */
SPhysEncExprMark(const SPhysEncExpr * self,const VSchema * schema)736 void SPhysEncExprMark ( const SPhysEncExpr *self, const VSchema *schema )
737 {
738 SPhysicalMark ( ( void * )self -> phys, ( void * )schema );
739 }
740
741
742 /*--------------------------------------------------------------------------
743 * VSchema
744 */
745
746 #if SLVL >= 1
747 static
const_vect_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SVectExpr ** xp)748 rc_t const_vect_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
749 const SchemaEnv *env, const VSchema *self, const SVectExpr **xp )
750 {
751 rc_t rc;
752 SVectExpr *x = malloc ( sizeof * x );
753 if ( x == NULL )
754 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
755
756 x -> dad . var = eVectorExpr;
757 atomic32_set ( & x -> dad . refcount, 1 );
758 VectorInit ( & x -> expr, 0, 16 );
759
760 do
761 {
762 SExpression *vx;
763 rc = const_expr ( tbl, src, next_token ( tbl, src, t ),
764 env, self, ( const SExpression** ) & vx );
765 if ( rc != 0 )
766 break;
767
768 if ( vx -> var == eVectorExpr )
769 {
770 SExpressionWhack ( vx );
771 rc = KTokenExpected ( t, klogErr, "scalar constant" );
772 break;
773 }
774
775 rc = VectorAppend ( & x -> expr, NULL, vx );
776 if ( rc != 0 )
777 {
778 SExpressionWhack ( vx );
779 break;
780 }
781 }
782 while ( t -> id == eComma );
783
784 if ( rc != 0 )
785 SExpressionWhack ( & x -> dad );
786 else
787 {
788 * xp = x;
789 rc = expect ( tbl, src, t, eRightSquare, "]", true );
790 }
791
792 return rc;
793 }
794 #endif
795
796 /*
797 * const-expr = <constname>
798 * | CONST-VALUE
799 */
800 #if SLVL >= 1
801 static
negate_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SExpression ** xp)802 rc_t negate_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
803 const SchemaEnv *env, const VSchema *self, const SExpression **xp )
804 {
805 rc_t rc = const_expr ( tbl, src, next_token ( tbl, src, t ), env, self, xp );
806 if ( rc == 0 )
807 {
808 SUnaryExpr *x;
809 SConstExpr *cx;
810 const SSymExpr *sx;
811 const SExpression *td;
812 const SDatatype *dt;
813
814 static atomic32_t s_I8_id;
815 static atomic32_t s_I16_id;
816 static atomic32_t s_I32_id;
817 static atomic32_t s_I64_id;
818
819 switch ( ( * xp ) -> var )
820 {
821 case eConstExpr:
822 cx = * ( SConstExpr** ) xp;
823 if ( cx -> td . dim < 2 )
824 {
825 dt = VSchemaFindTypeid ( self, cx -> td . type_id );
826 if ( dt != NULL ) switch ( dt -> domain )
827 {
828 case vtdUint:
829 switch ( dt -> size )
830 {
831 case 8:
832 cx -> td . type_id = VSchemaCacheIntrinsicTypeId ( self, & s_I8_id, "I8" );
833 break;
834 case 16:
835 cx -> td . type_id = VSchemaCacheIntrinsicTypeId ( self, & s_I16_id, "I16" );
836 break;
837 case 32:
838 cx -> td . type_id = VSchemaCacheIntrinsicTypeId ( self, & s_I32_id, "I32" );
839 break;
840 case 64:
841 cx -> td . type_id = VSchemaCacheIntrinsicTypeId ( self, & s_I64_id, "I64" );
842 break;
843 }
844 /* no break */
845 case vtdInt:
846 switch ( dt -> size )
847 {
848 case 8:
849 cx -> u . i8 [ 0 ] = - cx -> u . i8 [ 0 ];
850 return 0;
851 case 16:
852 cx -> u . i16 [ 0 ] = - cx -> u . i16 [ 0 ];
853 return 0;
854 case 32:
855 cx -> u . i32 [ 0 ] = - cx -> u . i32 [ 0 ];
856 return 0;
857 case 64:
858 cx -> u . i64 [ 0 ] = - cx -> u . i64 [ 0 ];
859 return 0;
860 }
861 break;
862 case vtdFloat:
863 switch ( dt -> size )
864 {
865 case 32:
866 cx -> u . f32 [ 0 ] = - cx -> u . f32 [ 0 ];
867 return 0;
868 case 64:
869 cx -> u . f64 [ 0 ] = - cx -> u . f64 [ 0 ];
870 return 0;
871 }
872 break;
873 }
874 }
875 break;
876
877 case eIndirectExpr:
878 /* if type is known, at least verify domain */
879 sx = * ( const SSymExpr** ) xp;
880 td = ( ( const SIndirectConst* ) sx -> _sym -> u . obj ) -> td;
881 if ( td != NULL )
882 {
883 const STypeExpr *tx = ( const STypeExpr* ) td;
884 if ( tx-> dad . var == eTypeExpr && tx -> resolved )
885 {
886 /* cannot have formats, but this is verified elsewhere */
887 if ( tx -> fd . fmt == 0 && tx -> fd . td . dim < 2 )
888 {
889 /* determine domain */
890 dt = VSchemaFindTypeid ( self, tx -> fd . td . type_id );
891 if ( dt != NULL ) switch ( dt -> domain )
892 {
893 case vtdUint:
894 KTokenExpected ( t, klogWarn, "signed integer" );
895 case vtdInt:
896 case vtdFloat:
897 goto introduce_negate_expr;
898 }
899 }
900 }
901
902 break;
903 }
904
905 introduce_negate_expr:
906 x = malloc ( sizeof * x );
907 if ( x == NULL )
908 {
909 SExpressionWhack ( & sx -> dad );
910 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
911 }
912
913 x -> dad . var = eNegateExpr;
914 atomic32_set ( & x -> dad . refcount, 1 );
915 x -> expr = & sx -> dad;
916 * xp = & x -> dad;
917 return 0;
918
919 case eNegateExpr:
920 /* double negate */
921 x = * ( SUnaryExpr** ) xp;
922 * xp = x -> expr;
923 free ( x );
924 return 0;
925
926 default:
927 SExpressionWhack ( * xp );
928 return KTokenExpected ( t, klogErr, "integer or floating point constant" );
929 }
930
931 rc = RC ( rcVDB, rcSchema, rcParsing, rcType, rcIncorrect );
932 KTokenRCExplain ( t, klogErr, rc );
933 }
934
935 return rc;
936 }
937
938 static
bool_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SConstExpr ** xp)939 rc_t bool_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
940 const SchemaEnv *env, const VSchema *self, const SConstExpr **xp )
941 {
942 static atomic32_t s_bool_id;
943
944 SConstExpr *x = malloc ( sizeof * x - sizeof x -> u + sizeof x -> u . b [ 0 ] );
945 if ( x == NULL )
946 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
947
948 assert ( t -> id == kw_true || t -> id == kw_false );
949 x -> u . b [ 0 ] = ( t -> id == kw_true );
950
951 x -> dad . var = eConstExpr;
952 atomic32_set ( & x -> dad . refcount, 1 );
953 x -> td . type_id = VSchemaCacheIntrinsicTypeId ( self, & s_bool_id, "bool" );
954 x -> td . dim = 1;
955
956 * xp = x;
957
958 next_token ( tbl, src, t );
959 return 0;
960 }
961
962 static
uint_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SConstExpr ** xp)963 rc_t uint_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
964 const SchemaEnv *env, const VSchema *self, const SConstExpr **xp )
965 {
966 rc_t rc;
967 static atomic32_t s_U64_id;
968
969 SConstExpr *x = malloc ( sizeof * x - sizeof x -> u + sizeof x -> u . u64 [ 0 ] );
970 if ( x == NULL )
971 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
972
973 rc = KTokenToU64 ( t, & x -> u . u64 [ 0 ] );
974 if ( rc != 0 )
975 {
976 free ( x );
977 return rc;
978 }
979
980 x -> dad . var = eConstExpr;
981 atomic32_set ( & x -> dad . refcount, 1 );
982 x -> td . type_id = VSchemaCacheIntrinsicTypeId ( self, & s_U64_id, "U64" );
983 x -> td . dim = 1;
984
985 * xp = x;
986
987 next_token ( tbl, src, t );
988 return 0;
989 }
990
991 static
float_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SConstExpr ** xp)992 rc_t float_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
993 const SchemaEnv *env, const VSchema *self, const SConstExpr **xp )
994 {
995 rc_t rc;
996 static atomic32_t s_F64_id;
997
998 SConstExpr *x = malloc ( sizeof * x - sizeof x -> u + sizeof x -> u . f64 [ 0 ] );
999 if ( x == NULL )
1000 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
1001
1002 rc = KTokenToF64 ( t, & x -> u . f64 [ 0 ] );
1003 if ( rc != 0 )
1004 {
1005 free ( x );
1006 return rc;
1007 }
1008
1009 x -> dad . var = eConstExpr;
1010 atomic32_set ( & x -> dad . refcount, 1 );
1011 x -> td . type_id = VSchemaCacheIntrinsicTypeId ( self, & s_F64_id, "F64" );
1012 x -> td . dim = 1;
1013
1014 * xp = x;
1015
1016 next_token ( tbl, src, t );
1017 return 0;
1018 }
1019
1020 static
string_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SConstExpr ** xp)1021 rc_t string_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
1022 const SchemaEnv *env, const VSchema *self, const SConstExpr **xp )
1023 {
1024 rc_t rc;
1025
1026 size_t size = t -> str . size + 1;
1027 SConstExpr *x = malloc ( sizeof * x - sizeof x -> u + size );
1028 if ( x == NULL )
1029 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
1030
1031 rc = KTokenToString ( t, x -> u . utf8, size, & size );
1032 if ( rc != 0 )
1033 {
1034 free ( x );
1035 return rc;
1036 }
1037
1038 x -> dad . var = eConstExpr;
1039 atomic32_set ( & x -> dad . refcount, 1 );
1040 x -> td . dim = ( uint32_t ) size;
1041
1042 if ( t -> id == eString || ( size_t ) string_len ( x -> u . utf8, size ) == size )
1043 {
1044 static atomic32_t s_ascii_id;
1045 x -> td . type_id = VSchemaCacheIntrinsicTypeId ( self, & s_ascii_id, "ascii" );
1046 }
1047 else
1048 {
1049 static atomic32_t s_utf8_id;
1050 x -> td . type_id = VSchemaCacheIntrinsicTypeId ( self, & s_utf8_id, "utf8" );
1051 }
1052
1053 * xp = x;
1054
1055 next_token ( tbl, src, t );
1056 return 0;
1057 }
1058
1059 static
sym_const_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SConstExpr ** xp)1060 rc_t sym_const_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
1061 const SchemaEnv *env, const VSchema *self, const SConstExpr **xp )
1062 {
1063 const KSymbol *sym = t -> sym;
1064 const SConstant *cnst = sym -> u . obj;
1065
1066 assert ( cnst -> expr != NULL );
1067 atomic32_inc ( & ( ( SExpression* ) cnst -> expr ) -> refcount );
1068 * xp = ( SConstExpr* ) cnst -> expr;
1069
1070 next_token ( tbl, src, t );
1071 return 0;
1072 }
1073 #endif /* SLVL >= 1 */
1074
1075
1076 #if SLVL >= 3
indirect_const_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SExpression ** xp)1077 LIB_EXPORT rc_t CC indirect_const_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
1078 const SchemaEnv *env, const VSchema *self, const SExpression **xp )
1079 {
1080 SSymExpr *x = malloc ( sizeof *x );
1081 if ( x == NULL )
1082 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
1083
1084 x -> dad . var = eIndirectExpr;
1085 atomic32_set ( & x -> dad . refcount, 1 );
1086 x -> _sym = t -> sym;
1087 x -> alt = false;
1088 * xp = & x -> dad;
1089
1090 next_token ( tbl, src, t );
1091 return 0;
1092 }
1093 #endif /* SLVL >= 1 */
1094
1095 /*
1096 * type-expr = <typeset>
1097 * | <fmtdecl>
1098 * | <fmtname> '/' <typeset>
1099 */
1100 #if SLVL >= 1
1101 static
type_expr_impl(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SExpression ** fd,bool vardim)1102 rc_t type_expr_impl ( const KSymTable *tbl, KTokenSource *src, KToken *t,
1103 const SchemaEnv *env, const VSchema *self, const SExpression **fd, bool vardim )
1104 {
1105 STypeExpr *x;
1106
1107 rc_t rc = next_fqn ( tbl, src, t, env );
1108 if ( rc != 0 )
1109 return rc;
1110
1111 x = malloc ( sizeof *x );
1112 if ( x == NULL )
1113 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
1114
1115 x -> dad . var = eTypeExpr;
1116 atomic32_set ( & x -> dad . refcount, 1 );
1117 x -> fmt = NULL;
1118 x -> dt = NULL;
1119 x -> ts = NULL;
1120 x -> id = NULL;
1121 x -> dim = NULL;
1122 x -> fd . fmt = 0;
1123 x -> fd . td . type_id = 0;
1124 x -> fd . td . dim = 0;
1125 x -> resolved = true;
1126
1127 if ( t -> id == eFormat )
1128 {
1129 x -> fmt = t -> sym -> u . obj;
1130 x -> fd . fmt = x -> fmt -> id;
1131 if ( next_token ( tbl, src, t ) -> id != eFwdSlash )
1132 {
1133 * fd = & x -> dad;
1134 return 0;
1135 }
1136
1137 rc = next_fqn ( tbl, src, next_token ( tbl, src, t ), env );
1138 if ( rc != 0 )
1139 {
1140 free ( x );
1141 return rc;
1142 }
1143 }
1144
1145 switch ( t -> id )
1146 {
1147 case eDatatype:
1148 x -> dt = t -> sym -> u . obj;
1149 x -> fd . td . type_id = x -> dt -> id;
1150 break;
1151 case eTypeset:
1152 x -> ts = t -> sym -> u . obj;
1153 x -> fd . td . type_id = x -> ts -> id;
1154 break;
1155 #if SLVL >= 3
1156 case eSchemaType:
1157 x -> id = t -> sym -> u . obj;
1158 x -> resolved = false;
1159 break;
1160 #endif
1161 default:
1162 free ( x );
1163 return KTokenExpected ( t, klogErr, "datatype or typeset" );
1164 }
1165
1166 if ( next_token ( tbl, src, t ) -> id != eLeftSquare )
1167 x -> fd . td . dim = 1;
1168 else
1169 {
1170 if ( next_token ( tbl, src, t ) -> id == eAsterisk && vardim )
1171 next_token ( tbl, src, t );
1172 else
1173 {
1174 const SConstExpr *cx;
1175
1176 rc = const_expr ( tbl, src, t, env, self, & x -> dim );
1177 if ( rc != 0 )
1178 {
1179 free ( x );
1180 return rc;
1181 }
1182
1183 switch ( x -> dim -> var )
1184 {
1185 case eConstExpr:
1186 cx = ( const SConstExpr* ) x -> dim;
1187 if ( cx -> td . dim == 1 )
1188 {
1189 const SDatatype *dt = VSchemaFindTypeid ( self, cx -> td . type_id );
1190 if ( dt != NULL && SDatatypeIntrinsicDim ( dt ) == 1 )
1191 {
1192 if ( dt -> domain == vtdUint )
1193 {
1194 switch ( dt -> size )
1195 {
1196 case 64:
1197 if ( cx -> u . u64 [ 0 ] <= 0xFFFFFFFF )
1198 x -> fd . td . dim = ( uint32_t ) cx -> u . u64 [ 0 ];
1199 break;
1200 case 32:
1201 x -> fd . td . dim = cx -> u . u32 [ 0 ];
1202 break;
1203 case 16:
1204 x -> fd . td . dim = cx -> u . u16 [ 0 ];
1205 break;
1206 case 8:
1207 x -> fd . td . dim = cx -> u . u8 [ 0 ];
1208 break;
1209 }
1210 }
1211 else if ( dt -> domain == vtdInt )
1212 {
1213 switch ( dt -> size )
1214 {
1215 case 64:
1216 if ( cx -> u . i64 [ 0 ] > 0 && cx -> u . i64 [ 0 ] <= 0xFFFFFFFF )
1217 x -> fd . td . dim = ( uint32_t ) cx -> u . i64 [ 0 ];
1218 break;
1219 case 32:
1220 if ( cx -> u . i32 [ 0 ] > 0 )
1221 x -> fd . td . dim = cx -> u . i32 [ 0 ];
1222 break;
1223 case 16:
1224 if ( cx -> u . i16 [ 0 ] > 0 )
1225 x -> fd . td . dim = cx -> u . i16 [ 0 ];
1226 break;
1227 case 8:
1228 if ( cx -> u . i8 [ 0 ] > 0 )
1229 x -> fd . td . dim = cx -> u . i8 [ 0 ];
1230 break;
1231 }
1232 }
1233
1234 if ( x -> fd . td . dim > 0 )
1235 break;
1236 }
1237 }
1238
1239 SExpressionWhack ( & x -> dad );
1240 return KTokenExpected ( t, klogErr, "constant integer expression" );
1241
1242 case eIndirectExpr:
1243 x -> resolved = false;
1244 break;
1245 default:
1246 SExpressionWhack ( & x -> dad );
1247 return KTokenExpected ( t, klogErr, "constant integer expression" );
1248 }
1249 }
1250
1251 rc = expect ( tbl, src, t, eRightSquare, "]", true );
1252 if ( rc != 0 )
1253 {
1254 SExpressionWhack ( & x -> dad );
1255 return rc;
1256 }
1257 }
1258
1259 * fd = & x -> dad;
1260 return 0;
1261 }
1262
type_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SExpression ** fd)1263 rc_t type_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
1264 const SchemaEnv *env, const VSchema *self, const SExpression **fd )
1265 {
1266 return type_expr_impl ( tbl, src, t, env, self, fd, false );
1267 }
1268
vardim_type_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SExpression ** fd)1269 rc_t vardim_type_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
1270 const SchemaEnv *env, const VSchema *self, const SExpression **fd )
1271 {
1272 return type_expr_impl ( tbl, src, t, env, self, fd, true );
1273 }
1274 #endif /* SLVL >= 1 */
1275
1276
1277 /*
1278 * cast_expr = '(' <type-expr> ')' <expression>
1279 */
1280 #if SLVL >= 1
1281 static
cast_expr(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SBinExpr ** xp,rc_t (* expr)(KSymTable *,KTokenSource *,KToken *,const SchemaEnv *,VSchema *,const SExpression **))1282 rc_t cast_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
1283 const SchemaEnv *env, VSchema *self, const SBinExpr **xp,
1284 rc_t ( * expr ) ( KSymTable*, KTokenSource*, KToken*,
1285 const SchemaEnv*, VSchema*, const SExpression** ) )
1286 {
1287 rc_t rc;
1288 SBinExpr *x = malloc ( sizeof * x );
1289 if ( x == NULL )
1290 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
1291
1292 rc = type_expr ( tbl, src, next_token ( tbl, src, t ), env, self, & x -> left );
1293 if ( rc == 0 )
1294 {
1295 rc = expect ( tbl, src, t, eRightParen, ")", true );
1296 if ( rc == 0 )
1297 {
1298 rc = ( * expr ) ( tbl, src, t, env, self, & x -> right );
1299 if ( rc == 0 )
1300 {
1301 x -> dad . var = eCastExpr;
1302 atomic32_set ( & x -> dad . refcount, 1 );
1303 * xp = x;
1304 return 0;
1305 }
1306 }
1307
1308 SExpressionWhack ( x -> left );
1309 }
1310
1311 free ( x );
1312 return rc;
1313 }
1314
1315
const_expr(const KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,const VSchema * self,const SExpression ** xp)1316 rc_t const_expr ( const KSymTable *tbl, KTokenSource *src, KToken *t,
1317 const SchemaEnv *env, const VSchema *self, const SExpression **xp )
1318 {
1319 switch ( t -> id )
1320 {
1321 case eDecimal:
1322 case eHex:
1323 case eOctal:
1324 return uint_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1325 case eFloat:
1326 case eExpFloat:
1327 return float_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1328 case eString:
1329 case eEscapedString:
1330 return string_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1331 case eConstant:
1332 return sym_const_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1333 #if SLVL >= 4
1334 case eFactParam:
1335 #endif
1336 #if SLVL >= 3
1337 case eSchemaParam:
1338 return indirect_const_expr ( tbl, src, t, env, self, xp );
1339 #endif
1340 case eLeftSquare:
1341 return const_vect_expr ( tbl, src, t, env, self, ( const SVectExpr** ) xp );
1342 case kw_false:
1343 case kw_true:
1344 return bool_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1345 case eLeftParen:
1346 return cast_expr ( ( KSymTable* ) tbl, src, t, env,
1347 ( VSchema* ) self, ( const SBinExpr** ) xp,
1348 ( rc_t ( * ) ( KSymTable*, KTokenSource*, KToken*,
1349 const SchemaEnv*, VSchema*, const SExpression** ) ) const_expr );
1350 case eMinus:
1351 /* unary minus sign */
1352 return negate_expr ( tbl, src, t, env, self, xp );
1353 case ePlus:
1354 /* unary plus sign */
1355 return const_expr ( tbl, src, next_token ( tbl, src, t ), env, self, xp );
1356 }
1357
1358 return KTokenExpected ( t, klogErr, "boolean, integer, float, string or symbolic constant" );
1359 }
1360 #endif /* SLVL >= 1 */
1361
1362
1363 /*
1364 * func-param-expr = <funcname>
1365 */
1366 #if SLVL >= 4
1367 static
sym_expr(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SSymExpr ** xp,uint32_t var,bool alt)1368 rc_t sym_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
1369 const SchemaEnv *env, VSchema *self, const SSymExpr **xp, uint32_t var, bool alt )
1370 {
1371 SSymExpr *x = malloc ( sizeof * x );
1372 if ( x == NULL )
1373 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
1374
1375 x -> dad . var = var;
1376 atomic32_set ( & x -> dad . refcount, 1 );
1377 x -> _sym = t -> sym;
1378 x -> alt = alt;
1379 * xp = x;
1380
1381 next_token ( tbl, src, t );
1382 return 0;
1383 }
1384
1385 #define func_param_expr( tbl, src, t, env, self, xp ) \
1386 sym_expr ( tbl, src, t, env, self, xp, eFuncParamExpr, false )
1387
1388 #endif
1389
1390
1391 /*
1392 * param-expr = <func-param>
1393 *
1394 */
1395 #if SLVL >= 4
1396
1397 #define param_expr( tbl, src, t, env, self, xp ) \
1398 sym_expr ( tbl, src, t, env, self, xp, eParamExpr, false )
1399
1400 #endif
1401
1402
1403 /*
1404 * prod-expr = <production>
1405 *
1406 */
1407 #if SLVL >= 4
1408
1409 #define prod_expr( tbl, src, t, env, self, xp ) \
1410 sym_expr ( tbl, src, t, env, self, xp, eProdExpr, false )
1411
1412 #endif
1413
1414
1415 /*
1416 * fwd-expr = ID
1417 */
1418 #if SLVL >= 4
1419 static
fwd_decl_expr(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SSymExpr ** xp,bool alt)1420 rc_t fwd_decl_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
1421 const SchemaEnv *env, VSchema *self, const SSymExpr **xp, bool alt )
1422 {
1423 rc_t rc;
1424 SSymExpr *x = malloc ( sizeof * x );
1425 if ( x == NULL )
1426 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
1427
1428 rc = KSymTableCreateConstSymbol ( tbl, & x -> _sym, & t -> str, eForward, NULL );
1429 if ( rc != 0 )
1430 {
1431 free ( x );
1432 return rc;
1433 }
1434
1435 x -> dad . var = eFwdExpr;
1436 atomic32_set ( & x -> dad . refcount, 1 );
1437 x -> alt = alt;
1438 * xp = x;
1439
1440 next_token ( tbl, src, t );
1441 return 0;
1442 }
1443
1444 #define fwd_ref_expr( tbl, src, t, env, self, xp, alt ) \
1445 sym_expr ( tbl, src, t, env, self, xp, eFwdExpr, alt )
1446
1447 #endif
1448
1449
1450 /*
1451 * column-expr = <column>
1452 */
1453 #if SLVL >= 8
1454
1455 #define column_expr( tbl, src, t, env, self, xp, alt ) \
1456 sym_expr ( tbl, src, t, env, self, xp, eColExpr, alt )
1457
1458 #endif
1459
1460
1461 /*
1462 * physical-expr = KCOL
1463 */
1464 #if SLVL >= 7
1465
1466 #define physical_expr( tbl, src, t, env, self, xp ) \
1467 sym_expr ( tbl, src, t, env, self, xp, ePhysExpr, false )
1468
1469 #endif
1470
1471
1472 /*
1473 * schema-parms = <schema-param> [ ',' <schema-parms> ]
1474 * schema-param = [ ID '=' ] <schema-value>
1475 * schema-value = <fmtdecl>
1476 * | <uint-expr>
1477 */
1478 #if SLVL >= 4
1479 static
schema_value(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SExpression ** v)1480 rc_t schema_value ( KSymTable *tbl, KTokenSource *src, KToken *t,
1481 const SchemaEnv *env, VSchema *self, const SExpression **v )
1482 {
1483 /* could be a typename */
1484 if ( t -> id == eNamespace )
1485 {
1486 rc_t rc = next_fqn ( tbl, src, t, env );
1487 if ( rc != 0 )
1488 return rc;
1489 }
1490
1491 /* param value */
1492 switch ( t -> id )
1493 {
1494 /* type parameter */
1495 case eFormat:
1496 case eDatatype:
1497 case eTypeset:
1498 case eSchemaType:
1499 return type_expr ( tbl, src, t, env, self, v );
1500
1501 /* manifest uint constant */
1502 case eDecimal:
1503 case eHex:
1504 case eOctal:
1505 return uint_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1506
1507 /* symbolic constant must be uint */
1508 case eConstant:
1509 return sym_const_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1510
1511 /* schema or factory constant must be uint
1512 but may not yet be completely resolved */
1513 case eSchemaParam:
1514 case eFactParam:
1515 return indirect_const_expr ( tbl, src, t, env, self, v );
1516 }
1517
1518 return KTokenExpected ( t, klogErr, "data type or unsigned int constant" );
1519 }
1520 #endif
1521
1522 /*
1523 * fact-parms = <fact-param> [ ',' <fact-parms> ]
1524 * fact-param = [ ID '=' ] <fact-value> ( "ID =" not implemented )
1525 * fact-value = <func-name>
1526 * | '[' <fact-const-list> ']'
1527 */
1528 #if SLVL >= 4
1529 static
fact_value(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SExpression ** v)1530 rc_t fact_value ( KSymTable *tbl, KTokenSource *src, KToken *t,
1531 const SchemaEnv *env, VSchema *self, const SExpression **v )
1532 {
1533 if ( t -> id == eNamespace )
1534 {
1535 rc_t rc = next_fqn ( tbl, src, t, env );
1536 if ( rc != 0 )
1537 return rc;
1538 }
1539
1540 switch ( t -> id )
1541 {
1542 /* const-expression */
1543 case eDecimal:
1544 case eHex:
1545 case eOctal:
1546 return uint_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1547 case eFloat:
1548 case eExpFloat:
1549 return float_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1550 case eString:
1551 case eEscapedString:
1552 return string_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1553 case eConstant:
1554 return sym_const_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1555 case eSchemaParam:
1556 case eFactParam:
1557 return indirect_const_expr ( tbl, src, t, env, self, v );
1558 case eLeftSquare:
1559 return const_vect_expr ( tbl, src, t, env, self, ( const SVectExpr** ) v );
1560 case kw_false:
1561 case kw_true:
1562 return bool_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1563
1564 /* cast expression */
1565 case eLeftParen:
1566 return cast_expr ( tbl, src, t, env, self, ( const SBinExpr** ) v, fact_value );
1567
1568 /* function name */
1569 case eFunction:
1570 return func_param_expr ( tbl, src, t, env, self, ( const SSymExpr** ) v );
1571
1572 case eMinus:
1573 /* unary minus sign */
1574 return negate_expr ( tbl, src, t, env, self, v );
1575 case ePlus:
1576 /* unary plus sign */
1577 return const_expr ( tbl, src, next_token ( tbl, src, t ), env, self, v );
1578 }
1579
1580 return KTokenExpected ( t, klogErr, "constant, function param or cast operator" );
1581 }
1582
1583 static
old_fact_value(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SExpression ** v)1584 rc_t old_fact_value ( KSymTable *tbl, KTokenSource *src, KToken *t,
1585 const SchemaEnv *env, VSchema *self, const SExpression **v )
1586 {
1587 switch ( t -> id )
1588 {
1589 /* const-expression */
1590 case eDecimal:
1591 case eHex:
1592 case eOctal:
1593 return uint_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1594 case eFloat:
1595 case eExpFloat:
1596 return float_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1597 case eString:
1598 case eEscapedString:
1599 return string_expr ( tbl, src, t, env, self, ( const SConstExpr** ) v );
1600 case eMinus:
1601 return negate_expr ( tbl, src, t, env, self, v );
1602 case ePlus:
1603 return old_fact_value ( tbl, src, next_token ( tbl, src, t ), env, self, v );
1604 }
1605
1606 return RC ( rcVDB, rcSchema, rcParsing, rcNoObj, rcNoErr );
1607 }
1608 #endif
1609
1610 /*
1611 * func-parms = <func-param> [ ',' <func-parms> ]
1612 * func-param = <colname>
1613 * | <physname>
1614 * | <production>
1615 * | <parmname>
1616 */
1617 #if SLVL >= 4
1618 static
param_value(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SExpression ** v)1619 rc_t param_value ( KSymTable *tbl, KTokenSource *src, KToken *t,
1620 const SchemaEnv *env, VSchema *self, const SExpression **v )
1621 {
1622 KToken t2;
1623 bool alt = false;
1624
1625 /* look for special modifiers */
1626 switch ( t -> id )
1627 {
1628 #if SLVL >= 7
1629 case ePeriod:
1630 /* detect special syntax for physical column names */
1631 physical_name ( tbl, src, t, env );
1632 break;
1633 #endif
1634 case eAtSign:
1635
1636 /* detect alternate column source */
1637 switch ( next_token ( tbl, src, & t2 ) -> id )
1638 {
1639 #if SLVL >= 8
1640 case eColumn:
1641 #endif
1642 case eIdent:
1643 case eForward:
1644 case eVirtual:
1645 * t = t2;
1646 alt = true;
1647 break;
1648
1649 default:
1650 KTokenSourceReturn ( src, & t2 );
1651 }
1652 break;
1653 }
1654
1655 switch ( t -> id )
1656 {
1657 /* handle function or script params, named productions */
1658 #if SLVL >= 5
1659 case eAtSign:
1660 t -> sym = KSymTableFind ( tbl, & t -> str );
1661 if ( t -> sym == NULL )
1662 break;
1663 t -> id = t -> sym -> type;
1664 /* no break */
1665 #endif
1666 case eFuncParam:
1667 return param_expr ( tbl, src, t, env, self, ( const SSymExpr** ) v );
1668 case eProduction:
1669 return prod_expr ( tbl, src, t, env, self, ( const SSymExpr** ) v );
1670
1671 /* forward reference */
1672 case eIdent:
1673 return fwd_decl_expr ( tbl, src, t, env, self, ( const SSymExpr** ) v, alt );
1674 case eForward:
1675 case eVirtual:
1676 return fwd_ref_expr ( tbl, src, t, env, self, ( const SSymExpr** ) v, alt );
1677 #if SLVL >= 8
1678 /* column expression */
1679 case eColumn:
1680 return column_expr ( tbl, src, t, env, self, ( const SSymExpr** ) v, alt );
1681 #endif
1682 #if SLVL >= 7
1683 /* physical column expression */
1684 case ePhysMember:
1685 return physical_expr ( tbl, src, t, env, self, ( const SSymExpr** ) v );
1686 #endif
1687 /* cast expression */
1688 case eLeftParen:
1689 return cast_expr ( tbl, src, t, env, self, ( const SBinExpr** ) v, param_value );
1690 }
1691
1692 return KTokenExpected ( t, klogErr, "column or production name or cast operator" );
1693 }
1694
1695 static
param_list(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,Vector * v,rc_t (* value)(KSymTable *,KTokenSource *,KToken *,const SchemaEnv *,VSchema *,const SExpression **))1696 rc_t param_list ( KSymTable *tbl, KTokenSource *src, KToken *t,
1697 const SchemaEnv *env, VSchema *self, Vector *v,
1698 rc_t ( * value ) ( KSymTable*, KTokenSource*, KToken*,
1699 const SchemaEnv*, VSchema*, const SExpression** ) )
1700 {
1701 rc_t rc;
1702 const SExpression *x;
1703
1704 while ( 1 )
1705 {
1706 /* param value */
1707 rc = ( * value ) ( tbl, src, t, env, self, & x );
1708 if ( rc != 0 )
1709 return rc;
1710
1711 /* record parameter */
1712 rc = VectorAppend ( v, NULL, x );
1713 if ( rc != 0 )
1714 {
1715 SExpressionWhack ( x );
1716 return KTokenRCExplain ( t, klogInt, rc );
1717 }
1718
1719 if ( t -> id != eComma )
1720 break;
1721
1722 next_token ( tbl, src, t );
1723 }
1724
1725 return 0;
1726 }
1727
1728 static
func_expression(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,SFuncExpr * fx,const KSymbol ** sym)1729 rc_t func_expression ( KSymTable *tbl, KTokenSource *src, KToken *t,
1730 const SchemaEnv *env, VSchema *self, SFuncExpr *fx, const KSymbol **sym )
1731 {
1732 rc_t rc;
1733
1734 /* schema-parms */
1735 if ( t -> id == eLeftAngle )
1736 {
1737 next_token ( tbl, src, t );
1738 rc = param_list ( tbl, src, t, env, self, & fx -> schem, schema_value );
1739 if ( rc == 0 )
1740 rc = expect ( tbl, src, t, eRightAngle, ">", true );
1741 if ( rc != 0 )
1742 return rc;
1743 }
1744
1745 /* locate function or schema */
1746 rc = next_fqn ( tbl, src, t, env );
1747 if ( rc != 0 )
1748 return rc;
1749
1750 if ( t -> id != eScriptFunc && t -> id != eFunction )
1751 return KTokenExpected ( t, klogErr, "function" );
1752 * sym = t -> sym;
1753
1754 /* look for requested version */
1755 if ( next_token ( tbl, src, t ) -> id == eHash )
1756 {
1757 fx -> version_requested = true;
1758 rc = maj_min_rel ( tbl, src, next_token ( tbl, src, t ),
1759 env, self, & fx -> version, false );
1760 if ( rc != 0 )
1761 return rc;
1762 }
1763
1764 /* look for factory params */
1765 if ( t -> id == eLeftAngle && ! env -> mixed_fact_param_list )
1766 {
1767 next_token ( tbl, src, t );
1768 rc = param_list ( tbl, src, t, env, self, & fx -> pfact, fact_value );
1769 if ( rc == 0 )
1770 rc = expect ( tbl, src, t, eRightAngle, ">", true );
1771 if ( rc != 0 )
1772 return rc;
1773 }
1774
1775 /* function params */
1776 if ( t -> id != eLeftParen )
1777 return KTokenExpected ( t, klogErr, "(" );
1778 if ( next_token ( tbl, src, t ) -> id != eRightParen )
1779 {
1780 /* handle old-style fact params */
1781 if ( env -> mixed_fact_param_list )
1782 {
1783 rc = param_list ( tbl, src, t, env, self, & fx -> pfact, old_fact_value );
1784 if ( GetRCState ( rc ) == rcNoErr )
1785 rc = 0;
1786 }
1787
1788 /* handle normal function params */
1789 if ( rc == 0 )
1790 rc = param_list ( tbl, src, t, env, self, & fx -> pfunc, param_value );
1791 }
1792 if ( rc == 0 )
1793 rc = expect ( tbl, src, t, eRightParen, ")", true );
1794
1795 return rc;
1796 }
1797
1798 static
func_expr(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SFuncExpr ** xp)1799 rc_t func_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
1800 const SchemaEnv *env, VSchema *self, const SFuncExpr **xp )
1801 {
1802 rc_t rc;
1803 const KSymbol *sym = NULL;
1804
1805 SFuncExpr *fx = malloc ( sizeof * fx );
1806 if ( fx == NULL )
1807 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
1808
1809 /* initialize */
1810 fx -> dad . var = eFuncExpr;
1811 atomic32_set ( & fx -> dad . refcount, 1 );
1812 fx -> func = NULL;
1813 VectorInit ( & fx -> schem, 0, 4 );
1814 VectorInit ( & fx -> pfact, 0, 8 );
1815 VectorInit ( & fx -> pfunc, 0, 8 );
1816 fx -> version = 0;
1817 fx -> version_requested = false;
1818 fx -> untyped = false;
1819
1820 /* parse expression */
1821 rc = func_expression ( tbl, src, t, env, self, fx, & sym );
1822 if ( rc == 0 )
1823 {
1824 const SNameOverload *vf = sym -> u . obj;
1825
1826 /* match expression */
1827 if ( vf -> name -> type == eScriptFunc )
1828 fx -> dad . var = eScriptExpr;
1829
1830 if ( fx -> version_requested )
1831 {
1832 fx -> func =
1833 VectorFind ( & vf -> items, & fx -> version, NULL, SFunctionCmp );
1834 }
1835 else
1836 {
1837 fx -> func = VectorLast ( & vf -> items );
1838 }
1839
1840 * xp = fx;
1841 return 0;
1842 }
1843
1844 SExpressionWhack ( & fx -> dad );
1845 return rc;
1846 }
1847 #endif /* SLVL >= 4 */
1848
1849 /*
1850 * expression = <param-value>
1851 * | <func-expr>
1852 * | '(' <type-expr> ')' <expression>
1853 */
1854 #if SLVL >= 4
expression(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SExpression ** xp)1855 rc_t expression ( KSymTable *tbl, KTokenSource *src, KToken *t,
1856 const SchemaEnv *env, VSchema *self, const SExpression **xp )
1857 {
1858 rc_t rc;
1859
1860 if ( t -> id == eNamespace )
1861 {
1862 rc = next_fqn ( tbl, src, t, env );
1863 if ( rc != 0 )
1864 return rc;
1865 }
1866
1867 #if SLVL >= 7
1868 /* detect special syntax for physical column names */
1869 if ( t -> id == ePeriod )
1870 physical_name ( tbl, src, t, env );
1871 #endif
1872
1873 switch ( t -> id )
1874 {
1875 /* handle function or script params, named productions */
1876 #if SLVL >= 5
1877 case eAtSign:
1878 t -> sym = KSymTableFind ( tbl, & t -> str );
1879 if ( t -> sym == NULL )
1880 break;
1881 t -> id = t -> sym -> type;
1882 /* no break */
1883 #endif
1884 case eFuncParam:
1885 return param_expr ( tbl, src, t, env, self, ( const SSymExpr** ) xp );
1886 case eProduction:
1887 return prod_expr ( tbl, src, t, env, self, ( const SSymExpr** ) xp );
1888
1889 /* forward reference */
1890 case eIdent:
1891 return fwd_decl_expr ( tbl, src, t, env, self, ( const SSymExpr** ) xp, false );
1892 case eForward:
1893 case eVirtual:
1894 return fwd_ref_expr ( tbl, src, t, env, self, ( const SSymExpr** ) xp, false );
1895 #if SLVL >= 8
1896 /* column expression */
1897 case eColumn:
1898 return column_expr ( tbl, src, t, env, self, ( const SSymExpr** ) xp, false );
1899 #endif
1900 #if SLVL >= 7
1901 /* physical column expression */
1902 case ePhysMember:
1903 return physical_expr ( tbl, src, t, env, self, ( const SSymExpr** ) xp );
1904 #endif
1905 /* function expression */
1906 case eLeftAngle:
1907 case eFunction:
1908 case eScriptFunc:
1909 return func_expr ( tbl, src, t, env, self, ( const SFuncExpr** ) xp );
1910
1911 /* cast expression */
1912 case eLeftParen:
1913 return cast_expr ( tbl, src, t, env, self,
1914 ( const SBinExpr** ) xp, expression );
1915
1916 /* type expression */
1917 case eFormat:
1918 case eDatatype:
1919 case eTypeset:
1920 case eSchemaType:
1921 return type_expr ( tbl, src, t, env, self, xp );
1922
1923 /* in case expression gets used for const-expression */
1924 case eDecimal:
1925 case eHex:
1926 case eOctal:
1927 return uint_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1928 case eFloat:
1929 case eExpFloat:
1930 return float_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1931 case eString:
1932 case eEscapedString:
1933 return string_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1934 case eConstant:
1935 return sym_const_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1936 case eSchemaParam:
1937 case eFactParam:
1938 return indirect_const_expr ( tbl, src, t, env, self, xp );
1939 case eLeftSquare:
1940 return const_vect_expr ( tbl, src, t, env, self, ( const SVectExpr** ) xp );
1941 case kw_false:
1942 case kw_true:
1943 return bool_expr ( tbl, src, t, env, self, ( const SConstExpr** ) xp );
1944
1945 case eMinus:
1946 /* unary minus sign */
1947 return negate_expr ( tbl, src, t, env, self, xp );
1948 case ePlus:
1949 /* unary plus sign */
1950 return const_expr ( tbl, src, next_token ( tbl, src, t ), env, self, xp );
1951 }
1952
1953 return KTokenExpected ( t, klogErr, "production name, column name, function or cast expression" );
1954 }
1955 #endif /* SLVL >= 4 */
1956
1957
1958 /*
1959 * cond-expr = <expression> [ '|' <cond-expr> ]
1960 */
1961 #if SLVL >= 4
cond_expr(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SExpression ** xp)1962 rc_t cond_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
1963 const SchemaEnv *env, VSchema *self, const SExpression **xp )
1964 {
1965 rc_t rc = expression ( tbl, src, t, env, self, xp );
1966 if ( rc != 0 )
1967 return rc;
1968
1969 if ( t -> id == ePipe )
1970 {
1971 SBinExpr *x = malloc ( sizeof * x );
1972 if ( x == NULL )
1973 {
1974 SExpressionWhack ( * xp ), * xp = NULL;
1975 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
1976 }
1977
1978 x -> dad . var = eCondExpr;
1979 atomic32_set ( & x -> dad . refcount, 1 );
1980 x -> left = * xp;
1981 x -> right = NULL;
1982 * xp = & x -> dad;
1983
1984 rc = cond_expr ( tbl, src, next_token ( tbl, src, t ), env, self, & x -> right );
1985 if ( rc != 0 )
1986 {
1987 SExpressionWhack ( & x -> dad );
1988 * xp = NULL;
1989 }
1990 }
1991
1992 return rc;
1993 }
1994 #endif /* SLVL >= 4 */
1995
1996 /*
1997 * untyped-expr = <fmtdecl> | <untyped-func-name> '(' ')'
1998 */
1999 #if SLVL >= 6
2000 static
untyped_func_expr(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SFuncExpr ** xp)2001 rc_t untyped_func_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
2002 const SchemaEnv *env, VSchema *self, const SFuncExpr **xp )
2003 {
2004 rc_t rc;
2005 const KSymbol *sym = t -> sym;
2006
2007 /* expect empty parameter list */
2008 next_token ( tbl, src, t );
2009 rc = expect ( tbl, src, t, eLeftParen, "(", true );
2010 if ( rc == 0 )
2011 rc = expect ( tbl, src, t, eRightParen, ")", true );
2012 if ( rc == 0 )
2013 {
2014 const SNameOverload *vf = sym -> u . obj;
2015
2016 SFuncExpr *fx = malloc ( sizeof * fx );
2017 if ( fx == NULL )
2018 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
2019
2020 /* initialize */
2021 fx -> dad . var = eFuncExpr;
2022 atomic32_set ( & fx -> dad . refcount, 1 );
2023 VectorInit ( & fx -> schem, 0, 4 );
2024 VectorInit ( & fx -> pfact, 0, 8 );
2025 VectorInit ( & fx -> pfunc, 0, 8 );
2026 fx -> version = 0;
2027 fx -> version_requested = false;
2028 fx -> untyped = true;
2029
2030 fx -> func = VectorLast ( & vf -> items );
2031
2032 * xp = fx;
2033 return 0;
2034 }
2035
2036 return rc;
2037 }
2038
untyped_expr(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,const SExpression ** xp)2039 LIB_EXPORT rc_t CC untyped_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
2040 const SchemaEnv *env, VSchema *self, const SExpression **xp )
2041 {
2042 rc_t rc;
2043
2044 if ( t -> id == eNamespace )
2045 {
2046 rc = next_fqn ( tbl, src, t, env );
2047 if ( rc != 0 )
2048 return rc;
2049 }
2050
2051 switch ( t -> id )
2052 {
2053 /* function expression */
2054 case eUntypedFunc:
2055 return untyped_func_expr ( tbl, src, t, env, self, ( const SFuncExpr** ) xp );
2056
2057 /* type expression */
2058 case eFormat:
2059 return type_expr ( tbl, src, t, env, self, xp );
2060 }
2061
2062 return KTokenExpected ( t, klogErr, "type or function expression" );
2063 }
2064 #endif /* SLVL >= 6 */
2065
2066
2067 /*
2068 * phys-encoding-expr = [ '<' <schema-parms> '>' ]
2069 * <phys-encoding-name> [ '#' <maj-min-rel> ]
2070 * [ '<' <fact-params> '>' ]
2071 */
2072 #if SLVL >= 7
2073 static
phys_enc_expr(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,SPhysEncExpr * x,const KSymbol ** sym)2074 rc_t phys_enc_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
2075 const SchemaEnv *env, VSchema *self, SPhysEncExpr *x, const KSymbol **sym )
2076 {
2077 rc_t rc;
2078
2079 /* schema parms */
2080 if ( t -> id == eLeftAngle )
2081 {
2082 next_token ( tbl, src, t );
2083 rc = param_list ( tbl, src, t, env, self, & x -> schem, schema_value );
2084 if ( rc == 0 )
2085 rc = expect ( tbl, src, t, eRightAngle, ">", true );
2086 if ( rc != 0 )
2087 return rc;
2088 }
2089
2090 /* phys-encoding-name */
2091 rc = next_fqn ( tbl, src, t, env );
2092 if ( rc != 0 )
2093 return rc;
2094
2095 if ( t -> id != ePhysical )
2096 return KTokenExpected ( t, klogErr, "physical encoding" );
2097 * sym = t -> sym;
2098
2099
2100 /* look for requested version */
2101 if ( next_token ( tbl, src, t ) -> id == eHash )
2102 {
2103 x -> version_requested = true;
2104 rc = maj_min_rel ( tbl, src, next_token ( tbl, src, t ),
2105 env, self, & x -> version, false );
2106 if ( rc != 0 )
2107 return rc;
2108 }
2109
2110 /* look for factory params */
2111 if ( t -> id == eLeftAngle )
2112 {
2113 next_token ( tbl, src, t );
2114 rc = param_list ( tbl, src, t, env, self, & x -> pfact, fact_value );
2115 if ( rc == 0 )
2116 rc = expect ( tbl, src, t, eRightAngle, ">", true );
2117 }
2118
2119 return rc;
2120 }
2121
phys_encoding_expr(KSymTable * tbl,KTokenSource * src,KToken * t,const SchemaEnv * env,VSchema * self,VTypedecl * td,const SExpression ** xp)2122 rc_t phys_encoding_expr ( KSymTable *tbl, KTokenSource *src, KToken *t,
2123 const SchemaEnv *env, VSchema *self, VTypedecl *td, const SExpression **xp )
2124 {
2125 rc_t rc;
2126 const KSymbol *sym = NULL;
2127
2128 SPhysEncExpr *x = malloc ( sizeof * x );
2129 if ( x == NULL )
2130 return RC ( rcVDB, rcSchema, rcParsing, rcMemory, rcExhausted );
2131
2132 /* initialize */
2133 x -> dad . var = ePhysEncExpr;
2134 atomic32_set ( & x -> dad . refcount, 1 );
2135 x -> phys = NULL;
2136 VectorInit ( & x -> schem, 0, 4 );
2137 VectorInit ( & x -> pfact, 0, 8 );
2138 x -> version = 0;
2139 x -> version_requested = false;
2140
2141 /* parse expression */
2142 rc = phys_enc_expr ( tbl, src, t, env, self, x, & sym );
2143 if ( rc == 0 )
2144 {
2145 const SNameOverload *name = sym -> u . obj;
2146
2147 if ( x -> version_requested )
2148 {
2149 x -> phys =
2150 VectorFind ( & name -> items, & x -> version, NULL, SPhysicalCmp );
2151 }
2152 else
2153 {
2154 x -> phys = VectorLast ( & name -> items );
2155 }
2156
2157 /* evaluate type expression */
2158 if ( x -> phys != NULL && td != NULL )
2159 {
2160 /* bind schema parameters */
2161 Vector prior, cx_bind;
2162 VectorInit ( & cx_bind, 1, self -> num_indirect ? self -> num_indirect : 16 );
2163 rc = SPhysicalBindSchemaParms ( x -> phys, & prior, & x -> schem, & cx_bind );
2164 if ( rc == 0 )
2165 {
2166 const SExpression *tx = x -> phys -> td;
2167 assert ( tx != NULL );
2168 rc = STypeExprResolveAsTypedecl ( ( const STypeExpr* ) tx, self, td, & cx_bind );
2169 SPhysicalRestSchemaParms ( x -> phys, & prior, & cx_bind );
2170 }
2171 VectorWhack ( & cx_bind, NULL, NULL );
2172 }
2173
2174 if ( rc == 0 )
2175 {
2176 * xp = & x -> dad;
2177 return 0;
2178 }
2179 }
2180
2181 SExpressionWhack ( & x -> dad );
2182 return rc;
2183 }
2184 #endif
2185