source: OFFICIAL/FCM_V1.3/lib/Fcm/CfgLine.pm

Last change on this file was 1, checked in by fcm, 15 years ago

creation de larborescence

File size: 8.9 KB
Line 
1#!/usr/bin/perl
2# ------------------------------------------------------------------------------
3# NAME
4#   Fcm::CfgLine
5#
6# DESCRIPTION
7#   This class is used for grouping the settings in each line of a FCM
8#   configuration file.
9#
10# COPYRIGHT
11#   (C) Crown copyright Met Office. All rights reserved.
12#   For further details please refer to the file COPYRIGHT.txt
13#   which you should have received as part of this distribution.
14# ------------------------------------------------------------------------------
15
16package Fcm::CfgLine;
17@ISA = qw(Fcm::Base);
18
19# Standard pragma
20use warnings;
21use strict;
22
23# Standard modules
24use File::Basename;
25
26# In-house modules
27use Fcm::Base;
28use Fcm::Config;
29use Fcm::Util;
30
31# List of property methods for this class
32my @scalar_properties = (
33  'bvalue',  # line value, in boolean
34  'comment', # (in)line comment
35  'error',   # error message for incorrect usage while parsing the line
36  'label',   # line label
37  'line',    # content of the line
38  'number',  # line number in source file
39  'parsed',  # has this line been parsed (by the extract/build system)?
40  'prefix',  # optional prefix for line label
41  'slabel',  # label without the optional prefix
42  'src',     # name of source file
43  'value',   # line value
44  'warning', # warning message for deprecated usage
45);
46
47# Useful variables
48our $COMMENT_RULER = '-' x 78;
49
50# ------------------------------------------------------------------------------
51# SYNOPSIS
52#   @cfglines = Fcm::CfgLine->comment_block (@comment);
53#
54# DESCRIPTION
55#   This method returns a list of Fcm::CfgLine objects representing a comment
56#   block with the comment string @comment.
57# ------------------------------------------------------------------------------
58
59sub comment_block {
60  my @return = (
61    Fcm::CfgLine->new (comment => $COMMENT_RULER),
62    (map {Fcm::CfgLine->new (comment => $_)} @_),
63    Fcm::CfgLine->new (comment => $COMMENT_RULER),
64    Fcm::CfgLine->new (),
65  );
66
67  return @return;
68}
69
70# ------------------------------------------------------------------------------
71# SYNOPSIS
72#   $obj = Fcm::CfgLine->new (%args);
73#
74# DESCRIPTION
75#   This method constructs a new instance of the Fcm::CfgLine class. See above
76#   for allowed list of properties. (KEYS should be in uppercase.)
77# ------------------------------------------------------------------------------
78
79sub new {
80  my $this  = shift;
81  my %args  = @_;
82  my $class = ref $this || $this;
83
84  my $self = Fcm::Base->new (%args);
85
86  for (@scalar_properties) {
87    $self->{$_} = exists $args{uc ($_)} ? $args{uc ($_)} : undef;
88    $self->{$_} = $args{$_} if exists $args{$_};
89  }
90
91  bless $self, $class;
92  return $self;
93}
94
95# ------------------------------------------------------------------------------
96# SYNOPSIS
97#   $value = $obj->X;
98#   $obj->X ($value);
99#
100# DESCRIPTION
101#   Details of these properties are explained in @scalar_properties.
102# ------------------------------------------------------------------------------
103
104for my $name (@scalar_properties) {
105  no strict 'refs';
106
107  *$name = sub {
108    my $self = shift;
109
110    if (@_) {
111      $self->{$name} = $_[0];
112
113      if ($name eq 'line' or $name eq 'label') {
114        $self->{slabel} = undef;
115
116      } elsif ($name eq 'line' or $name eq 'value') {
117        $self->{bvalue} = undef;
118      }
119    }
120
121    # Default value for property
122    if (not defined $self->{$name}) {
123      if ($name =~ /^(?:comment|error|label|line|prefix|src|value)$/) {
124        # Blank
125        $self->{$name} = '';
126
127      } elsif ($name eq 'slabel') {
128        if ($self->prefix and $self->label_starts_with ($self->prefix)) {
129          $self->{$name} = $self->label_from_field (1);
130
131        } else {
132          $self->{$name} = $self->label;
133        }
134
135      } elsif ($name eq 'bvalue') {
136        if (defined ($self->value)) {
137          $self->{$name} = ($self->value =~ /^(\s*|false|no|off|0*)$/i)
138                           ? 0 : $self->value;
139        }
140      }
141    }
142
143    return $self->{$name};
144  }
145}
146
147# ------------------------------------------------------------------------------
148# SYNOPSIS
149#   @fields = $obj->label_fields ();
150#   @fields = $obj->slabel_fields ();
151#
152# DESCRIPTION
153#   These method returns a list of fields in the (s)label.
154# ------------------------------------------------------------------------------
155
156for my $name (qw/label slabel/) {
157  no strict 'refs';
158
159  my $sub_name = $name . '_fields';
160  *$sub_name = sub  {
161    return (split (/$Fcm::Config::DELIMITER_PATTERN/, $_[0]->$name));
162  }
163}
164
165# ------------------------------------------------------------------------------
166# SYNOPSIS
167#   $string = $obj->label_from_field ($index);
168#   $string = $obj->slabel_from_field ($index);
169#
170# DESCRIPTION
171#   These method returns the (s)label from field $index onwards.
172# ------------------------------------------------------------------------------
173
174for my $name (qw/label slabel/) {
175  no strict 'refs';
176
177  my $sub_name = $name . '_from_field';
178  *$sub_name = sub  {
179    my ($self, $index) = @_;
180    my $method = $name . '_fields';
181    my @fields = $self->$method;
182    return join ($Fcm::Config::DELIMITER, @fields[$index .. $#fields]);
183  }
184}
185
186# ------------------------------------------------------------------------------
187# SYNOPSIS
188#   $flag = $obj->label_starts_with (@fields);
189#   $flag = $obj->slabel_starts_with (@fields);
190#
191# DESCRIPTION
192#   These method returns a true if (s)label starts with the labels in @fields
193#   (ignore case).
194# ------------------------------------------------------------------------------
195
196for my $name (qw/label slabel/) {
197  no strict 'refs';
198
199  my $sub_name = $name . '_starts_with';
200  *$sub_name = sub  {
201    my ($self, @fields) = @_;
202    my $return = 1;
203
204    my $method = $name . '_fields';
205    my @all_fields = $self->$method;
206
207    for my $i (0 .. $#fields) {
208      next if lc ($fields[$i]) eq lc ($all_fields[$i]);
209      $return = 0;
210      last;
211    }
212
213    return $return;
214  }
215}
216
217# ------------------------------------------------------------------------------
218# SYNOPSIS
219#   $flag = $obj->label_starts_with_cfg (@fields);
220#   $flag = $obj->slabel_starts_with_cfg (@fields);
221#
222# DESCRIPTION
223#   These method returns a true if (s)label starts with the configuration file
224#   labels in @fields (ignore case).
225# ------------------------------------------------------------------------------
226
227for my $name (qw/label slabel/) {
228  no strict 'refs';
229
230  my $sub_name = $name . '_starts_with_cfg';
231  *$sub_name = sub  {
232    my ($self, @fields) = @_;
233
234    for my $field (@fields) {
235      $field = $self->cfglabel ($field);
236    }
237
238    my $method = $name . '_starts_with';
239    return $self->$method (@fields);
240  }
241}
242
243# ------------------------------------------------------------------------------
244# SYNOPSIS
245#   $mesg = $obj->format_error ();
246#
247# DESCRIPTION
248#   This method returns a string containing a formatted error message for
249#   anything reported to the current line.
250# ------------------------------------------------------------------------------
251
252sub format_error {
253  my ($self) = @_;
254  my $mesg = '';
255
256  $mesg .= $self->format_warning;
257
258  if ($self->error or not $self->parsed) {
259    $mesg = 'ERROR: ' . $self->src . ': LINE ' . $self->number . ':' . "\n";
260    if ($self->error) {
261      $mesg .= '       ' . $self->error;
262
263    } else {
264      $mesg .= '       ' . $self->label . ': label not recognised.';
265    }
266  }
267
268  return $mesg;
269}
270
271# ------------------------------------------------------------------------------
272# SYNOPSIS
273#   $mesg = $obj->format_warning ();
274#
275# DESCRIPTION
276#   This method returns a string containing a formatted warning message for
277#   any warning reported to the current line.
278# ------------------------------------------------------------------------------
279
280sub format_warning {
281  my ($self) = @_;
282  my $mesg = '';
283
284  if ($self->warning) {
285    $mesg = 'WARNING: ' . $self->src . ': LINE ' . $self->number . ':' . "\n";
286    $mesg .= '         ' . $self->warning;
287  }
288
289  return $mesg;
290}
291
292# ------------------------------------------------------------------------------
293# SYNOPSIS
294#   $line = $obj->print_line ([$space]);
295#
296# DESCRIPTION
297#   This method returns a configuration line using $self->label, $self->value
298#   and $self->comment. The value in $self->line is re-set. If $space is set
299#   and is a positive integer, it sets the spacing between the label and the
300#   value in the line. The default is 1.
301# ------------------------------------------------------------------------------
302
303sub print_line {
304  my ($self, $space) = @_;
305
306  # Set space between label and value, default to 1 character
307  $space = 1 unless $space and $space =~ /^[1-9]\d*$/;
308
309  my $line = '';
310
311  # Add label and value, if label is set
312  if ($self->label) {
313    $line .= $self->label . ' ' x $space;
314    $line .= $self->value if defined $self->value;
315  }
316
317  # Add comment if necessary
318  my $comment = $self->comment;
319  $comment =~ s/^\s*//;
320
321  if ($comment) {
322    $comment = '# ' . $comment if $comment !~ /^#/;
323    $line .= ' ' if $line;
324    $line .= $comment;
325  }
326
327  return $self->line ($line);
328}
329
330# ------------------------------------------------------------------------------
331
3321;
333
334__END__
Note: See TracBrowser for help on using the repository browser.