1 #*************************************************************************
3 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 # Copyright 2008 by Sun Microsystems, Inc.
7 # OpenOffice.org - a multi-platform office productivity suite
9 # $RCSfile: GenInfoParser.pm,v $
13 # This file is part of OpenOffice.org.
15 # OpenOffice.org is free software: you can redistribute it and/or modify
16 # it under the terms of the GNU Lesser General Public License version 3
17 # only, as published by the Free Software Foundation.
19 # OpenOffice.org is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU Lesser General Public License version 3 for more details
23 # (a copy is included in the LICENSE file that accompanied this code).
25 # You should have received a copy of the GNU Lesser General Public License
26 # version 3 along with OpenOffice.org. If not, see
27 # <http://www.openoffice.org/license.html>
28 # for a copy of the LGPLv3 License.
30 #*************************************************************************
32 #*************************************************************************
34 # GenInfoParser - Perl extension for parsing general info databases
38 #*************************************************************************
40 package GenInfoParser
;
53 my $class = ref($proto) || $proto;
55 $self->{'LIST'} = undef;
57 bless ($self, $class);
65 # load list into memory
67 my $list_file = shift;
69 if ( $self->parse_list($list_file) ) {
77 # return a sorted list of keys, the sorting is case insensitive
79 my $access_path = shift;
81 my ($key, $value, $sub_data_ref) = $self->walk_accesspath($access_path);
84 if ( $sub_data_ref ) {
85 my @normalized_keys = keys %$sub_data_ref;
86 foreach my $normalized_key (sort keys %$sub_data_ref) {
87 push(@keys, $$sub_data_ref{$normalized_key}[0]);
98 # returns the key corresponding to the access_path
100 my $access_path = shift;
102 my ($key, $value, $sub_data_ref) = $self->walk_accesspath($access_path);
103 return undef if !$key;
109 # returns the value corresponding to the access_path
111 my $access_path = shift;
113 my ($key, $value, $sub_data_ref) = $self->walk_accesspath($access_path);
114 return undef if !$key;
115 $value = "" if !defined($value);
117 $value =~ tr/\r\n//d;
118 # trim trailing whitespace
123 ##### private methods #####
127 # parse complete list
129 my $list_file = shift;
132 return 0 if ! -r
$list_file;
134 open(FILE
, "<$list_file") or croak
("can't open $list_file: $!");
135 # my $t0 = new Benchmark;
136 $self->parse_block(\
*FILE
, $self->{'DATA'});
137 # my $t1 = new Benchmark;
138 # print STDERR "parsing $list_file took: ", timestr(timediff($t1, $t0)), "\n";
144 # parse each sub block and place it in a hash
145 # used data structure:
146 # $hash{$normalized_key} = [ $key, $value, 0 | $sub_hash_ref ]
148 my $glob_ref = shift;
149 my $data_ref = shift;
153 while( $line = <$glob_ref> ) {
154 # this is the inner loop, any additional pattern matching will
155 # have a notable affect on runtime behavior
156 # clean up of $value is done in get_value()
157 my ($key, $value) = split(' ', $line, 2);
158 next if !$key; # skip empty lines
159 my $chr = substr($key, 0, 1);
160 next if $chr eq '#'; # skip comment lines
161 last if $chr eq '}'; # return from block;
163 if ( !$current_key ) {
164 croak
("unexpected block start");
167 # create empty hash and start sub block parse
168 $$data_ref{$current_key}[2] = {};
169 $self->parse_block($glob_ref, $$data_ref{$current_key}[2]);
174 croak
("key $key is not well formed") if $key =~ /\//;
175 # normalize key for hash lookup
176 $current_key = lc($key);
177 # but we have to keep the original - not normalized - key, too
178 $$data_ref{($current_key)} = [$key, $value, 0];
184 # returns the key, value and sub_data_ref which
185 # corresponds to the access_path
188 my $access_path = shift;
190 my $sub_data_ref = $self->{'DATA'};
192 if ( $access_path ) {
195 $access_path = lc($access_path);
196 my @key_sequence = split(/\//, $access_path);
197 foreach my $key_element (@key_sequence) {
198 # at least one more key element, but no sub_hash, accesspath invalid
199 return () if !$sub_data_ref;
200 $lookup_ref = $$sub_data_ref{$key_element};
201 # lookup failed, accesspath invalid
202 return () if !defined($lookup_ref);
203 # we've got a valid key
204 $sub_data_ref = $$lookup_ref[2];
206 return ($$lookup_ref[0], $$lookup_ref[1], $sub_data_ref);
209 # empty access path is only vlaid for getting top level key list
210 return ( undef, undef, $sub_data_ref );
216 1; # needed by use or require
222 GenInfoParser - Perl extension for parsing general info databases
226 # example that will load a general info database called 'stand.lst'
230 # Create a new instance of the parser:
231 $a = GenInfoParser->new();
233 # Load the database into the parser:
234 $a->load_list('ssrc633.ini');
236 # get top level keys from database
237 @top_level_keys = $a->get_keys();
240 @sub_list_keys = $a->get_keys('src633/Drives/o:/Projects');
243 $key = $a->get_key('src633/Comment/build');
244 $value = $a->get_value('src633/Comment/build');
248 GenInfoParser is a perl extension to load and parse General Info Databses.
249 It uses a simple object oriented interface to retrieve the information stored
256 Creates a new instance of the parser. Can't fail.
259 GenInfoParser::load_list($database)
261 Loads and parses $database. Returns 1 on success and 0 on failure
264 GenInfoParser::get_keys($path)
266 Returns a sorted list of keys from the path $path. Returns an emtpy list if $path
267 has no sublist. If there is no $path spcified, the method will return the
268 primary key list. $path can be specified case insensitive. Sorting is done case
271 GenInfoParser::get_key($path)
273 Returns the key to $path or 'undef' if an invalid path is given.
274 Example: $path = 'src633/comment/build' will return 'Build' as key.
275 Note: $path can be specified case insensitive, but the returned key will
276 have the exact case as in the database.
278 GenInfoParser::get_value($path)
280 Returns the value to $path or 'undef' is invalid path is given.
286 GenInfoParser::load_list($database)
287 GenInfoParser::get_keys($path)
288 GenInfoParser::get_key($path)
289 GenInfoParser::get_value($path)
294 Jens-Heiner Rechtien, rechtien@sun.com