예제 #1
0
/********************************************************************
* FUNCTION write_full_check_val
* 
* generate entire val_value_t *w/filter)
* Write an entire val_value_t out as XML, including the top level
* Using an optional testfn to filter output
*
* INPUTS:
*   scb == session control block
*   msg == xml_msg_hdr_t in progress
*   val == value to write
*   startindent == start indent amount if indent enabled
*   testcb == callback function to use, NULL if not used
*   justone == TRUE if just one of these; FALSE if more than one
*   isfirst == TRUE if this is the first (top) val printed
*   isfirstchild == TRUE if this is the first value of an array
*                == FALSE if this is the 2nd - Nth value of an array
* RETURNS:
*   status
*********************************************************************/
static status_t
    write_full_check_val (ses_cb_t *scb,
                          xml_msg_hdr_t *msg,
                          val_value_t *val,
                          int32  startindent,
                          val_nodetest_fn_t testfn,
                          boolean justone,
                          boolean isfirst,
                          boolean isfirstchild)
{
    val_value_t       *out;
    boolean            malloced = FALSE;
    status_t           res = NO_ERR;

    out = val_get_value(scb, msg, val, testfn, TRUE, &malloced, &res);

    if (!out || res != NO_ERR) {
        if (res == ERR_NCX_SKIPPED) {
            res = NO_ERR;
        }
        if (out && malloced) {
            val_free_value(out);
        }
        return res;
    }

    /* check if this is an external file to send */
    if (out->btyp == NCX_BT_EXTERN ||
        out->btyp == NCX_BT_INTERN ||
        typ_is_simple(out->btyp)) {

        if (isfirst) {
            write_json_string_value(scb, out);
        } else {
            /* write the name of the node */
            ses_putchar(scb, '"');
            ses_putjstr(scb, out->name, -1);
            ses_putchar(scb, '"');
            ses_putchar(scb, ':');

            switch (out->btyp) {
            case NCX_BT_EXTERN:
                ses_putchar(scb, '"');
                val_write_extern(scb, out);
                ses_putchar(scb, '"');
                break;
            case NCX_BT_INTERN:
                ses_putchar(scb, '"');
                val_write_intern(scb, out);
                ses_putchar(scb, '"');
                break;
            case NCX_BT_ENUM:
                ses_putchar(scb, '"');
                if (VAL_ENUM_NAME(out)) {
                    ses_putjstr(scb, VAL_ENUM_NAME(out), -1);
                }
                ses_putchar(scb, '"');
                break;
            case NCX_BT_EMPTY:
                if (out->v.boo) {
                    ses_putjstr(scb, NCX_EL_NULL, -1);
                } // else skip this value! should already be checked
                break;
            case NCX_BT_BOOLEAN:
                if (out->v.boo) {
                    ses_putjstr(scb, NCX_EL_TRUE, -1);
                } else {
                    ses_putjstr(scb, NCX_EL_FALSE, -1);
                }
                break;
            default:
                write_json_string_value(scb, out);
            }
        }
    } else {
        val_value_t *chval;
        val_value_t *lastch = NULL;
        val_value_t *nextch = NULL;

        int32 indent = (startindent < 0) ? -1 : 
            startindent + ses_indent_count(scb);

        if (isfirst) {
            ses_putchar(scb, '{');
        }

        /* render a complex type; either an object or an array */
        if (isfirstchild) {
            ses_putchar(scb, '"');
            ses_putjstr(scb, out->name, -1);
            ses_putchar(scb, '"');
            ses_putchar(scb, ':');

            if (!justone) {
                ses_putchar(scb, '[');
            }
        }


        ses_indent(scb, indent);
        ses_putchar(scb, '{');

        for (chval = val_get_first_child(out); 
             chval != NULL; 
             chval = nextch) {

            /* JSON ignores XML namespaces, so foo:a and bar:a
             * are both encoded in the same array
             */
            uint32 childcnt = val_instance_count(out, NULL, chval->name);
            boolean firstchild = 
                (lastch && !xml_strcmp(lastch->name, chval->name)) ?
                FALSE : TRUE;

            lastch = chval;
            nextch = val_get_next_child(chval);

            res = write_full_check_val(scb, 
                                       msg,
                                       chval,
                                       indent,
                                       testfn,
                                       (childcnt > 1) ? FALSE : TRUE,
                                       FALSE,
                                       firstchild);
                                       
            if (res == ERR_NCX_SKIPPED) {
                ;
            } else if (res != NO_ERR) {
                /* FIXME: do something about error;
                 * may not always be OK to continue to next child node 
                 */ ;
            } else if (nextch) {
                ses_putchar(scb, ',');
                if (indent >= 0 && 
                    (typ_is_simple(nextch->btyp) || 
                     xml_strcmp(nextch->name, chval->name))) {
                    ses_indent(scb, indent);
                    ses_putchar(scb, ' ');
                }
            }
        }

        ses_indent(scb, indent);
        ses_putchar(scb, '}');

        if (!justone) {
            val_value_t *peeknext = val_get_next_child(val);            
            if (!peeknext || xml_strcmp(val->name, peeknext->name)) {
                ses_putchar(scb, ']');
            }
        }

        if (isfirst) {
            ses_indent(scb, startindent);
            ses_putchar(scb, '}');
        }            
    }

    if (malloced && out) {
        val_free_value(out);
    }

    return res;

}  /* write_full_check_val */
예제 #2
0
파일: conf.c 프로젝트: 0xDEC0DE8/OpenYuma
/********************************************************************
* FUNCTION parse_val
* 
* Parse, and fill one val_value_t struct during
* processing of a text config file
*
* Error messages are printed by this function!!
* Do not duplicate error messages upon error return
*
* The value name is the current token.
* Based on the value typdef, the res of the tokens
* comprising the value statement will be processed
*
* INPUTS:
*   tkc == token chain
*   obj == the object template struct to use for filling in 'val'
*   val == initialized value struct, without any value,
*          which will be filled in by this function
*   nsid == namespace ID to use for this value
*   valname == name of the value struct
*
* RETURNS:
*   status of the operation
*********************************************************************/
static status_t 
    parse_val (tk_chain_t  *tkc,
               obj_template_t *obj,
               val_value_t *val)
{
    obj_template_t  *chobj;
    val_value_t     *chval;
    const xmlChar   *valname, *useval;
    typ_def_t       *typdef;
    status_t         res;
    ncx_btype_t      btyp;
    boolean          done;
    xmlns_id_t       nsid;

    btyp = obj_get_basetype(obj);
    nsid = obj_get_nsid(obj);
    valname = obj_get_name(obj);
    typdef = obj_get_typdef(obj);

    /* check if there is an index clause expected */
    if (typ_has_index(btyp)) {
        res = parse_index(tkc, obj, val, nsid);
        if (res != NO_ERR) {
            return res;
        }
    }

    /* get next token, NEWLINE is significant at this point */
    res = adv_tk(tkc);
    if (res != NO_ERR) {
        return res;
    }

    /* the current token should be the value for a leaf
     * or a left brace for the start of a complex type
     * A NEWLINE is treated as if the user entered a
     * zero-length string for the value.  (Unless the
     * base type is NCX_BT_EMPTY, in which case the NEWLINE
     * is the expected token
     */
    if (typ_is_simple(btyp)) {
        /* form for a leaf is: foo [value] NEWLINE  */
        if (TK_CUR_TYP(tkc)==TK_TT_NEWLINE) {
            useval = NULL;
        } else {
            useval = TK_CUR_VAL(tkc);
        }
        res = val_set_simval(val, 
                             typdef, 
                             nsid, 
                             valname,
                             useval);

        if (res != NO_ERR) {
            log_error("\nError: '%s' cannot be set to '%s'",
                      valname,
                      (TK_CUR_VAL(tkc)) ? TK_CUR_VAL(tkc) : EMPTY_STRING);
            if (btyp == NCX_BT_EMPTY) {
                ncx_conf_exp_err(tkc, res, "empty");
            } else {
                ncx_conf_exp_err(tkc, res, "simple value string");
            }
            return res;
        }

        /* get a NEWLINE unless current token is already a NEWLINE */
        if (TK_CUR_TYP(tkc) != TK_TT_NEWLINE) {
            res = adv_tk(tkc);
            if (res != NO_ERR) {
                return res;
            }
            if (TK_CUR_TYP(tkc) != TK_TT_NEWLINE) {
                res = ERR_NCX_WRONG_TKTYPE;
                ncx_conf_exp_err(tkc, res, "\\n");
            }
        }
    } else {
        /* complex type is foo {  ... } or
         * foo index1 index2 { ... }
         * If there is an index, it was already parsed
         */
        res = consume_tk(tkc, TK_TT_LBRACE);
        if (res != NO_ERR) {
            ncx_conf_exp_err(tkc, res, "left brace");
            return res;
        }

        /* get all the child nodes specified for this complex type */
        res = NO_ERR;
        done = FALSE;
        while (!done && res==NO_ERR) {
            /* start out looking for a child node name or a
             * right brace to end the sub-section
             */
            if (tk_next_typ(tkc)==TK_TT_NEWLINE) {
                /* skip the NEWLINE token */
                (void)adv_tk(tkc);
            } else if (tk_next_typ(tkc)==TK_TT_RBRACE) {
                /* found end of sub-section */
                done = TRUE;
            } else {
                /* get the next token */
                res = adv_tk(tkc);
                if (res != NO_ERR) {
                    continue;
                }

                /* make sure cur token is an identifier string
                 * if so, find the child node and call this function
                 * recursively to fill it in and add it to
                 * the parent 'val'
                 */
                if (TK_CUR_ID(tkc)) {
                    /* parent 'typdef' must have a child with a name
                     * that matches the current token vale
                     */
                    chobj = obj_find_child(obj, 
                                           TK_CUR_MOD(tkc),
                                           TK_CUR_VAL(tkc));
                    if (chobj) {
                        chval = val_new_value();
                        if (!chval) {
                            res = ERR_INTERNAL_MEM;
                            ncx_print_errormsg(tkc, NULL, res);
                        } else {
                            val_init_from_template(chval, chobj);
                            res = parse_val(tkc, chobj, chval);
                            if (res == NO_ERR) {
                                val_add_child(chval, val);
                            } else {
                                val_free_value(chval);
                            }
                        }
                    } else {
                        /* string is not a child name in this typdef */
                        res = ERR_NCX_DEF_NOT_FOUND;
                        ncx_conf_exp_err(tkc, res, "identifier string");
                    }
                } else {
                    /* token is not an identifier string */
                    res = ERR_NCX_WRONG_TKTYPE;
                    ncx_conf_exp_err(tkc, res, "identifier string");
                }
            }
        }  /* end loop through all the child nodes */

        /* expecting a right brace to finish the complex value */
        if (res == NO_ERR) {
            res = consume_tk(tkc, TK_TT_RBRACE);
            if (res != NO_ERR) {
                ncx_conf_exp_err(tkc, res, "right brace");
                return res;
            }
        }
    }

    return res;

}  /* parse_val */
예제 #3
0
/********************************************************************
 * FUNCTION show_user_var
 * 
 * generate the output for a global or local variable
 *
 * INPUTS:
 *   server_cb == server control block to use
 *   varname == variable name to show
 *   vartype == type of user variable
 *   val == value associated with this variable
 *   mode == help mode in use
 *
 * RETURNS:
 *   status
 *********************************************************************/
static status_t
    show_user_var (server_cb_t *server_cb,
                   const xmlChar *varname,
                   var_type_t vartype,
                   val_value_t *val,
                   help_mode_t mode)
{
    session_cb_t *session_cb = server_cb->cur_session_cb;
    xmlChar      *objbuff;
    logfn_t       logfn;
    boolean imode = interactive_mode();
    int32 doubleindent = 1;
    status_t res = NO_ERR;


    if (imode) {
        logfn = log_stdout;
    } else {
        logfn = log_write;
    }

    switch (vartype) {
    case VAR_TYP_GLOBAL:
    case VAR_TYP_LOCAL:
    case VAR_TYP_SESSION:
    case VAR_TYP_SYSTEM:
    case VAR_TYP_CONFIG:
        if (xml_strcmp(varname, val->name)) {
            doubleindent = 2;

            (*logfn)("\n   %s ", varname);

            if (val->obj && obj_is_data_db(val->obj)) {
                res = obj_gen_object_id(val->obj, &objbuff);
                if (res != NO_ERR) {
                    (*logfn)("[no object id]\n   ");
                } else {
                    (*logfn)("[%s]\n   ", objbuff);
                    m__free(objbuff);
                }
            }
        } else if (session_cb->display_mode == NCX_DISPLAY_MODE_JSON) {
            (*logfn)("\n   %s: ", varname);
            if (!typ_is_simple(val->btyp)) {
                (*logfn)("\n");
            }
        }
        break;
    default:
        ;
    }

    if (!typ_is_simple(val->btyp) && mode == HELP_MODE_BRIEF) {
        if (doubleindent == 1) {
            (*logfn)("\n   %s (%s)",
                     varname, tk_get_btype_sym(val->btyp));
        } else {
            (*logfn)("\n      (%s)", 
                     tk_get_btype_sym(val->btyp));
        }
    } else {
        val_dump_value_max(val, 
                           session_cb->defindent * doubleindent,
                           session_cb->defindent,
                           (imode) ? DUMP_VAL_STDOUT : DUMP_VAL_LOG,
                           session_cb->display_mode,
                           FALSE, FALSE);
    }

    return res;

}  /* show_user_var */