static BOOLEAN variable_comp ( VARIABLE_PTR v1, VARIABLE_PTR v2 ) { FF_VALIDATE(v1); FF_VALIDATE(v2); if (!v1 || !v2) return(FALSE); #ifdef FF_CHK_ADDR if ((void *)v1 != v1->check_address) return(FALSE); if ((void *)v2 != v2->check_address) return(FALSE); #endif if (IS_ARRAY(v1) && IS_ARRAY(v2) && strcmp(v1->array_desc_str, v2->array_desc_str)) return(FALSE); if (strcmp(v1->name, v2->name)) return(FALSE); if (v1->type != v2->type) return(FALSE); if (v1->start_pos != v2->start_pos) return(FALSE); if (v1->end_pos != v2->end_pos) return(FALSE); if (v1->precision != v2->precision) return(FALSE); assert(!IS_CONVERT(v1)); if (IS_CONVERT(v1) && v1->misc.cv_var_num != v2->misc.cv_var_num) return(FALSE); else if (IS_TRANSLATOR(v1) && !nt_comp_translator_sll(v1, v2)) return(FALSE); return(TRUE); }
static int setSlice(Value c, Value a1, Value a2, Value b) { if (IS_ARRAY(c)) { ARRAY(c)->setSliceV(a1, a2, b); return 0; } else { return E_NOT_SLICEABLE; } }
int skip_array (jsmntok_t *tok, int size) { int i; for (i = 0; i < size; i++, tok++) { if (IS_ARRAY(*tok)) { return (i + skip_array (tok + 1, tok->size)); } if (IS_OBJECT(*tok)) { return -1; } } return i; }
static int tclArgNumberGen(DCL_NOM_STR *nom) { int n = -1; switch (nom->type->type) { case CHAR: case SHORT: case INT: case FLOAT: case DOUBLE: case ENUM: n = 1; break; case STRUCT: case UNION: { int p; DCL_NOM_LIST *m; n = 0; for (m = nom->type->members; m != NULL; m = m->next) { p = tclArgNumberGen(m->dcl_nom); if (p < 0) { fprintf(stderr, "Error: struct member %s was problematic.\n", m->dcl_nom->name); n = -1; break; } else n += p; } break; } case TYPEDEF: fprintf(stderr, "Warning: encountered a typedef for %s.\n", nom->name); break; } if (IS_ARRAY(nom)) { int i; for(i=0; i<nom->ndimensions-(IS_STRING(nom)?1:0); i++) n *= nom->dimensions[i]; } return n; }
inline Value doAdd(GC *gc, Value a, Value b) { int ta = TAG(a); if (IS_NUM_TAG(ta) && IS_NUM(b)) { return VAL_NUM(GET_NUM(a) + GET_NUM(b)); } else if (IS_STRING(a)) { return String::concat(gc, a, b); } else { if (ta != T_OBJ) { return E_WRONG_TYPE; } int type = O_TYPE(a); if (type == O_ARRAY && (IS_ARRAY(b) || IS_MAP(b) || IS_STRING(b))) { Array *array = Array::alloc(gc); array->add(a); array->add(b); return VAL_OBJ(array); } else if (type == O_MAP && (IS_ARRAY(b) || IS_MAP(b) || IS_STRING(b))) { Map *map = MAP(a)->copy(gc); map->add(b); return VAL_OBJ(map); } else { return VERR; } } }
void StringBuilder::append(Value v, bool raw) { void *ptr = GET_PTR(v); if (IS_STRING(v)) { if (!raw) { append('\''); } append(GET_CSTR(v), len(v)); if (!raw) { append('\''); } } else if (IS_NUM(v)) { append(GET_NUM(v)); return; } else if (IS_ARRAY(v)) { Array *a = (Array *) ptr; int size = a->size(); append('['); for (int i = 0; i < size; ++i) { append(i ? ", " : ""); append(a->getI(i)); } append(']'); } else if (IS_MAP(v)) { Map *m = (Map *) ptr; int size = m->size(); append('{'); Value *keys = m->keyBuf(); Value *vals = m->valBuf(); for (int i = 0; i < size; ++i) { append(i ? ", " : ""); append(keys[i]); append(':'); append(vals[i]); } append('}'); } else if (IS_NIL(v)) { append("nil"); } else { append('<'); append(typeStr(v)); append('>'); char tmp[32]; snprintf(tmp, sizeof(tmp), "%p", ptr); append(tmp); } }
static int prepareStackForCall(Value *base, int nArgs, int nEffArgs, GC *gc) { Array *tail = 0; int tailSize = 0; if (nEffArgs < 0) { //last arg is *args nEffArgs = -nEffArgs; Value v = base[nEffArgs - 1]; if (!IS_ARRAY(v)) { fprintf(stderr, "*args in call is not Array"); __builtin_abort(); } tail = ARRAY(v); --nEffArgs; tailSize = tail->size(); } bool hasEllipsis = nArgs < 0; if (hasEllipsis) { nArgs = -nArgs - 1; } int nFromTail = clamp(nArgs - nEffArgs, 0, tailSize); for (int i = 0; i < nFromTail; ++i) { base[nEffArgs + i] = tail->getI(i); } nEffArgs += nFromTail; if (nArgs != NARGS_CFUNC) { for (Value *p = base + nEffArgs, *end = base + nArgs; p < end; ++p) { *p = VNIL; } } if (hasEllipsis) { Array *a = Array::alloc(gc); for (Value *p = base + nArgs, *end = base + nEffArgs; p < end; ++p) { a->push(*p); } if (nFromTail < tailSize) { a->append(tail->buf() + nFromTail, tailSize - nFromTail); } base[nArgs] = VAL_OBJ(a); } return nEffArgs; }
static Value getSlice(GC *gc, Value a, Value b1, Value b2) { return IS_ARRAY(a) ? ARRAY(a)->getSliceV(gc, b1, b2) : IS_STRING(a) ? String::getSlice(gc, a, b1, b2) : VERR; }
// extern __thread jmp_buf jumpBuf; int VM::call(Value A, int nEffArgs, Value *regs, Stack *stack) { Vector<RetInfo> retInfo; // only used if FAST_CALL if (!(IS_O_TYPE(A, O_FUNC) || IS_CF(A) || IS_O_TYPE(A, O_CFUNC))) { return -1; } regs = stack->maybeGrow(regs, 256); int nExpectedArgs = IS_O_TYPE(A, O_FUNC) ? ((Func *)GET_OBJ(A))->proto->nArgs : NARGS_CFUNC; nEffArgs = prepareStackForCall(regs, nExpectedArgs, nEffArgs, gc); if (IS_CF(A) || IS_O_TYPE(A, O_CFUNC)) { if (IS_CF(A)) { tfunc f = GET_CF(A); *regs = f(this, CFunc::CFUNC_CALL, 0, regs, nEffArgs); } else { ((CFunc *) GET_OBJ(A))->call(this, regs, nEffArgs); } return 0; } unsigned code = 0; Value B; Value *ptrC; Func *activeFunc = (Func *) GET_OBJ(A); unsigned *pc = (unsigned *) activeFunc->proto->code.buf(); static void *dispatch[] = { #define _(name) &&name #include "opcodes.inc" #undef _ }; assert(sizeof(dispatch)/sizeof(dispatch[0]) == N_OPCODES); copyUpvals(activeFunc, regs); STEP; JMP: pc += OD(code); STEP; JT: if (!IS_FALSE(*ptrC)) { pc += OD(code); } STEP; JF: if ( IS_FALSE(*ptrC)) { pc += OD(code); } STEP; JLT: if (lessThan(A, B)) { pc += OSC(code); } STEP; JNIS: if (A != B) { pc += OSC(code); } STEP; FOR: A = *(ptrC + 1); B = *(ptrC + 2); if (!IS_NUM(A) || !IS_NUM(B)) { goto error; } // E_FOR_NOT_NUMBER *ptrC = B; if (!(GET_NUM(B) < GET_NUM(A))) { pc += OD(code); } STEP; LOOP: { const double counter = GET_NUM(*ptrC) + 1; if (counter < GET_NUM(*(ptrC+1))) { pc += OD(code); } *ptrC = VAL_NUM(counter); STEP; } FUNC: assert(IS_PROTO(A)); *ptrC = VAL_OBJ(Func::alloc(gc, PROTO(A), regs + 256, regs, OB(code))); STEP; // index, A[B] GETI: *ptrC = types->type(A)->indexGet(A, B); if (*ptrC == VERR) { goto error; } STEP; GETF: *ptrC = types->type(A)->fieldGet(A, B); if (*ptrC == VERR) { goto error; } STEP; SETI: if (!types->type(*ptrC)->indexSet(*ptrC, A, B)) { goto error; } STEP; SETF: if (!types->type(*ptrC)->fieldSet(*ptrC, A, B)) { goto error; } STEP; /* const int oa = OA(code); const int ob = OB(code); int top = max(oa, ob) + 1; top = max(top, activeFunc->proto->localsTop); Value *base = regs + top; printf("top %d\n", top); base[0] = A; base[1] = B; int cPos = ptrC - regs; DO_CALL(v, 2, regs, base, stack); regs[cPos] = base[0]; break; if (*ptrC == VERR) { goto error; } */ GETS: *ptrC = getSlice(gc, A, B, regs[OB(code)+1]); if (*ptrC==VERR) { goto error; } STEP; SETS: if (setSlice(*ptrC, A, regs[OA(code)+1], B)) { goto error; } STEP; RET: { regs[0] = A; Value *root = stack->base; gc->maybeCollect(root, regs - root + 1); #if FAST_CALL if (!retInfo.size()) { return 0; } RetInfo *ri = retInfo.top(); pc = ri->pc; regs = stack->base + ri->base; activeFunc = ri->func; retInfo.pop(); copyUpvals(activeFunc, regs); STEP; #else return 0; #endif } CALL: { if (!IS_OBJ(A) && !IS_CF(A)) { goto error; } // E_CALL_NOT_FUNC int nEffArgs = OSB(code); assert(nEffArgs != 0); Value *base = ptrC; #if FAST_CALL if (IS_O_TYPE(A, O_FUNC)) { Func *f = (Func *) GET_OBJ(A); Proto *proto = f->proto; prepareStackForCall(base, proto->nArgs, nEffArgs, gc); RetInfo *ret = retInfo.push(); ret->pc = pc; ret->base = regs - stack->base; ret->func = activeFunc; regs = stack->maybeGrow(base, 256); copyUpvals(f, regs); pc = proto->code.buf(); activeFunc = f; } else { #endif int ret = DO_CALL(A, nEffArgs, regs, base, stack); if (ret) { goto error; } #if FAST_CALL } #endif STEP; } MOVEUP: { const int slot = regs + 256 - ptrC; activeFunc->setUp(slot, A); } MOVE_R: *ptrC = A; STEP; MOVE_I: *ptrC = VAL_NUM(OD(code)); STEP; MOVE_V: { int id = OA(code); *ptrC = id == CONST_NIL ? VNIL : id == CONST_EMPTY_STRING ? EMPTY_STRING : id == CONST_EMPTY_ARRAY ? VAL_OBJ(emptyArray->copy(gc)) : VAL_OBJ(emptyMap->copy(gc)); STEP; } MOVE_C: { Value v = *pc | (((u64) *(pc+1)) << 32); pc += 2; if (IS_ARRAY(v)) { v = VAL_OBJ(ARRAY(v)->copy(gc)); } else if (IS_MAP(v)) { v = VAL_OBJ(MAP(v)->copy(gc)); } *ptrC = v; STEP; } LEN: *ptrC = VAL_NUM(len(A)); STEP; NOTL: *ptrC = IS_FALSE(A) ? TRUE : FALSE; STEP; // notb: *ptrC = IS_INT(A)? VAL_INT(~getInteger(A)):ERROR(E_WRONG_TYPE); STEP; ADD: *ptrC = doAdd(gc, A, B); if (*ptrC == VERR) { goto error; } STEP; SUB: *ptrC = BINOP(-, A, B); STEP; MUL: *ptrC = BINOP(*, A, B); STEP; DIV: *ptrC = BINOP(/, A, B); STEP; MOD: *ptrC = doMod(A, B); if (*ptrC == VERR) { goto error; } STEP; POW: *ptrC = doPow(A, B); if (*ptrC == VERR) { goto error; } STEP; AND: *ptrC = BITOP(&, A, B); STEP; OR: *ptrC = BITOP(|, A, B); STEP; XOR: *ptrC = BITOP(^, A, B); STEP; SHL_RR: ERR(!IS_NUM(B), E_WRONG_TYPE); *ptrC = doSHL(A, (int)GET_NUM(B)); STEP; SHR_RR: ERR(!IS_NUM(B), E_WRONG_TYPE); *ptrC = doSHR(A, (int)GET_NUM(B)); STEP; SHL_RI: *ptrC = doSHL(A, OSB(code)); STEP; SHR_RI: *ptrC = doSHR(A, OSB(code)); STEP; EQ: *ptrC = equals(A, B) ? TRUE : FALSE; STEP; NEQ: *ptrC = !equals(A, B) ? TRUE : FALSE; STEP; IS: *ptrC = A == B ? TRUE : FALSE; STEP; NIS: *ptrC = A != B ? TRUE : FALSE; STEP; LT: *ptrC = lessThan(A, B) ? TRUE : FALSE; STEP; LE: *ptrC = (equals(A, B) || lessThan(A, B)) ? TRUE : FALSE; STEP; error: return pc - (unsigned *) activeFunc->proto->code.buf(); }
int db_init ( FF_STD_ARGS_PTR std_args, DATA_BIN_HANDLE dbin_h, int (*error_cb)(int) ) { FORMAT_DATA_LIST format_data_list = NULL; int error = 0; int num_errors = 0; assert(dbin_h); if (!dbin_h) return(err_push(ERR_API, "NULL DATA_BIN_HANDLE in %s", ROUTINE_NAME)); if (!*dbin_h) { *dbin_h = db_make(std_args->input_file ? std_args->input_file : "Application Program"); if (!*dbin_h) return(err_push(ERR_MEM_LACK, "Standard Data Bin")); } /* Now set the formats and the auxillary files */ if (db_set(*dbin_h, DBSET_READ_EQV, std_args->input_file)) { err_push(ERR_SET_DBIN, "making name table for %s", std_args->input_file); return(DBSET_READ_EQV); } if (db_set(*dbin_h, DBSET_INPUT_FORMATS, std_args->input_file, std_args->output_file, std_args->input_format_file, std_args->input_format_buffer, std_args->input_format_title, &format_data_list ) ) { if (format_data_list) dll_free_holdings(format_data_list); err_push(ERR_SET_DBIN, "setting an input format for %s", std_args->input_file); return(DBSET_INPUT_FORMATS); } num_errors = err_count(); if (db_set(*dbin_h, DBSET_OUTPUT_FORMATS, std_args->input_file, std_args->output_file, std_args->output_format_file, std_args->output_format_buffer, std_args->output_format_title, &format_data_list ) ) { if (!error_cb || (*error_cb)(DBSET_OUTPUT_FORMATS)) { dll_free_holdings(format_data_list); err_push(ERR_SET_DBIN, "setting an output format for %s", std_args->input_file); return(DBSET_OUTPUT_FORMATS); } else { while (err_count() > num_errors) err_pop(); } } error = db_set(*dbin_h, DBSET_CREATE_CONDUITS, std_args, format_data_list); dll_free_holdings(format_data_list); if (error) { err_push(ERR_SET_DBIN, "creating array information for %s", std_args->input_file); return(DBSET_CREATE_CONDUITS); } /* Check for variable file */ if (std_args->var_file) { FORMAT_DATA_PTR output_fd = fd_get_data(*dbin_h, FFF_OUTPUT); if (IS_ARRAY(output_fd->format)) { err_push(ERR_SET_DBIN, "Cannot use variable file with arrays"); return(DBSET_VARIABLE_RESTRICTION); } if (db_set(*dbin_h, DBSET_VARIABLE_RESTRICTION, std_args->var_file, output_fd->format)) { err_push(ERR_SET_DBIN, "Unable to use variable file \"%s\"", std_args->var_file); return(DBSET_VARIABLE_RESTRICTION); } } if (db_set(*dbin_h, DBSET_EQUATION_VARIABLES)) { err_push(ERR_SET_DBIN, "setting equation variables for %s", std_args->input_file); return(DBSET_EQUATION_VARIABLES); } if (db_set(*dbin_h, DBSET_HEADER_FILE_NAMES, FFF_INPUT, std_args->input_file)) { err_push(ERR_SET_DBIN, "Determining input header file names for %s", std_args->input_file); return(DBSET_HEADER_FILE_NAMES); } num_errors = err_count(); if (db_set(*dbin_h, DBSET_HEADER_FILE_NAMES, FFF_OUTPUT, std_args->output_file)) { if (!error_cb || (*error_cb)(DBSET_OUTPUT_FORMATS)) { err_push(ERR_SET_DBIN, "Determining output header file names for %s", std_args->output_file); return(DBSET_HEADER_FILE_NAMES); } else { while (err_count() > num_errors) err_pop(); } } if (db_set(*dbin_h, DBSET_BYTE_ORDER, FFF_INPUT | FFF_HEADER)) { err_push(ERR_SET_DBIN, "Defining input data byte order"); return(DBSET_BYTE_ORDER); } if (db_set(*dbin_h, DBSET_HEADERS)) { err_push(ERR_SET_DBIN, "getting header file for %s", std_args->input_file); return(DBSET_HEADERS); } if (db_set(*dbin_h, DBSET_USER_UPDATE_FORMATS)) { err_push(ERR_SET_DBIN, "user update of a format for %s", std_args->input_file); return(DBSET_USER_UPDATE_FORMATS); } if (db_set(*dbin_h, DBSET_BYTE_ORDER, FFF_INPUT)) { err_push(ERR_SET_DBIN, "Defining input data byte order"); return(DBSET_BYTE_ORDER); } num_errors = err_count(); if (db_set(*dbin_h, DBSET_BYTE_ORDER, FFF_OUTPUT)) { if (!error_cb || (*error_cb)(DBSET_OUTPUT_FORMATS)) { err_push(ERR_SET_DBIN, "Defining output data byte order"); return(DBSET_BYTE_ORDER); } else { while (err_count() > num_errors) err_pop(); } } if (std_args->cache_size == 0) std_args->cache_size = DEFAULT_CACHE_SIZE; /* Check for query file */ if (std_args->query_file) { if (db_set(*dbin_h, DBSET_QUERY_RESTRICTION, std_args->query_file)) { err_push(ERR_GEN_QUERY, "setting query using %s", std_args->query_file); return(DBSET_QUERY_RESTRICTION); } } if (db_set(*dbin_h, DBSET_INIT_CONDUITS, FFF_DATA, std_args->records_to_read)) { err_push(ERR_SET_DBIN, "creating array information for %s", std_args->input_file); return(DBSET_INIT_CONDUITS); } if (error) return(error); error = merge_redundant_conduits((*dbin_h)->array_conduit_list); if (error) return(error); if (fd_get_data(*dbin_h, FFF_INPUT) && db_set(*dbin_h, DBSET_CACHE_SIZE, std_args->cache_size) ) { return(err_push(ERR_MEM_LACK, "setting data cache for %s", std_args->input_file)); } if (db_set(*dbin_h, DBSET_FORMAT_MAPPINGS)) { err_push(ERR_SET_DBIN, "mapping input to output formats for %s", std_args->input_file); return(DBSET_FORMAT_MAPPINGS); } error = make_unique_format_titles(*dbin_h); if (error) return ERR_MEM_LACK; num_errors = err_count(); if (db_set(*dbin_h, DBSET_VAR_MINMAX)) { if (!error_cb || (*error_cb)(DBSET_OUTPUT_FORMATS)) { err_push(ERR_SET_DBIN, "setting variable minimums and maximums for %s", std_args->input_file); return(DBSET_VAR_MINMAX); } else { while (err_count() > num_errors) err_pop(); } } error = check_file_access(*dbin_h); if (error) return error; return(error); }
static int add_to_variable_list(char *text_line, FORMAT_PTR format) { VARIABLE_PTR var = NULL; char save_char = STR_END; char *token = NULL; char *endptr = NULL; int error = 0; if (!format->variables) { format->variables = dll_init(); if (!format->variables) return(ERR_MEM_LACK); } token = text_line; token = get_token(token, &save_char); if (FF_STRLEN(token)) { var = ff_create_variable(token); if (var == NULL) return ERR_MEM_LACK; #if 0 error = ERR_MEM_LACK; #endif if (var->name[0] == '"' && var->name[strlen(var->name) - 1] == '"') { memmove(var->name, var->name + 1, strlen(var->name) - 2); var->name[strlen(var->name) - 2] = STR_END; } } else { error = err_push(ERR_VARIABLE_DESC, "Expecting a variable name (\"%s\")", format->name); goto add_to_variable_list_exit; } if (!dll_add(format->variables)) { ff_destroy_variable(var); error = ERR_MEM_LACK; goto add_to_variable_list_exit; } dll_assign(var, DLL_VAR, dll_last(format->variables)); token = get_token(token, &save_char); if (FF_STRLEN(token)) { errno = 0; var->start_pos = strtol(token, &endptr, 10); if (errno || FF_STRLEN(endptr)) { error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable start position: %s", token); goto add_to_variable_list_exit; } } else { error = err_push(ERR_VARIABLE_DESC, "Expecting a start position for \"%s\"", var->name); goto add_to_variable_list_exit; } token = get_token(token, &save_char); if (FF_STRLEN(token)) { errno = 0; var->end_pos = strtol(token, &endptr, 10); if (errno || FF_STRLEN(endptr)) { error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable end position: %s", token); goto add_to_variable_list_exit; } } else { error = err_push(ERR_VARIABLE_DESC, "Expecting an end position for \"%s\"", var->name); goto add_to_variable_list_exit; } token = get_token(token, &save_char); if (FF_STRLEN(token)) { FFV_TYPE(var) = ff_lookup_number(variable_types, token); if (FFV_TYPE(var) == FF_VAR_TYPE_FLAG) { if (os_strncmpi("ARRAY", token, 5) == 0) { RESTORE_CHAR(token, save_char); save_char = STR_END; error = parse_array_variable(&token, var); if (error) goto add_to_variable_list_exit; format->type |= FF_ARRAY; } else { /* Is this a keyworded variable type? If so, remember name of keyword in record_title */ if (IS_KEYWORDED_PARAMETER(token)) { FFV_TYPE(var) = 0; assert(!var->record_title); if (var->record_title) memFree(var->record_title, "var->record_title"); var->record_title = (char *)memStrdup(token, "token"); if (!var->record_title) { error = err_push(ERR_MEM_LACK, ""); goto add_to_variable_list_exit; } } else { error = err_push(ERR_UNKNOWN_VAR_TYPE, token); goto add_to_variable_list_exit; } } } } else { error = err_push(ERR_VARIABLE_DESC, "Expecting a variable type or array description for \"%s\"", var->name); goto add_to_variable_list_exit; } token = get_token(token, &save_char); if (FF_STRLEN(token)) { errno = 0; var->precision = (short)strtol(token, &endptr, 10); if (errno || FF_STRLEN(endptr)) { error = err_push(errno ? errno : ERR_PARAM_VALUE, "Bad number for variable precision: %s", token); goto add_to_variable_list_exit; } } else { if (IS_ARRAY(var)) { error = err_push(ERR_VARIABLE_DESC, "Expecting a precision for \"%s\"", var->name); goto add_to_variable_list_exit; } } if (var->end_pos < var->start_pos) { error = err_push(ERR_VARIABLE_DESC,"End Position < Start Position\n%s", text_line); goto add_to_variable_list_exit; } /* Determine The Variable Type */ if (var->start_pos == 0 && var->end_pos == 0) { if (IS_BINARY(format)) { error = err_push(ERR_UNKNOWN_FORMAT_TYPE, "Illegal to have delimited binary format"); goto add_to_variable_list_exit; } else if (IS_ARRAY(format)) { error = err_push(ERR_UNKNOWN_FORMAT_TYPE, "Illegal to have delimited array format"); goto add_to_variable_list_exit; } format->type |= FFF_VARIED; } if (NEED_TO_CHECK_VARIABLE_SIZE(format, var)) { if (ffv_type_size(var->type) != var->end_pos - var->start_pos + 1) { char save_eol_char = STR_END; char *end_of_line = find_EOL(text_line); if (end_of_line) { save_eol_char = *end_of_line; *end_of_line = STR_END; } error = err_push(ERR_VARIABLE_SIZE,"Expecting ending position for binary field %s to be %d", var->name, var->start_pos + ffv_type_size(var->type) - 1); if (end_of_line) *end_of_line = save_eol_char; goto add_to_variable_list_exit; } } check_old_style_EOL_var(var); /* Does length of CONSTANT variable name equal length of variable? */ if (IS_CONSTANT(var) && !IS_EOL(var)) { if (FF_STRLEN(var->name) > FF_VAR_LENGTH(var)) { error = err_push(ERR_VARIABLE_SIZE, "Constant variable initializer (%s) is too long for field", var->name); goto add_to_variable_list_exit; } else if (FF_STRLEN(var->name) < FF_VAR_LENGTH(var)) error = err_push(ERR_WARNING_ONLY + ERR_VARIABLE_SIZE, "Constant variable initializer (%s) is shorter than field", var->name); } format->num_vars++; format->length = max(format->length, var->end_pos); add_to_variable_list_exit: if (error) { char *cp; char EOL_char = STR_END; /* Don't destroy variable since it will be destroyed in ff_destroy_format */ cp = find_EOL(text_line); if (cp) { EOL_char = *cp; *cp = STR_END; } error = err_push(ERR_VARIABLE_DESC + (error > ERR_WARNING_ONLY ? ERR_WARNING_ONLY : 0),text_line); if (cp) *cp = EOL_char; } RESTORE_CHAR(token, save_char); return(error); }
/* * returns -1 if error, 0 if no users in realm, otherwise the number of users retrieved * user: pointer to an array containing pointers to returned users - it's allocated within this function * caller will free() the array after use * buflen: lenght in bytes of returned buffer * realm: specifies the realm; if NULL, the default realm will be used */ int sp_list_users (char ***user, const char *realm) { int len, i; char *r_ptr, **u_ptr, *u_str; jsmntok_t *tok; struct MemoryStruct chunk; if ((sp_config.status != SP_INITED)) { if (!(sp_init ())) return -1; } if (realm != NULL) r_ptr = (char *) realm; else r_ptr = sp_config.realm; char post_data[(strlen ("REALM=") + strlen (r_ptr) + 1)]; sprintf (post_data, "%s%s", "REALM=", r_ptr); len = do_curl(sp_config.URL_u_list, post_data, &tok, (struct MemoryStruct *) &chunk); if (len == -1) { return -1; } if (!(rc_ok (chunk.memory, tok, len))) { free (tok); free (chunk.memory); return -1; } /* * Get array from JSON response */ int idx = get_tok (chunk.memory, tok, len, "username"); if (idx == -1) { debug (1, "token \"username\" not found in JSON response"); free (tok); free (chunk.memory); return 0; } if (!(IS_ARRAY(tok[idx]))) { debug (1, "pair of token \"username\" in JSON response is not an array"); free (tok); free (chunk.memory); return 0; } len = tok[idx].size; idx++; /* * Allocate buffer to be returned and copy data to it. chunk.size is surely un upper bound to contain * the user list */ int ptrs_size = (len * sizeof (char *)); int buflen = ptrs_size + chunk.size; *user = (char **) malloc (buflen); if (!(*user)) { error ("malloc(%d) failed", buflen); free (tok); free (chunk.memory); return -1; } for (i = idx, u_ptr=(char **) *user, u_str=((char *) *user + ptrs_size); i < (idx + len); i++) { int l = tok[i].end - tok[i].start; memcpy (u_str, chunk.memory + tok[i].start, l); *(u_str + l) = 0; *u_ptr = u_str; u_str += l + 1; u_ptr++; } free (tok); free (chunk.memory); return len; }
static void _dump(VALUE v, int level) { char **symbols; void *symbols_buffer[1]; VALUE *ptr; size_t i; HASH_OBJECT_ENTRY *e; HASH_OBJECT_ENTRY **buckets; if(IS_NULL(v)) { printf("%*s* null\n", level << 1, ""); goto exit; } if(IS_TRUE(v)) { printf("%*s* true\n", level << 1, ""); goto exit; } if(IS_FALSE(v)) { printf("%*s* false\n", level << 1, ""); goto exit; } if(IS_UNDEF(v)) { printf("%*s* undef\n", level << 1, ""); goto exit; } if(IS_KWARGS_MARKER(v)){ printf("%*s* kwargs marker\n", level << 1, ""); goto exit; } if(IS_INT(v)) { printf("%*s* int %" VALUE_NUM_FMT "\n", level << 1, "", GET_INT(v)); goto exit; } if(IS_REAL(v)) { printf("%*s* real %g\n", level << 1, "", REAL_OBJECT_VAL(v)); goto exit; } if(IS_STRING(v)) { // TODO: properly handle // 1. non-printable characters // 2. zero character printf("%*s* string(len=%zu) %.*s\n", level << 1, "", OBJ_LEN(v), (int) OBJ_LEN(v), (char *)OBJ_DATA_PTR(v)); goto exit; } if(IS_NATIVE_METHOD(v)) { symbols_buffer[0] = OBJ_DATA_PTR(v); symbols = backtrace_symbols(symbols_buffer, 1); printf("%*s* native method %s at %p req_params=%d\n", level << 1, "", symbols[0], OBJ_DATA_PTR(v), NATIVE_METHOD_OBJ_N_REQ_PAR(v)); for(i=0; i<NATIVE_METHOD_OBJ_N_REQ_PAR(v); i++) { printf("%*s* required parameter %zu\n", (level+1) << 1, "", i+1); _dump(NATIVE_METHOD_OBJ_PARAMS(v)[i*2+0], level+2); _dump(NATIVE_METHOD_OBJ_PARAMS(v)[i*2+1], level+2); } goto exit; } if(IS_CLOSURE(v)) { printf("%*s* closure name=%s ip=%zu locals_including_params=%d req_params=%d opt_params=%d n_uplevels=%d params_flags=%d\n", level << 1, "", IS_NULL(CLOSURE_OBJ_NAME(v)) ? "(none)" : obj_to_cstring(CLOSURE_OBJ_NAME(v)), CLOSURE_OBJ_IP(v), CLOSURE_OBJ_N_LOCALS(v), CLOSURE_OBJ_N_REQ_PAR(v), CLOSURE_OBJ_N_OPT_PAR(v), CLOSURE_OBJ_N_UPLEVELS(v), CLOSURE_OBJ_PARAMS_FLAGS(v) ); for(i=0; i<CLOSURE_OBJ_N_REQ_PAR(v); i++) { printf("%*s* required parameter %zu (name and type follow)\n", (level+1) << 1, "", i+1); _dump(CLOSURE_OBJ_PARAMS(v)[i*2+0], level+2); _dump(CLOSURE_OBJ_PARAMS(v)[i*2+1], level+2); } for(i=0; i<CLOSURE_OBJ_N_OPT_PAR(v); i++) { printf("%*s* optional parameter %zu (name, type and default value follow)\n", (level+1) << 1, "", i+1); _dump(CLOSURE_OBJ_PARAMS(v)[CLOSURE_OBJ_N_REQ_PAR(v)*2 + i*3 + 0], level+2); _dump(CLOSURE_OBJ_PARAMS(v)[CLOSURE_OBJ_N_REQ_PAR(v)*2 + i*3 + 1], level+2); _dump(CLOSURE_OBJ_PARAMS(v)[CLOSURE_OBJ_N_REQ_PAR(v)*2 + i*3 + 2], level+2); } i = CLOSURE_OBJ_N_REQ_PAR(v)*2 + CLOSURE_OBJ_N_OPT_PAR(v)*3; if(CLOSURE_OBJ_PARAMS_FLAGS(v) & PARAMS_FLAG_ARR_SPLAT) { printf("%*s* array splat parameter\n", (level+1) << 1, ""); _dump(CLOSURE_OBJ_PARAMS(v)[i+0], level+2); _dump(CLOSURE_OBJ_PARAMS(v)[i+1], level+2); i+=3; } if(CLOSURE_OBJ_PARAMS_FLAGS(v) & PARAMS_FLAG_HASH_SPLAT) { printf("%*s* hash splat parameter\n", (level+1) << 1, ""); _dump(CLOSURE_OBJ_PARAMS(v)[i+0], level+2); _dump(CLOSURE_OBJ_PARAMS(v)[i+1], level+2); i+=3; } goto exit; } if(IS_ARRAY(v)) { printf("%*s* array of length %zu\n", level << 1, "", OBJ_LEN(v)); for(i=0, ptr=(VALUE *)OBJ_DATA_PTR(v); i<OBJ_LEN(v); i++, ptr++) { _dump(*ptr, level+1); } goto exit; } if(IS_HASH(v)) { printf("%*s* hash with total of %zu items in %zu buckets at %p\n", level << 1, "", OBJ_LEN(v), HASH_BUCKETS_N(v), OBJ_DATA_PTR(v)); buckets = OBJ_DATA_PTR(v); for(i=0; i<HASH_BUCKETS_N(v); i++) { if(!buckets[i]) { continue; } printf("%*s* bucket # %zu\n", (level+1) << 1, "", i); for(e=buckets[i]; e; e=e->bucket_next) { printf("%*s* item at %p with hash() of %u insertion_order_prev=%p insertion_order_next=%p \n", (level+2) << 1, "", (void *)e, e->hash, (void *)e->insertion_order_prev, (void *)e->insertion_order_next); printf("%*s* key\n", (level+3) << 1, ""); _dump(e->key, level+4); printf("%*s* value\n", (level+3) << 1, ""); _dump(e->val, level+4); } } goto exit; } if(IS_NGS_TYPE(v)) { printf("%*s* type (name and optionally constructors and parents follow) id=%" PRIdPTR " ptr=%p\n", level << 1, "", NGS_TYPE_ID(v), IS_NORMAL_TYPE(v) ? v.ptr : 0); _dump(NGS_TYPE_NAME(v), level + 1); if(level < 3) { _dump(NGS_TYPE_FIELDS(v), level + 1); _dump(NGS_TYPE_CONSTRUCTORS(v), level + 1); _dump(NGS_TYPE_PARENTS(v), level + 1); } goto exit; } if(IS_CLIB(v)) { printf("%*s* C library (name follows) ptr=%p\n", level << 1, "", OBJ_DATA_PTR(v)); _dump(CLIB_OBJECT_NAME(v), level + 1); goto exit; } if(IS_CSYM(v)) { printf("%*s* C symbol (name and libraray follow) ptr=%p\n", level << 1, "", OBJ_DATA_PTR(v)); _dump(CSYM_OBJECT_NAME(v), level + 1); _dump(CSYM_OBJECT_LIB(v), level + 1); goto exit; } if(IS_NORMAL_TYPE_CONSTRUCTOR(v)) { printf("%*s* user type constructor (type optionally follows)\n", level << 1, ""); if(level < 3) { _dump(OBJ_DATA(v), level + 1); } goto exit; } if(IS_NORMAL_TYPE_INSTANCE(v)) { printf("%*s* user type instance (type and fields optionally follow)\n", level << 1, ""); // level < 4 so that uncaught exception ImplNotFound could display the type of the arguments if(level < 4) { _dump(NORMAL_TYPE_INSTANCE_TYPE(v), level + 1); _dump(NORMAL_TYPE_INSTANCE_FIELDS(v), level + 1); } goto exit; } printf("%*s* (dump not implemented for the object at %p)\n", level << 1, "", OBJ_DATA_PTR(v)); exit: return; }
static int tclInputFormatGen(char **buf, char *name, DCL_NOM_STR *nom, RQST_INPUT_INFO_LIST **iinfo, int level) { char *arrayName = NULL; /* in the case of an array */ static char defaultDefault[20]; if (IS_POINTER(nom)) { fprintf(stderr, "Pointer %s does not make sense here.\n", name); return -1; } /* For an array, must do some loop */ if (IS_ARRAY(nom)) { int i; bufcat(&arrayName, name); for(i=0;i<nom->ndimensions-IS_STRING(nom)?1:0;i++) { bufcat(buf," for {set loop%d(%d) 0} " "{ \\$loop%d(%d)<%d } { incr loop%d(%d)} {\n", level, i, level, i, nom->dimensions[i], level, i); bufcat(&arrayName, "\\\\[\\$loop%d(%d)\\\\]", level, i); } if (arrayName == NULL) { /* must give up */ fprintf(stderr, "Warning: could not generate array name for %s.\n", name); return -1; } name = arrayName; } if (nom->type->type != STRUCT && nom->type->type != UNION) { bufcat(buf, " lappend format [list "); /* Echo the tcl func call */ switch (nom->type->type) { case CHAR: if (IS_STRING(nom)) bufcat(buf, "string"); else bufcat(buf, "short"); strcpy(defaultDefault, "\"\""); break; case SHORT: bufcat(buf, "short"); strcpy(defaultDefault, "0"); break; case INT: if (nom->type->flags & LONG_LONG_INT) bufcat(buf, "wide"); else bufcat(buf, "int"); strcpy(defaultDefault, "0"); break; case FLOAT: bufcat(buf, "float"); strcpy(defaultDefault, "0.0"); break; case DOUBLE: bufcat(buf, "double"); strcpy(defaultDefault, "0.0"); break; case STRUCT: case UNION: /* see 'else' statement below */ break; /* Affichage en clair des symboles de l'enum */ case ENUM: bufcat(buf, "{ "); if (tclGenEnumList(buf, nom->type) != 0) return -1; bufcat(buf, "}"); strcpy(defaultDefault, "\"\""); break; case TYPEDEF: fprintf(stderr, "Warning: encountered a typedef for %s.\n", name); break; } if (*iinfo != NULL && (*iinfo)->doc != NULL) { bufcat(buf, " \"%s\"", (*iinfo)->doc); switch((*iinfo)->type) { case INT: if (nom->type->type == ENUM) { int ok = 0; DCL_NOM_LIST *member; for(member = nom->type->members; member != NULL; member = member->next) { if (member->dcl_nom->pointeur == (*iinfo)->default_val.i_val) { bufcat(buf, " \"%s\"", member->dcl_nom->name); ok = 1; break; } } if (!ok) bufcat(buf, " %d", (*iinfo)->default_val.i_val); } else bufcat(buf, " %d", (*iinfo)->default_val.i_val); break; case DOUBLE: bufcat(buf, " %f", (*iinfo)->default_val.d_val); break; case CHAR: bufcat(buf, " \"%s\"", (*iinfo)->default_val.str_val); break; } } else bufcat(buf, " \"%s\" %s", name, defaultDefault); bufcat(buf, " ]\n"); } else { /* STRUCT || UNION */ /* recurse */ DCL_NOM_LIST *m; char *var; for (m = nom->type->members; m != NULL; m = m->next) { var = NULL; bufcat(&var, "%s.%s", name, m->dcl_nom->name); if (var == NULL) { fprintf(stderr, "Warning: null member name in %s.\n", name); continue; } if (tclInputFormatGen(buf, var, m->dcl_nom, iinfo, level+1)) fprintf(stderr, "Warning: struct member %s was problematic.\n", var); free(var); } } if (IS_ARRAY(nom)) { int i; /* End array scanning */ for(i=IS_STRING(nom)?1:0;i<nom->ndimensions;i++) { bufcat(buf, "}\n"); } free(arrayName); } if (nom->type->type != STRUCT && nom->type->type != UNION) if ((*iinfo) != NULL) *iinfo = (*iinfo)->next; return 0; }
/* * Parse the type and its initializer and emit it (recursively). */ static void emitInitVal(struct dbuf_s *oBuf, symbol *topsym, sym_link *my_type, initList *list) { symbol *sym; int size, i; long lit; unsigned char *str; size = getSize(my_type); if (IS_PTR(my_type)) { DEBUGprintf ("(pointer, %d byte) %p\n", size, list ? (void *)(long)list2int(list) : NULL); emitIvals(oBuf, topsym, list, 0, size); return; } if (IS_ARRAY(my_type) && topsym && topsym->isstrlit) { str = (unsigned char *)SPEC_CVAL(topsym->etype).v_char; emitIvalLabel(oBuf, topsym); do { dbuf_printf (oBuf, "\tretlw 0x%02x ; '%c'\n", str[0], (str[0] >= 0x20 && str[0] < 128) ? str[0] : '.'); } while (*(str++)); return; } if (IS_ARRAY(my_type) && list && list->type == INIT_NODE) { fprintf (stderr, "Unhandled initialized symbol: %s\n", topsym->name); assert ( !"Initialized char-arrays are not yet supported, assign at runtime instead." ); return; } if (IS_ARRAY(my_type)) { DEBUGprintf ("(array, %d items, %d byte) below\n", DCL_ELEM(my_type), size); assert (!list || list->type == INIT_DEEP); if (list) list = list->init.deep; for (i = 0; i < DCL_ELEM(my_type); i++) { emitInitVal(oBuf, topsym, my_type->next, list); topsym = NULL; if (list) list = list->next; } // for i return; } if (IS_FLOAT(my_type)) { // float, 32 bit DEBUGprintf ("(float, %d byte) %lf\n", size, list ? list2int(list) : 0.0); emitIvals(oBuf, topsym, list, 0, size); return; } if (IS_CHAR(my_type) || IS_INT(my_type) || IS_LONG(my_type)) { // integral type, 8, 16, or 32 bit DEBUGprintf ("(integral, %d byte) 0x%lx/%ld\n", size, list ? (long)list2int(list) : 0, list ? (long)list2int(list) : 0); emitIvals(oBuf, topsym, list, 0, size); return; } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == STRUCT) { // struct DEBUGprintf ("(struct, %d byte) handled below\n", size); assert (!list || (list->type == INIT_DEEP)); // iterate over struct members and initList if (list) list = list->init.deep; sym = SPEC_STRUCT(my_type)->fields; while (sym) { long bitfield = 0; int len = 0; if (IS_BITFIELD(sym->type)) { while (sym && IS_BITFIELD(sym->type)) { int bitoff = SPEC_BSTR(getSpec(sym->type)) + 8 * sym->offset; assert (!list || ((list->type == INIT_NODE) && IS_AST_LIT_VALUE(list->init.node))); lit = (long) (list ? list2int(list) : 0); DEBUGprintf ( "(bitfield member) %02lx (%d bit, starting at %d, bitfield %02lx)\n", lit, SPEC_BLEN(getSpec(sym->type)), bitoff, bitfield); bitfield |= (lit & ((1ul << SPEC_BLEN(getSpec(sym->type))) - 1)) << bitoff; len += SPEC_BLEN(getSpec(sym->type)); sym = sym->next; if (list) list = list->next; } // while assert (len < sizeof (long) * 8); // did we overflow our initializer?!? len = (len + 7) & ~0x07; // round up to full bytes emitIvals(oBuf, topsym, NULL, bitfield, len / 8); topsym = NULL; } // if if (sym) { emitInitVal(oBuf, topsym, sym->type, list); topsym = NULL; sym = sym->next; if (list) list = list->next; } // if } // while if (list) { assert ( !"Excess initializers." ); } // if return; } else if (IS_STRUCT(my_type) && SPEC_STRUCT(my_type)->type == UNION) { // union DEBUGprintf ("(union, %d byte) handled below\n", size); assert (list && list->type == INIT_DEEP); // iterate over union members and initList, try to map number and type of fields and initializers my_type = matchIvalToUnion(list, my_type, size); if (my_type) { emitInitVal(oBuf, topsym, my_type, list->init.deep); topsym = NULL; size -= getSize(my_type); if (size > 0) { // pad with (leading) zeros emitIvals(oBuf, NULL, NULL, 0, size); } return; } // if assert ( !"No UNION member matches the initializer structure."); } else if (IS_BITFIELD(my_type)) { assert ( !"bitfields should only occur in structs..." ); } else { printf ("SPEC_NOUN: %d\n", SPEC_NOUN(my_type)); assert( !"Unhandled initialized type."); } }
/* * pp_add_spec_to_decl() - Add the specifier to each of the declarators in * decl_chain. This is accomplished by cloning p_spec and then tacking it * onto the end of every declaration chain in decl_chain. * return : void * p_spec(in): A pointer to a specifier/declarator chain created by a previous * typedef, or to a single specifier. It is cloned and then tacked onto * the end of every declaration chain in the list pointed to by decl_chain. * decl_chain(out): A chain of declarators, each of which is to receive the * p_spec specifier. */ void pp_add_spec_to_decl (LINK * p_spec, SYMBOL * decl_chain) { LINK *clone_start, *clone_end; for (; decl_chain; decl_chain = decl_chain->next) { clone_start = pp_clone_type (p_spec, &clone_end); if (clone_start == NULL) { esql_yyverror (pp_get_msg (EX_DECL_SET, MSG_MALFORMED_CHAIN)); exit (1); } if (IS_PSEUDO_TYPE (clone_start) && clone_start->decl.s.val.v_struct == NULL) { LINK *old_etype; char tmp[32]; old_etype = decl_chain->etype; if (old_etype == NULL || (IS_VAR_TYPE (clone_start) && IS_ARRAY (old_etype) == 0)) { esql_yyverror (pp_get_msg (EX_DECL_SET, MSG_BAD_PSEUDO_DECL), pp_type_str (clone_start)); exit (1); } clone_start->decl.s.val.v_struct = pp_new_pseudo_def (clone_start->decl.s.noun, old_etype->decl.d.num_ele); if (clone_start->decl.s.noun == N_VARCHAR) { sprintf (tmp, " = { %s, \"\" }", old_etype->decl.d.num_ele); } else { sprintf (tmp, " = { ((%s)+7)/8, \"\" }", old_etype->decl.d.num_ele); } decl_chain->args = pp_new_symbol (tmp, decl_chain->level); pp_discard_link (old_etype); if (decl_chain->type == old_etype) { decl_chain->type = NULL; } else { LINK *parent; for (parent = decl_chain->type; parent->next != old_etype; parent = parent->next) { ; } parent->next = NULL; decl_chain->etype = parent; } } if (decl_chain->type == NULL) /* No declarators */ { decl_chain->type = clone_start; } else { decl_chain->etype->next = clone_start; } decl_chain->etype = clone_end; /* * If the declaration we're looking at is really a typedef, * record the symbol itself within the specifier. This will * make it easier to point back to the symbol from other * declarations, which will make it easier to print out * later declarations using the typedef name rather than its * expansion. */ if (IS_TYPEDEF (clone_end)) { pp_set_class_bit (0, clone_end); decl_chain->type->tdef = decl_chain; decl_chain->type->from_tdef = decl_chain; } } }
static int make_format ( char *origin, FF_BUFSIZE_PTR bufsize, FORMAT_HANDLE hformat ) { char *text_line = NULL; char *fmt_name; int error = 0; assert(hformat); assert(*hformat == NULL); *hformat = NULL; text_line = get_first_line(bufsize->buffer); if (!text_line) return(err_push(ERR_MISSING_TOKEN, "Expecting a newline")); else { FF_TYPES_t check_format_type; if (get_format_type_and_name(text_line, &check_format_type, &fmt_name)) { char *cp; char save_char = STR_END; cp = find_EOL(fmt_name); if (cp) { save_char = *cp; *cp = STR_END; } *hformat = ff_create_format(fmt_name, origin); if (!*hformat) return(ERR_MEM_LACK); (*hformat)->type = check_format_type; if (cp) *cp = save_char; if ((*hformat)->name[0] == '\"') (*hformat)->name[0] = ' '; cp = strrchr((*hformat)->name, '\"'); if (cp) *cp = ' '; os_str_trim_whitespace((*hformat)->name, (*hformat)->name); text_line = get_next_line(text_line); if (!text_line) return(err_push(ERR_VARIABLE_DESC, "Expecting a variable description")); } else { char *cp; char save_char = STR_END; cp = find_EOL(text_line); if (cp) { save_char = *cp; *cp = STR_END; } error = err_push(ERR_UNKNOWN_FORMAT_TYPE, text_line); if (cp) *cp = save_char; return(error); } } while (strlen(text_line)) { if (!is_comment_line(text_line) && strlen(text_line)) { error = add_to_variable_list(text_line, *hformat); if (error && error < ERR_WARNING_ONLY) return(error); } text_line = get_next_line(text_line); } if (IS_ARRAY(*hformat) && IS_RECORD_FORMAT(*hformat)) return(err_push(ERR_MAKE_FORM, "You cannot define a record format containing an array (%s)", (*hformat)->name)); if (!(*hformat)->variables) return(err_push(ERR_NO_VARIABLES, "%s", (*hformat)->name)); if (IS_ASCII(*hformat) && !IS_ARRAY(*hformat) && !IS_VARIED(*hformat)) error = append_EOL_to_format(*hformat); /* experimental */ if (IS_ARRAY(*hformat)) (*hformat)->length = 0; return(error); }