1*9780544fSAndrew Rist#************************************************************** 2cdf0e10cSrcweir# 3*9780544fSAndrew Rist# Licensed to the Apache Software Foundation (ASF) under one 4*9780544fSAndrew Rist# or more contributor license agreements. See the NOTICE file 5*9780544fSAndrew Rist# distributed with this work for additional information 6*9780544fSAndrew Rist# regarding copyright ownership. The ASF licenses this file 7*9780544fSAndrew Rist# to you under the Apache License, Version 2.0 (the 8*9780544fSAndrew Rist# "License"); you may not use this file except in compliance 9*9780544fSAndrew Rist# with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir# 11*9780544fSAndrew Rist# http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir# 13*9780544fSAndrew Rist# Unless required by applicable law or agreed to in writing, 14*9780544fSAndrew Rist# software distributed under the License is distributed on an 15*9780544fSAndrew Rist# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*9780544fSAndrew Rist# KIND, either express or implied. See the License for the 17*9780544fSAndrew Rist# specific language governing permissions and limitations 18*9780544fSAndrew Rist# under the License. 19cdf0e10cSrcweir# 20*9780544fSAndrew Rist#************************************************************** 21*9780544fSAndrew Rist 22*9780544fSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir#************************************************************************* 25cdf0e10cSrcweir# 26cdf0e10cSrcweir# SourceConfigHelper - Perl extension for parsing general info databases 27cdf0e10cSrcweir# 28cdf0e10cSrcweir# usage: see below 29cdf0e10cSrcweir# 30cdf0e10cSrcweir#************************************************************************* 31cdf0e10cSrcweir 32cdf0e10cSrcweirpackage SourceConfigHelper; 33cdf0e10cSrcweir 34cdf0e10cSrcweiruse strict; 35cdf0e10cSrcweir 36cdf0e10cSrcweiruse RepositoryHelper; 37cdf0e10cSrcweiruse SourceConfig; 38cdf0e10cSrcweiruse Cwd qw (cwd); 39cdf0e10cSrcweiruse Carp; 40cdf0e10cSrcweir 41cdf0e10cSrcweirmy $debug = 0; 42cdf0e10cSrcweirmy @source_config_list; # array of sourceconfig objects 43cdf0e10cSrcweir 44cdf0e10cSrcweir#----------------------------------------------------------------------- 45cdf0e10cSrcweir# Constants 46cdf0e10cSrcweir#----------------------------------------------------------------------- 47cdf0e10cSrcweir 48cdf0e10cSrcweiruse constant SOURCE_CONFIG_NONE => 0; 49cdf0e10cSrcweiruse constant SOURCE_CONFIG_CURRENT_FIRST => 1; 50cdf0e10cSrcweiruse constant SOURCE_CONFIG_ENVIRONMENT_FIRST => 2; 51cdf0e10cSrcweiruse constant SOURCE_CONFIG_CURRENT_ONLY => 3; 52cdf0e10cSrcweiruse constant SOURCE_CONFIG_ENVIRONMENT_ONLY => 4; 53cdf0e10cSrcweir 54cdf0e10cSrcweiruse constant SOURCE_CONFIG_DEFAULT => SOURCE_CONFIG_CURRENT_FIRST; 55cdf0e10cSrcweir 56cdf0e10cSrcweir##### profiling ##### 57cdf0e10cSrcweir 58cdf0e10cSrcweir##### ctor ##### 59cdf0e10cSrcweir 60cdf0e10cSrcweirsub new { 61cdf0e10cSrcweir my $proto = shift; 62cdf0e10cSrcweir my $class = ref($proto) || $proto; 63cdf0e10cSrcweir my $init_action = shift; 64cdf0e10cSrcweir my $self = {}; 65cdf0e10cSrcweir my $SourceConfigCurrent; 66cdf0e10cSrcweir my $SourceConfigEnvironment; 67cdf0e10cSrcweir 68cdf0e10cSrcweir $init_action = SOURCE_CONFIG_DEFAULT if (!defined ($init_action)); 69cdf0e10cSrcweir if (!eval ($init_action) or ($init_action < SOURCE_CONFIG_NONE) or ($init_action > SOURCE_CONFIG_ENVIRONMENT_ONLY)) { 70cdf0e10cSrcweir croak("wrong initial parameter: $init_action\n"); 71cdf0e10cSrcweir } 72cdf0e10cSrcweir 73cdf0e10cSrcweir if ($init_action != SOURCE_CONFIG_NONE) { 74cdf0e10cSrcweir my $repositoryHash_ref = {}; 75cdf0e10cSrcweir if ($init_action != SOURCE_CONFIG_ENVIRONMENT_ONLY) { 76cdf0e10cSrcweir my $initial_directory = cwd(); 77cdf0e10cSrcweir my $result = is_repository($initial_directory, $repositoryHash_ref); 78cdf0e10cSrcweir if ($result) { 79cdf0e10cSrcweir $SourceConfigCurrent = SourceConfig->new($repositoryHash_ref->{REPOSITORY_ROOT}); 80cdf0e10cSrcweir } 81cdf0e10cSrcweir } 82cdf0e10cSrcweir if ($init_action != SOURCE_CONFIG_CURRENT_ONLY) { 83cdf0e10cSrcweir my $source_config = $ENV{SOURCE_ROOT_DIR} . '/' . SourceConfig::SOURCE_CONFIG_FILE_NAME; 84cdf0e10cSrcweir if (-f $source_config) { 85cdf0e10cSrcweir $SourceConfigEnvironment = SourceConfig->new($source_config); 86cdf0e10cSrcweir } 87cdf0e10cSrcweir } 88cdf0e10cSrcweir 89cdf0e10cSrcweir # fill array 90cdf0e10cSrcweir 91cdf0e10cSrcweir if (($init_action == SOURCE_CONFIG_CURRENT_FIRST) or ($init_action == SOURCE_CONFIG_CURRENT_ONLY)) { 92cdf0e10cSrcweir if (defined ($SourceConfigCurrent)) { 93cdf0e10cSrcweir push (@source_config_list, $SourceConfigCurrent); 94cdf0e10cSrcweir } 95cdf0e10cSrcweir if ($init_action == SOURCE_CONFIG_CURRENT_FIRST) { 96cdf0e10cSrcweir if (defined ($SourceConfigEnvironment)) { 97cdf0e10cSrcweir push (@source_config_list, $SourceConfigEnvironment); 98cdf0e10cSrcweir } 99cdf0e10cSrcweir } 100cdf0e10cSrcweir } 101cdf0e10cSrcweir elsif (($init_action == SOURCE_CONFIG_ENVIRONMENT_FIRST) or ($init_action == SOURCE_CONFIG_ENVIRONMENT_ONLY)) { 102cdf0e10cSrcweir if (defined ($SourceConfigEnvironment)) { 103cdf0e10cSrcweir push (@source_config_list, $SourceConfigEnvironment); 104cdf0e10cSrcweir } 105cdf0e10cSrcweir if ($init_action == SOURCE_CONFIG_ENVIRONMENT_FIRST) { 106cdf0e10cSrcweir if (defined ($SourceConfigCurrent)) { 107cdf0e10cSrcweir push (@source_config_list, $SourceConfigCurrent); 108cdf0e10cSrcweir } 109cdf0e10cSrcweir } 110cdf0e10cSrcweir } 111cdf0e10cSrcweir } 112cdf0e10cSrcweir 113cdf0e10cSrcweir $self->{SOURCE_CONFIG_LIST} = \@source_config_list; 114cdf0e10cSrcweir 115cdf0e10cSrcweir bless($self, $class); 116cdf0e10cSrcweir return $self; 117cdf0e10cSrcweir} 118cdf0e10cSrcweir 119cdf0e10cSrcweir##### methods ##### 120cdf0e10cSrcweir 121cdf0e10cSrcweir############################################################################################ 122cdf0e10cSrcweir 123cdf0e10cSrcweirsub add_SourceConfig { 124cdf0e10cSrcweir my $self = shift; 125cdf0e10cSrcweir my $source_config = shift; 126cdf0e10cSrcweir push (@{$self->{SOURCE_CONFIG_LIST}}, $source_config); 127cdf0e10cSrcweir} 128cdf0e10cSrcweir 129cdf0e10cSrcweir############################################################################################ 130cdf0e10cSrcweir 131cdf0e10cSrcweirsub get_SourceConfigList { 132cdf0e10cSrcweir my $self = shift; 133cdf0e10cSrcweir return @{$self->{SOURCE_CONFIG_LIST}}; 134cdf0e10cSrcweir} 135cdf0e10cSrcweir 136cdf0e10cSrcweir############################################################################################ 137cdf0e10cSrcweir 138cdf0e10cSrcweirsub has_SourceConfig { 139cdf0e10cSrcweir my $self = shift; 140cdf0e10cSrcweir my $result = 0; 141cdf0e10cSrcweir my $count = @{$self->{SOURCE_CONFIG_LIST}}; 142cdf0e10cSrcweir $result = 1 if ($count > 0); 143cdf0e10cSrcweir return $result; 144cdf0e10cSrcweir} 145cdf0e10cSrcweir 146cdf0e10cSrcweir############################################################################################ 147cdf0e10cSrcweir 148cdf0e10cSrcweirsub get_module_path { 149cdf0e10cSrcweir my $self = shift; 150cdf0e10cSrcweir my $module = shift; 151cdf0e10cSrcweir my $function = \&SourceConfig::get_module_path; 152cdf0e10cSrcweir my $result; 153cdf0e10cSrcweir $result = $self->get_StringResult ($function, $module); 154cdf0e10cSrcweir return $result; 155cdf0e10cSrcweir} 156cdf0e10cSrcweir 157cdf0e10cSrcweir############################################################################################ 158cdf0e10cSrcweir 159cdf0e10cSrcweirsub get_active_modules { 160cdf0e10cSrcweir my $self = shift; 161cdf0e10cSrcweir my $parameter; # empty 162cdf0e10cSrcweir my $function = \&SourceConfig::get_active_modules; 163cdf0e10cSrcweir my $array_ref; 164cdf0e10cSrcweir $array_ref = $self->get_ArrayResult ($function, $parameter); 165cdf0e10cSrcweir return @$array_ref; 166cdf0e10cSrcweir} 167cdf0e10cSrcweir 168cdf0e10cSrcweir############################################################################################ 169cdf0e10cSrcweir 170cdf0e10cSrcweirsub get_repositories { 171cdf0e10cSrcweir my $self = shift; 172cdf0e10cSrcweir my $parameter; # empty 173cdf0e10cSrcweir my $function = \&SourceConfig::get_repositories; 174cdf0e10cSrcweir my $array_ref; 175cdf0e10cSrcweir $array_ref = $self->get_ArrayResult ($function, $parameter); 176cdf0e10cSrcweir return @$array_ref; 177cdf0e10cSrcweir} 178cdf0e10cSrcweir 179cdf0e10cSrcweir############################################################################################ 180cdf0e10cSrcweir 181cdf0e10cSrcweirsub get_module_repository { 182cdf0e10cSrcweir my $self = shift; 183cdf0e10cSrcweir my $module = shift; 184cdf0e10cSrcweir my $function = \&SourceConfig::get_module_repository; 185cdf0e10cSrcweir my $result; 186cdf0e10cSrcweir $result = $self->get_StringResult ($function, $module); 187cdf0e10cSrcweir return $result; 188cdf0e10cSrcweir} 189cdf0e10cSrcweir 190cdf0e10cSrcweir############################################################################################ 191cdf0e10cSrcweir 192cdf0e10cSrcweirsub is_active { 193cdf0e10cSrcweir my $self = shift; 194cdf0e10cSrcweir my $module = shift; 195cdf0e10cSrcweir my $function = \&SourceConfig::is_active; 196cdf0e10cSrcweir my $result_ref; 197cdf0e10cSrcweir my $is_active = 0; 198cdf0e10cSrcweir $result_ref = $self->get_ResultOfList ($function, $module); 199cdf0e10cSrcweir my $count = @$result_ref; 200cdf0e10cSrcweir if ($count>0) { 201cdf0e10cSrcweir foreach my $active (@$result_ref) { 202cdf0e10cSrcweir if ($active) { 203cdf0e10cSrcweir $is_active = $active; 204cdf0e10cSrcweir } 205cdf0e10cSrcweir } 206cdf0e10cSrcweir } 207cdf0e10cSrcweir return $is_active; 208cdf0e10cSrcweir} 209cdf0e10cSrcweir 210cdf0e10cSrcweir##### private methods ##### 211cdf0e10cSrcweir 212cdf0e10cSrcweir############################################################################################ 213cdf0e10cSrcweir# 214cdf0e10cSrcweir# is_repository () : check if the directory is a valid repository 215cdf0e10cSrcweir# 216cdf0e10cSrcweir# input: - directory 217cdf0e10cSrcweir# - hash reference, where the output will be stored 218cdf0e10cSrcweir# 219cdf0e10cSrcweir# output: 0 = FALSE, the directory is no valid repository 220cdf0e10cSrcweir# 1 = TRUE, the repository root can be found in $repositoryHash_ref->{REPOSITORY_ROOT} 221cdf0e10cSrcweir# 222cdf0e10cSrcweir############################################################################################ 223cdf0e10cSrcweir 224cdf0e10cSrcweirsub is_repository { 225cdf0e10cSrcweir my $directory = shift; 226cdf0e10cSrcweir my $repositoryHash_ref = shift; 227cdf0e10cSrcweir $repositoryHash_ref->{INITIAL_DIRECTORY} = $directory; 228cdf0e10cSrcweir $repositoryHash_ref->{REPOSITORY_ROOT} = undef; 229cdf0e10cSrcweir $repositoryHash_ref->{REPOSITORY_NAME} = undef; 230cdf0e10cSrcweir my $result = RepositoryHelper::search_via_build_lst($repositoryHash_ref); 231cdf0e10cSrcweir chdir $repositoryHash_ref->{INITIAL_DIRECTORY}; 232cdf0e10cSrcweir if (!$result) { 233cdf0e10cSrcweir $result = RepositoryHelper::search_for_hg($repositoryHash_ref); 234cdf0e10cSrcweir } 235cdf0e10cSrcweir return $result; 236cdf0e10cSrcweir} 237cdf0e10cSrcweir 238cdf0e10cSrcweir############################################################################################ 239cdf0e10cSrcweir# 240cdf0e10cSrcweir# get_ResultOfList(): give back an array reference from all SourceConfig Objects results 241cdf0e10cSrcweir# 242cdf0e10cSrcweir# input: - function : reference to the called function of each SourceConfig Object 243cdf0e10cSrcweir# - parameter : parameter for the called function 244cdf0e10cSrcweir# 245cdf0e10cSrcweir# output: result : array of all results 246cdf0e10cSrcweir# 247cdf0e10cSrcweir############################################################################################ 248cdf0e10cSrcweir 249cdf0e10cSrcweirsub get_ResultOfList { 250cdf0e10cSrcweir my $self = shift; 251cdf0e10cSrcweir my $function = shift; 252cdf0e10cSrcweir my $parameter = shift; 253cdf0e10cSrcweir my @result; 254cdf0e10cSrcweir foreach my $source_config (@{$self->{SOURCE_CONFIG_LIST}}) { 255cdf0e10cSrcweir push (@result, &$function ($source_config, $parameter)); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir return \@result; 258cdf0e10cSrcweir} 259cdf0e10cSrcweir 260cdf0e10cSrcweir############################################################################################ 261cdf0e10cSrcweir# 262cdf0e10cSrcweir# get_StringResult(): give back the first defined result from all SourceConfig Objects 263cdf0e10cSrcweir# 264cdf0e10cSrcweir# input: - function : reference to the called function of each SourceConfig Object 265cdf0e10cSrcweir# - parameter : parameter for the called function 266cdf0e10cSrcweir# 267cdf0e10cSrcweir# output: result : scalar variable (string), undef if no result 268cdf0e10cSrcweir# 269cdf0e10cSrcweir############################################################################################ 270cdf0e10cSrcweir 271cdf0e10cSrcweirsub get_StringResult { 272cdf0e10cSrcweir my $self = shift; 273cdf0e10cSrcweir my $function = shift; 274cdf0e10cSrcweir my $parameter = shift; 275cdf0e10cSrcweir my $result_ref; 276cdf0e10cSrcweir $result_ref = $self->get_ResultOfList ($function, $parameter); 277cdf0e10cSrcweir my $count = @$result_ref; 278cdf0e10cSrcweir if ($count>0) { 279cdf0e10cSrcweir my $value; 280cdf0e10cSrcweir my $i = 0; 281cdf0e10cSrcweir while (($i < $count) and !defined ($value)) { # search the first defined result 282cdf0e10cSrcweir $value = $$result_ref[$i]; 283cdf0e10cSrcweir $i++; 284cdf0e10cSrcweir } 285cdf0e10cSrcweir return $value; 286cdf0e10cSrcweir } 287cdf0e10cSrcweir return undef; 288cdf0e10cSrcweir} 289cdf0e10cSrcweir 290cdf0e10cSrcweir############################################################################################ 291cdf0e10cSrcweir# 292cdf0e10cSrcweir# get_StringResult(): give back a sorted and uniqe array reference of the results 293cdf0e10cSrcweir# from all SourceConfig Objects 294cdf0e10cSrcweir# 295cdf0e10cSrcweir# input: - function : reference to the called function of each SourceConfig Object 296cdf0e10cSrcweir# - parameter : parameter for the called function 297cdf0e10cSrcweir# 298cdf0e10cSrcweir# output: result : sorted and uniqe array reference 299cdf0e10cSrcweir# 300cdf0e10cSrcweir############################################################################################ 301cdf0e10cSrcweir 302cdf0e10cSrcweirsub get_ArrayResult { 303cdf0e10cSrcweir my $self = shift; 304cdf0e10cSrcweir my $function = shift; 305cdf0e10cSrcweir my $parameter = shift; 306cdf0e10cSrcweir my $result_ref; 307cdf0e10cSrcweir my @modules; 308cdf0e10cSrcweir $result_ref = $self->get_ResultOfList ($function, $parameter); 309cdf0e10cSrcweir my $count = @$result_ref; 310cdf0e10cSrcweir if ($count>0) { 311cdf0e10cSrcweir my %moduleHash; 312cdf0e10cSrcweir foreach my $module (@$result_ref) { 313cdf0e10cSrcweir $moduleHash{$module}++; 314cdf0e10cSrcweir } 315cdf0e10cSrcweir @modules = sort keys %moduleHash; 316cdf0e10cSrcweir } 317cdf0e10cSrcweir return \@modules; 318cdf0e10cSrcweir} 319cdf0e10cSrcweir 320cdf0e10cSrcweir ##### finish ##### 321cdf0e10cSrcweir 322cdf0e10cSrcweir1; # needed by use or require 323cdf0e10cSrcweir 324cdf0e10cSrcweir__END__ 325cdf0e10cSrcweir 326cdf0e10cSrcweir=head1 NAME 327cdf0e10cSrcweir 328cdf0e10cSrcweirSourceConfigHelper - Perl extension for handling with SourceConfigObjetcs 329cdf0e10cSrcweir 330cdf0e10cSrcweir=head1 SYNOPSIS 331cdf0e10cSrcweir 332cdf0e10cSrcweir # example that will read source_config file and return the active repositories 333cdf0e10cSrcweir 334cdf0e10cSrcweir use SourceConfigHelper; 335cdf0e10cSrcweir 336cdf0e10cSrcweir # Create a new instance: 337cdf0e10cSrcweir $a = SourceConfigHelper->new(); 338cdf0e10cSrcweir 339cdf0e10cSrcweir # Get repositories for the actual workspace: 340cdf0e10cSrcweir $a->get_repositories(); 341cdf0e10cSrcweir 342cdf0e10cSrcweir=head1 DESCRIPTION 343cdf0e10cSrcweir 344cdf0e10cSrcweirSourceConfigHelper is a perl extension to handle more than one objects of SourceConfig 345cdf0e10cSrcweirto set up a search order for modules. 346cdf0e10cSrcweir 347cdf0e10cSrcweirMethods: 348cdf0e10cSrcweir 349cdf0e10cSrcweirSourceConfigHelper::new() 350cdf0e10cSrcweir 351cdf0e10cSrcweirCreates a new instance of SourceConfigHelper. Can be initialized by: default - empty or with a constant of search order. default: the source_config will be taken first from the current repository and second from the environment 352cdf0e10cSrcweirPossible parameters are: 353cdf0e10cSrcweirSourceConfigHelper::SOURCE_CONFIG_NONE - no SourceConfig Object will be created 354cdf0e10cSrcweirSourceConfigHelper::SOURCE_CONFIG_CURRENT_FIRST - use the current repository first 355cdf0e10cSrcweirSourceConfigHelper::SOURCE_CONFIG_ENVIRONMENT_FIRST - use the repository of the environment first 356cdf0e10cSrcweirSourceConfigHelper::SOURCE_CONFIG_CURRENT_ONLY - use only the current repository 357cdf0e10cSrcweirSourceConfigHelper::SOURCE_CONFIG_ENVIRONMENT_ONLY - use only the repository of the environment 358cdf0e10cSrcweir 359cdf0e10cSrcweirSourceConfigHelper::get_repositories() 360cdf0e10cSrcweir 361cdf0e10cSrcweirReturns sorted list of active repositories for the actual workspace 362cdf0e10cSrcweir 363cdf0e10cSrcweirSourceConfigHelper::get_active_modules() 364cdf0e10cSrcweir 365cdf0e10cSrcweirReturns a sorted list of active modules 366cdf0e10cSrcweir 367cdf0e10cSrcweirSourceConfigHelper::get_all_modules() 368cdf0e10cSrcweir 369cdf0e10cSrcweirReturns sorted list of all modules in active repositories. 370cdf0e10cSrcweir 371cdf0e10cSrcweirSourceConfigHelper::get_module_path($module) 372cdf0e10cSrcweir 373cdf0e10cSrcweirReturns absolute module path. If the module is not active or don't exists, "undef" will be returned. 374cdf0e10cSrcweir 375cdf0e10cSrcweirSourceConfigHelper::get_module_repository($module) 376cdf0e10cSrcweir 377cdf0e10cSrcweirReturns the module's repository. If the module is not active or don't exists, "undef" will be returned. 378cdf0e10cSrcweir 379cdf0e10cSrcweirSourceConfigHelper::is_active() 380cdf0e10cSrcweir 381cdf0e10cSrcweirReturns 1 (TRUE) if a module is active 382cdf0e10cSrcweirReturns 0 (FALSE) if a module is not active 383cdf0e10cSrcweir 384cdf0e10cSrcweirSourceConfigHelper::add_SourceConfig($SourceConfigObject) 385cdf0e10cSrcweir 386cdf0e10cSrcweirAdd the SourceConfigObject to the end of the list 387cdf0e10cSrcweir 388cdf0e10cSrcweirSourceConfigHelper::get_SourceConfigList() 389cdf0e10cSrcweir 390cdf0e10cSrcweirReturn an array of SourceConfigObjects 391cdf0e10cSrcweir 392cdf0e10cSrcweirSourceConfigHelper::has_SourceConfig() 393cdf0e10cSrcweir 394cdf0e10cSrcweirReturns 1 (TRUE) if one or more SourceConfig Objects is in the list 395cdf0e10cSrcweirReturns 0 (FALSE) if no SourceConfig Object is in the list (can happen if there is no valid repository) 396cdf0e10cSrcweir 397cdf0e10cSrcweir=head2 EXPORT 398cdf0e10cSrcweir 399cdf0e10cSrcweirSourceConfigHelper::new() 400cdf0e10cSrcweirSourceConfigHelper::get_repositories() 401cdf0e10cSrcweirSourceConfigHelper::get_active_modules() 402cdf0e10cSrcweirSourceConfigHelper::get_all_modules() 403cdf0e10cSrcweirSourceConfigHelper::get_module_path($module) 404cdf0e10cSrcweirSourceConfigHelper::get_module_repository($module) 405cdf0e10cSrcweirSourceConfigHelper::is_active($module) 406cdf0e10cSrcweirSourceConfigHelper::add_SourceConfig($SourceConfigObject) 407cdf0e10cSrcweirSourceConfigHelper::get_SourceConfigList() 408cdf0e10cSrcweirSourceConfigHelper::has_SourceConfig() 409cdf0e10cSrcweir 410cdf0e10cSrcweir=head1 AUTHOR 411cdf0e10cSrcweir 412cdf0e10cSrcweirKurt Zenker, kz@openoffice.org 413cdf0e10cSrcweir 414cdf0e10cSrcweir=head1 SEE ALSO 415cdf0e10cSrcweir 416cdf0e10cSrcweirperl(1). 417cdf0e10cSrcweir 418cdf0e10cSrcweir=cut 419