Beispiel #1
0
/********************************************************************
* FUNCTION write_yin_contents
*  
* Go through the token chain and write all the
* YIN elements according to algoritm in sec. 11
*
* INPUTS:
*   pcb == parser control block of module to convert
*          This is returned from ncxmod_load_module_ex
*   cp == conversion parms to use
*   scb == session control block for writing output
*
* RETURNS:
*   status
*********************************************************************/
static status_t
    write_yin_contents (yang_pcb_t *pcb,
                        const yangdump_cvtparms_t *cp,
                        ses_cb_t *scb)
{
    status_t       res;
    boolean        done;
    int            i;

    tk_reset_chain(pcb->tkc);
    res = NO_ERR;

    /* need to skip the first 3 tokens because the
     * [sub]module name { tokens have already been
     * handled as a special case 
     */
    for (i = 0; i < 4; i++) {
        res = advance_token(pcb);
        if (res != NO_ERR) {
            return res;
        }
    }

    done = FALSE;
    while (!done && res == NO_ERR) {
        res = write_yin_stmt(pcb, 
                             cp, 
                             scb, 
                             cp->indent,
                             &done);
    }

    return res;

}   /* write_yin_contents */
Beispiel #2
0
struct Token* c_get_tokens(struct Grammar* grammar, char* text, int indent, struct cTokenError* error) {
    struct Token* start = NULL;
    struct Token* current = NULL;
    struct Token* tmp = NULL;

    struct TokenState state;
    state.at = 0;
    state.ln = strlen(text);
    // state.text = text;
    state.lineno = 1;
    state.charno = 1;
    state.indents = (int*)malloc(sizeof(int)*100);
    state.indents[0] = 0;
    state.max_indents = 100;
    state.num_indents = 1;

    struct PToken ptoken;

    int ID_t = grammar->tokens.num;
    int DD_t = grammar->tokens.num+1;

    int res = 0;

    int dirty;

    // printf("with text:: %s\n\n", text);

    while (state.at < state.ln) {
        int i;
        dirty = 0;
        for (i=0;i<grammar->tokens.num;i++) {
            // printf("looking for token: %d\n", i);
            ptoken = grammar->tokens.tokens[i];
            switch (ptoken.type) {
                case CTOKEN:
                    res = check_ctoken(ptoken.value.tid, state.at, text, state.ln, grammar->idchars);
                    break;
                case CHARTOKEN:
                    res = check_chartoken(ptoken.value.chars, ptoken.num, state.at, text, state.ln);
                    break;
                case STRTOKEN:
                    res = check_stringtoken(ptoken.value.strings, ptoken.num, state.at, text, state.ln);
                    break;
                case IDTOKEN:
                    res = check_idtoken(ptoken.value.strings, ptoken.num, state.at, text, state.ln, grammar->idchars);
                    break;
                case IIDTOKEN:
                    res = check_iidtoken(ptoken.value.strings, ptoken.num, state.at, text, state.ln, grammar->idchars);
                    break;
                default:
                    res = 0;
            }
            if (res > 0) {
                tmp = (struct Token*)malloc(sizeof(struct Token));
                tmp->value = (char*)malloc(sizeof(char)*(res+1));
                strncpy(tmp->value, text + state.at, res);
                tmp->value[res] = '\0';
                // printf("got token! %d (%s)\n", res, tmp->value);
                tmp->which = ptoken.which;
                tmp->next = NULL;
                tmp->lineno = state.lineno;
                tmp->charno = state.charno;
                if (start == NULL) {
                    start = tmp;
                } else {
                    current->next = tmp;
                }
                current = tmp;
                current = advance_token(res, current, indent, &state, text, ID_t, DD_t, error);
                if (current == NULL) {
                    return NULL;
                }
                state.at += res;
                dirty = 1;
                break;
            }
        }
        if (!dirty) {
            error->text = "no valid token found";
            error->lineno = state.lineno;
            error->charno = state.charno;
            return NULL;
        }
    }
    return start;
}
Beispiel #3
0
/********************************************************************
* FUNCTION write_yin_stmt
*  
* Go through the token chain and write YIN stmts
* recursively if needed, until 1 YANG stmt is handled
*
* INPUTS:
*   pcb == parser control block of module to convert
*          This is returned from ncxmod_load_module_ex
*   cp == conversion parms to use
*   scb == session control block for writing output
*   startindent == start indent count
*   done == address of done return var to use
*
* RETURNS:
*   status
*********************************************************************/
static status_t
    write_yin_stmt (yang_pcb_t *pcb,
                    const yangdump_cvtparms_t *cp,
                    ses_cb_t *scb,
                    int32 startindent,
                    boolean *done)
{
    const yin_mapping_t  *mapping;
    ncx_import_t         *import;
    ext_template_t       *extension;
    const xmlChar        *prefix, *modprefix;
    status_t              res;
    boolean               loopdone;

    res = NO_ERR;
    *done = FALSE;

    /* expecting a keyword [string] stmt-end sequence
     * or the very last closing right brace
     */
    if (TK_CUR_TYP(pcb->tkc) == TK_TT_RBRACE) {
        if (tk_next_typ(pcb->tkc) == TK_TT_NONE) {
            *done = TRUE;
            return NO_ERR;
        } else {
            return ERR_NCX_WRONG_TKTYPE;
        }
    } else if (!TK_CUR_ID(pcb->tkc)) {
        return ERR_NCX_WRONG_TKTYPE;
    }

    /* check the keyword type */
    switch (TK_CUR_TYP(pcb->tkc)) {
    case TK_TT_TSTRING:
        /* YANG keyword */
        mapping = yin_find_mapping(TK_CUR_VAL(pcb->tkc));
        if (mapping == NULL) {
            return ERR_NCX_DEF_NOT_FOUND;
        }

        /* output keyword part */
        start_yin_elem(scb, mapping->keyword, startindent);

        /* output [string] part if expected */
        if (mapping->argname == NULL) {
            if (tk_next_typ(pcb->tkc) == TK_TT_LBRACE) {
                ses_putchar(scb, '>');
            }
        } else {
            /* move token pointer to the argument string */
            res = advance_token(pcb);
            if (res != NO_ERR) {
                return res;
            }

            /* write the string part 
             * do not add any extra whiespace to the XML string
             */
            if (mapping->elem) {
                ses_putchar(scb, '>');

                /* encode argname,value as an element */
                start_yin_elem(scb, 
                               mapping->argname,
                               startindent + cp->indent);
                ses_putchar(scb, '>');
                write_cur_token(scb, pcb, TRUE);
                end_yin_elem(scb, mapping->argname, -1);
            } else {
                /* encode argname,value as an attribute */
                ses_putchar(scb, ' ');
                ses_putstr(scb, mapping->argname);
                ses_putchar(scb, '=');
                ses_putchar(scb, '"');
                write_cur_token(scb, pcb, FALSE);
                ses_putchar(scb, '"');
                if (tk_next_typ(pcb->tkc) != TK_TT_SEMICOL) {
                    ses_putchar(scb, '>');
                } /* else end with empty element */
            }
        }

        /* move token pointer to the stmt-end char */
        res = advance_token(pcb);
        if (res != NO_ERR) {
            return res;
        }

        switch (TK_CUR_TYP(pcb->tkc)) {
        case TK_TT_SEMICOL:
            /* advance to next stmt, this one is done */
            res = advance_token(pcb);
            if (res != NO_ERR) {
                return res;
            }
            if (mapping->elem) {
                /* end the complex element */
                end_yin_elem(scb, mapping->keyword, startindent);
            } else {
                /* end the empty element */
                ses_putstr(scb, (const xmlChar *)" />");
            }
            break;
        case TK_TT_LBRACE:
            /* advance to next sub-stmt, this one has child nodes */
            res = advance_token(pcb);
            if (res != NO_ERR) {
                return res;
            }

            /* write the nested sub-stmts as child nodes */
            if (TK_CUR_TYP(pcb->tkc) != TK_TT_RBRACE) {
                loopdone = FALSE;
                while (!loopdone) {
                    res = write_yin_stmt(pcb,
                                         cp,
                                         scb,
                                         startindent + cp->indent,
                                         done);
                    if (res != NO_ERR) {
                        return res;
                    }
                    if (TK_CUR_TYP(pcb->tkc) == TK_TT_RBRACE) {
                        loopdone = TRUE;
                    }
                }
            }

            /* move to next stmt, this one is done */
            res = advance_token(pcb);
            if (res != NO_ERR) {
                return res;
            }

            /* end the complex element */
            end_yin_elem(scb, mapping->keyword, startindent);
            break;
        default:
            return SET_ERROR(ERR_INTERNAL_VAL);
        }
        break;
    case TK_TT_MSTRING:
        /* extension keyword */
        prefix = TK_CUR_MOD(pcb->tkc);
        modprefix = ncx_get_mod_prefix(pcb->top);
        if (modprefix != NULL && !xml_strcmp(prefix, modprefix)) {
            /* local module */
            extension = ext_find_extension(pcb->top, 
                                           TK_CUR_VAL(pcb->tkc));
        } else {
            import = ncx_find_pre_import(pcb->top, prefix);
            if (import == NULL || import->mod == NULL) {
                return ERR_NCX_IMP_NOT_FOUND;
            }
            extension = ext_find_extension(import->mod, 
                                           TK_CUR_VAL(pcb->tkc));
        }
        if (extension == NULL) {
            return ERR_NCX_DEF_NOT_FOUND;
        }

        /* got the extension for this external keyword
         * output keyword part 
         */
        start_ext_elem(scb, 
                       prefix,
                       TK_CUR_VAL(pcb->tkc), 
                       startindent);

        /* output [string] part if expected */
        if (extension->arg == NULL) {
            if (tk_next_typ(pcb->tkc) == TK_TT_LBRACE) {
                ses_putchar(scb, '>');
            }
        } else {
            /* move token pointer to the argument string */
            res = advance_token(pcb);
            if (res != NO_ERR) {
                return res;
            }

            /* write the string part
             * do not add any extra whiespace chars to the string
             */
            if (extension->argel) {
                ses_putchar(scb, '>');

                /* encode argname,value as an element */
                start_ext_elem(scb, 
                               prefix,
                               extension->arg,
                               startindent + cp->indent);
                ses_putchar(scb, '>');
                write_cur_token(scb, pcb, TRUE);
                end_ext_elem(scb, prefix, extension->arg, -1);
            } else {
                /* encode argname,value as an attribute */
                ses_putchar(scb, ' ');
                ses_putstr(scb, extension->arg);
                ses_putchar(scb, '=');
                ses_putchar(scb, '"');
                write_cur_token(scb, pcb, FALSE);
                ses_putchar(scb, '"');
                if (tk_next_typ(pcb->tkc) != TK_TT_SEMICOL) {
                    ses_putchar(scb, '>');
                } /* else end with empty element */
            }
        }

        /* move token pointer to the stmt-end char */
        res = advance_token(pcb);
        if (res != NO_ERR) {
            return res;
        }

        switch (TK_CUR_TYP(pcb->tkc)) {
        case TK_TT_SEMICOL:
            /* advance to next stmt, this one is done */
            res = advance_token(pcb);
            if (res != NO_ERR) {
                return res;
            }
            if (extension->arg != NULL && extension->argel) {
                /* end the complex element */
                end_ext_elem(scb, 
                             prefix,
                             extension->name, 
                             startindent);
            } else {
                /* end the empty element */
                ses_putstr(scb, (const xmlChar *)" />");
            }
            break;
        case TK_TT_LBRACE:
            /* advance to next sub-stmt, this one has child nodes */
            res = advance_token(pcb);
            if (res != NO_ERR) {
                return res;
            }

            /* write the nested sub-stmts as child nodes */
            if (TK_CUR_TYP(pcb->tkc) != TK_TT_RBRACE) {
                loopdone = FALSE;
                while (!loopdone) {
                    res = write_yin_stmt(pcb,
                                         cp,
                                         scb,
                                         startindent + cp->indent,
                                         done);
                    if (res != NO_ERR) {
                        return res;
                    }
                    if (TK_CUR_TYP(pcb->tkc) == TK_TT_RBRACE) {
                        loopdone = TRUE;
                    }
                }
            }

            /* move to next stmt, this one is done */
            res = advance_token(pcb);
            if (res != NO_ERR) {
                return res;
            }

            /* end the complex element */
            end_ext_elem(scb, 
                         prefix,
                         extension->name,
                         startindent);
            break;
        default:
            return SET_ERROR(ERR_INTERNAL_VAL);
        }
        break;
    default:
        return SET_ERROR(ERR_INTERNAL_VAL);
    }
    

    return res;

}   /* write_yin_stmt */