Пример #1
0
/********************************************************************
 * FUNCTION output_pattern_diff
 * 
 *  Output the differences report for one pattern clause and
 *  any of its sub-clauses, within a leaf, leaf-list, or 
 *  typedef definition
 *
 * INPUTS:
 *    cp == parameter block to use
 *    oldpat == old internal pattern
 *    newpat == new internal pattern
 *    patnum == index number of pattern in the Q [1 .. N]
 *
 *********************************************************************/
static void
    output_pattern_diff (yangdiff_diffparms_t *cp,
                         const typ_pattern_t *oldpat,
                         const typ_pattern_t *newpat,
                         uint32 patnum)
{
    const ncx_errinfo_t *olderr, *newerr;
    const xmlChar       *oldstr, *newstr;
    xmlChar              buff[NCX_MAX_NUMLEN+16], *p;

    oldstr = (oldpat) ? oldpat->pat_str : NULL;
    newstr = (newpat) ? newpat->pat_str : NULL;

    olderr = (oldpat) ? &oldpat->pat_errinfo : NULL;
    newerr = (newpat) ? &newpat->pat_errinfo : NULL;

    p = buff;
    p += xml_strcpy(p, YANG_K_PATTERN);
    *p++ = ' ';
    *p++ = '[';
    p += (uint32)sprintf((char *)p, "%u", patnum);
    *p++ = ']';
    *p = 0;
    
    if (!oldstr && newstr) {
        /* pattern added in new revision */
        output_diff(cp, buff, oldstr, newstr, FALSE);
        indent_in(cp);
        output_errinfo_diff(cp, olderr, newerr);
        indent_out(cp);
    } else if (oldstr && !newstr) {
        /* pattern removed in new revision */
        output_diff(cp, buff, oldstr, newstr, FALSE);
        indent_in(cp);
        output_errinfo_diff(cp, olderr, newerr);
        indent_out(cp);
    } else if (oldstr && newstr) {
        /* check if pattern changed */
        if (xml_strcmp(oldstr, newstr)) {
            output_diff(cp, buff, oldstr, newstr, FALSE);
            indent_in(cp);
            output_errinfo_diff(cp, olderr, newerr);
            indent_out(cp);
        } else if (errinfo_changed(olderr, newerr)) {
            output_mstart_line(cp, buff, oldstr, FALSE);
            indent_in(cp);
            output_errinfo_diff(cp, olderr, newerr);
            indent_out(cp);
        }
    }

} /* output_pattern_diff */
Пример #2
0
/********************************************************************
 * FUNCTION output_typedefQ_diff
 * 
 *  Output the differences report for a Q of typedef definitions
 *  Not always called for top-level typedefs; Can be called
 *  for nested typedefs
 *
 * INPUTS:
 *    cp == parameter block to use
 *    oldQ == Q of old typ_template_t to use
 *    newQ == Q of new typ_template_t to use
 *
 *********************************************************************/
void
    output_typedefQ_diff (yangdiff_diffparms_t *cp,
                          dlq_hdr_t *oldQ,
                          dlq_hdr_t *newQ)
{
    typ_template_t *oldtyp, *newtyp;

    /* borrowing the 'used' flag for marking matched typedefs
     * first set all these flags to FALSE
     */
    for (newtyp = (typ_template_t *)dlq_firstEntry(newQ);
         newtyp != NULL;
         newtyp = (typ_template_t *)dlq_nextEntry(newtyp)) {
        newtyp->used = FALSE;
    }

    /* look through the old type Q for matching types in the new type Q */
    for (oldtyp = (typ_template_t *)dlq_firstEntry(oldQ);
         oldtyp != NULL;
         oldtyp = (typ_template_t *)dlq_nextEntry(oldtyp)) {

        /* find this revision in the new module */
        newtyp = ncx_find_type_que(newQ, oldtyp->name);
        if (newtyp) {
            output_one_typedef_diff(cp, oldtyp, newtyp);
            newtyp->used = TRUE;
        } else {
            /* typedef was removed from the new module */
            output_diff(cp, YANG_K_TYPEDEF, oldtyp->name, NULL, TRUE);
        }
    }

    /* look for typedefs that were added in the new module */
    for (newtyp = (typ_template_t *)dlq_firstEntry(newQ);
         newtyp != NULL;
         newtyp = (typ_template_t *)dlq_nextEntry(newtyp)) {
        if (!newtyp->used) {
            /* this typedef was added in the new version */
            output_diff(cp, YANG_K_TYPEDEF, NULL, newtyp->name, TRUE);
        }
    }

} /* output_typedefQ_diff */
Пример #3
0
void unified_difft::output(std::ostream &os) const
{
  goto_programt empty;

  for(const std::pair<irep_idt, differencest> &p : differences_map)
  {
    goto_functionst::function_mapt::const_iterator f1=
      old_goto_functions.function_map.find(p.first);
    goto_functionst::function_mapt::const_iterator f2=
      new_goto_functions.function_map.find(p.first);

    output_diff(
      p.first,
      f1==old_goto_functions.function_map.end()?empty:f1->second.body,
      f2==new_goto_functions.function_map.end()?empty:f2->second.body,
      p.second,
      os);
  }
}
Пример #4
0
/********************************************************************
 * FUNCTION output_union_diff
 * 
 *  Output the differences report for one union sub-clauses
 *  within a leaf, leaf-list, or typedef definition
 *
 * INPUTS:
 *    cp == parameter block to use
 *    oldtypdef == old internal typedef
 *    newtypdef == new internal typedef
 *********************************************************************/
static void
    output_union_diff (yangdiff_diffparms_t *cp,
                       typ_def_t *oldtypdef,
                       typ_def_t *newtypdef)
{
    typ_unionnode_t     *oldval, *newval, *curnew;
    dlq_hdr_t           *oldQ, *newQ;
    typ_def_t           *olddef, *newdef;
    uint32               oldid, newid;
    char                 oldnum[NCX_MAX_NUMLEN];
    char                 newnum[NCX_MAX_NUMLEN];

    olddef = typ_get_base_typdef(oldtypdef);
    newdef = typ_get_base_typdef(newtypdef);

    oldQ = &olddef->def.simple.unionQ,
    newQ = &newdef->def.simple.unionQ;

    if (!unQ_changed(cp, oldQ, newQ)) {
        return;
    }

    oldid = 0;
    newid = 0;

    /* clear the seen flag to be safe */
    for (newval = (typ_unionnode_t *)dlq_firstEntry(newQ);
         newval != NULL;
         newval = (typ_unionnode_t *)dlq_nextEntry(newval)) {
        newval->seen = FALSE;
    }

    /* start the diff output */
    output_mstart_line(cp, YANG_K_UNION, NULL, FALSE);
    if (cp->edifftype == YANGDIFF_DT_TERSE) {
        return;
    }

    indent_in(cp);

    /* check for matching unionnode entries */
    for (oldval = (typ_unionnode_t *)dlq_firstEntry(oldQ);
         oldval != NULL;
         oldval = (typ_unionnode_t *)dlq_nextEntry(oldval), oldid++) {

        curnew = NULL;
        sprintf(oldnum, "[%u]", oldid);
        olddef = typ_get_unionnode_ptr(oldval);

        /* first try the corresponded entry if available */
        newval = unQ_match_id(oldid, newQ);
        if (newval) {
            curnew = newval;
            newid = oldid;
            sprintf(newnum, "[%u]", newid);
            newdef = typ_get_unionnode_ptr(newval);

            /* if the corresponding entry did not change
             * then this is a match and continue to next type
             */
            if (!type_changed(cp, olddef, newdef)) {
                newval->seen = TRUE;
                continue;
            }
        }
            
        /* did not match the corresponding entry,
         * so see if the typdef moved in the new union
         */
        newval = unQ_match(cp, oldval, newQ, &newid);
        if (newval) {
            newval->seen = TRUE;
            if (oldid != newid) {
                sprintf(newnum, "[%u]", newid);
                /* old union node was moved in new version */
                output_diff(cp, YANG_K_TYPE, 
                            (const xmlChar *)oldnum, 
                            (const xmlChar *)newnum, TRUE);
            }
        } else if (curnew) {
            /* type node was changed in the new union */
            curnew->seen = TRUE;
            newdef = typ_get_unionnode_ptr(curnew);
            sprintf(newnum, "[%u]", oldid);
            output_one_type_diff(cp, olddef, newdef);
        } else {
            /* old union node was removed in new version */
            output_diff(cp, YANG_K_TYPE,
                        (const xmlChar *)oldnum, NULL, TRUE);
        }
    }

    indent_out(cp);

    /* check for new entries */
    newid = 0;
    for (newval = (typ_unionnode_t *)dlq_firstEntry(newQ);
         newval != NULL;
         newval = (typ_unionnode_t *)dlq_nextEntry(newval)) {
        if (!newval->seen) {
            sprintf(newnum, "[%u]", newid);
            output_diff(cp, YANG_K_TYPE, NULL,
                        (const xmlChar *)newnum, TRUE);
        }
        newid++;
    }

} /* output_union_diff */
Пример #5
0
/********************************************************************
 * FUNCTION output_eb_type_diff
 * 
 *  Output the differences report for one enum or bits sub-clauses
 *  within a leaf, leaf-list, or typedef definition
 *
 * INPUTS:
 *    cp == parameter block to use
 *    name == type name to use
 *    oldtypdef == old internal typedef
 *    newtypdef == new internal typedef
 *    isbits == TRUE if NCX_BT_BITS
 *              FALSE if NCX_BT_ENUM
 *********************************************************************/
static void
    output_eb_type_diff (yangdiff_diffparms_t *cp,
                         typ_def_t *oldtypdef,
                         typ_def_t *newtypdef,
                         boolean isbits)
{
    typ_enum_t      *oldval, *newval;
    dlq_hdr_t       *oldQ, *newQ;
    typ_def_t       *oldbase, *newbase;
    const xmlChar   *kw;
    xmlChar          oldnum[NCX_MAX_NUMLEN];
    xmlChar          newnum[NCX_MAX_NUMLEN];
    yangdiff_cdb_t   cdb[4];
    boolean          isrev;
    uint32           chcount, i;

    oldbase = typ_get_base_typdef(oldtypdef);
    newbase = typ_get_base_typdef(newtypdef);

    oldQ = &oldbase->def.simple.valQ;
    newQ = &newbase->def.simple.valQ;

    isrev = (cp->edifftype==YANGDIFF_DT_REVISION) ? TRUE : FALSE;
    kw = isbits ? YANG_K_BIT : YANG_K_ENUM;

    /* clear the seen flag to find new enums/bits */
    for (newval = (typ_enum_t *)dlq_firstEntry(newQ);
         newval != NULL;
         newval = (typ_enum_t *)dlq_nextEntry(newval)) {
        newval->flags &= ~TYP_FL_SEEN;
    }

    /* check for matching entries */
    for (oldval = (typ_enum_t *)dlq_firstEntry(oldQ);
         oldval != NULL;
         oldval = (typ_enum_t *)dlq_nextEntry(oldval)) {

        chcount = 0;
        newval = typ_find_enumdef(newQ, oldval->name);
        if (newval) {
            if (isbits) {
                sprintf((char *)oldnum, "%u", oldval->pos);
                sprintf((char *)newnum, "%u", newval->pos);                     
                chcount += str_field_changed(YANG_K_POSITION,
                                             oldnum, newnum,
                                             isrev, &cdb[0]);
            } else {
                sprintf((char *)oldnum, "%d", oldval->val);
                sprintf((char *)newnum, "%d", newval->val);                     
                chcount += str_field_changed(YANG_K_VALUE,
                                             oldnum, newnum,
                                             isrev, &cdb[0]);
            }
            chcount += status_field_changed(YANG_K_STATUS,
                                            oldval->status, newval->status,
                                            isrev, &cdb[1]);
            chcount += str_field_changed(YANG_K_DESCRIPTION,
                                         oldval->descr, newval->descr,
                                         isrev, &cdb[2]);
            chcount += str_field_changed(YANG_K_REFERENCE,
                                         oldval->ref, newval->ref,
                                         isrev, &cdb[3]);
            newval->flags |= TYP_FL_SEEN;
            if (chcount) {
                output_mstart_line(cp, kw, oldval->name, isbits);
                if (cp->edifftype != YANGDIFF_DT_TERSE) {
                    indent_in(cp);
                    for (i=0; i<4; i++) {
                        output_cdb_line(cp, &cdb[i]);
                    }
                    indent_out(cp);
                }
            }
        } else {
            /* removed name in new version */
            output_diff(cp, kw, oldval->name, NULL, isbits);
        }
    }

    /* check for new entries */
    for (newval = (typ_enum_t *)dlq_firstEntry(newQ);
         newval != NULL;
         newval = (typ_enum_t *)dlq_nextEntry(newval)) {
        if ((newval->flags & TYP_FL_SEEN) == 0) {
            output_diff(cp, kw, NULL, newval->name, isbits);
        }
    }

} /* output_eb_type_diff */
Пример #6
0
/********************************************************************
 * FUNCTION output_one_type_diff
 * 
 *  Output the differences report for one type section
 *  within a leaf, leaf-list, or typedef definition
 *
 * type_changed should be called first to determine
 * if the type actually changed.  Otherwise a 'M typedef foo'
 * output line will result and be a false positive
 *
 * INPUTS:
 *    cp == parameter block to use
 *    oldtypdef == old internal typedef
 *    newtypdef == new internal typedef
 *
 *********************************************************************/
void
    output_one_type_diff (yangdiff_diffparms_t *cp,
                          typ_def_t *oldtypdef,
                          typ_def_t *newtypdef)
{
    xmlChar            *p, *oldp, *newp;
    const xmlChar      *oldname, *newname;
    const xmlChar      *oldpath, *newpath;
    yangdiff_cdb_t      typcdb[5];
    ncx_btype_t         oldbtyp, newbtyp;
    ncx_tclass_t        oldclass, newclass;
    boolean             isrev;

    isrev = (cp->edifftype==YANGDIFF_DT_REVISION) ? TRUE : FALSE;

    oldclass = oldtypdef->tclass;
    newclass = newtypdef->tclass;

    oldname = typ_get_name(oldtypdef);
    newname = typ_get_name(newtypdef);

    oldbtyp = typ_get_basetype(oldtypdef);
    newbtyp = typ_get_basetype(newtypdef);

    if (oldbtyp == NCX_BT_LEAFREF) {
        oldpath = typ_get_leafref_path(oldtypdef);
    } else {
        oldpath = NULL;
    }
    if (newbtyp==NCX_BT_LEAFREF) {
        newpath = typ_get_leafref_path(newtypdef);
    } else {
        newpath = NULL;
    }

    /* check if there is a module prefix involved
     * in the change.  This may be a false positive
     * if the prefix simply changed
     * create YANG QNames for the type change record
     * use the scratch buffer cp->buff for both strings
     */
    p = cp->buff;
    if (oldtypdef->prefix) {
        oldp = p;
        p += xml_strcpy(p, oldtypdef->prefix);
        *p++ = ':';
        p += xml_strcpy(p, oldname);
        if (oldtypdef->tclass==NCX_CL_NAMED) {
            *p++ = ' ';
            *p++ = '(';
            p += xml_strcpy(p, (const xmlChar *)
                            tk_get_btype_sym(oldbtyp));
            *p++ = ')';
            *p = 0;         
        }
        p++;   /* leave last NULL char in place */
        oldname = oldp;
    }
    if (newtypdef->prefix) {
        newp = p;
        p += xml_strcpy(p, newtypdef->prefix);
        *p++ = ':';
        p += xml_strcpy(p, newname);
        if (newtypdef->tclass==NCX_CL_NAMED) {
            *p++ = ' ';
            *p++ = '(';
            p += xml_strcpy(p, (const xmlChar *)
                            tk_get_btype_sym(newbtyp));
            *p++ = ')';
            *p = 0;
        }
        newname = newp;
    }

    /* Print the type name change set only if it really
     * changed; otherwise force an M line to be printed
     */
    if (str_field_changed(YANG_K_TYPE, oldname, newname, 
                          isrev, &typcdb[0])) {
        output_cdb_line(cp, &typcdb[0]);
    } else {
        output_mstart_line(cp, YANG_K_TYPE, NULL, FALSE);
    }

    /* check invalid change of builtin type */
    if (oldbtyp != newbtyp) {
        /* need to figure out what type changes are really allowed */
        if (!((typ_is_number(oldbtyp) && typ_is_number(newbtyp)) ||
              (typ_is_string(oldbtyp) && typ_is_string(newbtyp)))) {
            /* ses_putstr(cp->scb, (const xmlChar *)" (invalid)"); */
            return;
        }
    }

    /* check if that is all the data requested */
    if (cp->edifftype == YANGDIFF_DT_TERSE) {
        return;
    }

    /* check corner-case, no sub-fields to compare */
    if (oldclass==NCX_CL_BASE && newclass==NCX_CL_BASE) {
        /* type field is a plain builtin like 'int32;' */
        return;
    }

    /* in all modes except 'normal', indent 1 level and
     * show the specific sub-clauses that have changed
     */
    indent_in(cp);

    /* special case -- check leafref here */
    if (oldpath || newpath) {
        output_diff(cp, YANG_K_PATH, oldpath, newpath, FALSE);
    }

    if (typ_is_number(oldbtyp)) {
        output_range_diff(cp, YANG_K_RANGE, oldtypdef, newtypdef);
    } else if (typ_is_string(oldbtyp)) {
        output_range_diff(cp, YANG_K_LENGTH, oldtypdef, newtypdef);
        output_patternQ_diff(cp, oldtypdef, newtypdef);
    } else {
        switch (oldbtyp) {
        case NCX_BT_ENUM:
            output_eb_type_diff(cp, oldtypdef, newtypdef, FALSE);
            break;
        case NCX_BT_BITS:
            output_eb_type_diff(cp, oldtypdef, newtypdef, TRUE);
            break;
        case NCX_BT_UNION:
            output_union_diff(cp, oldtypdef, newtypdef);
            break;
        default:
            ;
        }
    }

    indent_out(cp);

} /* output_one_type_diff */