home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 March B / SCO_CASTOR4RRT.iso / nsfast / root.9 / usr / ns-home / install / ObjConf.pm / ObjConf
Text File  |  1998-08-19  |  5KB  |  206 lines

  1. package ObjConf;
  2.  
  3. # An ObjConf object represents the data in the file passed in
  4. # objects is an array of objects in the order they were in the file
  5. # names is a hash indexed by object name
  6. # ppaths is a hash indexed by the ppaths
  7. # directives is an array of extra-object information
  8. sub new {
  9.     my    $header = shift;
  10.     my    $self = {};
  11.     my    $curObj = undef;
  12.     my    $nextLine;
  13.  
  14.     $self->{'file'} = shift;
  15.  
  16.     open( FILE, $self->{'file'} ) || ( $@ = $!, return undef );
  17.     $nextLine = <FILE>;
  18.     while ( $nextLine ) {
  19.     $_ = $nextLine;
  20.     $nextLine = <FILE>;
  21.     while ( $nextLine && $nextLine =~ /^\s/ ) {
  22.             $_ .= $nextLine;
  23.             $nextLine = <FILE>;
  24.         }
  25.     push( @{$self->{'source'}}, $_ );
  26.     next if ( m'^(#|$)' );    # skip comments and blank lines
  27.     if ( /^<Object\s+/i ) {
  28.         if ( defined( $curObj ) ) {
  29.         $@ = "recursive Object definition in $self->{'file'}, line $.";
  30.         return undef;
  31.         } else {
  32.         $curObj = new ConfObject( $', $#{$self->{'source'}} );
  33.         return undef unless $curObj;
  34.         }
  35.     } elsif ( defined( $curObj ) ) {
  36.         if ( m'^</Object>'i ) {
  37.         push( @{$self->{'objects'}}, $curObj );
  38.         if ( $curObj->{'type'} eq 'name' ) {
  39.             $self->{'names'}->{$curObj->{'name'}} = $curObj;
  40.         } elsif ( $curObj->{'type'} eq 'ppath' ) {
  41.             $self->{'ppaths'}->{$curObj->{'ppath'}} = $curObj;
  42.         } else {
  43.             $@ = "Unknown object type: $curObj->{'type'}";
  44.             return undef;
  45.         }
  46.         undef( $curObj );
  47.         } else {
  48.         $curObj->sourceLine( $_, $#{$self->{'source'}} )
  49.             || return undef;
  50.         }
  51.     } else {
  52.         chomp( $_ );
  53.         push( @{$self->{'directives'}},
  54.           new ConfDirective( $_, $#{$self->{'source'}} ) );
  55.     }
  56.     }
  57.     close( FILE );
  58.     bless $self;
  59. }
  60.  
  61. sub write {
  62.     my    $self = shift;
  63.     my    $backupPolicy = shift;
  64.     my    $i;
  65.  
  66.     &main::makeBackup( $self->{'file'}, $backupPolicy ) if $backupPolicy;
  67.     open( FILE, ">$self->{'file'}" ) || ( $@ = $!, return undef );
  68.     for ( $i = 0 ; $i < scalar( @{$self->{'source'}} ) ; ++$i ) {
  69.     print FILE $self->{'source'}[$i] unless $self->{'deletedSource'}->{$i};
  70.     }
  71.     close( FILE ) || ( $@ = $! );
  72. }
  73.  
  74. sub removeDirective {
  75.     my    $self = shift;
  76.     my    $object = shift;
  77.     my    $directive = shift;
  78.  
  79.     $self->{'deletedSource'}->{$directive->{'sourceIndex'}} = 1;
  80.     $object->remove( $directive );
  81. }
  82.  
  83. package ConfDirective;
  84.  
  85. # conf directive has a type, name, and params
  86. sub new {
  87.     my    $header = shift;
  88.     my    $line = shift;
  89.     my    $self = {};
  90.     my    @params;
  91.     my    $param;
  92.     my    $name;
  93.     my    $value;
  94.  
  95.     $self->{'sourceIndex'} = shift;
  96.     $self->{'client'} = shift;
  97.     $line =~ /\s+/;
  98.     $self->{'type'} = $`;
  99.     $line = $';
  100.     $self->{'params'} = {};
  101.     while ( $param = &nextExp( \$line ) ) {
  102.     ( $name, $value ) = split( /\s*=\s*/, $param );
  103.     $value =~ s/^"//;    # Trim "s;
  104.     $value =~ s/"$//;    # Trim "s;
  105.     $name = "\L$name";
  106.     if ( $name =~ /^fn$/i ) {
  107.         $self->{'name'} = $value;
  108.     } else {
  109.         $self->{'params'}->{$name} = $value;
  110.     }
  111.     }
  112.     bless $self;
  113. }
  114.  
  115. sub nextExp {
  116.     my    $string = shift;    # reference, so we can hack it
  117.     my    $result;
  118.  
  119.     return undef if $$string =~ /^$/;
  120.     if ( $$string =~ /\s+/ ) {
  121.     my    $space = $&;
  122.  
  123.     $result = $`;
  124.     $$string = $';
  125.     while ( $result =~ m'^\w+\s*=\s*"' &&
  126.             substr( $result, length( $result ) - 1, 1 ) ne '"' ) {
  127.         $result .= $space;
  128.         if ( $$string =~ /\s+/ ) {
  129.         $result .= $`;
  130.         $space = $&;
  131.         $$string = $';
  132.         } else {
  133.         $result .= $$string;
  134.         $$string = '';
  135.         }
  136.     }
  137.     } else {    # last token
  138.     $result = $$string;
  139.     $$string = '';
  140.     }
  141.     return $result;
  142. }
  143.  
  144. package ConfObject;
  145.  
  146. sub new {
  147.     my    $header = shift;
  148.     my    $id = shift;
  149.     my    $self = {};
  150.  
  151.     $self->{'sourceIndex'} = shift;
  152.     chomp( $id );
  153.     if ( $id =~ /^name\s*=\s*/i ) {    # named object
  154.     $self->{'type'} = 'name';
  155.     ( $id = $' ) =~ s/^"//;    # "; Clean off quotes
  156.     $id =~ s/"?\s*>\s*$//;    # "; Clean off quotes and >
  157.     $self->{'name'} = $id;
  158.     } elsif ( $id =~ /^ppath\s*=\s*/i ) {
  159.     $self->{'type'} = 'ppath';
  160.     ( $id = $' ) =~ s/^"//;    # "; Clean off quotes
  161.     $id =~ s/"?\s*>\s*$//;    # "; Clean off quotes and >
  162.     $self->{'ppath'} = $id;
  163.     } else {
  164.     $@ = "Syntax error in Object definition: $id";
  165.     return undef;
  166.     }
  167.     bless $self;
  168. }
  169.  
  170. sub sourceLine {
  171.     my    $self = shift;
  172.     my    $line = shift;
  173.     my    $sourceIndex = shift;
  174.  
  175.     chomp( $line );
  176.     if ( $line =~ /<client\s*/i ) {    # new Client
  177.     if ( $self->{'curClient'} ) {
  178.         $@ = "Recursive Client: $.";
  179.         return undef;
  180.     } else {
  181.         ( $self->{'curClient'} = $' ) =~ s/\s*>\s*$//;
  182.     }
  183.     } elsif ( $line =~ m'</client>'i ) {
  184.     delete $self->{'curClient'};
  185.     } else {
  186.     push( @{$self->{'directives'}},
  187.           new ConfDirective( $line, $sourceIndex, $self->{'curClient'} ) );
  188.     }
  189.     1;
  190. }
  191.  
  192. sub remove {
  193.     my    $self = shift;
  194.     my    $directive = shift;
  195.     my    $i;
  196.  
  197.     for ( $i = 0 ; $i < scalar( @{$self->{'directives'}} ) ; ++$i ) {
  198.     if ( $self->{'directives'}->[$i] == $directive ) {
  199.         splice( @{$self->{'directives'}}, $i, 1 );
  200.         last;
  201.     }
  202.     }
  203. }
  204.  
  205. 1;
  206.