modules/up/src/rpsl/rpsl/rpsl_attr.cc

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. print
  2. print
  3. print
  4. print
  5. print
  6. print
  7. print
  8. print
  9. print
  10. print
  11. print
  12. print
  13. print
  14. print
  15. print
  16. print
  17. searchMethod
  18. searchNextMethod
  19. startMandatoryCheck
  20. missingMandatoryOption
  21. searchOption
  22. searchNextOption
  23. searchOption
  24. validateArgs
  25. reset
  26. searchAttr
  27. validate
  28. print
  29. print
  30. print

   1 //  $Id: rpsl_attr.cc,v 1.1.1.1 2000/03/10 16:32:23 engin Exp $
   2 //
   3 //  Copyright (c) 1994 by the University of Southern California
   4 //  All rights reserved.
   5 //
   6 //  Permission to use, copy, modify, and distribute this software and its
   7 //  documentation in source and binary forms for lawful non-commercial
   8 //  purposes and without fee is hereby granted, provided that the above
   9 //  copyright notice appear in all copies and that both the copyright
  10 //  notice and this permission notice appear in supporting documentation,
  11 //  and that any documentation, advertising materials, and other materials
  12 //  related to such distribution and use acknowledge that the software was
  13 //  developed by the University of Southern California, Information
  14 //  Sciences Institute. The name of the USC may not be used to endorse or
  15 //  promote products derived from this software without specific prior
  16 //  written permission.
  17 //
  18 //  THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY
  19 //  REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
  20 //  PURPOSE.  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  21 //  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  22 //  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
  23 //  TITLE, AND NON-INFRINGEMENT.
  24 //
  25 //  IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
  26 //  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, TORT,
  27 //  OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, THE USE
  28 //  OR PERFORMANCE OF THIS SOFTWARE.
  29 //
  30 //  Questions concerning this software should be directed to 
  31 //  ratoolset@isi.edu.
  32 //
  33 //  Author(s): Cengiz Alaettinoglu <cengiz@ISI.EDU>
  34 
  35 #include "config.h"
  36 #include <cstdio>
  37 #include "rpsl_attr.hh"
  38 #include "object.hh"
  39 #include "schema.hh"
  40 
  41 //// printing ////////////////////////////////////////////////////////
  42 
  43 ostream &Attr::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
  44    if (object && object->contents)
  45       out.write(object->getTextAt(offset), len);
  46    return out;
  47 }
  48 
  49 ostream &AttrGeneric::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
  50    out << type->name() << ":\t" << *items;
  51    return out;
  52 }
  53 
  54 ostream &AttrImport::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
  55    out << "import: ";
  56    if (fromProt && fromProt->name && strcasecmp(fromProt->name, "BGP4"))
  57       out << "protocol " << fromProt->name << " ";
  58    if (intoProt && intoProt->name && strcasecmp(intoProt->name, "BGP4"))
  59       out << "into " << intoProt->name << " ";
  60    out << *policy;
  61    return out;
  62 }
  63 
  64 ostream &AttrExport::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
  65    out << "export: " << *policy;
  66    return out;
  67 }
  68 
  69 ostream &AttrDefault::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
  70    out << "default:\tto   " << *peering << "\n";
  71 
  72    if (!action->isEmpty())
  73       out << "       \t " << *action << "\n";
  74 
  75    if (filter && typeid(filter) != typeid(FilterANY))
  76       out << "       \t networks " << *filter;
  77 
  78    return out;
  79 }
  80 
  81 ostream &AttrFilter::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
  82    out << "filter: " << *filter;
  83 
  84    return out;
  85 }
  86 
  87 ostream &AttrPeering::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
  88    out << "peering: " << *peering;
  89 
  90    return out;
  91 }
  92 
  93 ostream &AttrIfAddr::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
  94    static char buffer[128];
  95    out << "ifaddr:\t" << int2quad(buffer, ifaddr.get_ipaddr())
  96        << " masklen " << ifaddr.get_length();
  97    return out;
  98 }
  99 
 100 ostream &AttrPeerOption::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 101    out << option << "(" << *args << ")";
 102    return out;
 103 }
 104 
 105 ostream &AttrPeer::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 106    out << "peer:\t" << protocol->name
 107        << " " << *peer << " ";
 108    for (AttrPeerOption *nd = options->head(); nd; ) {
 109       nd->print(out);
 110       nd = options->next(nd);
 111       if (nd)
 112          out << ", ";
 113    }
 114    return out;
 115 }
 116 
 117 ostream &AttrTypedef::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 118    if (type)
 119       out << "typedef: " << name << " " << *type;   
 120    else 
 121       out << "typedef: " << name << "<error in type spec>";   
 122    return out;
 123 }
 124 
 125 ostream &AttrProtocol::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 126    out << "protocol: " << name;
 127    for (AttrProtocolOption *nd = options->head(); nd; nd = options->next(nd)) {
 128       nd->print(out);
 129       out << "\n             ";
 130    }
 131    return out;
 132 }
 133 
 134 ostream &AttrProtocolOption::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 135    out << (optional ? " optional " : " mandatory ") << *option << " ";
 136    return out;
 137 }
 138 
 139 ostream &AttrMethod::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 140    out << name << "(";
 141    for (RPTypeNode *n = args->head(); n; ) {
 142       out << *n->type;
 143       n = args->next(n);
 144       if (n)
 145          out << ", ";
 146    }   
 147    if (varargs)
 148       out << ", ...";
 149    out << ")";
 150    return out;
 151 }
 152 
 153 ostream &AttrRPAttr::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 154    out << "rp-attribute: " << name;
 155    for (AttrMethod *nd = methods->head(); nd; nd = methods->next(nd))
 156       out << " " << *nd;
 157    return out;
 158 }
 159 
 160 ostream &AttrAttr::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 161    out << "attr: " << _name << " syntax(?) ?";
 162 
 163    return out;
 164 }
 165 
 166 
 167 
 168 
 169 
 170 
 171 
 172 
 173 const AttrMethod *AttrRPAttr::searchMethod(const char *name) const {
     /* [<][>][^][v][top][bottom][index][help] */
 174    char buffer[1024] = "";
 175 
 176    if (!isalpha(*name))
 177       strcpy(buffer, "operator");
 178 
 179    strcat(buffer, name);
 180 
 181    // return method or NULL
 182    for (AttrMethod *m = methods->head(); m; m = methods->next(m))
 183       if (!strcasecmp(m->name, buffer))
 184          return m;
 185 
 186    return NULL;
 187 }
 188 
 189 const AttrMethod *AttrRPAttr::searchNextMethod(const AttrMethod *last) const {
     /* [<][>][^][v][top][bottom][index][help] */
 190    // return method or NULL
 191    const AttrMethod *m = last;
 192 
 193    if (!last)
 194       return NULL;
 195 
 196    for (m = methods->next(m); m; m = methods->next(m))
 197       if (!strcasecmp(m->name, last->name))
 198          return m;
 199 
 200    return NULL;
 201 }
 202 
 203 void AttrProtocol::startMandatoryCheck() {
     /* [<][>][^][v][top][bottom][index][help] */
 204    for (AttrProtocolOption *m = options->head(); m; m = options->next(m))
 205       m->found = false;
 206 }
 207 
 208 const AttrProtocolOption *AttrProtocol::missingMandatoryOption() {
     /* [<][>][^][v][top][bottom][index][help] */
 209    AttrProtocolOption *m, *n;
 210 
 211    for (m = options->head(); m; m = options->next(m)) {
 212       if (! m->found && ! m->optional)
 213          return m;
 214       if (m->found)
 215          for (n = options->next(m); n; n = options->next(n))
 216             if (!strcasecmp(m->option->name, n->option->name))
 217                n->found = true;
 218    }
 219    
 220    return NULL;
 221 }
 222 
 223 const AttrProtocolOption *AttrProtocol::searchOption(const char *name) const {
     /* [<][>][^][v][top][bottom][index][help] */
 224    // return method or NULL
 225    for (AttrProtocolOption *m = options->head(); m; m = options->next(m))
 226       if (!strcasecmp(m->option->name, name)) {
 227          m->found = true;
 228          return m;
 229       }
 230 
 231    return NULL;
 232 }
 233 
 234 const AttrProtocolOption *AttrProtocol::searchNextOption
     /* [<][>][^][v][top][bottom][index][help] */
 235    (const AttrProtocolOption *last) const {
 236    // return method or NULL
 237    AttrProtocolOption *m = (AttrProtocolOption *) last;
 238 
 239    if (!last)
 240       return NULL;
 241 
 242    for (m = options->next(m); m; m = options->next(m))
 243       if (!strcasecmp(m->option->name, last->option->name)) {
 244          m->found = true;
 245          return m;
 246       }
 247 
 248    return NULL;
 249 }
 250 
 251 const AttrPeerOption *AttrPeer::searchOption(const char *name) const {
     /* [<][>][^][v][top][bottom][index][help] */
 252    // return method or NULL
 253    for (AttrPeerOption *m = options->head(); m; m = options->next(m))
 254       if (!strcasecmp(m->option, name))
 255          return m;
 256 
 257    return NULL;
 258 }
 259 
 260 bool AttrMethod::validateArgs(ItemList *actualArgs, int &position, 
     /* [<][>][^][v][top][bottom][index][help] */
 261                               const RPType *&correctType) const {
 262    RPTypeNode *tnode = args->head();
 263    Item *arg = actualArgs->head();
 264    position = 0;
 265    Item *arg2;
 266 
 267    if (!tnode && !arg)
 268       return true;
 269 
 270    if (!tnode)
 271       return false;
 272 
 273    position = 1;
 274    correctType = tnode->type;
 275    while (correctType && arg) {
 276       if (!correctType->validate(arg)) {
 277          arg2 = correctType->typeCast(arg);
 278          if (arg2) {
 279             actualArgs->insertAfter(arg, arg2);
 280             actualArgs->remove(arg);
 281             delete arg;
 282             arg = arg2;
 283          } else
 284             return false;
 285       }
 286 
 287       position++;
 288       arg = actualArgs->next(arg);
 289       tnode = args->next(tnode);
 290       correctType = tnode ? tnode->type : NULL; 
 291    }
 292    
 293    if (!correctType && arg && varargs) { // extra args
 294       tnode = args->tail();
 295       correctType = tnode->type;
 296       while (correctType && arg) {
 297          if (!correctType->validate(arg)) {
 298             arg2 = correctType->typeCast(arg);
 299             if (arg2) {
 300                actualArgs->insertAfter(arg, arg2);
 301                actualArgs->remove(arg);
 302                delete arg;
 303                arg = arg2;
 304             } else
 305                return false;
 306          }
 307 
 308          arg = actualArgs->next(arg);
 309          position++;
 310       }
 311       correctType = (RPType *) NULL;
 312    }
 313 
 314    if (!correctType && !arg)
 315       return true;
 316    
 317    position = 0;
 318    return false;
 319 }
 320 
 321 void AttrClass::reset() {
     /* [<][>][^][v][top][bottom][index][help] */
 322    for (int i = 0; i < attribs.size(); ++i)
 323       attribs[i]->reset();
 324 }
 325 
 326 AttrAttr* AttrClass::searchAttr(const char *name) {
     /* [<][>][^][v][top][bottom][index][help] */
 327    for (int i = 0; i < attribs.size(); ++i)
 328       if (!strcasecmp(name, attribs[i]->name())) {
 329          attribs[i]->touch();
 330          return attribs[i];
 331       }
 332       
 333    return NULL;
 334 }
 335 
 336 bool AttrClass::validate(string &errors) {
     /* [<][>][^][v][top][bottom][index][help] */
 337    // return true if valid i.e. no error
 338    static char buffer[1024];
 339    bool result = true;
 340 
 341    for (int i = 0; i < attribs.size(); ++i) {
 342       if (!attribs[i]->testKey()) {
 343          sprintf(buffer, "***Error: key attribute %s is not specified.\n",
 344                  attribs[i]->name());
 345          errors += buffer;
 346          result = false;
 347       }
 348       if ((!schema.isForgiving() || attribs[i]->isKey())
 349           && !attribs[i]->testMandatory()) {
 350          sprintf(buffer, "***Error: mandatory attribute %s is not specified.\n",
 351                  attribs[i]->name());
 352          errors += buffer;
 353          result = false;
 354       }
 355       if ((!schema.isForgiving() || attribs[i]->isKey())
 356           && !attribs[i]->testSingleValued()) {
 357          sprintf(buffer, 
 358                  "***Error: single-valued attribute %s occurs multiple times.\n",
 359                  attribs[i]->name());
 360          errors += buffer;
 361          result = false;
 362       }
 363    if (!attribs[i]->testGenerated()) {
 364          sprintf(buffer, 
 365                  "***Error: generated attribute %s cannot appear in an update.\n",
 366                  attribs[i]->name());
 367          errors += buffer;
 368          result = false;
 369       }
 370 
 371    }
 372    return result;
 373 }
 374 
 375 ostream& AttrClass::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 376 }
 377 
 378 ostream& AttrMntRoutes::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 379    out << "mnt-routes:";
 380    for (MntPrfxPair *p = mntPrfxList->head(); p; p = mntPrfxList->next(p)) {
 381       out << " " << p->mnt;
 382       if (p->prefixes)
 383          out << " " << p->prefixes;
 384       out << ",\n";
 385    }
 386 }
 387 
 388 ostream& AttrTRLabel::print(ostream &out) const {
     /* [<][>][^][v][top][bottom][index][help] */
 389    out << "transaction-label: " 
 390        << *source << " " << *seq << " " << *stamp;
 391 }
 392 

/* [<][>][^][v][top][bottom][index][help] */