/* Output a declaration. Used for function locals, and struct/union members. */ void xml_generic_decl(tree decl, int indent, const char *tag, FILE *out) { fprintf(out, "%s<%s", spc(indent), tag); xml_location(decl, out); fprintf(out, ">\n"); indent += INDENT; xml_decl_binding(decl, indent, "binding", out); fprintf(out, "%s<type", spc(indent)); if (DECL_SIZE(decl)) fprintf(out, " size='%lu'", TREE_INT_CST_LOW(DECL_SIZE(decl))); if (DECL_ALIGN(decl)) fprintf(out, " alignment='%d'", DECL_ALIGN(decl)); fprintf(out, ">\n"); /* Output the type. */ xml_type(TREE_TYPE(decl), decl, indent + INDENT, out); fprintf(out, "%s</type>\n", spc(indent)); if (TREE_CODE(decl) == VAR_DECL && DECL_INITIAL(decl)) { fprintf(out, "%s<initial>\n", spc(indent)); xml_expr(DECL_INITIAL(decl), indent + INDENT, out); fprintf(out, "%s</initial>\n", spc(indent)); } indent -= INDENT; fprintf(out, "%s</%s>\n", spc(indent), tag); }
void xml_type_ref(tree t, int indent, FILE *out) { const char *tag; /* For non-aggregates, just print the type. It can't * be that bad. */ if (!AGGREGATE_TYPE_P(t)) return xml_type(t, NULL, indent, out); switch (TREE_CODE(t)) { case UNION_TYPE: tag = "union"; goto write; case RECORD_TYPE: tag = "structure"; goto write; case ARRAY_TYPE: tag = "array"; goto write; default: abort(); } write: lh_memo_type(t); fprintf(out, "%s<%s id='%u'", spc(indent), tag, TYPE_UID(t)); xml_type_quals(TYPE_QUALS(t), out); xml_location(t, out); fprintf(out, "/>\n"); }
void xml_type_aggregate(tree t, int indent, FILE *out) { tree member; const char *tag = NULL; switch (TREE_CODE(t)) { case UNION_TYPE: tag = "union"; case RECORD_TYPE: if (!tag) tag = "structure"; fprintf(out, "%s<%s id='%d'", spc(indent), tag, TYPE_UID(t)); xml_type_quals(TYPE_QUALS(t), out); xml_type_name(TYPE_NAME(t), out); fprintf(out, ">\n"); for (member = TYPE_FIELDS(t); member; member = TREE_CHAIN(member)) { xml_member_decl(member, indent + INDENT, out); } fprintf(out, "%s</%s>\n", spc(indent), tag); break; case ARRAY_TYPE: fprintf(out, "%s<array id='%d'", spc(indent), TYPE_UID(t)); xml_type_quals(TYPE_QUALS(t), out); xml_type_name(TYPE_NAME(t), out); fprintf(out, ">\n"); fprintf(out, "%s<type>\n", spc(indent + INDENT)); xml_type(TREE_TYPE(t), NULL, indent + INDENT + INDENT, out); fprintf(out, "%s</type>\n", spc(indent + INDENT)); if (TYPE_DOMAIN(t)) { fprintf(out, "%s<domain>\n", spc(indent + INDENT)); xml_type(TYPE_DOMAIN(t), NULL, indent + INDENT + INDENT, out); fprintf(out, "%s</domain>\n", spc(indent + INDENT)); } fprintf(out, "%s</array>\n", spc(indent)); break; default: abort(); } }
// Return the data for all the names[], start .. end etc. // as get_values() is supposed to return them. // // Returns raw values if interpol <= 0.0. // Returns 0 on error. xmlrpc_value *get_sheet_data(xmlrpc_env *env, int key, const stdVector<stdString> names, const epicsTime &start, const epicsTime &end, long count, ReaderFactory::How how, double delta) { try { #ifdef LOGFILE stdString txt; LOG_MSG("get_sheet_data\n"); LOG_MSG("Start : %s\n", epicsTimeTxt(start, txt)); LOG_MSG("End : %s\n", epicsTimeTxt(end, txt)); LOG_MSG("Method: %s\n", ReaderFactory::toString(how, delta)); #endif AutoPtr<Index> index(open_index(env, key)); if (env->fault_occurred) return 0; AutoPtr<SpreadsheetReader> sheet(new SpreadsheetReader(*index, how, delta)); AutoXmlRpcValue results(xmlrpc_build_value(env, "()")); if (env->fault_occurred) return 0; long name_count = names.size(); AutoArrayPtr<AutoXmlRpcValue> meta (new AutoXmlRpcValue[name_count]); AutoArrayPtr<AutoXmlRpcValue> values (new AutoXmlRpcValue[name_count]); AutoArrayPtr<xmlrpc_int32> xml_type (new xmlrpc_int32[name_count]); AutoArrayPtr<xmlrpc_int32> xml_count(new xmlrpc_int32[name_count]); AutoArrayPtr<size_t> ch_vals (new size_t[name_count]); bool ok = sheet->find(names, &start); long i; // Per-channel meta-info. for (i=0; i<name_count; ++i) { #ifdef LOGFILE LOG_MSG("Handling '%s'\n", names[i].c_str()); #endif ch_vals[i] = 0; values[i] = xmlrpc_build_value(env, "()"); if (env->fault_occurred) return 0; if (sheet->found(i)) { // Fix meta/type/count based on first value meta[i] = encode_ctrl_info(env, &sheet->getInfo(i)); dbr_type_to_xml_type(sheet->getType(i), sheet->getCount(i), xml_type[i], xml_count[i]); #if 0 LOG_MSG("Ch %lu: type, count = %d, %d\n", i, (int)xml_type[i], (int)xml_count[i]); #endif } else { // Channel exists, but has no data meta[i] = encode_ctrl_info(env, 0); xml_type[i] = XML_ENUM; xml_count[i] = 1; } } // Collect values long num_vals = 0; while (ok && num_vals < count && sheet->getTime() < end) { for (i=0; i<name_count; ++i) { if (sheet->get(i)) { ++ch_vals[i]; encode_value(env, sheet->getType(i), sheet->getCount(i), sheet->getTime(), sheet->get(i), xml_type[i], xml_count[i], values[i]); } else { // Encode as no value, but one of them ;-) // to avoid confusion w/ viewers that like to see some data in any case. encode_value(env, 0, 1, sheet->getTime(), 0, xml_type[i], xml_count[i], values[i]); } } ++num_vals; ok = sheet->next(); } // Assemble result = { name, meta, type, count, values } for (i=0; i<name_count; ++i) { AutoXmlRpcValue result( xmlrpc_build_value(env, "{s:s,s:V,s:i,s:i,s:V}", "name", names[i].c_str(), "meta", meta[i].get(), "type", xml_type[i], "count", xml_count[i], "values", values[i].get())); // Add to result array xmlrpc_array_append_item(env, results, result); #ifdef LOGFILE LOG_MSG("Ch %lu: %zu values\n", i, ch_vals[i]); #endif } #ifdef LOGFILE LOG_MSG("%ld values total\n", num_vals); #endif return results.release(); } catch (GenericException &e) { #ifdef LOGFILE LOG_MSG("Error:\n%s\n", e.what()); #endif xmlrpc_env_set_fault_formatted(env, ARCH_DAT_DATA_ERROR, "%s", e.what()); } return 0; }
void xml_expr(tree expr, int indent, FILE *out) { size_t el; switch (TREE_CODE(expr)) { case REAL_CST: case STRING_CST: case INTEGER_CST: fprintf(out, "%s<constant>\n", spc(indent)); /* For strings, we output the full type here. The backend should be fixed to resolve this though. */ if (TREE_CODE(expr) == STRING_CST) xml_type_aggregate(TREE_TYPE(expr), indent + INDENT, out); else xml_type(TREE_TYPE(expr), NULL, indent + INDENT, out); fprintf(out, "%s", spc(indent + INDENT)); xml_short_constant(expr, out); fprintf(out, "\n%s</constant>\n", spc(indent)); break; case COMPONENT_REF: fprintf(out, "%s<member-ref>\n", spc(indent)); fprintf(out, "%s<structure>\n", spc(INDENT + indent)); xml_expr(TREE_OPERAND(expr, 0), indent + INDENT + INDENT, out); fprintf(out, "%s</structure>\n", spc(indent + INDENT)); fprintf(out, "%s<member>\n", spc(indent + INDENT)); xml_decl_binding(TREE_OPERAND(expr, 1), indent + INDENT + INDENT, "bound", out); fprintf(out, "%s</member>\n", spc(indent + INDENT)); fprintf(out, "%s</member-ref>\n", spc(indent)); break; case BIT_FIELD_REF: fprintf(out, "%s<bitfield-ref>\n", spc(indent)); fprintf(out, "%s<structure>\n", spc(INDENT + indent)); xml_expr(TREE_OPERAND(expr, 0), indent + INDENT + INDENT, out); fprintf(out, "%s</structure>\n", spc(indent + INDENT)); assert(TREE_OPERAND(expr, 1) != NULL); assert(TREE_OPERAND(expr, 2) != NULL); assert(INTEGER_CST == TREE_CODE(TREE_OPERAND(expr, 1))); assert(INTEGER_CST == TREE_CODE(TREE_OPERAND(expr, 2))); fprintf(out, "%s<bits start='%lld' size='%lld' />", spc(indent + INDENT), double_int_to_ll(TREE_INT_CST(TREE_OPERAND(expr, 1))), double_int_to_ll(TREE_INT_CST(TREE_OPERAND(expr, 2)))); fprintf(out, "%s<as-type>\n", spc(INDENT + indent)); assert(TREE_TYPE(expr) != NULL); xml_type(TREE_TYPE(expr), NULL, indent + INDENT + INDENT, out); fprintf(out, "%s</as-type>\n", spc(indent + INDENT)); fprintf(out, "%s</bitfield-ref>\n", spc(indent)); break; case INDIRECT_REF: fprintf(out, "%s<indirection>\n", spc(indent)); xml_expr(TREE_OPERAND(expr, 0), indent + INDENT, out); fprintf(out, "%s</indirection>\n", spc(indent)); break; case RESULT_DECL: xml_decl_binding(expr, indent, "result", out); break; case VAR_DECL: xml_decl_binding(expr, indent, "bound", out); break; case PARM_DECL: xml_decl_binding(expr, indent, "bound-parameter", out); break; case ADDR_EXPR: fprintf(out, "%s<addr-of>\n", spc(indent)); xml_expr(TREE_OPERAND(expr, 0), indent + INDENT, out); fprintf(out, "%s</addr-of>\n", spc(indent)); break; case FUNCTION_DECL: fprintf(out, "%s<function>\n", spc(indent)); xml_decl_binding(expr, indent + INDENT, "bound", out); fprintf(out, "%s</function>\n", spc(indent)); break; #define SIMPLE_TAG(when, tt) \ case when: \ fprintf(out, "%s<" tt " />\n", spc(indent)); \ break #define SIMPLE_TAGS \ SIMPLE_TAG(PLUS_EXPR, "plus");\ SIMPLE_TAG(MINUS_EXPR, "minus");\ SIMPLE_TAG(MULT_EXPR, "multiply");\ SIMPLE_TAG(POINTER_PLUS_EXPR, "pointer-offset");\ \ SIMPLE_TAG(TRUNC_DIV_EXPR, "division-truncate");\ SIMPLE_TAG(CEIL_DIV_EXPR, "division-ceil");\ SIMPLE_TAG(FLOOR_DIV_EXPR, "division-floor");\ SIMPLE_TAG(ROUND_DIV_EXPR, "division-round");\ SIMPLE_TAG(EXACT_DIV_EXPR, "division-exact");\ SIMPLE_TAG(RDIV_EXPR, "division-real");\ \ SIMPLE_TAG(TRUNC_MOD_EXPR, "modulo-truncate");\ SIMPLE_TAG(CEIL_MOD_EXPR, "modulo-ceil");\ SIMPLE_TAG(FLOOR_MOD_EXPR, "modulo-floor");\ SIMPLE_TAG(ROUND_MOD_EXPR, "modulo-round");\ \ SIMPLE_TAG(FLOAT_EXPR, "float");\ SIMPLE_TAG(FIX_TRUNC_EXPR, "fixed-point-truncate");\ SIMPLE_TAG(NEGATE_EXPR, "negate");\ SIMPLE_TAG(ABS_EXPR, "absolute");\ \ SIMPLE_TAG(LSHIFT_EXPR, "shift-left");\ SIMPLE_TAG(RSHIFT_EXPR, "shift-right");\ SIMPLE_TAG(LROTATE_EXPR, "rotate-left");\ SIMPLE_TAG(RROTATE_EXPR, "rotate-right");\ \ SIMPLE_TAG(BIT_IOR_EXPR, "bitwise-or");\ SIMPLE_TAG(BIT_XOR_EXPR, "bitwise-xor");\ SIMPLE_TAG(BIT_AND_EXPR, "bitwise-and");\ SIMPLE_TAG(BIT_NOT_EXPR, "bitwise-not");\ \ SIMPLE_TAG(MIN_EXPR, "min");\ SIMPLE_TAG(MAX_EXPR, "max");\ SIMPLE_TAG(UNORDERED_EXPR, "unordered");\ SIMPLE_TAG(ORDERED_EXPR, "ordered");\ \ SIMPLE_TAG(TRUTH_ANDIF_EXPR, "logical-short-and");\ SIMPLE_TAG(TRUTH_ORIF_EXPR, "logical-short-or");\ SIMPLE_TAG(TRUTH_AND_EXPR, "logical-and");\ SIMPLE_TAG(TRUTH_OR_EXPR, "logical-or");\ SIMPLE_TAG(TRUTH_XOR_EXPR, "logical-xor");\ SIMPLE_TAG(TRUTH_NOT_EXPR, "logical-not");\ \ SIMPLE_TAG(LT_EXPR, "less-than");\ SIMPLE_TAG(LE_EXPR, "less-than-or-equal");\ SIMPLE_TAG(GT_EXPR, "greater-than");\ SIMPLE_TAG(GE_EXPR, "greater-than-or-equal");\ SIMPLE_TAG(EQ_EXPR, "equal");\ SIMPLE_TAG(NE_EXPR, "not-equal");\ SIMPLE_TAG(NOP_EXPR, "nop-convert");\ SIMPLE_TAG(CONVERT_EXPR, "convert"); SIMPLE_TAGS #undef SIMPLE_TAG case ARRAY_REF: fprintf(out, "%s<item-ref>\n", spc(indent)); fprintf(out, "%s<array>\n", spc(INDENT + indent)); xml_expr(TREE_OPERAND(expr, 0), indent + INDENT + INDENT, out); fprintf(out, "%s</array>\n", spc(INDENT + indent)); fprintf(out, "%s<index>\n", spc(indent + INDENT)); xml_expr(TREE_OPERAND(expr, 1), indent + INDENT + INDENT, out); fprintf(out, "%s</index>\n", spc(indent + INDENT)); fprintf(out, "%s</item-ref>\n", spc(indent)); break; case CONSTRUCTOR: fprintf(out, "%s<constructor>\n", spc(indent)); for (el = 0; el < CONSTRUCTOR_NELTS(expr); el++) { xml_expr(CONSTRUCTOR_ELT(expr, el)->value, indent + INDENT, out); } fprintf(out, "%s</constructor>\n", spc(indent)); break; case REFERENCE_TYPE: fprintf(stderr, "lighthouse warning: ignoring unhandled expression tree type %s\n", tree_code_name[TREE_CODE(expr)]); break; default: fprintf(stderr, "xml_expr: unhandled expression tree type %s\n", tree_code_name[TREE_CODE(expr)]); assert(0); abort(); } }
void xml_type(tree t, tree opt_decl, int indent, FILE *out) { tree a = NULL; if (AGGREGATE_TYPE_P(t)) return xml_type_ref(t, indent, out); switch (TREE_CODE(t)) { case POINTER_TYPE: fprintf(out, "%s<addr-of", spc(indent)); xml_type_quals(TYPE_QUALS(t), out); xml_type_name(TYPE_NAME(t), out); fprintf(out, ">\n"); xml_type(TREE_TYPE(t), NULL, indent + INDENT, out); fprintf(out, "%s</addr-of>\n", spc(indent)); break; case REAL_TYPE: fprintf(out, "%s<float", spc(indent)); xml_type_quals(TYPE_QUALS(t), out); xml_type_name(TYPE_NAME(t), out); fprintf(out, " precision='%d'", TYPE_PRECISION(t)); fprintf(out, " />\n"); break; case INTEGER_TYPE: fprintf(out, "%s<integer", spc(indent)); xml_type_quals(TYPE_QUALS(t), out); xml_type_name(TYPE_NAME(t), out); if (TYPE_UNSIGNED(t)) fprintf(out, " unsigned='1'"); fprintf(out, " precision='%d'", TYPE_PRECISION(t)); /* TREE_TYPE here indicates that there is an interesting domain. */ if (TREE_TYPE(t) && TYPE_MIN_VALUE(t)) fprintf(out, (TYPE_UNSIGNED(t) ? " min='%llu'" : " min='%lld'"), double_int_to_ll(TREE_INT_CST(TYPE_MIN_VALUE(t)))); if (TREE_TYPE(t) && TYPE_MAX_VALUE(t)) fprintf(out, (TYPE_UNSIGNED(t) ? " max='%llu'" : " max='%lld'"), double_int_to_ll(TREE_INT_CST(TYPE_MAX_VALUE(t)))); fprintf(out, " />\n"); break; case VOID_TYPE: fprintf(out, "%s<void />\n", spc(indent)); break; case BOOLEAN_TYPE: fprintf(out, "%s<boolean />\n", spc(indent)); break; case RESULT_DECL: fprintf(out, "%s<result />\n", spc(indent)); break; case ENUMERAL_TYPE: /* TODO: finish this (output tags). */ fprintf(out, "%s<enum", spc(indent)); xml_type_quals(TYPE_QUALS(t), out); xml_type_name(TYPE_NAME(t), out); fprintf(out, " />\n"); break; case METHOD_TYPE: case FUNCTION_TYPE: fprintf(out, "%s<function", spc(indent)); xml_type_quals(TYPE_QUALS(t), out); xml_type_name(TYPE_NAME(t), out); xml_type_attribs(TYPE_ATTRIBUTES(t), (opt_decl && TREE_THIS_VOLATILE(opt_decl)) ? "noreturn" : NULL, out); indent += INDENT; fprintf(out, ">\n%s<return>\n", spc(indent)); xml_type(TREE_TYPE(t), NULL, indent + INDENT, out); fprintf(out, "%s</return>\n", spc(indent)); /* varargs if last is not void. */ for (a = TYPE_ARG_TYPES(t); a && TREE_CHAIN(a); a = TREE_CHAIN(a)) ; fprintf(out, "%s<arguments %s>\n", spc(indent), (!a || TREE_CODE(TREE_VALUE(a)) == VOID_TYPE) ? "" : "varargs='1' "); for (a = TYPE_ARG_TYPES(t); a; a = TREE_CHAIN(a)) { xml_type(TREE_VALUE(a), NULL, indent + INDENT, out); } fprintf(out, "%s</arguments>\n", spc(indent)); indent -= INDENT; fprintf(out, "%s</function>\n", spc(indent)); break; case REFERENCE_TYPE: fprintf(stderr, "lighthouse warning: ignoring unhandled tree type '%s'.\n", tree_code_name[TREE_CODE(t)]); break; default: fprintf(stderr, "failing: unhandled tree type %s\n", tree_code_name[TREE_CODE(t)]); assert(0); abort(); } }