OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [snmp/] [agent/] [v2_0/] [utils/] [mib2c/] [mib2c.storage.conf] - Rev 174

Compare with Previous | Blame | View Log

# mib2c.storage.conf:
#
#  This is a special mib2c.conf file that assumes that you want to do
#  all storage of information locally rather than pulling the
#  information from another source outside the agent (EG, the
#  kernel).  To accomplish this, it defines a structure for the
#  storage of tables and assumes you want to use the header_complex
#  functions for retrieving and storing that data in a local data
#  store.  It even writes a .conf file parser for you and sets you up
#  for being able to do persistant storage fairly simply.
#
#  In short:  it trys to do almost all of the work for you...  Almost...

# 
# Define types of data by mib type, and translate into needed C code.
#

# We need to get some extra stuff into the variable declarations
# before sourcing the main mib2c.vartypes.conf file below.
type:           OCTETSTR
storage:            char   *${name};
storage:            size_t  ${name}Len;
varlenname:     StorageTmp->${name}Len
vartest:          if (StorageTmp->${name} == NULL) {
vartest:            config_perror(\"invalid specification for ${name}\");
vartest:            return;
vartest:          }
vartest:
action:              tmpvar = StorageTmp->$name;
action:              tmplen = StorageTmp->${name}Len;
action:              memdup((u_char **) &StorageTmp->$name, var_val, var_val_len);
action:              StorageTmp->${name}Len = var_val_len;
undo:                SNMP_FREE(StorageTmp->${name});
undo:                StorageTmp->${name} = tmpvar;
undo:                StorageTmp->${name}Len = tmplen;
commit:              SNMP_FREE(tmpvar);
sizeofstart:    
sizeofend:      Len
tmpvar:         char *
casttmp:        strdup((char *) tmpvar);
#
type:           INTEGER
storage:            long    $name;
storageret:     &
varlenname:     tmpint
sizeofstart:    sizeof(
sizeofend:      )
tmpvar:         int
action:              tmpvar = StorageTmp->$name;
action:              StorageTmp->${name} = *((long *) var_val);
undo:                StorageTmp->${name} = tmpvar;
casttmp:        tmpvar;
#
type:           OBJECTID
storage:            oid     *$name;
storage:            size_t   ${name}Len
varlenname:     StorageTmp->${name}Len
vartest:          if (StorageTmp->${name} == NULL) {
vartest:            config_perror(\"invalid specification for ${name}\");
vartest:            return;
vartest:          }
vartest:
action:              tmpvar = StorageTmp->$name;
action:              tmplen = StorageTmp->${name}Len;
action:              memdup((u_char **) &StorageTmp->$name, var_val, var_val_len);
action:              StorageTmp->${name}Len = var_val_len/sizeof(oid);
undo:                SNMP_FREE(StorageTmp->${name});
undo:                StorageTmp->${name} = tmpvar;
undo:                StorageTmp->${name}Len = tmplen;
commit:              SNMP_FREE(tmpvar);
sizeofstart:    
sizeofend:      Len
tmpvar:         oid *
casttmp:        (oid *) tmpvar;
freetmp:        SNMP_FREE(tmpvar);
#
type:           COUNTER64
storage:            struct counter64 $name;
varlenname:     tmpint
sizeofstart:    sizeof(
sizeofend:      )
tmpvar:         struct counter64 *
casttmp:        (struct counter64 *) tmpvar;

############################################################################
# source variable typing information:
include: mib2c.vartypes.conf

############################################################################
# The .h file
############################################################################
type:   code-dot-h
code:   /* This file was generated by mib2c and is intended for use as a mib module
code:     for the ucd-snmp snmpd agent. */
code:
code:   #ifndef _MIBGROUP_${OUTPUTNAME}_H
code:   #define _MIBGROUP_${OUTPUTNAME}_H
code:   
code:   /* we may use header_complex from the header_complex module */
code:   
code:   config_require(header_complex)
code:
code:   /* our storage structure(s) */
code:   $variables{'code-structure-per-table'}{'processed'}
code:
code:   /* enum definitions from the covered mib sections */
code:
code:   $variables{'code-enums'}{'processed'}
code:
code:   /* function prototypes */
code:   
code:   void   init_$outputName(void);
code:   $variables{'code-var-table-decl'}{'processed'}
code:   $variables{'code-write-func-decl'}{'processed'}
code:   $variables{'code-write-rowstatus-decl'}{'processed'}
code:   
code:   #endif /* _MIBGROUP_${OUTPUTNAME}_H */

#
# Structure definition, one per table
#
type:           code-structure-per-table
processtable:   code-structure-per-table

code:   struct ${vtable}_data {
code:   $variables{$vtable}{'code-structure'}{'processed'}
code:   };

#
# Structure storage arrays, one per table
#
type:           code-structure-storage
processtable:   code-structure-storage

code:   static struct header_complex_index *${vtable}Storage = NULL;

#
# Structure definition line.
#
type:   code-structure
process: code-structure

code:   " . eval ("\"$variables{$mib->{'type'}}{'storage'}\"") . "
#$variables{$i}{'code'}\""evalstr(
#
# ENUM definitions
#
type:           code-enums
process:        code-enums
skipif: $mib->{'textualConvention'} eq "RowStatus" || $mib->{'textualConvention'} eq "StorageType"

code:   " . eval{ my ($i, $x); foreach $i (sort {$mib->{'enums'}{$a} <=> $mib->{'enums'}{$b}} keys(%{$mib->{'enums'}})) { $x .= sprintf("#define %-40s %d\n","${NAME}_" . uc($i),$mib->{'enums'}{$i}); } $x; } . "

############################################################################
# The .c file, top
############################################################################
type:   code-main-part
code:   /* This file was generated by mib2c and is intended for use as
code:      a mib module for the ucd-snmp snmpd agent. */
code:   
code:   /* This should always be included first before anything else */
code:   #include <config.h>
code:   #if HAVE_STDLIB_H
code:   #include <stdlib.h>
code:   #endif
code:   #if HAVE_STRING_H
code:   #include <string.h>
code:   #else
code:   #include <strings.h>
code:   #endif
code:   
code:   /* minimal include directives */
code:   #include \"mibincl.h\"
code:   #include \"header_complex.h\"
code:   #include \"$outputName.h\"
code:   #include \"snmp-tc.h\"
code:   
code:   /* 
code:    * ${outputName}_variables_oid:
code:    *   this is the top level oid that we want to register under.  This
code:    *   is essentially a prefix, with the suffix appearing in the
code:    *   variable below.
code:    */
code:   
code:   oid ${outputName}_variables_oid[] = { $commaoid };
code:   
code:   /* 
code:    * variable$varlen ${outputName}_variables:
code:    *   this variable defines function callbacks and type return information 
code:    *   for the $outputName mib section 
code:    */
code:   
code:   struct variable$varlen ${outputName}_variables[] = {
code:   /*  magic number        , variable type , ro/rw , callback fn  , L, oidsuffix */
code:   $variables{'variable-structure-info'}{'processed'}
code:   };
code:   /*    (L = length of the oidsuffix) */
code:   
code:   /* global storage of our data, saved in and configured by header_complex() */
code:   $variables{'code-structure-storage'}{'processed'}
code:
code:   /*
code:    * init_$outputName():
code:    *   Initialization routine.  This is called when the agent starts up.
code:    *   At a minimum, registration of your variables should take place here.
code:    */
code:   void init_$outputName(void) {
code:     DEBUGMSGTL((\"$outputName\", \"initializing...  \"));
code:   
code:     /* register ourselves with the agent to handle our mib tree */
code:     REGISTER_MIB(\"$outputName\", ${outputName}_variables, variable$varlen,\
code:                  ${outputName}_variables_oid);
code:
code:     /* register our config handler(s) to deal with registrations */
code:   $variables{'code-parser-registration'}{'processed'}
code:
code:     /* place any other initialization junk you need here */
code:   
code:     DEBUGMSGTL((\"$outputName\", \"done.\\n\"));
code:   }
code:   
code:   $variables{'code-parser'}{'processed'}
code:   
code:   $variables{'code-var_table'}{'processed'}
code:
code:   $variables{'code-write-func'}{'processed'}
code:
code:   $variables{'code-write-rowstatus'}{'processed'}

############################################################################
# var_ function for tables, which is handled specially and used above
#
#   Note: $vtable is set to the table name in the processtable loop.
############################################################################

#
# header file defs first
#
type:           code-var-table-decl
processtable:   code-var-table-decl

code:   FindVarMethod var_$vtable;
code:   void parse_$vtable(char *, char *);

#
# .conf Parser Code per table
#
type:           code-parser-registration
processtable:   code-parser-registration
code:     snmpd_register_config_handler(\"$vtable\", parse_$vtable, NULL,
code:                                   \"HELP STRING\");

type:           code-varlist-add
process:        code-varlist-add
skipif:         $variables{$vroutine}{$name}{'isanindex'} != 1
code:     snmp_varlist_add_variable(&vars, NULL, 0, $variables{$mib->{type}}{asnType}, ($variables{$mib->{type}}{'cast'}) thedata->$name, $variables{$mib->{type}}{'sizeofstart'}thedata->$name$variables{$mib->{type}}{'sizeofend'}); /* $name */

type:           code-parser
processtable:   code-parser

code:   /* 
code:    * ${vtable}_add(): adds a structure node to our data set 
code:    */
code:   int
code:   ${vtable}_add(struct ${vtable}_data *thedata) {
code:     struct variable_list *vars = NULL;
code:
code:     DEBUGMSGTL((\"$outputName\", \"adding data...  \"));
code:    /* add the index variables to the varbind list, which is 
code:       used by header_complex to index the data */
code:
code:   $variables{$vtable}{'code-varlist-add'}{'processed'}
code:
code:     header_complex_add_data(&${vtable}Storage, vars, thedata);
code:     DEBUGMSGTL((\"$vtable\",\"registered an entry\\n\"));
code:   
code:     DEBUGMSGTL((\"$outputName\", \"done.\\n\"));
code:     return SNMPERR_SUCCESS;
code:   }
code:
code:   /*
code:    * parse_$vtable():
code:    *   parses .conf file entries needed to configure the mib.
code:    */
code:   void
code:   parse_$vtable(char *token, char *line) {
code:     size_t tmpint;
code:     struct ${vtable}_data *StorageTmp = SNMP_MALLOC_STRUCT(${vtable}_data);
code:     struct variable_list *vars = NULL;
code:
code:       DEBUGMSGTL((\"$outputName\", \"parsing config...  \"));
code:
code:     if (StorageTmp == NULL) {
code:       config_perror(\"malloc failure\");
code:       return;
code:     }
code:
code:   $variables{$vtable}{'code-parser-sections'}{'processed'}
code:
code:     ${vtable}_add(StorageTmp);
code:       
code:     DEBUGMSGTL((\"$outputName\", \"done.\\n\"));
code:   }
code:   
code:   
code:   /*
code:    * store_$vtable():
code:    *   stores .conf file entries needed to configure the mib.
code:    */
code:   void
code:   store_$vtable(void) {
code:     char line[SNMP_MAXBUF];
code:     char *cptr;
code:     size_t tmpint;
code:     struct ${vtable}_data *StorageTmp;
code:     struct header_complex_index *hcindex;
code:   
code:     DEBUGMSGTL((\"$outputName\", \"storing data...  \"));
code:   
code:     memset(line,0,sizeof(line));
code:   
code:     strcat(line, \"$vtable\");
code:     cptr = line + strlen(line);
code:
code:     for(hcindex=${vtable}Storage; hcindex != NULL; 
code:         hcindex = hcindex->next) {
code:       StorageTmp = (struct ${vtable}_data *) hcindex->data;
code:
code:   $variables{$vtable}{'code-persistent-sections'}{'processed'}
code:
code:       snmpd_store_config(line);
code:     }
code:     DEBUGMSGTL((\"$outputName\", \"done.\\n\"));
code:   }

# individual sections for the parser
type:           code-parser-sections
process:        code-parser-sections
skipif:         $mib->{'access'} =~ /NoAccess/

code:     line = read_config_read_data($variables{$mib->{type}}{asnType}, line, &StorageTmp->$name, &" . eval ("\"$variables{$mib->{type}}{varlenname}\"") . ");
code:   " . eval ("\"$variables{$mib->{type}}{vartest}\"") . "

#
# .conf persistent save Code per table
#
type:           code-persistent-sections
process:        code-persistent-sections
skipif:         $mib->{'access'} =~ /NoAccess/
code:       cptr = read_config_store_data($variables{$mib->{type}}{asnType}, cptr, &StorageTmp->$name, &" . eval ("\"$variables{$mib->{type}}{varlenname}\"") . ");

#
# Code code per table
#
type:           code-var_table
processtable:   code-var_table

code:   /*
code:    * var_$vtable():
code:    *   Handle this table separately from the scalar value case.
code:    *   The workings of this are basically the same as for var_$outputName above.
code:    */
code:   unsigned char *
code:   var_$vtable(struct variable *vp,
code:               oid     *name,
code:               size_t  *length,
code:               int     exact,
code:               size_t  *var_len,
code:               WriteMethod **write_method)
code:   {
code:
code:   struct ${vtable}_data *StorageTmp = NULL;
code:   
code:     DEBUGMSGTL((\"$outputName\", \"var_$vtable: Entering...  \\n\"));
code:     /* 
code:      * this assumes you have registered all your data properly
cdoe:      * with header_complex_add() somewhere before this
code:      */
code:     if ((StorageTmp =
code:          header_complex(${vtable}Storage, vp,name,length,exact,
code:                              var_len,write_method)) == NULL)
code:       return NULL;
code:   
code:     /* 
code:      * this is where we do the value assignments for the mib results.
code:      */
code:     switch(vp->magic) {\n\n
code:   $variables{$vtable}{'code-case-statements'}{'processed'}
code:       default:
code:         ERROR_MSG(\"\");
code:     }
code:     return NULL;
code:   }


############################################################################
# case statement sections
############################################################################
type:           code-case-statements
process:        code-case-statements
skipif:         $mib->{'access'} =~ /NoAccess/

code:               case $NAME:
code:                   " . (($mib->{'access'} =~ /ReadWrite|WriteOnly|Create/) ? "*write_method = write_$mib->{label};" : "") . "
code:                   *var_len = $variables{$mib->{'type'}}{'sizeofstart'}StorageTmp->$mib->{label}$variables{$mib->{'type'}}{'sizeofend'};
code:                   return (u_char *) $variables{$mib->{'type'}}{'storageret'}StorageTmp->$mib->{label};
code:           

############################################################################
# storage structure information
############################################################################
type:           variable-structure-info
process:        variable-structure-info
skipif:         $mib->{'access'} =~ /NoAccess/
code:           " . sprintf("#define   %-20s  $count", $NAME) . "
code:           " . sprintf("  { %-20s, %-14s, %-6.6s, %s, %d, { %s } },", $NAME, $variables{$mib->{'type'}}{'asnType'}, $accessToUCD{$mib->{'access'}}, "var_$vroutine", $depth-1, $subid) . "

############################################################################
# write function definition, also appended to the end of the .c file.
############################################################################
#
# Header info: declair write functions for set processing
#
process:        code-write-func-decl
type:           code-write-func-decl
skipif:         $mib->{'access'} !~ /Write|Create/
code:           WriteMethod write_$name;
#
# C code
#
type:           code-write-func
process:        code-write-func
skipif:         $mib->{'textualConvention'} eq "RowStatus" || $mib->{'access'} !~ /Write|Create/
code:   int
code:   write_$name(int      action,
code:               u_char   *var_val,
code:               u_char   var_val_type,
code:               size_t   var_val_len,
code:               u_char   *statP,
code:               oid      *name,
code:               size_t    name_len)
code:   {
code:     static $variables{$mib->{'type'}}{tmpvar} tmpvar;
code:     struct ${vroutine}_data *StorageTmp = NULL;
code:     static size_t tmplen;
code:     size_t newlen=name_len - (sizeof(${outputName}_variables_oid)/sizeof(oid) + $depth - 1);
code:
code:     DEBUGMSGTL((\"$outputName\", \"write_$name entering action=%d...  \\n\", action));
code:     if ((StorageTmp =
code:          header_complex(${vroutine}Storage, NULL,
code:                         &name[sizeof(${outputName}_variables_oid)/sizeof(oid) + $depth - 1], 
code:                         &newlen, 1, NULL, NULL)) == NULL)
code:         return SNMP_ERR_NOSUCHNAME; /* remove if you support creation here */
code:   
code:     switch ( action ) {
code:           case RESERVE1:
code:             if (var_val_type != $variables{$mib->{'type'}}{asnType}){
code:                 fprintf(stderr, \"write to $name not $variables{$mib->{'type'}}{asnType}\\n\");
code:                 return SNMP_ERR_WRONGTYPE;
code:             }
code:             break;
code:   
code:           case RESERVE2:
code:                /* memory reseveration, final preparation... */
code:             break;
code:   
code:           case FREE:
code:                /* Release any resources that have been allocated */
code:             break;
code:   
code:           case ACTION:
code:                /* The variable has been stored in $variables{$mib->{'type'}}{variable} for
code:                you to use, and you have just been asked to do something with
code:                it.  Note that anything done here must be reversable in the UNDO case */
code:           ".eval ("\"$variables{$mib->{type}}{action}\"")."
code:             break;
code:   
code:           case UNDO:
code:                /* Back out any changes made in the ACTION case */
code:           ".eval ("\"$variables{$mib->{type}}{undo}\"")."
code:             break;
code:   
code:           case COMMIT:
code:                /* Things are working well, so it's now safe to make the change
code:                permanently.  Make sure that anything done here can't fail! */
code:           ".eval ("\"$variables{$mib->{'type'}}{'commit'}\"")."
code:             break;
code:     }
code:     return SNMP_ERR_NOERROR;
code:   }
code:
code:
############################################################################
# copy memory from varlist
############################################################################
type:           code-varlist-copy
process:        code-varlist-copy
skipif:         $variables{$vroutine}{$name}{'isanindex'} != 1
code:               memdup((u_char **) &(StorageNew->$name), 
code:                      vp->val.$variables{$mib->{'type'}}{variable},
code:                      vp->val_len);
code:               StorageNew->${name}Len = vp->val_len;
code:               vp = vp->next_variable;
############################################################################
# add null pointers to a varlist; value to be parsed later
############################################################################
type:           code-varlist-add-null
process:        code-varlist-add-null
skipif:         $variables{$vroutine}{$name}{'isanindex'} != 1
code:             snmp_varlist_add_variable(&vars, NULL, 0, $variables{$mib->{'type'}}{asnType}, NULL, 0); /* $name */
############################################################################
# write function definition for a RowStatus object, 
#   - allows for creation/deletion.
############################################################################
#
# Header info: declair write functions for set processing
#
process:        code-write-rowstatus-decl
type:           code-write-rowstatus-decl
skipif:         $mib->{'textualConvention'} ne "RowStatus"
code:           WriteMethod write_$name;
#
# code
#
type:           code-write-rowstatus
process:        code-write-rowstatus
skipif:         $mib->{'textualConvention'} ne "RowStatus"
code:   int
code:   write_$name(int      action,
code:               u_char   *var_val,
code:               u_char   var_val_type,
code:               size_t   var_val_len,
code:               u_char   *statP,
code:               oid      *name,
code:               size_t    name_len)
code:   {
code:     struct ${vroutine}_data *StorageTmp = NULL;
code:     static struct ${vroutine}_data *StorageNew, *StorageDel;
code:     size_t newlen=name_len - (sizeof(${vroutine}_variables_oid)/sizeof(oid) + 3 - 1);
code:     static int old_value;
code:     int set_value;
code:     static struct variable_list *vars, *vp;
code:     struct header_complex_index *hciptr;
code:     char who[MAX_OID_LEN], flagName[MAX_OID_LEN];
code:   
code:     StorageTmp =
code:       header_complex(${vroutine}Storage, NULL,
code:                      &name[sizeof(${vroutine}_variables_oid)/sizeof(oid) + 3 - 1], 
code:                      &newlen, 1, NULL, NULL);
code:     
code:     
code:     if (var_val_type != ASN_INTEGER || var_val == NULL){
code:       fprintf(stderr, \"write to $name not ASN_INTEGER\\n\");
code:       return SNMP_ERR_WRONGTYPE;
code:     }
code:     set_value = *((long *) var_val);
code:   
code:     /* check legal range, and notReady is reserved for us, not a user */
code:     if (set_value < 1 || set_value > 6 || set_value == RS_NOTREADY)
code:       return SNMP_ERR_INCONSISTENTVALUE;
code:       
code:     switch ( action ) {
code:           case RESERVE1:
code:             /* stage one: test validity */
code:             if (StorageTmp == NULL) {
code:               /* create the row now? */
code:   
code:               /* ditch illegal values now */
code:               if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE)
code:                 return SNMP_ERR_INCONSISTENTVALUE;
code:       
code:               /* destroying a non-existent row is actually legal */
code:               if (set_value == RS_DESTROY) {
code:                 return SNMP_ERR_NOERROR;
code:               }
code:   
code:               /* illegal creation values */
code:               if (set_value == RS_ACTIVE || set_value == RS_NOTINSERVICE) {
code:                 return SNMP_ERR_INCONSISTENTVALUE;
code:               }
code:             } else {
code:               /* row exists.  Check for a valid state change */
code:               if (set_value == RS_CREATEANDGO || set_value == RS_CREATEANDWAIT) {
code:                 /* can't create a row that exists */
code:                 return SNMP_ERR_INCONSISTENTVALUE;
code:               }
code:               /* XXX: interaction with row storage type needed */
code:             }
code:             break;
code:   
code:   
code:           case RESERVE2:
code:             /* memory reseveration, final preparation... */
code:             if (StorageTmp == NULL) {
code:               /* creation */
code:               vars = NULL;
code:   
code:   $variables{'code-varlist-add-null'}{'processed'}
code:                       
code:               if (header_complex_parse_oid(&(name[sizeof(${vroutine}_variables_oid)/sizeof(oid)+2]), newlen,
code:                                            vars) != SNMPERR_SUCCESS) {
code:                 /* XXX: free, zero vars */
code:                 return SNMP_ERR_INCONSISTENTNAME;
code:               }
code:               vp = vars;
code:   
code:               StorageNew = SNMP_MALLOC_STRUCT(${vroutine}_data);
code:   $variables{'code-varlist-copy'}{'processed'}
code:   
code:               StorageNew->$name = set_value;
code:               /* XXX: free, zero vars, no longer needed? */
code:             }
code:             
code:             break;
code:   
code:   
code:           case FREE:
code:             /* XXX: free, zero vars */
code:             /* Release any resources that have been allocated */
code:             break;
code:   
code:   
code:           case ACTION:
code:                /* The variable has been stored in set_value for you to
code:                use, and you have just been asked to do something with
code:                it.  Note that anything done here must be reversable in
code:                the UNDO case */
code:                
code:                if (StorageTmp == NULL) {
code:                  /* row creation, so add it */
code:                  if (StorageNew != NULL)
code:                    ${vroutine}_add(StorageNew);
code:                  /* XXX: ack, and if it is NULL? */
code:                } else if (set_value != RS_DESTROY) {
code:                  /* set the flag? */
code:                  old_value = StorageTmp->$name;
code:                  StorageTmp->$name = *((long *) var_val);
code:                } else {
code:                  /* destroy...  extract it for now */
code:                  hciptr =
code:                    header_complex_find_entry(${vroutine}Storage,
code:                                              StorageTmp);
code:                  StorageDel =
code:                    header_complex_extract_entry(&${vroutine}Storage,
code:                                                 hciptr);
code:                }
code:             break;
code:   
code:   
code:           case UNDO:
code:                /* Back out any changes made in the ACTION case */
code:                if (StorageTmp == NULL) {
code:                  /* row creation, so remove it again */
code:                  hciptr =
code:                    header_complex_find_entry(${vroutine}Storage,
code:                                              StorageTmp);
code:                  StorageDel =
code:                    header_complex_extract_entry(&${vroutine}Storage,
code:                                                 hciptr);
code:                  /* XXX: free it */
code:                } else if (StorageDel != NULL) {
code:                  /* row deletion, so add it again */
code:                  ${vroutine}_add(StorageDel);
code:                } else {
code:                  StorageTmp->$name = old_value;
code:                }
code:             break;
code:   
code:   
code:           case COMMIT:
code:                /* Things are working well, so it's now safe to make the change
code:                permanently.  Make sure that anything done here can't fail! */
code:             if (StorageDel != NULL) {
code:               StorageDel == 0;
code:               /* XXX: free it, its dead */
code:             }
code:             break;
code:     }
code:     return SNMP_ERR_NOERROR;
code:   }
code:   

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.