int popStack(Stack* s, void* data){ if(bottomStack(s) == STACKUNDERRUN) return STACKUNDERRUN; bcopy(s->top->value, data, s->size); ec_free(s->top->value); StackElement* holder = s->top->prevelement; ec_free(s->top); s->top = holder; return STACKSUCCESS; }
int breakStack(Stack* s){ // this needs to free the stack all the way to the bottom. StackElement* holder; while (bottomStack(s)==STACKSUCCESS){ holder = s->top->prevelement; ec_free(s->top->value); ec_free(s->top); s->top = holder; } ec_free(s); return STACKSUCCESS; }
static void match_free( EC_OBJ obj ) { if (! EC_MATCH(obj)) return; EC_MATCH_NSUB(obj) = 0; if (EC_MATCH_OVECTOR(obj)) ec_free( EC_MATCH_OVECTOR(obj) ); EC_MATCH_OVECTOR(obj) = NULL; EC_MATCH_OVECSIZE(obj) = 0; EC_MATCH_SUBJECT(obj) = EC_NIL; EC_MATCH_REGEXP(obj) = EC_NIL; ec_free( EC_MATCH(obj) ); EC_MATCH(obj) = NULL; }
EC_API void ec_hash_iterator_destroy( ec_hash_iterator iterator ) { ENTERF; iterator->hash = NULL; iterator->next = 0; ec_free( iterator ); }
static EcBool hash_cleanup( ec_hash table ) { EcUInt i; ec_hash_entry entry; ASSERT(table); ASSERT( (H_CAPACITY(table) == 0) || H_ENTRYBASE(table) ); for (i = 0; i < H_CAPACITY(table); i++) { entry = H_ENTRY(table, i); ASSERT( entry ); if (H_DEF(table).key_destroy && (EC_HASH_ENTRY_KEY(entry) != H_INVKEY(table))) H_KEYDESTROY(table, EC_HASH_ENTRY_KEY(entry)); if (H_DEF(table).value_destroy && (EC_HASH_ENTRY_VALUE(entry) != H_INVVAL(table))) H_VALDESTROY(table, EC_HASH_ENTRY_VALUE(entry)); } ec_free( H_ENTRYBASE(table) ); H_ENTRYBASE(table) = NULL; H_CAPACITY(table) = 0; H_PRIMEINDEX(table) = 0; H_ENTRIES(table) = 0; return TRUE; }
int cp_ecss_sig(bn_t e, bn_t s, uint8_t *msg, int len, bn_t d) { bn_t n, k, x, r; ec_t p; uint8_t hash[MD_LEN]; uint8_t m[len + FC_BYTES]; int result = STS_OK; bn_null(n); bn_null(k); bn_null(x); bn_null(r); ec_null(p); TRY { bn_new(n); bn_new(k); bn_new(x); bn_new(r); ec_new(p); ec_curve_get_ord(n); do { bn_rand_mod(k, n); ec_mul_gen(p, k); ec_get_x(x, p); bn_mod(r, x, n); } while (bn_is_zero(r)); memcpy(m, msg, len); bn_write_bin(m + len, FC_BYTES, r); md_map(hash, m, len + FC_BYTES); if (8 * MD_LEN > bn_bits(n)) { len = CEIL(bn_bits(n), 8); bn_read_bin(e, hash, len); bn_rsh(e, e, 8 * MD_LEN - bn_bits(n)); } else { bn_read_bin(e, hash, MD_LEN); } bn_mod(e, e, n); bn_mul(s, d, e); bn_mod(s, s, n); bn_sub(s, n, s); bn_add(s, s, k); bn_mod(s, s, n); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); bn_free(k); bn_free(x); bn_free(r); ec_free(p); } return result; }
//breakList() deallocates all memory used in a LinkedList //list : a pointer to the LinkedList to be deallocated //returns : a status code as defined in linklist.h int breakList(LinkedList list){ while(isEmpty(list)==LLSUCCESS){ deleteLastElement(list); } ec_free(list); return LLSUCCESS; }
static void array_free( EC_OBJ obj ) { ec_free( EC_ARRAYMEM(obj) ); EC_ARRAYMEM(obj) = NULL; EC_ARRAYLEN(obj) = 0; EC_ARRAYREAL(obj) = 0; }
static void ustring_free( EC_OBJ obj ) { EC_ASSERT( EC_USTRINGP(obj) ); ec_free( EC_USTRDATA(obj) ); EC_USTRDATA(obj) = NULL; EC_USTRLEN(obj) = 0; }
static void printQualifiedSymbol( int lev, ASTNode node ) { char *string; indent( lev ); string = EcQualifiedString( QSYM(node) ); ec_stderr_printf( "<qsymbol `%s'>", string ); ec_free( string ); }
static void printVariable( int lev, ASTNode node ) { char *name; name = EcQualifiedString( QSYM(node) ); indent( lev ); ec_stderr_printf( "<var `%s'>", name ); ec_free( name ); }
EC_API void ec_arena_destroy( ec_arena *arena ) { ASSERT(arena); ec_free( arena->mem ); arena->mem = NULL; arena->last = NULL; arena->head = NULL; arena->tail = NULL; arena->size = 0; }
//deleteElement() deletes an existing ListElement //toDelete : a pointer to the ListElement to delete //returns : a status code as defined in linklist.h // fails fatally if pointer toDelete is NULL static int deleteElement(ListElement* toDelete){ if(toDelete==NULL) return LLFAIL; ListElement* beforeDelete = toDelete->prevElement; ListElement* afterDelete = toDelete->nextElement; if(beforeDelete!=NULL) { beforeDelete->nextElement = afterDelete; } if(afterDelete!=NULL){ afterDelete->prevElement = beforeDelete; } ec_free(toDelete->value); ec_free(toDelete); return LLSUCCESS; }
bool dev_find_iface_by_ipaddr(ajws_dev_t *dev) { if (dev->name != NULL) { ec_free(dev->name); dev->name = NULL; } return dev_find_iface(dev, __dev_cmp_ipaddr); }
static void class_free( EC_OBJ obj ) { ASSERT( EC_CLASSP(obj) ); EC_CLASSSUPER(obj) = EC_NIL; EC_CLASSNMETHODS(obj) = 0; ec_free( EC_CLASSMTABLE(obj) ); EC_CLASSMTABLE(obj) = NULL; EC_CLASSNCMETHODS(obj) = 0; ec_free( EC_CLASSCMTABLE(obj) ); EC_CLASSCMTABLE(obj) = NULL; EC_CLASSIOFFSET(obj) = 0; EC_CLASSNIVARS(obj) = 0; ec_free( EC_CLASSIVTABLE(obj) ); EC_CLASSIVTABLE(obj) = NULL; EC_CLASSNCVARS(obj) = 0; ec_free( EC_CLASSCVTABLE(obj) ); EC_CLASSCVTABLE(obj) = NULL; EC_CLASSPACKAGE(obj) = EC_NIL; EC_CLASSNAME(obj) = EC_NIL; EC_CLASSSHORTNAME(obj) = EC_NIL; EC_CLASSCODE(obj) = EC_NIL; }
static void object_free( EC_OBJ obj ) { ASSERT( EC_OBJECTP(obj) ); /* Is there a user-defined free method ? If so, call it */ /* TODO: call user-defined free method */ if (EcDoesUnderstand( obj, PRIVATE(gcfreeID) )) { EcSendMessage( obj, PRIVATE(gcfreeID), EC_NIL ); } EC_OBJECTCLASS(obj) = EC_NIL; ec_free( EC_OBJECTIVARS(obj) ); EC_OBJECTIVARS(obj) = NULL; EC_OBJECTUSER(obj) = NULL; }
EC_API void ec_list_destroy( ec_list list ) { ec_list_node node, next; check_list(list); if (! list) return; node = HEAD(list); next = NULL; while (node) { check_node(node); next = NEXT(node); free_node( node ); node = next; } del_magic_list(list); ec_free( list ); }
int cp_ecdh_key(uint8_t *key, int key_len, bn_t d, ec_t q) { ec_t p; bn_t x, h; int l, result = STS_OK; uint8_t _x[FC_BYTES]; ec_null(p); bn_null(x); bn_null(h); TRY { ec_new(p); bn_new(x); bn_new(h); ec_curve_get_cof(h); if (bn_bits(h) < BN_DIGIT) { ec_mul_dig(p, q, h->dp[0]); } else { ec_mul(p, q, h); } ec_mul(p, p, d); if (ec_is_infty(p)) { result = STS_ERR; } ec_get_x(x, p); l = bn_size_bin(x); bn_write_bin(_x, l, x); md_kdf2(key, key_len, _x, l); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ec_free(p); bn_free(x); bn_free(h); } return result; }
static void free_node( ec_list_node node ) { check_node(node); del_magic_node(node); ec_free( node ); }
int breakLLIterator(LLIterator iterator){ ec_free(iterator); iterator = NULL; return LLSUCCESS; }
EC_API void EcCleanup( void ) { void _ec_releaseOT( void ); EcInt i; PRIVATE(in_cleanup) = TRUE; #if MEM_STATS fprintf( stderr, "\nTYPE ALLOCATED MARKINGS\n" ); fprintf( stderr, "============================================\n" ); for (i = 0; i <= PRIVATE(usertypes); i++) fprintf( stderr, "%-20s %8ld %8ld\n", EcTypeName( i ), _ec_make_stats[i], _ec_mark_stats[i] ); #endif _ec_packageio_cleanup(); if (PRIVATE(builtin_name)) ec_hash_destroy( PRIVATE(builtin_name) ); PRIVATE(builtin_name) = NULL; ec_free( PRIVATE(cpointer) ); PRIVATE(ncpointers) = 0; PRIVATE(cpointer) = NULL; EcGCUnprotectAll(); PRIVATE(patchmap) = NULL; /* BREAK THE LINKS between toplevel and objects ! */ PRIVATE(rt.activeFrame) = EC_NIL; PRIVATE(globalFrame) = EC_NIL; PRIVATE(mainTarget) = EC_NIL; for (i = 0; i < PRIVATE(nglobals); i++) PRIVATE(global[i]) = EC_NIL; for (i = 0; i < PRIVATE(npackages); i++) PRIVATE(package[i].obj) = EC_NIL; #if EC_STACK_RECYCLE { EcInt j; #if EC_STACK_RECYCLE_STATS fprintf( stderr, "\n== Stack statistics =================\n" ); fprintf( stderr, "Calls to EcMakeStack() : %ld\n", (long)PRIVATE(n_makestack) ); fprintf( stderr, "# stores in recycle bin : %ld\n", (long)PRIVATE(n_recycle_put) ); fprintf( stderr, "# failed stores : %ld\n", (long)(PRIVATE(n_recycle_put_attempts) - PRIVATE(n_recycle_put)) ); fprintf( stderr, "# fetched from rec. bin : %ld\n", (long)PRIVATE(n_recycle_get) ); fprintf( stderr, "# failed fetches : %ld\n", (long)(PRIVATE(n_recycle_get_attempts) - PRIVATE(n_recycle_get)) ); fprintf( stderr, "# times the bin was empty: %ld\n", (long)PRIVATE(n_pool_empty) ); fprintf( stderr, "# times the bin was full : %ld\n", (long)PRIVATE(n_pool_full) ); /* fprintf( stderr, "bin max fill : %ld\n", (long)PRIVATE(pool_max_fill) ); */ fprintf( stderr, "# refcount increments : %ld\n", (long)PRIVATE(n_ref_inc) ); fprintf( stderr, "# refcount decrements : %ld\n", (long)PRIVATE(n_ref_dec) ); fprintf( stderr, "\n" ); #endif for (j = 0; j < EC_STACK_POOL_SIZE; j++) PRIVATE(stack_pool)[j] = EC_NIL; ec_bit_nclear(PRIVATE(stack_pool_bmap), 0, EC_STACK_POOL_SIZE-1); } #endif for (i = 0; i < GC_FINAL_PASSES; i++) EcGC(); /* Release all objects in a linear fashion */ _ec_releaseOT(); for (i = 0; i < PRIVATE(npackages); i++) { if (PRIVATE(package)[i].dlhandle) { if (PRIVATE(package)[i].dlcleanup_fcn) (*(PRIVATE(package)[i].dlcleanup_fcn))(); EcDLClose( PRIVATE(package)[i].dlhandle ); } ec_string_destroy( PRIVATE(package)[i].name ); PRIVATE(package)[i].name = NULL; PRIVATE(package)[i].dlhandle = NULL; PRIVATE(package)[i].dlinit_fcn = NULL; PRIVATE(package)[i].dlcleanup_fcn = NULL; } ec_free( PRIVATE(package) ); PRIVATE(package) = NULL; PRIVATE(npackages) = 0; for (i = tc_userbase; i <= PRIVATE(usertypes); i++) { ec_free( USERTYPE(i).name ); USERTYPE(i).name = NULL; ec_free( USERTYPE(i).sequence_cb ); ec_free( USERTYPE(i).numeric_cb ); } ec_free( PRIVATE(typespec) ); PRIVATE(typespec) = NULL; PRIVATE(usertypes) = 0; EcTrueObject = EC_NIL; EcFalseObject = EC_NIL; Ec_ERROR = EC_NIL; EcUndefinedObject = EC_NIL; EcMemoryErrorObject = EC_NIL; PRIVATE(rt).exc = EC_NIL; PRIVATE(rt).activeFrame = EC_NIL; PRIVATE(globalFrame) = EC_NIL; PRIVATE(rt).vm_level = -1; /* CloseScope( PRIVATE(currentScope) ); */ PRIVATE(currentScope) = NULL; PRIVATE(globalScope) = NULL; ec_freepool( PRIVATE(nodePool) ); PRIVATE(nodePool) = NULL; if (PRIVATE(symName)) { EcUInt i; for (i = 1; i <= PRIVATE(currentId); i++) { ec_free( PRIVATE(symName)[i] ); PRIVATE(symName)[i] = NULL; } ec_freeblock( PRIVATE(symName) ); PRIVATE(symName) = NULL; PRIVATE(symNameSize) = 0; } if (PRIVATE(symTable)) ec_strtable_destroy( PRIVATE(symTable) ); PRIVATE(symTable) = NULL; PRIVATE(currentId) = 0; ec_free( PRIVATE(fileOutput) ); ec_free( PRIVATE(fileSource) ); ec_free( PRIVATE(sourceOrigin) ); PRIVATE(sourceOrigin) = NULL; PRIVATE(fileSource) = NULL; PRIVATE(fileOutput) = NULL; PRIVATE(startLine) = 0; PRIVATE(startColumn) = 0; PRIVATE(endLine) = 0; PRIVATE(endColumn) = 0; #if 0 for (i = 0; i < PRIVATE(argc); i++) ec_free( PRIVATE(argv)[i] ); ec_free( PRIVATE(argv) ); PRIVATE(argc) = 0; PRIVATE(argv) = NULL; #endif _ec_list_cleanup(); _ec_hash_cleanup(); _ec_object_cleanup(); _ec_class_cleanup(); _ec_package_cleanup(); _ec_handler_cleanup(); _ec_compiled_cleanup(); _ec_stack_cleanup(); _ec_string_cleanup(); _ec_char_cleanup(); _ec_array_cleanup(); EcDLCleanup(); PRIVATE(in_cleanup) = FALSE; }
int main( int argc, char *argv[] ) { int ch; char *source; /* Scan options */ while ((ch = getopt( argc, argv, "dhvlVo:" )) != -1) { switch ((char) ch) { case 'd': option_debug = TRUE; break; case 'o': option_outputfile = ec_stringdup( optarg ); break; case 'h': usage(); exit( EXIT_SUCCESS ); break; case 'v': option_verbose = TRUE; break; case 'l': option_lazy = TRUE; break; case 'V': version(); exit( EXIT_SUCCESS ); break; default: usage(); exit( EXIT_FAILURE ); break; } } if (optind >= argc) { usage(); exit( EXIT_FAILURE ); } source = argv[optind]; #ifdef EC_THREADING if (! EcThreadingInit() || ! EcInit()) #else if (! EcInit()) #endif { error( "can't initialize elastiC environment" ); goto onError; } if (! doCompile( source, option_outputfile, option_lazy )) { error( "error during compilation" ); goto onError; } /* OK */ ec_free( option_outputfile ); EcCleanup(); exit( EXIT_SUCCESS ); onError: ec_free( option_outputfile ); EcCleanup(); exit( EXIT_FAILURE ); }
int cp_ecss_ver(bn_t e, bn_t s, uint8_t *msg, int len, ec_t q) { bn_t n, ev, rv; ec_t p; uint8_t hash[MD_LEN]; uint8_t m[len + FC_BYTES]; int result = 0; bn_null(n); bn_null(ev); bn_null(rv); ec_null(p); TRY { bn_new(n); bn_new(ev); bn_new(rv); ec_new(p); ec_curve_get_ord(n); if (bn_sign(e) == BN_POS && bn_sign(s) == BN_POS && !bn_is_zero(s)) { if (bn_cmp(e, n) == CMP_LT && bn_cmp(s, n) == CMP_LT) { ec_mul_sim_gen(p, s, q, e); ec_get_x(rv, p); bn_mod(rv, rv, n); memcpy(m, msg, len); bn_write_bin(m + len, FC_BYTES, rv); md_map(hash, m, len + FC_BYTES); if (8 * MD_LEN > bn_bits(n)) { len = CEIL(bn_bits(n), 8); bn_read_bin(ev, hash, len); bn_rsh(ev, ev, 8 * MD_LEN - bn_bits(n)); } else { bn_read_bin(ev, hash, MD_LEN); } bn_mod(ev, ev, n); result = dv_cmp_const(ev->dp, e->dp, MIN(ev->used, e->used)); result = (result == CMP_NE ? 0 : 1); if (ev->used != e->used) { result = 0; } } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); bn_free(ev); bn_free(rv); ec_free(p); } return result; }
void cp_ecss_sig(bn_t e, bn_t s, unsigned char *msg, int len, bn_t d) { bn_t n, k, x, r; ec_t p; unsigned char hash[MD_LEN]; unsigned char m[len + EC_BYTES]; bn_null(n); bn_null(k); bn_null(x); bn_null(r); ec_null(p); TRY { bn_new(n); bn_new(k); bn_new(x); bn_new(r); ec_new(p); ec_curve_get_ord(n); do { do { bn_rand(k, BN_POS, bn_bits(n)); bn_mod(k, k, n); } while (bn_is_zero(k)); ec_mul_gen(p, k); ec_get_x(x, p); bn_mod(r, x, n); } while (bn_is_zero(r)); memcpy(m, msg, len); bn_write_bin(m + len, EC_BYTES, r); md_map(hash, m, len + EC_BYTES); if (8 * MD_LEN > bn_bits(n)) { len = CEIL(bn_bits(n), 8); bn_read_bin(e, hash, len); bn_rsh(e, e, 8 * MD_LEN - bn_bits(n)); } else { bn_read_bin(e, hash, MD_LEN); } bn_mod(e, e, n); bn_mul(s, d, e); bn_mod(s, s, n); bn_sub(s, n, s); bn_add(s, s, k); bn_mod(s, s, n); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); bn_free(k); bn_free(x); bn_free(r); ec_free(p); } }
static void hash_free( ec_hash table ) { ec_free( table ); }
EC_API void ec_list_iterator_destroy( ec_list_iterator iterator ) { check_iter(iterator); del_magic_iter(iterator); ec_free( iterator ); }
static void tests_relic_ecdh(void) { /* The following is an example for doing an elliptic-curve Diffie-Hellman key exchange. */ /* Select an elliptic curve configuration */ if (ec_param_set_any() == STS_OK) { #if (TEST_RELIC_SHOW_OUTPUT == 1) ec_param_print(); #endif bn_t privateA; ec_t publicA; uint8_t sharedKeyA[MD_LEN]; bn_t privateB; ec_t publicB; uint8_t sharedKeyB[MD_LEN]; bn_null(privateA); ec_null(publicA); bn_new(privateA); ec_new(publicA); bn_null(privateB); ec_null(publicB); bn_new(privateB); ec_new(publicB); /* User A generates private/public key pair */ TEST_ASSERT_EQUAL_INT(STS_OK, cp_ecdh_gen(privateA, publicA)); #if (TEST_RELIC_SHOW_OUTPUT == 1) printf("User A\n"); printf("======\n"); printf("private key: "); bn_print(privateA); printf("\npublic key: "); ec_print(publicA); printf("\n"); #endif /* User B generates private/public key pair */ TEST_ASSERT_EQUAL_INT(STS_OK, cp_ecdh_gen(privateB, publicB)); #if (TEST_RELIC_SHOW_OUTPUT == 1) printf("User B\n"); printf("======\n"); printf("private key: "); bn_print(privateB); printf("\npublic key: "); ec_print(publicB); printf("\n"); #endif /* In a protocol you would exchange the public keys now */ /* User A calculates shared secret */ TEST_ASSERT_EQUAL_INT(STS_OK, cp_ecdh_key(sharedKeyA, MD_LEN, privateA, publicB)); #if (TEST_RELIC_SHOW_OUTPUT == 1) printf("\nshared key computed by user A: "); print_mem(sharedKeyA, MD_LEN); #endif /* User B calculates shared secret */ TEST_ASSERT_EQUAL_INT(STS_OK, cp_ecdh_key(sharedKeyB, MD_LEN, privateB, publicA)); #if (TEST_RELIC_SHOW_OUTPUT == 1) printf("\nshared key computed by user B: "); print_mem(sharedKeyB, MD_LEN); #endif /* The secrets should be the same now */ TEST_ASSERT_EQUAL_INT(CMP_EQ, util_cmp_const(sharedKeyA, sharedKeyB, MD_LEN)); bn_free(privateA); ec_free(publicA); bn_free(privateB); ec_free(publicB); #if (TEST_RELIC_SHOW_OUTPUT == 1) printf("\nRELIC EC-DH test successful\n"); #endif } }
static void string_destroy( EcAny obj ) { ec_free( (void *)obj ); }
static EC_OBJ EcLibRe_Match( EC_OBJ stack, EcAny userdata ) { EC_OBJ regexp; EC_OBJ subject_obj; const char *subject; EcInt length; EcInt startoffset = 0; EC_OBJ opts = EC_NIL; int options; pcre *code = NULL; pcre_extra *extra = NULL; EcBool compiledhere = FALSE; ov_int *ovector; EcInt ovecsize; EcInt ncapsub; int exec_res; int rc; EC_OBJ res; res = EcParseStackFunction( "re.match", TRUE, stack, "OO!|iO", ®exp, tc_string, &subject_obj, &startoffset, opts ); if (EC_ERRORP(res)) return res; if (!(EC_REGEXPP(regexp) || (EC_STRINGP(regexp)))) { return EC_TYPEERROR_F( "re.match", 1, tc_none, regexp, "expected 'regexp' or 'string'" ); } if (EC_STRINGP(regexp)) { /* compile the pattern */ const char *errptr = NULL; int erroffs = 0; code = pcre_compile( EC_STRDATA(regexp), 0, /* we'll use options at matching time */ &errptr, &erroffs, /* tableptr */ NULL ); if (! code) return EcReError( errptr, erroffs ); extra = NULL; compiledhere = TRUE; } else { code = EC_PCRE(regexp); extra = EC_PCREXTRA(regexp); compiledhere = FALSE; } subject = EC_STRDATA(subject_obj); length = EC_STRLEN(subject_obj); opts = obj2options( "re.match", 4, opts, &options ); if (EC_ERRORP(opts)) return opts; rc = pcre_fullinfo( code, extra, PCRE_INFO_CAPTURECOUNT, &ncapsub ); if (rc < 0) return EcReError( "internal error: pcre_fullinfo", -1 ); ovecsize = (ncapsub + 1) * 3; ovector = ec_malloc( sizeof(ov_int) * ovecsize ); if (! ovector) return EcMemoryError(); memset( ovector, 0x00, sizeof(ov_int) * ovecsize ); exec_res = pcre_exec( code, extra, subject, length, startoffset, options, ovector, ovecsize ); if (compiledhere) { if (code) free( code ); if (extra) free( extra ); } switch (exec_res) { case PCRE_ERROR_NOMATCH: ec_free( ovector ); return EC_NIL; break; case PCRE_ERROR_NULL: ec_free( ovector ); return EcReError( "internal error: PCRE_ERROR_NULL", -1 ); break; case PCRE_ERROR_BADOPTION: ec_free( ovector ); return EcReError( "internal error: PCRE_ERROR_BADOPTION", -1 ); break; case PCRE_ERROR_BADMAGIC: ec_free( ovector ); return EcReError( "internal error: PCRE_ERROR_BADMAGIC", -1 ); break; case PCRE_ERROR_UNKNOWN_NODE: ec_free( ovector ); return EcReError( "internal error: PCRE_ERROR_UNKNOWN_MODE", -1 ); break; case PCRE_ERROR_NOMEMORY: ec_free( ovector ); return EcMemoryError(); break; } #if 0 if (exec_res == 0) { ec_free( ovector ); return EC_NIL; } #endif ASSERT( exec_res >= 0 ); return make_match( regexp, subject_obj, ovector, ovecsize, exec_res ); }