cwal

Check-in [73df044fc1]
Login

Check-in [73df044fc1]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:core: internal refactoring to make Buffer Values containers, so they may now hold properties and be prototypes. It was much easier than expected to implement and the cost increase is negligible (48 bytes) in the amalgamated s2 unit tests.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 73df044fc169aa1e0970b974bb8aa7b608419d9f
User & Date: stephan 2014-12-17 04:32:23
References
2015-07-16
14:47
Fixed a silly memory-overwrite and an unrelated off-by-one-arg error in s2.tmpl(). Its require.s2 tests pass again. The first problem was a side-effect of changes made in [73df044fc1]. check-in: 2b17ae620d user: stephan tags: trunk
Context
2014-12-17
22:09
added a couple missing struct member inits. check-in: b6ca87c4a5 user: stephan tags: trunk
04:32
core: internal refactoring to make Buffer Values containers, so they may now hold properties and be prototypes. It was much easier than expected to implement and the cost increase is negligible (48 bytes) in the amalgamated s2 unit tests. check-in: 73df044fc1 user: stephan tags: trunk
03:12
build fix for disabled linenoise. check-in: 9ce7a303a0 user: stephan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to cwal.c.
54
55
56
57
58
59
60

61
62
63
64
65
66
67
const cwal_scope cwal_scope_empty = cwal_scope_empty_m;
const cwal_state cwal_state_empty = cwal_state_empty_m;
const cwal_trace_state cwal_trace_state_empty = cwal_trace_state_empty_m;
const cwal_value_vtab cwal_value_vtab_empty = cwal_value_vtab_empty_m;
const cwal_memchunk_config cwal_memchunk_config_empty = cwal_memchunk_config_empty_m;
static const cwal_memchunk_overlay cwal_memchunk_overlay_empty = {0,0};
const cwal_memcap_config cwal_memcap_config_empty = cwal_memcap_config_empty_m;


/**
   If CWAL_INT_DOUBLE_SAME_SIZE is true then we can pack integers
   and doubles into the same recycling bins.
*/
#define CWAL_INT_DOUBLE_SAME_SIZE (sizeof(cwal_double_t)==sizeof(cwal_int_t))








>







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
const cwal_scope cwal_scope_empty = cwal_scope_empty_m;
const cwal_state cwal_state_empty = cwal_state_empty_m;
const cwal_trace_state cwal_trace_state_empty = cwal_trace_state_empty_m;
const cwal_value_vtab cwal_value_vtab_empty = cwal_value_vtab_empty_m;
const cwal_memchunk_config cwal_memchunk_config_empty = cwal_memchunk_config_empty_m;
static const cwal_memchunk_overlay cwal_memchunk_overlay_empty = {0,0};
const cwal_memcap_config cwal_memcap_config_empty = cwal_memcap_config_empty_m;
const cwal_buffer_obj cwal_buffer_obj_empty = cwal_buffer_obj_empty_m;

/**
   If CWAL_INT_DOUBLE_SAME_SIZE is true then we can pack integers
   and doubles into the same recycling bins.
*/
#define CWAL_INT_DOUBLE_SAME_SIZE (sizeof(cwal_double_t)==sizeof(cwal_int_t))

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
      cwal_value_cleanup_hash,
      cwal_value_hash_ptr,
      cwal_value_cmp_ptr_only,
      cwal_rescope_children_hash
    };
static const cwal_value_vtab cwal_value_vtab_buffer =
    { CWAL_TYPE_BUFFER, "buffer",
      CWAL_F_NONE,
      cwal_value_cleanup_buffer,
      cwal_value_hash_ptr,
      cwal_value_cmp_buffer,
      NULL/*rescope_children()*/
    };
static const cwal_value_vtab cwal_value_vtab_function =
    { CWAL_TYPE_FUNCTION, "function",
      CWAL_F_ISA_OBASE,
      cwal_value_cleanup_function,
      cwal_value_hash_ptr,
      cwal_value_cmp_func,







|



|







443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
      cwal_value_cleanup_hash,
      cwal_value_hash_ptr,
      cwal_value_cmp_ptr_only,
      cwal_rescope_children_hash
    };
static const cwal_value_vtab cwal_value_vtab_buffer =
    { CWAL_TYPE_BUFFER, "buffer",
      CWAL_F_ISA_OBASE,
      cwal_value_cleanup_buffer,
      cwal_value_hash_ptr,
      cwal_value_cmp_buffer,
      cwal_rescope_children_obase
    };
static const cwal_value_vtab cwal_value_vtab_function =
    { CWAL_TYPE_FUNCTION, "function",
      CWAL_F_ISA_OBASE,
      cwal_value_cleanup_function,
      cwal_value_hash_ptr,
      cwal_value_cmp_func,
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
#define CWAL_VOBASE(V) (CWAL_V_IS_OBASE(V) ? CWAL_VVPCAST(cwal_obase,(V)) : 0)

/**
   Casts CWAL_TYPE_NATIVE value V to (cwal_native*).
*/
#define CWAL_V2NATIVE(V) CWAL_VVPCAST(cwal_native,(V))
/**
   CWAL_BUF(V) casts CWAL_TYPE_BUFFER (cwal_value*) V to a (cwal_buffer*).
*/
#define CWAL_BUF(V) (((V) && (V)->vtab && (CWAL_TYPE_BUFFER==(V)->vtab->typeID)) ? CWAL_VVPCAST(cwal_buffer,(V)) : 0)

/**
   CWAL_UNIQUE_VALPP(V) casts gets the wrapped (cwal_value**) part of
   CWAL_TYPE_UNIQUE (cwal_value*) V. If V is-not-a Unique, it evals
   to 0.
*/
#define CWAL_UNIQUE_VALPP(V) (((V) && (V)->vtab && (CWAL_TYPE_UNIQUE==(V)->vtab->typeID)) ? (CWAL_VVPCAST(cwal_value*,(V))) : 0)







|

|







658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
#define CWAL_VOBASE(V) (CWAL_V_IS_OBASE(V) ? CWAL_VVPCAST(cwal_obase,(V)) : 0)

/**
   Casts CWAL_TYPE_NATIVE value V to (cwal_native*).
*/
#define CWAL_V2NATIVE(V) CWAL_VVPCAST(cwal_native,(V))
/**
   CWAL_BUFOBJ(V) casts CWAL_TYPE_BUFFER (cwal_value*) V to a (cwal_buffer_obj*).
*/
#define CWAL_BUFOBJ(V) (((V) && (V)->vtab && (CWAL_TYPE_BUFFER==(V)->vtab->typeID)) ? CWAL_VVPCAST(cwal_buffer_obj,(V)) : 0)

/**
   CWAL_UNIQUE_VALPP(V) casts gets the wrapped (cwal_value**) part of
   CWAL_TYPE_UNIQUE (cwal_value*) V. If V is-not-a Unique, it evals
   to 0.
*/
#define CWAL_UNIQUE_VALPP(V) (((V) && (V)->vtab && (CWAL_TYPE_UNIQUE==(V)->vtab->typeID)) ? (CWAL_VVPCAST(cwal_value*,(V))) : 0)
1166
1167
1168
1169
1170
1171
1172








1173
1174
1175
1176
1177
1178
1179
1180
          assert(cwalRecyclerInfo.indexes[typeID]>=0);
          return cwalRecyclerInfo.indexes[typeID];
      default:
          return -1;
    }
}











/** @internal

   Checks whether child refers to a higher scope than parent, and if
   it does then it moves child to par. If par is 0 this function
   sets *res (if not NULL) to 1 and returns.








>
>
>
>
>
>
>
>
|







1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
          assert(cwalRecyclerInfo.indexes[typeID]>=0);
          return cwalRecyclerInfo.indexes[typeID];
      default:
          return -1;
    }
}

/**
   Overwrites all state in buf with defaults (zeroes) but
   retains the buf->self member.
*/
static void cwal_buffer_wipe_keep_self( cwal_buffer * buf ){
    void * self = buf->self;
    *buf = cwal_buffer_empty;
    buf->self = self;
}

/** @internal

   Checks whether child refers to a higher scope than parent, and if
   it does then it moves child to par. If par is 0 this function
   sets *res (if not NULL) to 1 and returns.

2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988







2989
2990
2991
2992
2993
2994
2995
ISA(bool,BOOL)
ISA(integer,INTEGER)
ISA(double,DOUBLE)
ISA(string,STRING)
ISA(array,ARRAY)
ISA(object,OBJECT)
ISA(native,NATIVE)
ISA(buffer,BUFFER)
ISA(function,FUNCTION)
ISA(exception,EXCEPTION)
ISA(hash,HASH)
ISA(unique,UNIQUE)
#undef ISA








char cwal_value_is_number( cwal_value const * v ){
    if(!v) return 0;
    else switch(v->vtab->typeID){
      case CWAL_TYPE_INTEGER:
      case CWAL_TYPE_DOUBLE:
      case CWAL_TYPE_BOOL:
          return 1;







|






>
>
>
>
>
>
>







2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
ISA(bool,BOOL)
ISA(integer,INTEGER)
ISA(double,DOUBLE)
ISA(string,STRING)
ISA(array,ARRAY)
ISA(object,OBJECT)
ISA(native,NATIVE)
/* ISA(buffer,BUFFER) */
ISA(function,FUNCTION)
ISA(exception,EXCEPTION)
ISA(hash,HASH)
ISA(unique,UNIQUE)
#undef ISA


char cwal_value_is_buffer( cwal_value const * v ){
    cwal_buffer_obj const * bo = CWAL_BUFOBJ(v);
    assert(bo ? (bo==bo->buf.self) : 1);
    return (bo && bo == bo->buf.self) ? 1 : 0;
}

char cwal_value_is_number( cwal_value const * v ){
    if(!v) return 0;
    else switch(v->vtab->typeID){
      case CWAL_TYPE_INTEGER:
      case CWAL_TYPE_DOUBLE:
      case CWAL_TYPE_BOOL:
          return 1;
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
      case CWAL_TYPE_STRING: return sizeof(cwal_value)+sizeof(cwal_string);
      case CWAL_TYPE_UNIQUE: return sizeof(cwal_value)+sizeof(cwal_value*);
      case CWAL_TYPE_INTEGER: return sizeof(cwal_value)+sizeof(cwal_int_t);
      case CWAL_TYPE_DOUBLE: return sizeof(cwal_value)+sizeof(cwal_double_t);
      case CWAL_TYPE_ARRAY: return sizeof(cwal_value)+sizeof(cwal_array);
      case CWAL_TYPE_OBJECT: return sizeof(cwal_value)+sizeof(cwal_object);
      case CWAL_TYPE_NATIVE: return sizeof(cwal_value)+sizeof(cwal_native);
      case CWAL_TYPE_BUFFER: return sizeof(cwal_value)+sizeof(cwal_buffer);
      case CWAL_TYPE_FUNCTION: return sizeof(cwal_value)+sizeof(cwal_function);
      case CWAL_TYPE_EXCEPTION: return sizeof(cwal_value)+sizeof(cwal_exception);
      case CWAL_TYPE_HASH: return sizeof(cwal_value)+sizeof(cwal_hash);
      case CWAL_TYPE_SCOPE: return sizeof(cwal_scope);
      case CWAL_TYPE_KVP: return sizeof(cwal_kvp);
      case CWAL_TYPE_WEAK_REF: return sizeof(cwal_weak_ref);
      case CWAL_TYPE_XSTRING:







|







5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
      case CWAL_TYPE_STRING: return sizeof(cwal_value)+sizeof(cwal_string);
      case CWAL_TYPE_UNIQUE: return sizeof(cwal_value)+sizeof(cwal_value*);
      case CWAL_TYPE_INTEGER: return sizeof(cwal_value)+sizeof(cwal_int_t);
      case CWAL_TYPE_DOUBLE: return sizeof(cwal_value)+sizeof(cwal_double_t);
      case CWAL_TYPE_ARRAY: return sizeof(cwal_value)+sizeof(cwal_array);
      case CWAL_TYPE_OBJECT: return sizeof(cwal_value)+sizeof(cwal_object);
      case CWAL_TYPE_NATIVE: return sizeof(cwal_value)+sizeof(cwal_native);
      case CWAL_TYPE_BUFFER: return sizeof(cwal_value)+sizeof(cwal_buffer_obj);
      case CWAL_TYPE_FUNCTION: return sizeof(cwal_value)+sizeof(cwal_function);
      case CWAL_TYPE_EXCEPTION: return sizeof(cwal_value)+sizeof(cwal_exception);
      case CWAL_TYPE_HASH: return sizeof(cwal_value)+sizeof(cwal_hash);
      case CWAL_TYPE_SCOPE: return sizeof(cwal_scope);
      case CWAL_TYPE_KVP: return sizeof(cwal_kvp);
      case CWAL_TYPE_WEAK_REF: return sizeof(cwal_weak_ref);
      case CWAL_TYPE_XSTRING:
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
          assert( 0 == extra );
          def = cwal_value_exception_empty;
          tx = sizeof(cwal_exception);
          break;
      case CWAL_TYPE_BUFFER:
          assert( 0 == extra );
          def = cwal_value_buffer_empty;
          tx = sizeof(cwal_buffer);
          break;
      case CWAL_TYPE_HASH:
          assert( 0 == extra );
          def = cwal_value_hash_empty;
          tx = sizeof(cwal_hash);
          break;
      case CWAL_TYPE_UNIQUE:







|







5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
          assert( 0 == extra );
          def = cwal_value_exception_empty;
          tx = sizeof(cwal_exception);
          break;
      case CWAL_TYPE_BUFFER:
          assert( 0 == extra );
          def = cwal_value_buffer_empty;
          tx = sizeof(cwal_buffer_obj);
          break;
      case CWAL_TYPE_HASH:
          assert( 0 == extra );
          def = cwal_value_hash_empty;
          tx = sizeof(cwal_hash);
          break;
      case CWAL_TYPE_UNIQUE:
5974
5975
5976
5977
5978
5979
5980

5981
5982


5983

5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999

6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020

6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
    return CWAL_VALPART(s);
}

cwal_value * cwal_new_buffer_value(cwal_engine *e, cwal_size_t startingSize){
    cwal_value * v = cwal_value_new(e, e->current, CWAL_TYPE_BUFFER,0);
    if( NULL != v )
    {

        cwal_buffer * b = CWAL_BUF(v);
        assert(NULL != b);


        *b = cwal_buffer_empty;

        if(startingSize &&
           cwal_buffer_reserve(e, b, startingSize)){
            cwal_value_unref2(e, v);
            v = NULL;
        }
    }
    return v;
}

int cwal_buffer_unref(cwal_engine *e, cwal_buffer *v){
    return (e&&v)
        ? cwal_value_unref2( e, cwal_buffer_value(v) )
        : CWAL_RC_MISUSE;
}

int cwal_value_fetch_buffer( cwal_value const * val, cwal_buffer ** x){

    if( ! val ) return CWAL_RC_MISUSE;
    else if( !cwal_value_is_buffer(val) ) return CWAL_RC_TYPE;
    else{
        if(x) *x = CWAL_VVPCAST(cwal_buffer,val);
        return 0;
    }
}
    
cwal_buffer * cwal_value_get_buffer( cwal_value const * v ) {
    cwal_buffer * ar = NULL;
    cwal_value_fetch_buffer( v, &ar );
    return ar;
}

cwal_buffer * cwal_new_buffer(cwal_engine *e, cwal_size_t startingSize){
    return cwal_value_get_buffer(cwal_new_buffer_value(e, startingSize));
}

cwal_value * cwal_buffer_value(cwal_buffer const * s){
    if(!s) return 0;
    else{

        cwal_value * v = CWAL_VALPART(s);
        return (v && v->vtab && (CWAL_TYPE_BUFFER==v->vtab->typeID))
            /* trying to protect against misuse of stack-allocated
               buffers there. */
            ? v : 0;
    }
}

cwal_string * cwal_buffer_to_zstring(cwal_engine * e, cwal_buffer * b){
    if(!e || !e->current || !b) return 0;
    else{
        cwal_string * s;







>
|
|
>
>
|
>
















>

|

|





|
|
|







|

>
|
|

|
|







5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
    return CWAL_VALPART(s);
}

cwal_value * cwal_new_buffer_value(cwal_engine *e, cwal_size_t startingSize){
    cwal_value * v = cwal_value_new(e, e->current, CWAL_TYPE_BUFFER,0);
    if( NULL != v )
    {
        cwal_buffer_obj * bo = CWAL_BUFOBJ(v);
        cwal_buffer * b;
        assert(NULL != bo);
        b = &bo->buf;
        b->self = bo;
        cwal_buffer_wipe_keep_self(b);
        assert(bo == b->self);
        if(startingSize &&
           cwal_buffer_reserve(e, b, startingSize)){
            cwal_value_unref2(e, v);
            v = NULL;
        }
    }
    return v;
}

int cwal_buffer_unref(cwal_engine *e, cwal_buffer *v){
    return (e&&v)
        ? cwal_value_unref2( e, cwal_buffer_value(v) )
        : CWAL_RC_MISUSE;
}

int cwal_value_fetch_buffer( cwal_value const * val, cwal_buffer ** x){
    cwal_buffer_obj * bo;
    if( ! val ) return CWAL_RC_MISUSE;
    else if( !(bo = CWAL_BUFOBJ(val)) ) return CWAL_RC_TYPE;
    else{
        if(x) *x = &bo->buf;
        return 0;
    }
}
    
cwal_buffer * cwal_value_get_buffer( cwal_value const * v ) {
    cwal_buffer * b = NULL;
    cwal_value_fetch_buffer( v, &b );
    return b;
}

cwal_buffer * cwal_new_buffer(cwal_engine *e, cwal_size_t startingSize){
    return cwal_value_get_buffer(cwal_new_buffer_value(e, startingSize));
}

cwal_value * cwal_buffer_value(cwal_buffer const * s){
    if(!s || !s->self) return 0;
    else{
        cwal_buffer_obj const * bo = (cwal_buffer_obj const *)s->self;
        cwal_value * v = CWAL_VALPART(bo);
        assert(v && v->vtab && (CWAL_TYPE_BUFFER==v->vtab->typeID))
            /* trying to protect against misuse of stack-allocated
               buffers there. */;
        return v;
    }
}

cwal_string * cwal_buffer_to_zstring(cwal_engine * e, cwal_buffer * b){
    if(!e || !e->current || !b) return 0;
    else{
        cwal_string * s;
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076

6077


6078
6079
6080
6081
6082
6083
6084
6085
6086
                                           b->used);
        if(s){
            /* Re-tweak the metrics which the ctor just counted,
               discounting b->used, as that was already counted
               elsewhere. */
            assert(e->metrics.bytes[CWAL_TYPE_ZSTRING] >= b->used);
            e->metrics.bytes[CWAL_TYPE_ZSTRING] -= b->used;
            *b = cwal_buffer_empty;
        }
        return s;
    }
}

cwal_value * cwal_buffer_to_zstring_value(cwal_engine * e, cwal_buffer * b){
    return cwal_string_value(cwal_buffer_to_zstring(e,b));
}
    
/**
   cwal_value_vtab::destroy_value() impl for Buffer
   values. Cleans up self-owned memory, but does not
   free self.
*/
void cwal_value_cleanup_buffer( cwal_engine * e, void * self ){
    cwal_value * v = (cwal_value*)self;

    cwal_buffer_reserve(e, CWAL_BUF(v), 0 );


}


void cwal_value_cleanup_exception( cwal_engine * e, void * self ){
    cwal_value * v = (cwal_value*)self;
    cwal_exception * f = CWAL_VVPCAST(cwal_exception,v);
    cwal_cleanup_obase(e, &f->base, 1);
    *f = cwal_exception_empty;
}







|
















>
|
>
>

<







6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103

6104
6105
6106
6107
6108
6109
6110
                                           b->used);
        if(s){
            /* Re-tweak the metrics which the ctor just counted,
               discounting b->used, as that was already counted
               elsewhere. */
            assert(e->metrics.bytes[CWAL_TYPE_ZSTRING] >= b->used);
            e->metrics.bytes[CWAL_TYPE_ZSTRING] -= b->used;
            cwal_buffer_wipe_keep_self(b);
        }
        return s;
    }
}

cwal_value * cwal_buffer_to_zstring_value(cwal_engine * e, cwal_buffer * b){
    return cwal_string_value(cwal_buffer_to_zstring(e,b));
}
    
/**
   cwal_value_vtab::destroy_value() impl for Buffer
   values. Cleans up self-owned memory, but does not
   free self.
*/
void cwal_value_cleanup_buffer( cwal_engine * e, void * self ){
    cwal_value * v = (cwal_value*)self;
    cwal_buffer_obj * bo = CWAL_BUFOBJ(v);
    cwal_buffer_reserve(e, &bo->buf, 0);
    cwal_cleanup_obase(e, &bo->base, 1);
    *bo = cwal_buffer_obj_empty;
}


void cwal_value_cleanup_exception( cwal_engine * e, void * self ){
    cwal_value * v = (cwal_value*)self;
    cwal_exception * f = CWAL_VVPCAST(cwal_exception,v);
    cwal_cleanup_obase(e, &f->base, 1);
    *f = cwal_exception_empty;
}
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675


cwal_string * cwal_new_stringfv(cwal_engine * e, char const * fmt, va_list args ){
    if(!e || !fmt) return 0;
    else if(!*fmt) return cwal_new_string(e,"",0);
    else{
        int rc;
        /*
          = cwal_buffer_reserve(e, &e->buffer, 32);
        if(rc) return NULL;
        cwal_buffer_reset(&e->buffer);
        */
#if 0
        cwal_buffer buf = cwal_buffer_empty;
        cwal_string * sv;
        rc = cwal_buffer_printfv(e, &buf, fmt, args);
        sv = rc
            ? NULL
            : cwal_new_string(e,
                    buf.used ? (char const*)(buf.mem) : NULL,
                    buf.used);
        cwal_buffer_reserve(e, &buf, 0);
        return sv;
#else
        cwal_size_t const oldUsed = e->buffer.used;
        cwal_size_t slen;
        rc = cwal_buffer_printfv(e, &e->buffer, fmt, args);
        slen = e->buffer.used - oldUsed;
        e->buffer.used = oldUsed;
        return rc
            ? NULL
            : cwal_new_string(e,
                    slen ? (char const*)(e->buffer.mem+oldUsed) : NULL,
                    slen);
            ;
#endif
    }
}

cwal_string * cwal_new_stringf(cwal_engine * e, char const * fmt, ...){
    if(!e || !fmt) return 0;
    else if(!*fmt) return cwal_new_string(e,"",0);
    else{







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











<







6657
6658
6659
6660
6661
6662
6663

















6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674

6675
6676
6677
6678
6679
6680
6681


cwal_string * cwal_new_stringfv(cwal_engine * e, char const * fmt, va_list args ){
    if(!e || !fmt) return 0;
    else if(!*fmt) return cwal_new_string(e,"",0);
    else{
        int rc;

















        cwal_size_t const oldUsed = e->buffer.used;
        cwal_size_t slen;
        rc = cwal_buffer_printfv(e, &e->buffer, fmt, args);
        slen = e->buffer.used - oldUsed;
        e->buffer.used = oldUsed;
        return rc
            ? NULL
            : cwal_new_string(e,
                    slen ? (char const*)(e->buffer.mem+oldUsed) : NULL,
                    slen);
            ;

    }
}

cwal_string * cwal_new_stringf(cwal_engine * e, char const * fmt, ...){
    if(!e || !fmt) return 0;
    else if(!*fmt) return cwal_new_string(e,"",0);
    else{
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
int cwal_props_copy( cwal_value * src, cwal_value * dest ){
    if(!src || !dest) return CWAL_RC_MISUSE;
    else if(!cwal_props_can(src) || !cwal_props_can(dest)) return CWAL_RC_TYPE;
    else return cwal_props_visit_kvp( src, cwal_kvp_visitor_props_copy, dest );
}


#if 0
int cwal_value_clear_mutable_state( cwal_value * v ){
    cwal_engine * e = CWAL_VENGINE(v);
    assert(e);
    if(!e || !v) return CWAL_RC_MISUSE;
    else if(V_IS_BUILTIN(v)) return 0;
    switch(v->vtab->typeID){
      case CWAL_TYPE_INTEGER:
      case CWAL_TYPE_DOUBLE:
      case CWAL_TYPE_STRING:
          return 0;
      case CWAL_TYPE_ARRAY:
          cwal_value_cleanup_array_impl( e, v, 1, 1, 0 );
          return 0;
      case CWAL_TYPE_OBJECT:
      case CWAL_TYPE_BUFFER:
      case CWAL_TYPE_NATIVE:
      case CWAL_TYPE_FUNCTION:
      case CWAL_TYPE_EXCEPTION:{
          cwal_obase * b = CWAL_VOBASE(v);
          cwal_value * proto = b ? b->prototype : NULL;
          assert(b);
          b->prototype = 0/* kludge */;
          v->vtab->cleanup( e, v );
          b->prototype = proto;
          return 0;
      }
      default:
          assert(!"unhandled type");
          return CWAL_RC_CANNOT_HAPPEN;
    }

}
#endif
    
char cwal_props_has_any( cwal_value const * c ){
    cwal_obase const * b = CWAL_VOBASE(c);
    return b && b->kvp ? 1 : 0;
}

cwal_size_t cwal_props_count( cwal_value const * c ){
    cwal_obase const * b = CWAL_VOBASE(c);







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







8458
8459
8460
8461
8462
8463
8464



































8465
8466
8467
8468
8469
8470
8471
int cwal_props_copy( cwal_value * src, cwal_value * dest ){
    if(!src || !dest) return CWAL_RC_MISUSE;
    else if(!cwal_props_can(src) || !cwal_props_can(dest)) return CWAL_RC_TYPE;
    else return cwal_props_visit_kvp( src, cwal_kvp_visitor_props_copy, dest );
}





































char cwal_props_has_any( cwal_value const * c ){
    cwal_obase const * b = CWAL_VOBASE(c);
    return b && b->kvp ? 1 : 0;
}

cwal_size_t cwal_props_count( cwal_value const * c ){
    cwal_obase const * b = CWAL_VOBASE(c);
10948
10949
10950
10951
10952
10953
10954
10955



10956
10957
10958
10959
10960
10961
10962
int cwal_buffer_reserve( cwal_engine * e, cwal_buffer * buf, cwal_size_t n ){
    if( !e || !buf ) return CWAL_RC_MISUSE;
    else if( 0 == n ){
        if(buf->mem){
            assert(buf->capacity);
            assert((cwal_size_t)-1 != buf->capacity);
            cwal_memchunk_add(e, buf->mem, buf->capacity);
            *buf = cwal_buffer_empty;



        }
        return 0;
    }
    else if( buf->capacity >= n ){
            return 0;
    }
    







|
>
>
>







10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
int cwal_buffer_reserve( cwal_engine * e, cwal_buffer * buf, cwal_size_t n ){
    if( !e || !buf ) return CWAL_RC_MISUSE;
    else if( 0 == n ){
        if(buf->mem){
            assert(buf->capacity);
            assert((cwal_size_t)-1 != buf->capacity);
            cwal_memchunk_add(e, buf->mem, buf->capacity);
            cwal_buffer_wipe_keep_self(buf);
            assert(0==buf->mem);
            assert(0==buf->capacity);
            assert(0==buf->used);
        }
        return 0;
    }
    else if( buf->capacity >= n ){
            return 0;
    }
    
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
    {/*CWAL_TYPE_DOUBLE*/0, sizeof(cwal_value)+sizeof(cwal_double_t)},
    {/*CWAL_TYPE_STRING*/ "Incl. string bytes plus NULs", sizeof(cwal_value)+sizeof(cwal_string)},
    {/*CWAL_TYPE_ARRAY*/ "Not incl. cwal_list memory", sizeof(cwal_value)+sizeof(cwal_array)},
    {/*CWAL_TYPE_OBJECT*/ 0, sizeof(cwal_value)+sizeof(cwal_object)},
    {/*CWAL_TYPE_FUNCTION*/ 0, sizeof(cwal_value)+sizeof(cwal_function)},
    {/*CWAL_TYPE_EXCEPTION*/ 0, sizeof(cwal_value)+sizeof(cwal_exception)},
    {/*CWAL_TYPE_NATIVE*/ "Not including (opaque/unknown) native memory", sizeof(cwal_value)+sizeof(cwal_native)},
    {/*CWAL_TYPE_BUFFER*/ "[2] Incl. total allocated buffer memory and non-Value buffers", sizeof(cwal_value)+sizeof(cwal_buffer)},
    {/*CWAL_TYPE_HASH*/ "Not incl. cwal_list table memory.", sizeof(cwal_value)+sizeof(cwal_hash)},
    {/*CWAL_TYPE_SCOPE*/ "[3]", sizeof(cwal_scope)},
    {/*CWAL_TYPE_KVP*/ "Key/value pairs (obj. properties/hash entries)", sizeof(cwal_kvp)},
    {/*CWAL_TYPE_WEAK_REF*/ 0, sizeof(cwal_weak_ref)},
    {/*CWAL_TYPE_XSTRING*/ "Not incl. external string bytes", sizeof(cwal_value)+sizeof(cwal_string)+sizeof(char **)},
    {/*CWAL_TYPE_ZSTRING*/ "Incl. string bytes", sizeof(cwal_value)+sizeof(cwal_string)+sizeof(char **)},
    {/*CWAL_TYPE_UNIQUE*/ 0, sizeof(cwal_value)+sizeof(cwal_value*)},







|







11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
    {/*CWAL_TYPE_DOUBLE*/0, sizeof(cwal_value)+sizeof(cwal_double_t)},
    {/*CWAL_TYPE_STRING*/ "Incl. string bytes plus NULs", sizeof(cwal_value)+sizeof(cwal_string)},
    {/*CWAL_TYPE_ARRAY*/ "Not incl. cwal_list memory", sizeof(cwal_value)+sizeof(cwal_array)},
    {/*CWAL_TYPE_OBJECT*/ 0, sizeof(cwal_value)+sizeof(cwal_object)},
    {/*CWAL_TYPE_FUNCTION*/ 0, sizeof(cwal_value)+sizeof(cwal_function)},
    {/*CWAL_TYPE_EXCEPTION*/ 0, sizeof(cwal_value)+sizeof(cwal_exception)},
    {/*CWAL_TYPE_NATIVE*/ "Not including (opaque/unknown) native memory", sizeof(cwal_value)+sizeof(cwal_native)},
    {/*CWAL_TYPE_BUFFER*/ "[2] Incl. total allocated buffer memory and non-Value buffers", sizeof(cwal_value)+sizeof(cwal_buffer_obj)},
    {/*CWAL_TYPE_HASH*/ "Not incl. cwal_list table memory.", sizeof(cwal_value)+sizeof(cwal_hash)},
    {/*CWAL_TYPE_SCOPE*/ "[3]", sizeof(cwal_scope)},
    {/*CWAL_TYPE_KVP*/ "Key/value pairs (obj. properties/hash entries)", sizeof(cwal_kvp)},
    {/*CWAL_TYPE_WEAK_REF*/ 0, sizeof(cwal_weak_ref)},
    {/*CWAL_TYPE_XSTRING*/ "Not incl. external string bytes", sizeof(cwal_value)+sizeof(cwal_string)+sizeof(char **)},
    {/*CWAL_TYPE_ZSTRING*/ "Incl. string bytes", sizeof(cwal_value)+sizeof(cwal_string)+sizeof(char **)},
    {/*CWAL_TYPE_UNIQUE*/ 0, sizeof(cwal_value)+sizeof(cwal_value*)},
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
        else v = cwal_value_prototype_get(e, v);
    }while(v);
    return NULL;
}

cwal_buffer * cwal_value_buffer_part( cwal_engine * e,
                                      cwal_value * v ){
    cwal_buffer * f;
    do{
        if( (f = CWAL_BUF(v)) ) return f;
        else v = cwal_value_prototype_get(e, v);
    }while(v);
    return NULL;
}

cwal_native * cwal_value_native_part( cwal_engine * e,
                                      cwal_value * v,







|

|







11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
        else v = cwal_value_prototype_get(e, v);
    }while(v);
    return NULL;
}

cwal_buffer * cwal_value_buffer_part( cwal_engine * e,
                                      cwal_value * v ){
    cwal_buffer_obj * f;
    do{
        if( (f = CWAL_BUFOBJ(v)) ) return &f->buf;
        else v = cwal_value_prototype_get(e, v);
    }while(v);
    return NULL;
}

cwal_native * cwal_value_native_part( cwal_engine * e,
                                      cwal_value * v,
Changes to cwal_internal.h.
845
846
847
848
849
850
851



852
853
854
855
856
857
858
        0/*native*/,\
        0/*typeID*/,\
        0/*finalize*/, \
        0/*rescope_children*/ \
        }
extern const cwal_native cwal_native_empty;




struct cwal_hash {
    /**
       base MUST be the first member for casting reasons.
    */
    cwal_obase base;
    /**
       Array (hash table) of (cwal_kvp*) values.







>
>
>







845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
        0/*native*/,\
        0/*typeID*/,\
        0/*finalize*/, \
        0/*rescope_children*/ \
        }
extern const cwal_native cwal_native_empty;

/** @internal
   Hash table Value type.
*/
struct cwal_hash {
    /**
       base MUST be the first member for casting reasons.
    */
    cwal_obase base;
    /**
       Array (hash table) of (cwal_kvp*) values.
873
874
875
876
877
878
879























880
881
882
883
884
885
886
#define cwal_hash_empty_m {            \
    cwal_obase_empty_m/*base*/,        \
    cwal_list_empty_m/*table*/,    \
    0/*hashSize*/\
    }
extern const cwal_hash cwal_hash_empty;
























/** @internal

    Internal impl of the weak reference class.
*/
struct cwal_weak_ref {
    void * value;
    cwal_type_id typeID;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
#define cwal_hash_empty_m {            \
    cwal_obase_empty_m/*base*/,        \
    cwal_list_empty_m/*table*/,    \
    0/*hashSize*/\
    }
extern const cwal_hash cwal_hash_empty;


/** @internal

    An object-style representation for cwal_buffer. This type is
    strictly internal, not exposed to clients.
*/
struct cwal_buffer_obj {
    /**
       base MUST be the first member for casting reasons.
    */
    cwal_obase base;
    /**
       The buffer owned/tracked by this object.
    */
    cwal_buffer buf;
};
typedef struct cwal_buffer_obj cwal_buffer_obj;
#define cwal_buffer_obj_empty_m {\
    cwal_obase_empty_m/*base*/, \
    cwal_buffer_empty_m/*buf*/ \
}
extern const cwal_buffer_obj cwal_buffer_obj_empty;

/** @internal

    Internal impl of the weak reference class.
*/
struct cwal_weak_ref {
    void * value;
    cwal_type_id typeID;
Changes to include/wh/cwal/cwal.h.
2175
2176
2177
2178
2179
2180
2181













2182
2183
2184
2185
2186
2187
2188
       (You might also need to store buf.used and buf.capacity,
       depending on what you want to do with the memory.)
       
       When doing so, the memory must eventually be passed to free()
       to deallocate it.
    */
    unsigned char * mem;













};


/**
   A typedef used by cwal_engine_type_name_proxy() to allow
   clients to hook their own type names into
   cwal_value_type_name().







>
>
>
>
>
>
>
>
>
>
>
>
>







2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
       (You might also need to store buf.used and buf.capacity,
       depending on what you want to do with the memory.)
       
       When doing so, the memory must eventually be passed to free()
       to deallocate it.
    */
    unsigned char * mem;

    /**
       For internal use by cwal to differentiate between
       container-style buffers and non-container style without
       requiring a complete overhaul of the buffer API to make
       Container-type representations of them.

       Clients MUST NOT modify this. It is only non-NULL for buffers
       created via cwal_new_buffer() resp.  cwal_new_buffer_value(),
       and its non-NULL value has a very specific meaning. To
       reiterate: clients MUST NOT modify this.
    */
    void * self;
};


/**
   A typedef used by cwal_engine_type_name_proxy() to allow
   clients to hook their own type names into
   cwal_value_type_name().
5671
5672
5673
5674
5675
5676
5677
5678

5679
5680
5681
5682
5683
5684
5685
   Returns non-0 (true) if c is of a type capable of
   containing per-instance properties, else 0 (false).

   The following value types will return true from
   this function:

   CWAL_TYPE_ARRAY, CWAL_TYPE_OBJECT, CWAL_TYPE_FUNCTION,
   CWAL_TYPE_EXCEPTION, CWAL_TYPE_NATIVE, CWAL_TYPE_HASH


   All others return false.

   Note that arrays can also contain integer-indexed properties and
   hashes can contain hashed properties.
*/
char cwal_props_can( cwal_value const * c );







|
>







5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
   Returns non-0 (true) if c is of a type capable of
   containing per-instance properties, else 0 (false).

   The following value types will return true from
   this function:

   CWAL_TYPE_ARRAY, CWAL_TYPE_OBJECT, CWAL_TYPE_FUNCTION,
   CWAL_TYPE_EXCEPTION, CWAL_TYPE_NATIVE, CWAL_TYPE_HASH,
   CWAL_TYPE_BUFFER (as of 20141217).

   All others return false.

   Note that arrays can also contain integer-indexed properties and
   hashes can contain hashed properties.
*/
char cwal_props_can( cwal_value const * c );
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014

/**
   An empty-initialized cwal_buffer object.

   ALWAYS initialize embedded-in-struct cwal_buffers by copying
   this object!
*/
#define cwal_buffer_empty_m {0/*capacity*/,0/*used*/,NULL/*mem*/}

/**
   An empty-initialized cwal_buffer object. ALWAYS initialize
   stack-allocated cwal_buffers by copying this object!
*/
extern const cwal_buffer cwal_buffer_empty;








|







7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028

/**
   An empty-initialized cwal_buffer object.

   ALWAYS initialize embedded-in-struct cwal_buffers by copying
   this object!
*/
#define cwal_buffer_empty_m {0/*capacity*/,0/*used*/,NULL/*mem*/, 0/*self*/}

/**
   An empty-initialized cwal_buffer object. ALWAYS initialize
   stack-allocated cwal_buffers by copying this object!
*/
extern const cwal_buffer cwal_buffer_empty;

Changes to s2/s2_str.c.
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    }\
  } (void)0


#define THIS_BUFFER                                             \
  cwal_buffer * self; ARGS_SE;                                  \
  if(!se) return CWAL_RC_MISUSE;                                \
  else if(!(self=cwal_value_get_buffer(args->self))){         \
    return cwal_exception_setf( args->engine, CWAL_RC_TYPE,      \
                                "'this' is-not-a Buffer." );     \
  } (void)0


static int s2_cb_str_concat( cwal_callback_args const * args, cwal_value **rv ){
  if(!args->argc){







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    }\
  } (void)0


#define THIS_BUFFER                                             \
  cwal_buffer * self; ARGS_SE;                                  \
  if(!se) return CWAL_RC_MISUSE;                                \
  else if(!(self=cwal_value_buffer_part(args->engine, args->self))){ \
    return cwal_exception_setf( args->engine, CWAL_RC_TYPE,      \
                                "'this' is-not-a Buffer." );     \
  } (void)0


static int s2_cb_str_concat( cwal_callback_args const * args, cwal_value **rv ){
  if(!args->argc){
Changes to s2/shell.c.
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
    */
    REMAX(UNIQUE,20)/* will end up being trumped by integer (32-bit)
                       and/or double (64-bit) */;
    REMAX(KVP,80) /* guaranteed individual recycler */;
    REMAX(WEAK_REF,30) /* guaranteed individual recycler */;
    REMAX(STRING,50) /* guaranteed individual recycler */;
    REMAX(EXCEPTION,3);
    REMAX(HASH,15) /* might also include: function, native */;
    REMAX(BUFFER,20) /* might also include: object */ ;
    REMAX(XSTRING,20 /* also Z-strings, might also include doubles */);
    REMAX(NATIVE,20)  /* might also include: function, hash */;
    REMAX(DOUBLE,50)/* might also include z-/x-strings,
                       integer (64-bit), unique (64-bit)*/;
    REMAX(FUNCTION,50) /* might include: hash, native */;
    REMAX(ARRAY,30);
    REMAX(OBJECT,30) /* might include: buffer */;
    REMAX(INTEGER,80) /* might include: double, unique */;

#endif
  }
#undef REMAX







|
|




|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
    */
    REMAX(UNIQUE,20)/* will end up being trumped by integer (32-bit)
                       and/or double (64-bit) */;
    REMAX(KVP,80) /* guaranteed individual recycler */;
    REMAX(WEAK_REF,30) /* guaranteed individual recycler */;
    REMAX(STRING,50) /* guaranteed individual recycler */;
    REMAX(EXCEPTION,3);
    REMAX(HASH,15) /* might also include: function, native, buffer */;
    REMAX(BUFFER,20) /* might also include: function, native, buffer, hash */ ;
    REMAX(XSTRING,20 /* also Z-strings, might also include doubles */);
    REMAX(NATIVE,20)  /* might also include: function, hash */;
    REMAX(DOUBLE,50)/* might also include z-/x-strings,
                       integer (64-bit), unique (64-bit)*/;
    REMAX(FUNCTION,50) /* might include: hash, native, buffer */;
    REMAX(ARRAY,30);
    REMAX(OBJECT,30) /* might include: buffer */;
    REMAX(INTEGER,80) /* might include: double, unique */;

#endif
  }
#undef REMAX
1298
1299
1300
1301
1302
1303
1304
1305





1306
1307
1308
1309
1310
1311
1312
  if(0==strcmp("ta",pos)){
    App.memcap.maxTotalAllocCount = parse_cap_value(val, &rc)
      /* Caps the cumulative total number of memory allocations made
         by the engine. 0=disabled. OOM errors after this total is hit
         are not recoverable without resetting the engine. */
      ;
  }else if(0==strcmp("tb",pos)){
    App.memcap.maxTotalMem =  parse_cap_value(val, &rc);





  }else if(0==strcmp("ca",pos)){
    App.memcap.maxConcurrentAllocCount = parse_cap_value(val, &rc)
      /* Max number of memory chunks the allocator should serve
         at a time. After this, it will fail until a chunk
         is freed. */
      ;
  }else if(0==strcmp("sb",pos)){







|
>
>
>
>
>







1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
  if(0==strcmp("ta",pos)){
    App.memcap.maxTotalAllocCount = parse_cap_value(val, &rc)
      /* Caps the cumulative total number of memory allocations made
         by the engine. 0=disabled. OOM errors after this total is hit
         are not recoverable without resetting the engine. */
      ;
  }else if(0==strcmp("tb",pos)){
    App.memcap.maxTotalMem =  parse_cap_value(val, &rc)
      /* Caps the cumulative total memory allocated by the engine.
         0=disabled. Requires over-allocation so that reallocs can be
         properly tracked. OOM errors after this total is hit are not
         recoverable without resetting the engine. */
      ;
  }else if(0==strcmp("ca",pos)){
    App.memcap.maxConcurrentAllocCount = parse_cap_value(val, &rc)
      /* Max number of memory chunks the allocator should serve
         at a time. After this, it will fail until a chunk
         is freed. */
      ;
  }else if(0==strcmp("sb",pos)){
1334
1335
1336
1337
1338
1339
1340






1341
1342
1343
1344
1345
1346
1347
{
  int rc = 0;
  int i;
  char const * arg;
  int gotNoOp = 0;
  assert(!App.shellExitFlag);
  App.appName = argv[0];






  for( i = 1; i < argc; ++i ){
    cwal_size_t argLen;
    arg = argv[i];
    argLen = cwal_strlen(arg);
#define ARG(STR) else if(0==strcmp(STR, arg))
#define GET_FLAG_VAL(TGT) \
    if( (rc=check_flag_val(arg, (i<argc-1) ? argv[i+1] : 0)) ) break; \







>
>
>
>
>
>







1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
{
  int rc = 0;
  int i;
  char const * arg;
  int gotNoOp = 0;
  assert(!App.shellExitFlag);
  App.appName = argv[0];

#if 0
  /* just for one test... */
  App.memcap.maxTotalMem = 1 << 30;
#endif

  for( i = 1; i < argc; ++i ){
    cwal_size_t argLen;
    arg = argv[i];
    argLen = cwal_strlen(arg);
#define ARG(STR) else if(0==strcmp(STR, arg))
#define GET_FLAG_VAL(TGT) \
    if( (rc=check_flag_val(arg, (i<argc-1) ? argv[i+1] : 0)) ) break; \
Changes to test.c.
1383
1384
1385
1386
1387
1388
1389

1390
1391
1392
1393
1394
1395
1396
    C(CWAL_INT_T_BITS);
    C(CWAL_VOID_PTR_IS_BIG);
    
#undef C
#define SO(T) total += sizeof(T); MARKER("sizeof(%s)=%u\n", #T, (unsigned int)sizeof(T))
    SO(void*);
    SO(cwal_array);

    SO(cwal_callback_args);
    SO(cwal_double_t);
    SO(cwal_engine);
    SO(cwal_engine_vtab);
    SO(cwal_int_t);
    SO(cwal_kvp);
    SO(cwal_list);







>







1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
    C(CWAL_INT_T_BITS);
    C(CWAL_VOID_PTR_IS_BIG);
    
#undef C
#define SO(T) total += sizeof(T); MARKER("sizeof(%s)=%u\n", #T, (unsigned int)sizeof(T))
    SO(void*);
    SO(cwal_array);
    SO(cwal_buffer);
    SO(cwal_callback_args);
    SO(cwal_double_t);
    SO(cwal_engine);
    SO(cwal_engine_vtab);
    SO(cwal_int_t);
    SO(cwal_kvp);
    SO(cwal_list);