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

//  $Id: rpsl_attr.cc,v 1.1.1.1 2000/03/10 16:32:23 engin Exp $
//
//  Copyright (c) 1994 by the University of Southern California
//  All rights reserved.
//
//  Permission to use, copy, modify, and distribute this software and its
//  documentation in source and binary forms for lawful non-commercial
//  purposes and without fee is hereby granted, provided that the above
//  copyright notice appear in all copies and that both the copyright
//  notice and this permission notice appear in supporting documentation,
//  and that any documentation, advertising materials, and other materials
//  related to such distribution and use acknowledge that the software was
//  developed by the University of Southern California, Information
//  Sciences Institute. The name of the USC may not be used to endorse or
//  promote products derived from this software without specific prior
//  written permission.
//
//  THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY
//  REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
//  PURPOSE.  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
//  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
//  TITLE, AND NON-INFRINGEMENT.
//
//  IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
//  SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, TORT,
//  OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, THE USE
//  OR PERFORMANCE OF THIS SOFTWARE.
//
//  Questions concerning this software should be directed to 
//  ratoolset@isi.edu.
//
//  Author(s): Cengiz Alaettinoglu <cengiz@ISI.EDU>

#include "config.h"
#include <cstdio>
#include "rpsl_attr.hh"
#include "object.hh"
#include "schema.hh"

//// printing ////////////////////////////////////////////////////////

ostream &Attr::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   if (object && object->contents)
      out.write(object->getTextAt(offset), len);
   return out;
}

ostream &AttrGeneric::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << type->name() << ":\t" << *items;
   return out;
}

ostream &AttrImport::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "import: ";
   if (fromProt && fromProt->name && strcasecmp(fromProt->name, "BGP4"))
      out << "protocol " << fromProt->name << " ";
   if (intoProt && intoProt->name && strcasecmp(intoProt->name, "BGP4"))
      out << "into " << intoProt->name << " ";
   out << *policy;
   return out;
}

ostream &AttrExport::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "export: " << *policy;
   return out;
}

ostream &AttrDefault::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "default:\tto   " << *peering << "\n";

   if (!action->isEmpty())
      out << "       \t " << *action << "\n";

   if (filter && typeid(filter) != typeid(FilterANY))
      out << "       \t networks " << *filter;

   return out;
}

ostream &AttrFilter::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "filter: " << *filter;

   return out;
}

ostream &AttrPeering::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "peering: " << *peering;

   return out;
}

ostream &AttrIfAddr::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   static char buffer[128];
   out << "ifaddr:\t" << int2quad(buffer, ifaddr.get_ipaddr())
       << " masklen " << ifaddr.get_length();
   return out;
}

ostream &AttrPeerOption::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << option << "(" << *args << ")";
   return out;
}

ostream &AttrPeer::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "peer:\t" << protocol->name
       << " " << *peer << " ";
   for (AttrPeerOption *nd = options->head(); nd; ) {
      nd->print(out);
      nd = options->next(nd);
      if (nd)
         out << ", ";
   }
   return out;
}

ostream &AttrTypedef::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   if (type)
      out << "typedef: " << name << " " << *type;   
   else 
      out << "typedef: " << name << "<error in type spec>";   
   return out;
}

ostream &AttrProtocol::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "protocol: " << name;
   for (AttrProtocolOption *nd = options->head(); nd; nd = options->next(nd)) {
      nd->print(out);
      out << "\n             ";
   }
   return out;
}

ostream &AttrProtocolOption::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << (optional ? " optional " : " mandatory ") << *option << " ";
   return out;
}

ostream &AttrMethod::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << name << "(";
   for (RPTypeNode *n = args->head(); n; ) {
      out << *n->type;
      n = args->next(n);
      if (n)
         out << ", ";
   }   
   if (varargs)
      out << ", ...";
   out << ")";
   return out;
}

ostream &AttrRPAttr::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "rp-attribute: " << name;
   for (AttrMethod *nd = methods->head(); nd; nd = methods->next(nd))
      out << " " << *nd;
   return out;
}

ostream &AttrAttr::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "attr: " << _name << " syntax(?) ?";

   return out;
}








const AttrMethod *AttrRPAttr::searchMethod(const char *name) const {
/* [<][>][^][v][top][bottom][index][help] */
   char buffer[1024] = "";

   if (!isalpha(*name))
      strcpy(buffer, "operator");

   strcat(buffer, name);

   // return method or NULL
   for (AttrMethod *m = methods->head(); m; m = methods->next(m))
      if (!strcasecmp(m->name, buffer))
         return m;

   return NULL;
}

const AttrMethod *AttrRPAttr::searchNextMethod(const AttrMethod *last) const {
/* [<][>][^][v][top][bottom][index][help] */
   // return method or NULL
   const AttrMethod *m = last;

   if (!last)
      return NULL;

   for (m = methods->next(m); m; m = methods->next(m))
      if (!strcasecmp(m->name, last->name))
         return m;

   return NULL;
}

void AttrProtocol::startMandatoryCheck() {
/* [<][>][^][v][top][bottom][index][help] */
   for (AttrProtocolOption *m = options->head(); m; m = options->next(m))
      m->found = false;
}

const AttrProtocolOption *AttrProtocol::missingMandatoryOption() {
/* [<][>][^][v][top][bottom][index][help] */
   AttrProtocolOption *m, *n;

   for (m = options->head(); m; m = options->next(m)) {
      if (! m->found && ! m->optional)
         return m;
      if (m->found)
         for (n = options->next(m); n; n = options->next(n))
            if (!strcasecmp(m->option->name, n->option->name))
               n->found = true;
   }
   
   return NULL;
}

const AttrProtocolOption *AttrProtocol::searchOption(const char *name) const {
/* [<][>][^][v][top][bottom][index][help] */
   // return method or NULL
   for (AttrProtocolOption *m = options->head(); m; m = options->next(m))
      if (!strcasecmp(m->option->name, name)) {
         m->found = true;
         return m;
      }

   return NULL;
}

const AttrProtocolOption *AttrProtocol::searchNextOption
/* [<][>][^][v][top][bottom][index][help] */
   (const AttrProtocolOption *last) const {
   // return method or NULL
   AttrProtocolOption *m = (AttrProtocolOption *) last;

   if (!last)
      return NULL;

   for (m = options->next(m); m; m = options->next(m))
      if (!strcasecmp(m->option->name, last->option->name)) {
         m->found = true;
         return m;
      }

   return NULL;
}

const AttrPeerOption *AttrPeer::searchOption(const char *name) const {
/* [<][>][^][v][top][bottom][index][help] */
   // return method or NULL
   for (AttrPeerOption *m = options->head(); m; m = options->next(m))
      if (!strcasecmp(m->option, name))
         return m;

   return NULL;
}

bool AttrMethod::validateArgs(ItemList *actualArgs, int &position, 
/* [<][>][^][v][top][bottom][index][help] */
                              const RPType *&correctType) const {
   RPTypeNode *tnode = args->head();
   Item *arg = actualArgs->head();
   position = 0;
   Item *arg2;

   if (!tnode && !arg)
      return true;

   if (!tnode)
      return false;

   position = 1;
   correctType = tnode->type;
   while (correctType && arg) {
      if (!correctType->validate(arg)) {
         arg2 = correctType->typeCast(arg);
         if (arg2) {
            actualArgs->insertAfter(arg, arg2);
            actualArgs->remove(arg);
            delete arg;
            arg = arg2;
         } else
            return false;
      }

      position++;
      arg = actualArgs->next(arg);
      tnode = args->next(tnode);
      correctType = tnode ? tnode->type : NULL; 
   }
   
   if (!correctType && arg && varargs) { // extra args
      tnode = args->tail();
      correctType = tnode->type;
      while (correctType && arg) {
         if (!correctType->validate(arg)) {
            arg2 = correctType->typeCast(arg);
            if (arg2) {
               actualArgs->insertAfter(arg, arg2);
               actualArgs->remove(arg);
               delete arg;
               arg = arg2;
            } else
               return false;
         }

         arg = actualArgs->next(arg);
         position++;
      }
      correctType = (RPType *) NULL;
   }

   if (!correctType && !arg)
      return true;
   
   position = 0;
   return false;
}

void AttrClass::reset() {
/* [<][>][^][v][top][bottom][index][help] */
   for (int i = 0; i < attribs.size(); ++i)
      attribs[i]->reset();
}

AttrAttr* AttrClass::searchAttr(const char *name) {
/* [<][>][^][v][top][bottom][index][help] */
   for (int i = 0; i < attribs.size(); ++i)
      if (!strcasecmp(name, attribs[i]->name())) {
         attribs[i]->touch();
         return attribs[i];
      }
      
   return NULL;
}

bool AttrClass::validate(string &errors) {
/* [<][>][^][v][top][bottom][index][help] */
   // return true if valid i.e. no error
   static char buffer[1024];
   bool result = true;

   for (int i = 0; i < attribs.size(); ++i) {
      if (!attribs[i]->testKey()) {
         sprintf(buffer, "***Error: key attribute %s is not specified.\n",
                 attribs[i]->name());
         errors += buffer;
         result = false;
      }
      if ((!schema.isForgiving() || attribs[i]->isKey())
          && !attribs[i]->testMandatory()) {
         sprintf(buffer, "***Error: mandatory attribute %s is not specified.\n",
                 attribs[i]->name());
         errors += buffer;
         result = false;
      }
      if ((!schema.isForgiving() || attribs[i]->isKey())
          && !attribs[i]->testSingleValued()) {
         sprintf(buffer, 
                 "***Error: single-valued attribute %s occurs multiple times.\n",
                 attribs[i]->name());
         errors += buffer;
         result = false;
      }
   if (!attribs[i]->testGenerated()) {
         sprintf(buffer, 
                 "***Error: generated attribute %s cannot appear in an update.\n",
                 attribs[i]->name());
         errors += buffer;
         result = false;
      }

   }
   return result;
}

ostream& AttrClass::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
}

ostream& AttrMntRoutes::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "mnt-routes:";
   for (MntPrfxPair *p = mntPrfxList->head(); p; p = mntPrfxList->next(p)) {
      out << " " << p->mnt;
      if (p->prefixes)
         out << " " << p->prefixes;
      out << ",\n";
   }
}

ostream& AttrTRLabel::print(ostream &out) const {
/* [<][>][^][v][top][bottom][index][help] */
   out << "transaction-label: " 
       << *source << " " << *seq << " " << *stamp;
}


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