Exemplo n.º 1
0
/********************************************************************
* 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 */
Exemplo n.º 2
0
/********************************************************************
* FUNCTION dump_typdef_data
*
* Dump some contents from a  typ_def_t struct for help text
*
* INPUTS:
*   obj == obj_template_t to dump help for
*   mode == requested help mode
*   indent == start indent count
*********************************************************************/
static void
    dump_typdef_data (obj_template_t *obj,
                      help_mode_t mode,
                      uint32 indent)
{
    if (mode == HELP_MODE_BRIEF) {
        return;
    }

    typ_def_t *typdef = obj_get_typdef(obj);
    if (!typdef) {
        return;
    }

    typ_def_t *basetypdef = typ_get_base_typdef(typdef);
    ncx_btype_t btyp = typ_get_basetype(typdef);

    const xmlChar *datastr = typ_get_rangestr(typdef);
    if (datastr) {
        if (typ_is_string(btyp)) {
            help_write_lines((const xmlChar *)"length: ", indent, TRUE);
        } else {
            help_write_lines((const xmlChar *)"range: ", indent, TRUE);
        }
        help_write_lines(datastr, 0, FALSE);
    }

    typ_def_t *testdef = typdef;
    while (testdef) {
        typ_pattern_t *pattern;
        for (pattern = typ_get_first_pattern(testdef);
             pattern != NULL;
             pattern = typ_get_next_pattern(pattern)) {

            help_write_lines((const xmlChar *)"pattern: ", indent, TRUE);
            help_write_lines(pattern->pat_str, 0, FALSE);
        }
        testdef = typ_get_parent_typdef(testdef);
    }

    typ_enum_t *tenum = NULL;
    switch (btyp) {
    case NCX_BT_ENUM:
    case NCX_BT_BITS:
        if (btyp == NCX_BT_ENUM) {
            help_write_lines((const xmlChar *)"enum values:", indent, TRUE);
        } else {
            help_write_lines((const xmlChar *)"bit values:", indent, TRUE);
        }
        
        for (tenum = typ_first_enumdef(basetypdef);
             tenum != NULL;
             tenum = typ_next_enumdef(tenum)) {
            if (mode == HELP_MODE_NORMAL) {
                help_write_lines((const xmlChar *)" ", 0, FALSE);
                help_write_lines(tenum->name, 0, FALSE);
            } else {
                help_write_lines(tenum->name, indent+NCX_DEF_INDENT, TRUE);

                /* !!! removed since not allowed in syntax;
                 * !!! position or value is meta-data usually set-by-default
                 *
                help_write_lines((const xmlChar *)"   (", 0, FALSE);
                help_write_lines(numlabel, 0, FALSE);
                help_write_lines((const xmlChar *)": ", 0, FALSE);

                xmlChar numbuff[NCX_MAX_NUMLEN];

                if (btyp == NCX_BT_ENUM) {
                    snprintf((char *)numbuff, sizeof(numbuff), "%d",
                             tenum->val);
                } else {
                    snprintf((char *)numbuff, sizeof(numbuff), "%u",
                             tenum->pos);
                }
                help_write_lines(numbuff, 0, FALSE);
                help_write_lines((const xmlChar *)")", 0, FALSE);
                */

                if (tenum->descr) {
                    help_write_lines(tenum->descr, 
                                     indent+(2*NCX_DEF_INDENT), TRUE);
                }
                if (tenum->ref) {
                    help_write_lines(tenum->ref, 
                                     indent+(2*NCX_DEF_INDENT), TRUE);
                }
            }
        }
        break;
    case NCX_BT_LEAFREF:
        datastr = typ_get_leafref_path(basetypdef);
        if (datastr) {
            help_write_lines((const xmlChar *)"leafref path:",
                             indent, TRUE);
            help_write_lines(datastr, indent+NCX_DEF_INDENT, TRUE);
        }
        break;
    default:
        ;
    }

    
}  /* dump_typdef_data */