/******************************************************************** * FUNCTION ncx_clone_iffeature * * Clone a new ncx_iffeature_t struct * * INPUTS: * srciff == ifffeature struct to clone * RETURNS: * pointer to a malloced ncx_iffeature_t struct, * or NULL if malloc error *********************************************************************/ ncx_iffeature_t * ncx_clone_iffeature (ncx_iffeature_t *srciff) { ncx_iffeature_t *iff; iff = m__getObj(ncx_iffeature_t); if (!iff) { return NULL; } memset(iff, 0x0, sizeof(ncx_iffeature_t)); if (srciff->prefix) { iff->prefix = xml_strdup(srciff->prefix); if (iff->prefix == NULL) { ncx_free_iffeature(iff); return NULL; } } if (srciff->name) { iff->name = xml_strdup(srciff->name); if (iff->name == NULL) { ncx_free_iffeature(iff); return NULL; } } iff->feature = srciff->feature; ncx_set_error(&iff->tkerr, srciff->tkerr.mod, srciff->tkerr.linenum, srciff->tkerr.linepos); //iff->seen not set return iff; } /* ncx_clone_iffeature */
/******************************************************************** * FUNCTION yang_ext_consume_extension * * Parse the next N tokens as an extension-stmt * Create an ext_template_t struct and add it to the specified Q * * Error messages are printed by this function!! * Do not duplicate error messages upon error return * * Current token is the 'extension' keyword * * INPUTS: * tkc == token chain * mod == module in progress * * RETURNS: * status of the operation *********************************************************************/ status_t yang_ext_consume_extension (tk_chain_t *tkc, ncx_module_t *mod) { ext_template_t *ext, *testext; const xmlChar *val; const char *expstr; yang_stmt_t *stmt; tk_type_t tktyp; boolean done, arg, stat, desc, ref; status_t res, retres; #ifdef DEBUG if (!tkc || !mod) { return SET_ERROR(ERR_INTERNAL_PTR); } #endif val = NULL; expstr = "keyword"; done = FALSE; arg = FALSE; stat = FALSE; desc = FALSE; ref = FALSE; res = NO_ERR; retres = NO_ERR; /* Get a new ext_template_t to fill in */ ext = ext_new_template(); if (!ext) { res = ERR_INTERNAL_MEM; ncx_print_errormsg(tkc, mod, res); return res; } ncx_set_error(&ext->tkerr, mod, TK_CUR_LNUM(tkc), TK_CUR_LPOS(tkc)); /* Get the mandatory extension name */ res = yang_consume_id_string(tkc, mod, &ext->name); CHK_EXT_EXIT; /* Get the starting left brace for the sub-clauses * or a semi-colon to end the extension-stmt */ res = TK_ADV(tkc); if (res != NO_ERR) { ncx_print_errormsg(tkc, mod, res); ext_free_template(ext); return res; } switch (TK_CUR_TYP(tkc)) { case TK_TT_SEMICOL: done = TRUE; break; case TK_TT_LBRACE: break; default: retres = ERR_NCX_WRONG_TKTYPE; expstr = "semi-colon or left brace"; ncx_mod_exp_err(tkc, mod, retres, expstr); done = TRUE; } /* get the extension statements and any appinfo extensions */ while (!done) { /* get the next token */ res = TK_ADV(tkc); if (res != NO_ERR) { ncx_print_errormsg(tkc, mod, res); ext_free_template(ext); return res; } tktyp = TK_CUR_TYP(tkc); val = TK_CUR_VAL(tkc); /* check the current token type */ switch (tktyp) { case TK_TT_NONE: res = ERR_NCX_EOF; ncx_print_errormsg(tkc, mod, res); ext_free_template(ext); return res; case TK_TT_MSTRING: /* vendor-specific clause found instead */ res = ncx_consume_appinfo(tkc, mod, &ext->appinfoQ); CHK_EXT_EXIT; continue; case TK_TT_RBRACE: done = TRUE; continue; case TK_TT_TSTRING: break; /* YANG clause assumed */ default: retres = ERR_NCX_WRONG_TKTYPE; ncx_mod_exp_err(tkc, mod, retres, expstr); continue; } /* Got a token string so check the value */ if (!xml_strcmp(val, YANG_K_ARGUMENT)) { res = consume_yang_arg(tkc, mod, ext, &arg); } else if (!xml_strcmp(val, YANG_K_STATUS)) { res = yang_consume_status(tkc, mod, &ext->status, &stat, &ext->appinfoQ); } else if (!xml_strcmp(val, YANG_K_DESCRIPTION)) { res = yang_consume_descr(tkc, mod, &ext->descr, &desc, &ext->appinfoQ); } else if (!xml_strcmp(val, YANG_K_REFERENCE)) { res = yang_consume_descr(tkc, mod, &ext->ref, &ref, &ext->appinfoQ); } else { res = ERR_NCX_WRONG_TKVAL; ncx_mod_exp_err(tkc, mod, res, expstr); } CHK_EXT_EXIT; } /* save or delete the ext_template_t struct */ if (ext->name && ncx_valid_name2(ext->name)) { testext = ext_find_extension_all(mod, ext->name); if (testext) { log_error("\nError: extension '%s' already defined " "in '%s' at line %u", ext->name, testext->tkerr.mod->name, testext->tkerr.linenum); retres = ERR_NCX_DUP_ENTRY; ncx_print_errormsg(tkc, mod, retres); ext_free_template(ext); } else { dlq_enque(ext, &mod->extensionQ); /* may have some errors */ if (mod->stmtmode) { stmt = yang_new_ext_stmt(ext); if (stmt) { dlq_enque(stmt, &mod->stmtQ); } else { log_error("\nError: malloc failure for ext_stmt"); retres = ERR_INTERNAL_MEM; ncx_print_errormsg(tkc, mod, retres); } } } } else { ext_free_template(ext); } return retres; } /* yang_ext_consume_extension */