Browse Source

Merging 'de' libcm into 'cmtest' libcm

master
kevin 11 years ago
parent
commit
ead258c822
4 changed files with 697 additions and 14 deletions
  1. 668
    9
      cmData.c
  2. 22
    5
      cmData.h
  3. 4
    0
      cmGrPage.h
  4. 3
    0
      cmStack.h

+ 668
- 9
cmData.c View File

@@ -4,7 +4,11 @@
4 4
 #include "cmCtx.h"
5 5
 #include "cmMem.h"
6 6
 #include "cmMallocDebug.h"
7
+#include "cmLinkedHeap.h"
7 8
 #include "cmData.h"
9
+#include "cmLex.h"
10
+#include "cmText.h"
11
+#include "cmStack.h"
8 12
 
9 13
 cmDtRC_t _cmDataErrNo = kOkDtRC;
10 14
 
@@ -666,20 +670,26 @@ cmData_t* cmDataSetDoublePtr( cmData_t* p, double* vp,         unsigned cnt )
666 670
 
667 671
 // Set the value of an existing array based data object. 
668 672
 // Allocate the internal array and copy the array into it.
669
-cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s )
673
+cmData_t* cmDataSetStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt )
670 674
 {
671 675
   if( cmIsFlag(p->flags,kDynPtrDtFl) )
672
-    cmMemResizeStr(p->u.z,s);
676
+    cmMemResizeStrN(p->u.z,s,charCnt);
673 677
   else
674 678
   {
675 679
     _cmDataFreeArray(p);
676
-    p->u.z = cmMemAllocStr(s);
680
+    p->u.z = cmMemAllocStrN(s,charCnt);
677 681
   }
678 682
   p->tid    = kStrDtId;
679 683
   p->flags  = cmSetFlag(p->flags,kDynPtrDtFl);
680 684
   return p;
681 685
 }
682 686
 
687
+cmData_t* cmDataSetStrAlloc( cmData_t* p, const cmChar_t* s )
688
+{ return cmDataSetStrAllocN(p,s,strlen(s)); }
689
+
690
+cmData_t* cmDataSetConstStrAllocN(  cmData_t* p, const cmChar_t* s, unsigned charCnt )
691
+{ return cmDataSetStrAllocN(p,s,charCnt); }
692
+
683 693
 cmData_t* cmDataSetConstStrAlloc(  cmData_t* p, const cmChar_t* s )
684 694
 { return cmDataSetStrAlloc(p,s); }
685 695
 
@@ -695,6 +705,7 @@ cmData_t* cmDataSetCharAllocPtr(  cmData_t* p, const char* vp,  unsigned cnt )
695 705
     _cmDataFreeArray(p);
696 706
     p->u.cp = cmMemAlloc(char, cnt );
697 707
   }
708
+
698 709
   memcpy(p->u.cp,vp,sizeof(char)*cnt);
699 710
   p->tid   = kCharPtrDtId;
700 711
   p->flags = cmSetFlag(p->flags,kDynPtrDtFl);
@@ -1032,6 +1043,14 @@ cmData_t* cmDataStrAlloc( cmData_t* parent, cmChar_t* str )
1032 1043
   return p;
1033 1044
 }
1034 1045
 
1046
+cmData_t* cmDataConstStrAllocN( cmData_t* parent, const cmChar_t* str, unsigned charCnt )
1047
+{
1048
+  cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId);
1049
+  cmDataSetConstStrAllocN(p,str,charCnt);
1050
+  return p;
1051
+}
1052
+
1053
+
1035 1054
 cmData_t* cmDataConstStrAlloc( cmData_t* parent, const cmChar_t* str )
1036 1055
 {
1037 1056
   cmData_t* p = _cmDataAllocNode(parent,kConstStrDtId);
@@ -1458,6 +1477,15 @@ cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t *label, cmData_
1458 1477
   cmDataAppendChild(p,value);
1459 1478
   return p;
1460 1479
 }
1480
+
1481
+cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value)
1482
+{
1483
+  cmData_t* p  = _cmDataAllocNode(parent,kPairDtId);
1484
+  cmDataConstStrAllocN(p,label,charCnt);
1485
+  cmDataAppendChild(p,value);
1486
+  return p;
1487
+}
1488
+
1461 1489
   
1462 1490
 //----------------------------------------------------------------------------
1463 1491
 
@@ -1757,7 +1785,7 @@ const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index )
1757 1785
   return label;
1758 1786
 }
1759 1787
   
1760
-cmData_t*       cmRecdMake( cmData_t* parent, cmData_t* p )
1788
+cmData_t*       cmDataRecdMake( cmData_t* parent, cmData_t* p )
1761 1789
 {
1762 1790
   _cmDataFree(p);
1763 1791
   p->parent  = parent;
@@ -1767,10 +1795,10 @@ cmData_t*       cmRecdMake( cmData_t* parent, cmData_t* p )
1767 1795
   return p;
1768 1796
 }
1769 1797
 
1770
-cmData_t*       cmRecdAlloc(cmData_t* parent)
1798
+cmData_t*       cmDataRecdAlloc(cmData_t* parent)
1771 1799
 { return _cmDataAllocNode(parent,kRecordDtId); }
1772 1800
 
1773
-cmData_t* cmRecdAppendPair( cmData_t* p, cmData_t* pair )
1801
+cmData_t* cmDataRecdAppendPair( cmData_t* p, cmData_t* pair )
1774 1802
 {
1775 1803
   assert( p!=NULL && p->tid==kRecordDtId);
1776 1804
   cmDataAppendChild(p,pair);
@@ -1820,7 +1848,7 @@ cmDtRC_t  _cmDataRecdParseInputV(cmData_t* parent, unsigned idFl, va_list vl )
1820 1848
 
1821 1849
 cmData_t*       cmDataRecdAllocLabelV( cmData_t* parent, va_list vl )
1822 1850
 {
1823
-  cmData_t* p = cmRecdAlloc(parent);
1851
+  cmData_t* p = cmDataRecdAlloc(parent);
1824 1852
   cmDtRC_t rc = _cmDataRecdParseInputV(p, false, vl );
1825 1853
   if( rc != kOkDtRC )
1826 1854
   {
@@ -1841,7 +1869,7 @@ cmData_t*       cmDataRecdAllocLabelA( cmData_t* parent, ... )
1841 1869
 
1842 1870
 cmData_t*       cmDataRecdAllocIdV( cmData_t* parent, va_list vl )
1843 1871
 {
1844
-  cmData_t* p = cmRecdAlloc(parent);
1872
+  cmData_t* p = cmDataRecdAlloc(parent);
1845 1873
   cmDtRC_t rc = _cmDataRecdParseInputV(p, true, vl );
1846 1874
   if( rc != kOkDtRC )
1847 1875
   {
@@ -2061,7 +2089,10 @@ cmDtRC_t cmDataRecdParseId(cmData_t* p, cmErr_t* err, unsigned errRC, ... )
2061 2089
 
2062 2090
 
2063 2091
 
2064
-//----------------------------------------------------------------------------  
2092
+//============================================================================
2093
+//============================================================================
2094
+//============================================================================
2095
+  
2065 2096
 unsigned _cmDataSerializeNodeByteCount( const cmData_t* p )
2066 2097
 {
2067 2098
   unsigned n = 0;
@@ -2191,6 +2222,590 @@ cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp
2191 2222
   return kOkDtRC;
2192 2223
 }
2193 2224
 
2225
+//============================================================================
2226
+//============================================================================
2227
+//============================================================================
2228
+enum
2229
+{
2230
+  kLCurlyLexTId = kUserLexTId + 1,
2231
+  kRCurlyLexTId,
2232
+  kLParenLexTId,
2233
+  kRParenLexTId,
2234
+  kLBrackLexTId,
2235
+  kRBrackLexTId,
2236
+  kColonLexTId,
2237
+  kCommaLexTId,
2238
+};
2239
+
2240
+typedef struct
2241
+{
2242
+  unsigned        id;
2243
+  const cmChar_t* label;
2244
+} cmDtToken_t;
2245
+
2246
+cmDtToken_t _cmDtTokenArray[] = 
2247
+{
2248
+  { kLCurlyLexTId, "{" },
2249
+  { kRCurlyLexTId, "}" },
2250
+  { kLBrackLexTId,  "[" },
2251
+  { kRBrackLexTId,  "]" },
2252
+  { kLParenLexTId,  "(" },
2253
+  { kRParenLexTId,  ")" },
2254
+  { kColonLexTId,  ":" },
2255
+  { kCommaLexTId,  "," },
2256
+  { kErrorLexTId,""}
2257
+  
2258
+};
2259
+
2260
+typedef struct
2261
+{
2262
+  cmErr_t    err;
2263
+  cmLexH    lexH;
2264
+  cmStackH_t stH;
2265
+
2266
+} cmDataParser_t;
2267
+
2268
+
2269
+cmDataParserH_t cmDataParserNullHandle = cmSTATIC_NULL_HANDLE;
2270
+
2271
+cmDataParser_t* _cmDataParserHandleToPtr( cmDataParserH_t h )
2272
+{
2273
+  cmDataParser_t* p = (cmDataParser_t*)h.h;
2274
+  assert( p!= NULL );
2275
+  return p;
2276
+}
2277
+
2278
+cmDtRC_t _cmDataParserDestroy( cmDataParser_t* p )
2279
+{
2280
+  if( cmLexFinal(&p->lexH) != kOkLexRC )
2281
+    cmErrMsg(&p->err,kLexFailDtRC,"Lexer release failed.");
2282
+
2283
+  if( cmStackFree(&p->stH) != kOkStRC )
2284
+    cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack release failed.");
2285
+
2286
+  return kOkDtRC;
2287
+}
2288
+
2289
+cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp )
2290
+{
2291
+  cmDtRC_t rc;
2292
+  unsigned i;
2293
+
2294
+  if((rc = cmDataParserDestroy(hp)) != kOkDtRC )
2295
+    return rc;
2296
+
2297
+  cmDataParser_t* p = cmMemAllocZ(cmDataParser_t,1);
2298
+
2299
+  cmErrSetup(&p->err,&ctx->rpt,"Data Parser");
2300
+
2301
+  if(cmLexIsValid(p->lexH = cmLexInit(NULL,0,0,&ctx->rpt))==false)
2302
+  {
2303
+    rc = cmErrMsg(&p->err, kLexFailDtRC, "The data object parser lexer create failed.");
2304
+    goto errLabel;
2305
+  }
2306
+
2307
+  for(i=0; _cmDtTokenArray[i].id != kErrorLexTId; ++i)
2308
+    if( cmLexRegisterToken(p->lexH, _cmDtTokenArray[i].id, _cmDtTokenArray[i].label) != kOkLexRC )
2309
+    {
2310
+      rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object parser lexer could not register the '%s' token.",_cmDtTokenArray[i].label);
2311
+      goto errLabel;
2312
+    }
2313
+
2314
+  if( cmStackAlloc(ctx, &p->stH, 1024, 1024, sizeof(cmData_t*)) != kOkStRC )
2315
+  {
2316
+    rc = cmErrMsg(&p->err,kParseStackFailDtRC,"The data object parser stack create failed.");
2317
+    goto errLabel;
2318
+  }
2319
+
2320
+  hp->h = p;
2321
+
2322
+ errLabel:
2323
+  if( rc != kOkDtRC )
2324
+    _cmDataParserDestroy(p);
2325
+
2326
+  return kOkDtRC;
2327
+}
2328
+
2329
+cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp )
2330
+{
2331
+  cmDtRC_t rc=kOkDtRC;
2332
+
2333
+  if( hp==NULL || cmDataParserIsValid(*hp)==false )
2334
+    return rc;
2335
+
2336
+  cmDataParser_t* p = _cmDataParserHandleToPtr(*hp);
2337
+
2338
+  if((rc = _cmDataParserDestroy(p)) != kOkDtRC )
2339
+    return rc;
2340
+
2341
+  hp->h = NULL;
2342
+
2343
+  return kOkDtRC;
2344
+}
2345
+
2346
+
2347
+bool     cmDataParserIsValid( cmDataParserH_t h )
2348
+{ return h.h != NULL; }
2349
+
2350
+
2351
+
2352
+// {
2353
+//  id0 : scalar_value
2354
+//  id1 : ( heterogenous, array, value )
2355
+//  id2 : [ homogeneous array values ]
2356
+//  id3 : 
2357
+// }
2358
+
2359
+
2360
+// flags describing the expected next token
2361
+enum
2362
+{
2363
+  kValueExpFl = 0x01,
2364
+  kIdExpFl    = 0x02,
2365
+  kColonExpFl = 0x04,
2366
+  kCommaExpFl = 0x08
2367
+};
2368
+
2369
+typedef struct
2370
+{
2371
+  cmData_t* dp;
2372
+} cmDataStEle_t;
2373
+
2374
+typedef struct
2375
+{
2376
+  cmDataParser_t*  p;
2377
+  cmData_t*        cnp;
2378
+  unsigned         flags;
2379
+  cmChar_t*        tmpStr;
2380
+
2381
+  unsigned         arrayCnt;
2382
+  void*            arrayMem;
2383
+  
2384
+} cmDataParserCtx_t;
2385
+
2386
+cmDtRC_t _cmDpSyntaxErrV( cmDataParserCtx_t* c, const cmChar_t* fmt, va_list vl )
2387
+{
2388
+  cmChar_t* s0 = NULL;
2389
+  s0 = cmTsVPrintfP(s0,fmt,vl);
2390
+  cmDtRC_t rc = cmErrMsg(&c->p->err,kSyntaxErrDtRC,"Syntax error on line %i. %s",cmLexCurrentLineNumber(c->p->lexH),cmStringNullGuard(s0));
2391
+  cmMemFree(s0);
2392
+  return rc;
2393
+}
2394
+
2395
+cmDtRC_t _cmDpSyntaxErr( cmDataParserCtx_t* c, const cmChar_t* fmt, ... )
2396
+{
2397
+  va_list vl;
2398
+  va_start(vl,fmt);
2399
+  cmDtRC_t rc = _cmDpSyntaxErrV(c,fmt,vl);
2400
+  va_end(vl);
2401
+  return rc;
2402
+}
2403
+
2404
+cmDtRC_t _cmDpPopStack(  cmDataParserCtx_t* c, cmData_t** pp )
2405
+{
2406
+  const void* vp;
2407
+  if((vp = cmStackTop(c->p->stH)) == NULL )
2408
+    return _cmDpSyntaxErr(c,"Stack underflow.");
2409
+  
2410
+  *pp = *(cmData_t**)vp;
2411
+
2412
+  return kOkDtRC;
2413
+}
2414
+
2415
+cmDtRC_t _cmDpStoreArrayEle( cmDataParserCtx_t* c, void* dp, unsigned byteCnt )
2416
+{
2417
+  char* vp = cmMemResize(char, c->cnp->u.vp, c->cnp->cnt+byteCnt);
2418
+  
2419
+  memcpy(vp + c->cnp->cnt,dp,byteCnt);
2420
+  c->cnp->u.vp = vp;
2421
+  c->cnp->cnt += byteCnt;
2422
+  
2423
+  c->flags = kValueExpFl | kCommaExpFl;
2424
+
2425
+  return kOkDtRC;
2426
+}
2427
+
2428
+cmDtRC_t _cmDataParserOpenPair( cmDataParserCtx_t* c )
2429
+{
2430
+  assert( c->cnp->tid == kRecordDtId );
2431
+
2432
+  cmData_t* nnp = cmDataAllocNull(NULL);
2433
+  cmData_t* pnp = cmDataAllocPairLabelN( c->cnp, cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH), nnp );
2434
+
2435
+  // store the current node
2436
+  if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC )
2437
+    return _cmDpSyntaxErr(c,"Parser stack push failed.");
2438
+
2439
+  // make the new pair the current node
2440
+  c->cnp = pnp;
2441
+
2442
+  // pair openings must be followed by a colon.
2443
+  c->flags  = kColonExpFl;
2444
+ 
2445
+  return kOkDtRC;
2446
+}
2447
+
2448
+cmDtRC_t _cmDataParserClosePair( cmDataParserCtx_t* c )
2449
+{
2450
+  cmDtRC_t rc;
2451
+
2452
+  // make the pair's parent record the current node
2453
+  if((rc = _cmDpPopStack(c, &c->cnp )) != kOkDtRC )
2454
+    return rc;
2455
+
2456
+  // pairs only occur in records
2457
+  if( c->cnp->tid != kRecordDtId )
2458
+    return _cmDpSyntaxErr(c,"A 'pair' end was found outside of a 'record'.");
2459
+
2460
+  // pairs must be followed by id's or comma's
2461
+  c->flags = kIdExpFl | kCommaExpFl; 
2462
+
2463
+  return rc;
2464
+}
2465
+
2466
+cmDtRC_t _cmDpStoreValue( cmDataParserCtx_t* c, cmData_t* np, const cmChar_t* typeLabel )
2467
+{
2468
+  assert( np != NULL );
2469
+
2470
+  cmDtRC_t rc = kOkDtRC;
2471
+
2472
+  switch( c->cnp->tid )
2473
+  {
2474
+    case kPairDtId:
2475
+
2476
+      // assign the new node as the value of the pair
2477
+      cmDataPairSetValue(c->cnp,np);
2478
+
2479
+      // close the values parent pair
2480
+      rc = _cmDataParserClosePair(c);
2481
+      break;
2482
+
2483
+    case kListDtId:      
2484
+      cmDataAppendChild(c->cnp,np);
2485
+      c->flags = kValueExpFl;
2486
+      break;
2487
+
2488
+    default:
2489
+      rc = _cmDpSyntaxErr(c,"A '%s' value was found outside of a valid container.",typeLabel);
2490
+  }
2491
+
2492
+  c->flags |= kCommaExpFl;
2493
+
2494
+  return rc;
2495
+}
2496
+
2497
+cmDtRC_t _cmDataParserReal( cmDataParserCtx_t* c )
2498
+{
2499
+  cmDtRC_t rc  = kOkDtRC;
2500
+  double   val = cmLexTokenDouble(c->p->lexH);
2501
+
2502
+  if( c->cnp->tid == kVoidPtrDtId )
2503
+    rc = _cmDpStoreArrayEle(c,&val,sizeof(val));
2504
+  else
2505
+    rc = _cmDpStoreValue(c,cmDataAllocDouble(NULL,val),"real");
2506
+
2507
+  return rc;
2508
+}
2509
+
2510
+cmDtRC_t _cmDataParserInt( cmDataParserCtx_t* c )
2511
+{
2512
+  cmDtRC_t rc  = kOkDtRC;
2513
+  int      val = cmLexTokenInt(c->p->lexH);
2514
+
2515
+  if( c->cnp->tid == kVoidPtrDtId )
2516
+    rc = _cmDpStoreArrayEle(c,&val,sizeof(val));
2517
+  else
2518
+    rc = _cmDpStoreValue(c,cmDataAllocInt(NULL,val),"int");
2519
+
2520
+  return rc;
2521
+}
2522
+
2523
+cmDtRC_t _cmDataParserString( cmDataParserCtx_t* c )
2524
+{
2525
+  // if we are expecting a pair label
2526
+  if( cmIsFlag(c->flags,kIdExpFl) )
2527
+    return _cmDataParserOpenPair(c);
2528
+    
2529
+  // otherwise a 'value' must be expected
2530
+  if( cmIsNotFlag(c->flags,kValueExpFl) )
2531
+    return _cmDpSyntaxErr(c,"Unexpected string.");
2532
+
2533
+  cmData_t* np = cmDataConstStrAllocN(NULL,cmLexTokenText(c->p->lexH), cmLexTokenCharCount(c->p->lexH));
2534
+
2535
+  return _cmDpStoreValue(c,np,"string");
2536
+}
2537
+
2538
+cmDtRC_t _cmDataParserOpenRecd( cmDataParserCtx_t* c )
2539
+{
2540
+  // records are values - so we must be expecting a value
2541
+  if( cmIsFlag(c->flags,kValueExpFl) == false )
2542
+    return _cmDpSyntaxErr(c,"Unexpected '{'.");
2543
+
2544
+  // store the current node
2545
+  if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC )
2546
+    return _cmDpSyntaxErr(c,"Parser stack push failed.");
2547
+
2548
+  // alloc a new record and make it the current node
2549
+  if( (c->cnp = cmDataRecdAlloc(c->cnp)) == NULL )
2550
+    return _cmDpSyntaxErr(c,"'recd' allocate failed.");
2551
+
2552
+  // new records must be followed by an id token.
2553
+  c->flags = kIdExpFl;
2554
+
2555
+  return kOkDtRC;
2556
+}
2557
+
2558
+cmDtRC_t _cmDataParserCloseRecd( cmDataParserCtx_t* c )
2559
+{
2560
+  cmDtRC_t rc;
2561
+
2562
+  // make the parent node the new curren node
2563
+  if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC )
2564
+    return rc;
2565
+
2566
+  switch( c->cnp->tid )
2567
+  {
2568
+    case kPairDtId:
2569
+      // if the parent node is a pair then close it
2570
+      rc = _cmDataParserClosePair(c);
2571
+      break;
2572
+
2573
+    case kListDtId:
2574
+      // parent node is a list - so expect another value
2575
+      c->flags = kValueExpFl;
2576
+      break;
2577
+
2578
+    default:
2579
+      return _cmDpSyntaxErr(c,"'records' may only be contained in other records or heterogenous arrays.");
2580
+      
2581
+  }
2582
+
2583
+  c->flags |= kCommaExpFl;
2584
+    
2585
+  return rc;
2586
+}
2587
+
2588
+cmDtRC_t _cmDataParserOpenList( cmDataParserCtx_t* c )
2589
+{
2590
+  // lists are values - so we must be expecting a value
2591
+  if( cmIsFlag(c->flags,kValueExpFl) == false )
2592
+    return _cmDpSyntaxErr(c,"Unexpected '('.");
2593
+
2594
+  // store the current node
2595
+  if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC )
2596
+    return _cmDpSyntaxErr(c,"Parser stack push failed.");
2597
+
2598
+  // create a new list
2599
+  if( (c->cnp = cmDataListAlloc(c->cnp)) == NULL )
2600
+    return _cmDpSyntaxErr(c,"'list' allocate failed.");
2601
+
2602
+  // new lists must be followed by a value
2603
+  c->flags = kValueExpFl;
2604
+
2605
+  return kOkDtRC;
2606
+}
2607
+
2608
+cmDtRC_t _cmDataParserCloseList( cmDataParserCtx_t* c )
2609
+{
2610
+  cmDtRC_t rc;
2611
+
2612
+  // make the list's parent the current node
2613
+  if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC )
2614
+    return rc;
2615
+
2616
+  switch( c->cnp->tid )
2617
+  {
2618
+    case kPairDtId:
2619
+      // if the list's parent is a pair then close it
2620
+      rc = _cmDataParserClosePair(c);
2621
+      break;
2622
+
2623
+    case kListDtId:
2624
+      // the list's parent is another list so expect a value
2625
+      c->flags = kValueExpFl;
2626
+      break;
2627
+
2628
+    default:
2629
+      return _cmDpSyntaxErr(c,"'lists' may only be contained in other records or lists.");
2630
+      
2631
+  }
2632
+
2633
+  c->flags |= kCommaExpFl;
2634
+    
2635
+  return rc;
2636
+}
2637
+
2638
+cmDtRC_t _cmDataParserOpenArray( cmDataParserCtx_t* c )
2639
+{
2640
+
2641
+  // arrays are values - so we must be expecting a value
2642
+  if( cmIsFlag(c->flags,kValueExpFl) == false )
2643
+    return _cmDpSyntaxErr(c,"Unexpected '('.");
2644
+
2645
+  // store the current node
2646
+  if( cmStackPush(c->p->stH, &c->cnp, 1 ) != kOkStRC )
2647
+    return _cmDpSyntaxErr(c,"Parser stack push failed.");
2648
+
2649
+  // create a new array
2650
+  if( (c->cnp = cmDataSetVoidAllocPtr(c->cnp, NULL, 0 )) == NULL )
2651
+    return _cmDpSyntaxErr(c,"'array' allocate failed.");
2652
+
2653
+  // new arrays must be followed by a value
2654
+  c->flags = kValueExpFl;
2655
+
2656
+  return kOkDtRC;
2657
+
2658
+}
2659
+
2660
+cmDtRC_t _cmDataParserCloseArray( cmDataParserCtx_t* c )
2661
+{
2662
+  cmDtRC_t rc;
2663
+  
2664
+  // make the arrays parent the current node
2665
+  if((rc = _cmDpPopStack(c,&c->cnp)) != kOkDtRC )
2666
+    return rc;
2667
+
2668
+  switch( c->cnp->tid )
2669
+  {
2670
+    
2671
+    case kPairDtId:
2672
+      // the arrays parent is a pair - so close it
2673
+      rc = _cmDataParserClosePair(c);
2674
+      break;
2675
+      
2676
+    case kListDtId:
2677
+      // the arrays parent is a list - so expect a value
2678
+      c->flags = kValueExpFl;
2679
+      break;
2680
+
2681
+    default:
2682
+      return _cmDpSyntaxErr(c,"'arrays' may only be contained in other records or lists.");
2683
+      
2684
+  }
2685
+
2686
+  c->flags |= kCommaExpFl;
2687
+    
2688
+  return rc;
2689
+}
2690
+
2691
+cmDtRC_t _cmDataParserOnColon( cmDataParserCtx_t* c )
2692
+{
2693
+  // colons only follow field identifiers and are always followed by values.
2694
+  if( cmIsFlag(c->flags,kColonExpFl) == false )
2695
+    return _cmDpSyntaxErr(c,"Unexpected colon.");
2696
+
2697
+  c->flags = kValueExpFl;
2698
+
2699
+  return kOkDtRC;
2700
+}
2701
+
2702
+cmDtRC_t _cmDataParserOnComma( cmDataParserCtx_t* c )
2703
+{
2704
+  // comma's may be found in three places:
2705
+  // 1) following field values
2706
+  // 2) between list values
2707
+  // 3) between  array values
2708
+  // comma's are always followed by values
2709
+  if( cmIsFlag(c->flags,kCommaExpFl) == false )
2710
+    return  _cmDpSyntaxErr(c, "Unexpected comma.");
2711
+
2712
+  c->flags = kValueExpFl;
2713
+
2714
+  return kOkDtRC;      
2715
+}
2716
+
2717
+
2718
+cmDtRC_t cmDataParserExec( cmDataParserH_t h, const cmChar_t* text, cmData_t** pp )
2719
+{
2720
+  cmDtRC_t rc = kOkDtRC;
2721
+  unsigned tokenId;
2722
+
2723
+  cmDataParserCtx_t ctx;
2724
+  cmDataParser_t* p   = _cmDataParserHandleToPtr(h);
2725
+
2726
+  ctx.cnp   = NULL;  // current node ptr
2727
+  ctx.p     = p;
2728
+  ctx.flags = kValueExpFl;
2729
+
2730
+  if( cmLexSetTextBuffer(p->lexH,text,strlen(text)) != kOkLexRC )
2731
+    return cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed during reset.");
2732
+
2733
+  cmStackClear(p->stH,false);
2734
+
2735
+  while((tokenId = cmLexGetNextToken(p->lexH)) != kEofLexTId )
2736
+  {
2737
+    switch(tokenId)
2738
+    {
2739
+      case kRealLexTId:     // real number (contains a decimal point or is in scientific notation) 
2740
+        rc = _cmDataParserReal(&ctx);
2741
+        break;
2742
+
2743
+      case kIntLexTId:      // decimal integer
2744
+        rc = _cmDataParserInt(&ctx);
2745
+        break;
2746
+
2747
+      case kHexLexTId:      // hexidecimal integer
2748
+        rc = _cmDataParserInt(&ctx);
2749
+        break;
2750
+
2751
+      case kIdentLexTId:    // identifiers are treated as strings
2752
+      case kQStrLexTId:     // quoted string
2753
+        rc = _cmDataParserString(&ctx);
2754
+        break;
2755
+
2756
+      case kLCurlyLexTId:    // a new record is starting
2757
+        rc = _cmDataParserOpenRecd(&ctx);
2758
+      break;
2759
+
2760
+      case kRCurlyLexTId:   // the current record is finished
2761
+        rc = _cmDataParserCloseRecd(&ctx);
2762
+        break;
2763
+
2764
+      case kLParenLexTId:   // a list is starting
2765
+        rc = _cmDataParserOpenList(&ctx);
2766
+        break;
2767
+
2768
+      case kRParenLexTId:   // a list is finished
2769
+        rc = _cmDataParserCloseList(&ctx);
2770
+        break;
2771
+
2772
+      case kLBrackLexTId:   // an  array is starting
2773
+        rc = _cmDataParserOpenArray(&ctx);
2774
+        break;
2775
+
2776
+      case kRBrackLexTId:   // an array is ending
2777
+        rc = _cmDataParserCloseArray(&ctx);
2778
+        break;
2779
+
2780
+      case kColonLexTId:    // the previous id was a field id 
2781
+        rc = _cmDataParserOnColon(&ctx);
2782
+        break;
2783
+
2784
+      case kCommaLexTId:    // comma sep. for array or fields
2785
+        rc = _cmDataParserOnComma(&ctx);
2786
+        break;
2787
+
2788
+      case kBlockCmtLexTId: // block comment
2789
+      case kLineCmtLexTId:  // line comment
2790
+      case kErrorLexTId:    // the lexer was unable to identify the current token
2791
+      case kUnknownLexTId:  // the token is of an unknown type (only used when kReturnUnknownLexFl is set)
2792
+      case kEofLexTId:      // the lexer reached the end of input
2793
+      case kSpaceLexTId:    // white space
2794
+        {
2795
+          rc = cmErrMsg(&p->err,kLexFailDtRC,"The data object lexer failed with an unexpected token '%s' on line '%i'.",cmLexIdToLabel(p->lexH,tokenId),cmLexCurrentLineNumber(p->lexH));
2796
+          goto errLabel;
2797
+        }
2798
+    }
2799
+  }
2800
+
2801
+ errLabel:
2802
+  return rc;
2803
+}
2804
+
2805
+//============================================================================
2806
+//============================================================================
2807
+//============================================================================
2808
+
2194 2809
 #define parr(rpt,fmt,arr,n) do{int i=0; cmRptPrintf(rpt,"[ "); for(;i<n;++i) cmRptPrintf(rpt,fmt,arr[i]); cmRptPrintf(rpt," ]"); }while(0) 
2195 2810
 
2196 2811
 void _cmDataPrintIndent( cmRpt_t* rpt, unsigned indent )
@@ -2280,10 +2895,54 @@ void     _cmDataPrint( const cmData_t* p, cmRpt_t* rpt, unsigned indent )
2280 2895
 void cmDataPrint( const cmData_t* p, cmRpt_t* rpt )
2281 2896
 { _cmDataPrint(p,rpt,0); }
2282 2897
 
2898
+
2899
+cmDtRC_t cmDataParserTest( cmCtx_t* ctx )
2900
+{
2901
+  cmDtRC_t        rc = kOkDtRC;
2902
+  cmDataParserH_t h  = cmDataParserNullHandle;
2903
+  cmErr_t         err;
2904
+  cmData_t*       dp = NULL;
2905
+
2906
+  const cmChar_t text[] =
2907
+  {
2908
+    "{ f0:1.23 f1:\"hey\" "
2909
+  };
2910
+
2911
+  cmErrSetup(&err,&ctx->rpt,"Data Parser Tester");
2912
+
2913
+  if((rc = cmDataParserCreate(ctx, &h )) != kOkDtRC )
2914
+  {
2915
+    rc = cmErrMsg(&err,rc,"Data parser create failed.");
2916
+    goto errLabel;
2917
+  }
2918
+
2919
+  if( cmDataParserExec(h,text,&dp) != kOkDtRC )
2920
+    rc = cmErrMsg(&err,rc,"Data parser exec failed.");
2921
+  else
2922
+  {
2923
+    cmDataPrint(dp,&ctx->rpt);
2924
+  }
2925
+
2926
+ errLabel:
2927
+  if( cmDataParserDestroy( &h ) != kOkDtRC )
2928
+  {
2929
+    rc = cmErrMsg(&err,rc,"Data parser destroy failed.");
2930
+    goto errLabel;
2931
+  }
2932
+
2933
+  cmDataFree(dp);
2934
+
2935
+  return rc;
2936
+}
2937
+
2938
+
2283 2939
 void     cmDataTest( cmCtx_t* ctx )
2284 2940
 {
2285 2941
   float farr[] = { 1.23, 45.6, 7.89 };
2286 2942
 
2943
+  cmDataParserTest(ctx);
2944
+  return;
2945
+
2287 2946
   cmData_t* d0 = cmDataRecdAllocLabelA(NULL,
2288 2947
     "name",kConstStrDtId,"This is a string.",
2289 2948
     "id",  kUIntDtId,    21,

+ 22
- 5
cmData.h View File

@@ -11,6 +11,9 @@ extern "C" {
11 11
     kCvtErrDtRC,
12 12
     kVarArgErrDtRC,
13 13
     kMissingFieldDtRC,
14
+    kLexFailDtRC,
15
+    kParseStackFailDtRC,
16
+    kSyntaxErrDtRC,
14 17
     kEolDtRC
15 18
   };
16 19
 
@@ -64,8 +67,8 @@ extern "C" {
64 67
 
65 68
     kMinStructDtId,
66 69
     kListDtId = kMinStructDtId, // children nodes are array elements, cnt=child count
67
-    kPairDtId,                  // key/value pairs, cnt=2, first child is key, second is value
68
-    kRecordDtId,                // children nodes are pairs, cnt=pair count
70
+    kPairDtId,                   // key/value pairs, cnt=2, first child is key, second is value
71
+    kRecordDtId,                 // children nodes are pairs, cnt=pair count
69 72
     kMaxStructDtId,
70 73
 
71 74
     kOptArgDtFl = 0x80000000
@@ -271,7 +274,9 @@ extern "C" {
271 274
   // These functions begin by releasing any resources help by *p
272 275
   // and then dynamically allocate the internal array and copy 
273 276
   // the array data into it.
277
+  cmData_t* cmDataSetStrAllocN(      cmData_t* p, const cmChar_t* s, unsigned charCnt );
274 278
   cmData_t* cmDataSetStrAlloc(       cmData_t* p, const cmChar_t* s );
279
+  cmData_t* cmDataSetConstStrAllocN( cmData_t* p, const cmChar_t* s, unsigned charCnt );
275 280
   cmData_t* cmDataSetConstStrAlloc(  cmData_t* p, const cmChar_t* s );
276 281
   cmData_t* cmDataSetVoidAllocPtr(   cmData_t* p, const void* vp,           unsigned cnt );
277 282
   cmData_t* cmDataSetCharAllocPtr(   cmData_t* p, const char* vp,           unsigned cnt );
@@ -324,6 +329,7 @@ extern "C" {
324 329
   // and copy v[cnt] into it.
325 330
   cmData_t* cmDataStrAlloc(       cmData_t* parent, cmChar_t* str );
326 331
   cmData_t* cmDataConstStrAlloc(  cmData_t* parent, const cmChar_t* str );
332
+  cmData_t* cmDataConstStrAllocN( cmData_t* parent, const cmChar_t* str, unsigned charCnt );
327 333
   cmData_t* cmDataCharAllocPtr(   cmData_t* parent, const char* v,           unsigned cnt );
328 334
   cmData_t* cmDataUCharAllocPtr(  cmData_t* parent, const unsigned char* v,  unsigned cnt );
329 335
   cmData_t* cmDataShortAllocPtr(  cmData_t* parent, const short* v,          unsigned cnt );
@@ -428,6 +434,7 @@ extern "C" {
428 434
   cmData_t* cmDataAllocPairId(    cmData_t* parent, unsigned  keyId,       cmData_t* value );
429 435
 
430 436
   // Dynamically allocate the label but link (w/o realloc) the value.
437
+  cmData_t* cmDataAllocPairLabelN(cmData_t* parent, const cmChar_t* label, unsigned charCnt, cmData_t* value);
431 438
   cmData_t* cmDataAllocPairLabel( cmData_t* parent, const cmChar_t* label, cmData_t* value );
432 439
 
433 440
   //----------------------------------------------------------------------------
@@ -487,13 +494,13 @@ extern "C" {
487 494
   unsigned        cmDataRecdKeyId(    cmData_t* p, unsigned index );
488 495
   const cmChar_t* cmDataRecdKeyLabel( cmData_t* p, unsigned index );
489 496
   
490
-  cmData_t*       cmRecdMake( cmData_t* parent, cmData_t* p );
491
-  cmData_t*       cmRecdAlloc( cmData_t* parent );
497
+  cmData_t*       cmDataRecdMake( cmData_t* parent, cmData_t* p );
498
+  cmData_t*       cmDataRecdAlloc( cmData_t* parent );
492 499
   
493 500
   // Append a pair node by linking the pair node 'pair' to the record node 'p'.
494 501
   // 'pair' is simply linked to 'p' via cmDataAppendChild() no 
495 502
   // reallocation or duplicattion takes place.
496
-  cmData_t*       cmRecdAppendPair( cmData_t* p, cmData_t* pair );
503
+  cmData_t*       cmDataRecdAppendPair( cmData_t* p, cmData_t* pair );
497 504
 
498 505
 
499 506
   // Var-args format:
@@ -529,6 +536,16 @@ extern "C" {
529 536
   unsigned cmDataSerializeByteCount( const cmData_t* p );
530 537
   cmDtRC_t cmDataSerialize(   const cmData_t* p, void* buf, unsigned bufByteCnt );
531 538
   cmDtRC_t cmDataDeserialize( const void* buf, unsigned bufByteCnt, cmData_t** pp );
539
+
540
+  //-----------------------------------------------------------------------------
541
+  typedef cmHandle_t cmDataParserH_t;
542
+  //static cmDataParserH_t cmDataParserNullHandle;
543
+
544
+  cmDtRC_t cmDataParserCreate( cmCtx_t* ctx, cmDataParserH_t* hp );
545
+  cmDtRC_t cmDataParserDestroy( cmDataParserH_t* hp );
546
+  bool     cmDataParserIsValid( cmDataParserH_t h );
547
+  cmDtRC_t cmDataParserExec(   cmDataParserH_t  h, const cmChar_t* text, cmData_t** pp );
548
+  //-----------------------------------------------------------------------------
532 549
   
533 550
   void     cmDataPrint( const cmData_t* p, cmRpt_t* rpt );
534 551
   

+ 4
- 0
cmGrPage.h View File

@@ -60,7 +60,11 @@ extern "C" {
60 60
   // Draw the page.
61 61
   void      cmGrPageDraw( cmGrPgH_t h, cmGrDcH_t dcH );
62 62
 
63
+  // Label callback functions are used to translate numeric axis values to
64
+  // text strings.  Multiple label callback functions can be registered with
65
+  // a page and then assigned to a given view axis via cmGrViewSetLabelFunc().
63 66
   typedef void (*cmGrLabelFunc_t)( void* arg, cmChar_t* label, unsigned labelCharCnt, cmGrV_t value );
67
+
64 68
   // Returns id of the new page label function.
65 69
   unsigned         cmGrPageLabelFuncRegister( cmGrPgH_t h, cmGrLabelFunc_t func, void* arg, const cmChar_t* label );      
66 70
   unsigned         cmGrPageLabelFuncCount(    cmGrPgH_t h );

+ 3
- 0
cmStack.h View File

@@ -42,12 +42,15 @@ extern "C" {
42 42
   const void* cmStackTop(     cmStackH_t h );
43 43
 
44 44
   // Set the value of 'dataEleCnt' elements on the stack.
45
+  // The top element is at index cmStackCount() - 1.
45 46
   cmStRC_t    cmStackSet(     cmStackH_t h, unsigned index, const void* data, unsigned dataEleCnt );
46 47
 
47 48
   // Copy 'dataEleCnt' elements into the buffer pointed to by 'data'.
49
+  // The top element is at index cmStackCount() - 1.
48 50
   cmStRC_t    cmStackGetN(    cmStackH_t h, unsigned index, void* data, unsigned dataEleCnt );
49 51
 
50 52
   // Return a pointer to a single element on the stack.
53
+  // The top element is at index cmStackCount() - 1.
51 54
   const void* cmStackGet(     cmStackH_t h, unsigned index );
52 55
 
53 56
   // Convert the internal representation of the stack to a linear array and return

Loading…
Cancel
Save