void BinaryOpUnwind:: UnparseAux( std::string &buffer, std::string &fnName, std::vector<ExprTree*>& args ) { if (strcasecmp(fnName.c_str(),"member") == 0) { if ((args[0])->GetKind() == ExprTree::LITERAL_NODE && (args[1])->GetKind() == ExprTree::ATTRREF_NODE) { std::string attribute_name; std::string attribute_value; ExprTree *expr; bool absolute; // We just care about the attribute name, not about its base ad. ((AttributeReference*)args[1])->GetComponents(expr, attribute_name, absolute); Value v; EvalState state; args[0]->Evaluate(state,v); Unparse( attribute_value, v ); collapse_quotes(attribute_value); std::stringstream result_line; result_line << attribute_name << "[" << m_member_list_counter_[attribute_name]++ << "]='" << attribute_value << "'"; m_unwind_output.push_back(result_line.str()); } } // Fall back to base class to complete unparsing. ClassAdUnParser::UnparseAux( buffer, fnName, args ); return; }
const char *Unparse(apr_pool_t *pool, struct Signature *signature) { const char *value = ""; size_t offset; for (offset = 0; offset != signature->count; ++offset) { const char *type = Unparse(pool, signature->elements[offset].type); value = apr_pstrcat(pool, value, type, NULL); } return value; }
const char *Unparse(apr_pool_t *pool, struct Type *type) { if (type == NULL) return "?"; else switch (type->primitive) { case typename_P: return "#"; case union_P: return apr_psprintf(pool, "(%s)", Unparse(pool, &type->data.signature)); case string_P: return "*"; case selector_P: return ":"; case block_P: return "@?"; case object_P: return type->name == NULL ? "@" : apr_psprintf(pool, "@\"%s\"", type->name); case boolean_P: return "B"; case uchar_P: return "C"; case uint_P: return "I"; case ulong_P: return "L"; case ulonglong_P: return "Q"; case ushort_P: return "S"; case array_P: { const char *value = Unparse(pool, type->data.data.type); return apr_psprintf(pool, "[%"APR_SIZE_T_FMT"%s]", type->data.data.size, value); } break; case pointer_P: return apr_psprintf(pool, "^%s", type->data.data.type == NULL ? "v" : Unparse(pool, type->data.data.type)); case bit_P: return apr_psprintf(pool, "b%"APR_SIZE_T_FMT"", type->data.data.size); case char_P: return "c"; case double_P: return "d"; case float_P: return "f"; case int_P: return "i"; case long_P: return "l"; case longlong_P: return "q"; case short_P: return "s"; case void_P: return "v"; case struct_P: return apr_psprintf(pool, "{%s=%s}", type->name == NULL ? "?" : type->name, Unparse(pool, &type->data.signature)); } _assert(false); return NULL; }
// Special top-level form void AstCompilationUnit::Unparse(LexStream* lex_stream, const char* const directory) { char* in_file_name = lex_stream -> FileName(); // const char* suffix = ".unparse"; const char* suffix = ""; char* out_file_name = strcat3(directory, in_file_name, suffix); // Create the directory if necessary SystemMkdirhierForFile(out_file_name); ofstream os_base(out_file_name); if (! os_base) { Ostream() << "Cannot open output file " << out_file_name << endl; abort(); } Ostream os(&os_base); Unparse(os, lex_stream); delete [] out_file_name; }
void ClassAdJsonUnParser:: UnparseAuxClassAd( std::string &buffer, const std::vector< std::pair< std::string, ExprTree*> >& attrs ) { vector< pair<string, ExprTree*> >::const_iterator itr; buffer += "{"; m_indentLevel += m_indentIncrement; for( itr=attrs.begin( ); itr!=attrs.end( ); itr++ ) { if ( itr != attrs.begin() ) { buffer += ","; } buffer += "\n" + string( m_indentLevel, ' ' ) + "\""; UnparseAuxEscapeString( buffer, itr->first ); buffer += "\": "; Unparse( buffer, itr->second ); } m_indentLevel -= m_indentIncrement; buffer += "\n" + string( m_indentLevel, ' ' ) + "}"; }
void ClassAdJsonUnParser:: Unparse( string &buffer, const Value &val ) { char tempBuf[512]; switch( val.GetType( ) ) { case Value::NULL_VALUE: buffer += "(null-value)"; break; case Value::STRING_VALUE: { string s; val.IsStringValue( s ); buffer += '"'; UnparseAuxEscapeString( buffer, s ); buffer += '"'; return; } case Value::INTEGER_VALUE: { long long i; val.IsIntegerValue( i ); sprintf( tempBuf, "%lld", i ); buffer += tempBuf; return; } case Value::REAL_VALUE: { double real; val.IsRealValue(real); if (real == 0.0) { // It might be positive or negative and it's // hard to tell. printf is good at telling though. // We also want to print it with as few // digits as possible, which is why we don't use the // case below. sprintf(tempBuf, "%.1f", real); buffer += tempBuf; } else if (classad_isnan(real)) { UnparseAuxQuoteExpr( buffer, "real(\"NaN\")" ); } else if (classad_isinf(real) == -1){ UnparseAuxQuoteExpr( buffer, "real(\"-INF\")" ); } else if (classad_isinf(real) == 1) { UnparseAuxQuoteExpr( buffer, "real(\"INF\")" ); } else { // Use the more user-friendly formatting of reals // that we use for old ClassAds format sprintf(tempBuf, "%.16G", real); // %G may print something that looks like an integer or exponent. // In that case, tack on a ".0" if (tempBuf[strcspn(tempBuf, ".Ee")] == '\0') { strcat(tempBuf, ".0"); } buffer += tempBuf; } return; } case Value::BOOLEAN_VALUE: { bool b; val.IsBooleanValue( b ); buffer += b ? "true" : "false"; return; } case Value::UNDEFINED_VALUE: { buffer += "null"; return; } case Value::ERROR_VALUE: { UnparseAuxQuoteExpr( buffer, "error" ); return; } case Value::ABSOLUTE_TIME_VALUE: { abstime_t asecs; string s; val.IsAbsoluteTimeValue(asecs); s += "absTime(\""; absTimeToString(asecs, s); s += "\")"; UnparseAuxQuoteExpr( buffer, s ); return; } case Value::RELATIVE_TIME_VALUE: { double rsecs; string s; val.IsRelativeTimeValue(rsecs); s += "relTime(\""; relTimeToString(rsecs, s); s += "\")"; UnparseAuxQuoteExpr( buffer, s ); return; } case Value::SCLASSAD_VALUE: case Value::CLASSAD_VALUE: { const ClassAd *ad = NULL; val.IsClassAdValue( ad ); Unparse( buffer, ad ); return; } case Value::SLIST_VALUE: case Value::LIST_VALUE: { const ExprList *el = NULL; val.IsListValue( el ); Unparse( buffer, el ); return; } default: break; } }
void ClassAdJsonUnParser:: Unparse( string &buffer, const ExprTree *tree ) { if( !tree ) { buffer = "<error:null expr>"; return; } switch( tree->GetKind( ) ) { case ExprTree::LITERAL_NODE: { #if 1 Value::NumberFactor factor; const Value & cval = ((const Literal*)tree)->getValue(factor); if (factor != Value::NumberFactor::NO_FACTOR) { Unparse( buffer, cval ); return; } #endif Value val; ((Literal*)tree)->GetValue( val ); Unparse( buffer, val ); return; } case ExprTree::ATTRREF_NODE: { UnparseAuxQuoteExpr( buffer, tree ); return; } case ExprTree::OP_NODE: { UnparseAuxQuoteExpr( buffer, tree ); return; } case ExprTree::FN_CALL_NODE: { UnparseAuxQuoteExpr( buffer, tree ); return; } case ExprTree::CLASSAD_NODE: { vector< pair<string, ExprTree*> > attrs; ((ClassAd*)tree)->GetComponents( attrs ); UnparseAuxClassAd( buffer, attrs ); return; } case ExprTree::EXPR_LIST_NODE: { vector<ExprTree*> exprs; vector<ExprTree*>::iterator itr; ((ExprList*)tree)->GetComponents( exprs ); buffer += "["; m_indentLevel += m_indentIncrement; for( itr=exprs.begin( ); itr!=exprs.end( ); itr++ ) { if ( itr != exprs.begin() ) { buffer += ","; } buffer += "\n" + string( m_indentLevel, ' ' ); Unparse( buffer, *itr ); } m_indentLevel -= m_indentIncrement; buffer += "\n" + string( m_indentLevel, ' ' ) + "]"; return; } case ExprTree::EXPR_ENVELOPE: { // recurse b/c we indirect for this element. Unparse( buffer, ((CachedExprEnvelope*)tree)->get()); return; } default: // I really wonder whether we should except here, but I // don't want to do that without further consultation. // wenger 2003-12-11. buffer = ""; CondorErrno = ERR_BAD_EXPRESSION; CondorErrMsg = "unknown expression type"; return; } }
void BinaryOpUnwind:: UnparseAux(std::string &buffer,Operation::OpKind op, ExprTree *t1, ExprTree *t2, ExprTree *t3) { // We are interested just in a subset of binary operations if ( op == Operation::LESS_THAN_OP || op == Operation::GREATER_THAN_OP || op == Operation::LESS_OR_EQUAL_OP || op == Operation::GREATER_OR_EQUAL_OP || op == Operation::EQUAL_OP || op == Operation::IS_OP ) { // Check that we have one attribute reference and one literal. ExprTree *attr, *value; bool args_ok = false; bool value_at_right; bool numeric_value; std::string attribute_name; std::string attribute_value; if (t1->GetKind() == ExprTree::LITERAL_NODE && t2->GetKind() == ExprTree::ATTRREF_NODE) { args_ok = true; attr = t2; value = t1; value_at_right = false; } if (t2->GetKind() == ExprTree::LITERAL_NODE && t1->GetKind() == ExprTree::ATTRREF_NODE) { args_ok = true; attr = t1; value = t2; value_at_right = true; } numeric_value = false; if (args_ok) { ExprTree *expr; bool absolute; // We just care about the attribute name, not about its base ad. ((AttributeReference*)attr)->GetComponents(expr, attribute_name, absolute); Value v; EvalState state; //state.SetScopes( ad ); value->Evaluate(state,v); int intres; std::string strres; if (v.IsIntegerValue( intres )) { Unparse( attribute_value, v ); numeric_value = true; } else if (v.IsStringValue( strres )) { // There's extra quoting rules in the string Unparse function. Unparse( attribute_value, v ); } else { args_ok = false; } } collapse_quotes(attribute_value); /* Comparison on numeric value ?*/ if ((!numeric_value) && op != Operation::EQUAL_OP && op != Operation::IS_OP) args_ok = false; if (args_ok) { if ( ( value_at_right && ( op == Operation::LESS_THAN_OP || op == Operation::LESS_OR_EQUAL_OP ) ) || ( !value_at_right && ( op == Operation::GREATER_THAN_OP || op == Operation::GREATER_OR_EQUAL_OP ) ) ) { std::string result_line = attribute_name; result_line.append("_Max='"); result_line.append(attribute_value); result_line.append("'"); m_unwind_output.push_back(result_line); } if ( ( !value_at_right && ( op == Operation::LESS_THAN_OP || op == Operation::LESS_OR_EQUAL_OP ) ) || ( value_at_right && ( op == Operation::GREATER_THAN_OP || op == Operation::GREATER_OR_EQUAL_OP ) ) ) { std::string result_line = attribute_name; result_line.append("_Min='"); result_line.append(attribute_value); result_line.append("'"); m_unwind_output.push_back(result_line); } if ( op == Operation::EQUAL_OP || op == Operation::IS_OP ) { std::string result_line = attribute_name; result_line.append("='"); result_line.append(attribute_value); result_line.append("'"); m_unwind_output.push_back(result_line); } } } // Fall back to base class to complete unparsing. ClassAdUnParser::UnparseAux( buffer, op, t1, t2, t3 ); return; }