Subversion Repositories DevTools

Rev

Rev 255 | Rev 267 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
#! perl
2
########################################################################
3
# Copyright ( C ) 2004 ERG Limited, All rights reserved
4
#
5
# Module name   : jats.sh
6
# Module type   : Makefile system
7
# Compiler(s)   : n/a
8
# Environment(s): jats
9
#
10
# Description   : Provide varions functions used by the BuildVersion
11
#                 directive.
12
#
13
#                 Use only within buildlib.pl as this package assumes
14
#                 a great deal about its environment.
15
#
16
# Usage:
17
#
18
# Version   Who      Date        Description
19
#
20
#......................................................................#
21
 
255 dpurdie 22
require 5.006_001;
227 dpurdie 23
use strict;
24
use warnings;
25
 
26
our $Clobber;
27
our $CurrentYear;
28
our $CurrentTime;
29
our $Srcdir;
30
our $BuildVersion;
31
our $BUILDNAME;
32
our $BUILDNAME_PACKAGE;
33
our $BUILDNAME_VERSION;
34
our $BUILDNAME_PROJECT;
35
 
36
package BuildVersion;
37
use JatsError;
38
use JatsSystem;
39
use JatsVersionUtils;
40
 
41
our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
42
use Exporter;
43
 
44
$VERSION = 1.00;
45
@ISA = qw(Exporter);
46
 
47
# Symbols to autoexport (:DEFAULT tag)
48
@EXPORT = qw( BuildVersionC
49
              BuildVersionCdefs
50
              BuildVersionCSharp
51
              BuildVersionWinRC
229 dpurdie 52
              BuildVersionProperties
227 dpurdie 53
            );
54
 
55
#-------------------------------------------------------------------------------
56
# Function        : BuildVersionCSharp
57
#
58
# Description     : Generate a C# versionn information file to allow
59
#                   insertion of data into an assembly
60
#
61
# Inputs          : $FileName           - Output filename (Optional)
62
#
63
# Returns         :
64
#
65
sub BuildVersionCSharp
66
{
67
    my ( $fname ) = @_;
68
    $fname = 'AssemblyVersionInfo.cs' unless $fname;
69
 
247 dpurdie 70
    #
71
    #   Store the files location for use at runtime
72
    #   It will be a file that is 'known' to JATS
73
    #
74
    $fname = ::BuildAddKnownFile ( $Srcdir, $fname );
75
    return if ( $Clobber );      # clobber mode ?
227 dpurdie 76
 
77
    #
78
    #   Determine the build version
79
    #
80
    my ($major, $minor, $patch, $build, $raw_patch) = SplitVersion($BUILDNAME_VERSION);
81
    my $vstring = "$major.$minor.$patch.$build";
82
 
83
 
247 dpurdie 84
    my $fh = ConfigurationFile::New( $fname, '--Type=CSharp' );
227 dpurdie 85
    $fh->HeaderSimple( "buildlib (Version $BuildVersion)",
86
                       "CSharp Assembly Version Definition" );
87
 
88
    $fh->Write( "\n" );
89
    $fh->Write( "using System.Reflection;\n" );
90
    $fh->Write( "using System.Runtime.CompilerServices;\n" );
91
    $fh->Write( "\n" );
92
    $fh->Write( "[assembly: AssemblyCompany(\"ERG Group\")]\n" );
93
    $fh->Write( "[assembly: AssemblyProduct(\"$BUILDNAME_PACKAGE\")]\n" );
94
    $fh->Write( "[assembly: AssemblyCopyright(\"ERG Group $CurrentYear\")]\n" );
95
    $fh->Write( "[assembly: AssemblyTrademark(\"\")]\n" );
96
    $fh->Write( "\n");
97
    $fh->Comment( "\n");
98
    $fh->Comment( "Version information for an assembly consists of the following four values:\n");
99
    $fh->Comment( "\n");
100
    $fh->Comment( "     Major Version   -ERG:Major\n");
101
    $fh->Comment( "     Minor Version  - ERG:Minor\n");
102
    $fh->Comment( "     Build Number   - ERG:Patch\n");
103
    $fh->Comment( "     Revision       - ERG:Build Number\n");
104
    $fh->Comment( "\n");
105
    $fh->Write( "\n");
106
    $fh->Write( "[assembly: AssemblyVersion(\"$vstring\")]\n" );
107
    $fh->Write( "\n");
108
 
109
    $fh->Close();
110
}
111
 
112
#-------------------------------------------------------------------------------
113
# Function        : BuildVersionWinRC
114
#
115
# Description     : Create a Windows RC file to describe the build version
116
#                   This file may be used directly
117
#
118
# Inputs          : $FileName           - Output filename (Optional)
235 dpurdie 119
#                   $icon               - Name of icon (optional )
263 dpurdie 120
#                   $defs               - Definitions Only (optional)
227 dpurdie 121
#
122
# Returns         :
123
#
124
sub BuildVersionWinRC
125
{
263 dpurdie 126
    my ( $fname, $icon, $defs ) = @_;
227 dpurdie 127
    $fname = 'version.rc' unless $fname;
128
 
129
    #
247 dpurdie 130
    #   Store the files location for use at runtime
131
    #   It will be a file that is 'known' to JATS
132
    #
133
    $fname = ::BuildAddKnownFile ( $Srcdir, $fname );
134
    return if ( $Clobber );      # clobber mode ?
135
 
136
    Message ("Creating Windows Resource File: $fname" );
137
    #
227 dpurdie 138
    #   Determine the build version
139
    #
140
    my ($major, $minor, $patch, $build, $raw_patch) = SplitVersion($BUILDNAME_VERSION);
141
    my $product_version = "$major, $minor, $patch, $build";
142
 
143
 
144
    #
145
    #   Create the file
146
    #
247 dpurdie 147
    my $fh = ConfigurationFile::New( $fname, '--Type=C++' );
227 dpurdie 148
    $fh->HeaderSimple( "buildlib (Version $BuildVersion)",
149
                       "Windows Resource Version Definition" );
150
 
151
    sub prc
152
    {
153
        return "@_\n";
154
    }
155
 
156
    sub pdefs
157
    {
158
        my ($arg, $val) = @_;
159
        return "#define $arg \"$val\\0\"\n";
160
    }
161
 
162
    sub pdef
163
    {
164
        my ($arg, $val) = @_;
165
        return "#define $arg $val\n";
166
    }
167
 
168
    $fh->Write(prc     (""));
169
#    $fh->Write(prc     ("#include \"afxres.h\""));
170
#    $fh->Write(prc     (""));
171
    $fh->Write(prc     (""));
172
    $fh->Write(pdefs   ("RC_STR_EMPTY"         , "" ));
173
    $fh->Write(pdefs   ("RC_STR_COMPANY"       , "ERG Group" ));
174
    $fh->Write(pdefs   ("RC_STR_PRODUCTNAME"   , "ERG Group test" ));
175
    $fh->Write(pdefs   ("RC_STR_COMMENT"       , "Build Date: $CurrentTime" ));
176
    $fh->Write(pdefs   ("RC_STR_DESCRIPTION"   , "From: $BUILDNAME_PACKAGE" ));
177
    $fh->Write(pdefs   ("RC_STR_NAME"          , $BUILDNAME_PACKAGE ));
178
    $fh->Write(pdefs   ("RC_STR_VERSION"       , $product_version ));
179
    $fh->Write(pdef    ("RC_NUM_VERSION"       , $product_version ));
180
    $fh->Write(pdefs   ("RC_STR_COPYRIGHT"     , "Copyright ERG Group $CurrentYear" ));
181
    $fh->Write(prc     ('#ifdef _DEBUG'));
182
    $fh->Write(pdefs   ("RC_STR_SPECIAL"       , "Debug Version" ));
183
    $fh->Write(prc     ('#else'));
184
    $fh->Write(pdefs   ("RC_STR_SPECIAL"       , "Production Version" ));
185
    $fh->Write(prc     ('#endif'));
186
    $fh->Write(prc     (""));
187
 
263 dpurdie 188
    unless ( $defs )
189
    {
190
        $fh->Write(prc     (''));
191
        $fh->Write(prc     ('VS_VERSION_INFO VERSIONINFO'));
192
        $fh->Write(prc     (' FILEVERSION      RC_NUM_VERSION'));
193
        $fh->Write(prc     (' PRODUCTVERSION   RC_NUM_VERSION'));
194
        $fh->Write(prc     (' FILEFLAGSMASK 0x3fL'));
195
        $fh->Write(prc     ('#ifdef _DEBUG'));
196
        $fh->Write(prc     (' FILEFLAGS 0x1L'));
197
        $fh->Write(prc     ('#else'));
198
        $fh->Write(prc     (' FILEFLAGS 0x0L'));
199
        $fh->Write(prc     ('#endif'));
200
        $fh->Write(prc     (' FILEOS 0x40004L'));
201
        $fh->Write(prc     (' FILETYPE 0x1L'));
202
        $fh->Write(prc     (' FILESUBTYPE 0x0L'));
203
        $fh->Write(prc     ('BEGIN'));
204
        $fh->Write(prc     ('    BLOCK "StringFileInfo"'));
205
        $fh->Write(prc     ('    BEGIN'));
206
        $fh->Write(prc     ('        BLOCK "0c0904b0"'));
207
        $fh->Write(prc     ('        BEGIN'));
208
        $fh->Write(prc     ('            VALUE "Comments",         RC_STR_COMMENT'));
209
        $fh->Write(prc     ('            VALUE "CompanyName",      RC_STR_COMPANY'));
210
        $fh->Write(prc     ('            VALUE "FileDescription",  RC_STR_DESCRIPTION'));
211
        $fh->Write(prc     ('            VALUE "FileVersion",      RC_STR_VERSION'));
212
        $fh->Write(prc     ('            VALUE "InternalName",     RC_STR_NAME'));
213
        $fh->Write(prc     ('            VALUE "LegalCopyright",   RC_STR_COPYRIGHT'));
214
        $fh->Write(prc     ('            VALUE "LegalTrademarks",  RC_STR_EMPTY'));
215
        $fh->Write(prc     ('            VALUE "OriginalFilename", RC_STR_NAME'));
216
        $fh->Write(prc     ('            VALUE "PrivateBuild",     RC_STR_EMPTY'));
217
        $fh->Write(prc     ('            VALUE "ProductName",      RC_STR_PRODUCTNAME'));
218
        $fh->Write(prc     ('            VALUE "ProductVersion",   RC_STR_VERSION'));
219
        $fh->Write(prc     ('            VALUE "SpecialBuild",     RC_STR_SPECIAL'));
220
        $fh->Write(prc     ('        END'));
221
        $fh->Write(prc     ('    END'));
222
        $fh->Write(prc     ('        BLOCK "VarFileInfo"'));
223
        $fh->Write(prc     ('        BEGIN'));
224
        $fh->Write(prc     ('            VALUE "Translation", 0xc09, 1200'));
225
        $fh->Write(prc     ('        END'));
226
        $fh->Write(prc     ('END'));
227
        $fh->Write(prc     (''));
227 dpurdie 228
 
263 dpurdie 229
        if ( $icon )
230
        {
231
        $fh->Write(prc     (''));
232
        $fh->Write(prc     ('/////////////////////////////////////////////////////////////////////////////'));
233
        $fh->Write(prc     ('//'));
234
        $fh->Write(prc     ('// Icon'));
235
        $fh->Write(prc     ('//'));
236
        $fh->Write(prc     ('// Icon with lowest ID value placed first to ensure application icon'));
237
        $fh->Write(prc     ('// remains consistent on all systems.'));
238
        $fh->Write(prc     ("101       ICON    DISCARDABLE     \"$icon\""));
239
        $fh->Write(prc     (''));
240
        }
235 dpurdie 241
    }
242
 
243
 
227 dpurdie 244
    $fh->Close();
245
}
246
 
247
#-------------------------------------------------------------------------------
248
# Function        : BuildVersionC
249
#
250
# Description     : Create a "C" style version.c and version.h file
251
#
252
# Inputs          : $Prefix         - Text to prefix generated variables with
253
#                                     Used to avoid namespace conflicts
254
#                   $Type           - Type of version to create
255
#                                     Only allowed value is 'array'
256
#
257
# Returns         :
258
#
259
 
260
sub BuildVersionC
261
{
262
    my( $Prefix, $Type ) = @_;
263
    my $ver;
264
 
265
    if ( $Clobber )                             # clobber mode ?
266
    {
267
        #
268
        #   Clobber common version.c and version.h
269
        #
270
        System( "$::GBE_BIN/rm -f $Srcdir/version.c $Srcdir/version.h" );
271
        return;
272
    }
273
 
274
    #
275
    #   Default prefix is none
276
    #   Set to a defined, bet empty, string
277
    #
278
    $Prefix = "" if ( ! defined( $Prefix ) );
279
    $Type   = "" if ( ! defined( $Type ) );
280
 
281
    #   src/version.c
282
    #..
283
    open( VERSIONC, ">$Srcdir/version.c" ) ||
284
        Error( "cannot create $Srcdir/version.c" );
285
 
286
    print VERSIONC
287
        "/* Please do not edit this file.\n" .
288
        " * It was auto-generated by Buildlib ($BuildVersion) on $::CurrentTime\n" .
289
        " */\n" .
290
        "#include \"version.h\"\n";
291
 
292
    print VERSIONC
293
        "\n" .
294
        "static char what[] = \"@(#) $BUILDNAME $::CurrentDate ERG\";\n" .
295
        "\n";
296
 
297
 
298
    my @PACKAGEVERS = PackageEntry::GetPackageVersionList();
299
    if ( $Type eq "array" )
300
    {                                           # new style
301
        print VERSIONC
302
           "static const char *pkgarray[] = \n" .
303
           "{\n";
304
 
305
        foreach $ver ( @PACKAGEVERS   ) {
306
            print VERSIONC "    \"$ver\",\n";
307
        }
308
 
309
        print VERSIONC
310
           "    0\n",
311
           "};\n\n";
312
 
313
        print VERSIONC
314
           "\nconst char *\n$Prefix"."VersionString(void)\n" .
315
           "{\n".
316
           "    return \"$BUILDNAME\";\n" .
317
           "}\n" .
318
           "\nconst char **\n$Prefix"."PkgStrings(void)\n" .
319
           "{\n".
320
           "    return pkgarray;\n" .
321
           "}\n" .
322
           "\nconst char *\n$Prefix"."GetModuleInfo(void)\n" .
323
           "{\n" .
324
           "    return \"$BUILDNAME_PACKAGE ($BUILDNAME_VERSION.$BUILDNAME_PROJECT) @PACKAGEVERS\";\n" .
325
           "}\n";
326
    }
327
    else
328
    {                                           # old style
329
        print VERSIONC
330
           "\nconst char *\n$Prefix"."VersionString(void)\n" .
331
           "{\n".
332
           "    return \"$BUILDNAME @PACKAGEVERS\";\n" .
333
           "}\n" .
334
           "\nconst char *\n$Prefix"."GetModuleInfo(void)\n" .
335
           "{\n" .
336
           "    return \"$BUILDNAME_PACKAGE ($BUILDNAME_VERSION.$BUILDNAME_PROJECT) @PACKAGEVERS\";\n" .
337
           "}\n";
338
    }
339
    close VERSIONC;
340
 
341
#   src/version.h
342
#..
343
    open( VERSIONH, ">$Srcdir/version.h" ) ||
344
        Error( "cannot create $Srcdir/version.h" );
345
 
346
    print VERSIONH
347
        "#ifndef VERSION_H_INCLUDED\n" .
348
        "#define VERSION_H_INCLUDED\n" .
349
        "/* Please do not edit this file.\n" .
350
        " * It was auto-generated by Buildlib ($BuildVersion) on $::CurrentTime\n" .
351
        " */\n\n" .
352
        "#define BUILDNAME     \"$BUILDNAME\"\n" .
353
        "#define BUILDDATE     \"$::CurrentTime\"\n" .
354
        "\n";
355
 
356
    print VERSIONH
357
        "#ifdef __cplusplus\n" .
358
        "    extern \"C\" {           /* force C calling convention when using C++ */\n" .
359
        "#endif\n" .
360
        "\n";
361
 
362
    if ( $Type eq "array" )
363
    {                                           # extended interface
364
        print VERSIONH
365
        "extern const char **  $Prefix"."PkgStrings(void);\n";
366
    }
367
    print VERSIONH
368
        "extern const char *   $Prefix"."VersionString(void);\n".
369
        "extern const char *   $Prefix"."GetModuleInfo(void);\n";
370
 
371
    print VERSIONH
372
        "\n" .
373
        "#ifdef __cplusplus\n" .
374
        "    } /* extern \"C\" */\n" .
375
        "#endif\n" .
376
        "\n";
377
 
378
    print VERSIONH
379
        "\n#endif /*VERSION_H_INCLUDED*/\n";
380
    close VERSIONH;
381
}
382
 
383
#-------------------------------------------------------------------------------
384
# Function        : BuildVersionCdefs
385
#
386
# Description     : Generate a "C" style version definitions file
387
#                   This file simply contains definitions
388
#
389
# Inputs          : $Mode           - File suffix
390
#                   $ModePrefix     - Tag for all generated definitions
391
#
392
# Returns         :
393
#
394
 
395
sub BuildVersionCdefs
396
{
397
    my ( $Mode, $ModePrefix ) = @_;
398
    my $fname = "version_$Mode.h";
399
 
400
    if ( $Clobber )                             # clobber mode ?
401
    {
402
        System( "$::GBE_BIN/rm -f $Srcdir/$fname" );
403
        return;
404
    }
405
 
406
    #
407
    #   Generate version_defs.h
408
    #   This file contains ONLY definitions. It may be used by assembler
409
    #   programs (that support a preprocessor) to access version information
410
    #
411
    #   Allow for a user supplied filename fragment that will be used within
412
    #   all the definitions with in the file.
413
    #
414
    my ($major, $minor, $patch, $build, $raw_patch) = SplitVersion($BUILDNAME_VERSION);
415
    my @PACKAGEVERS = PackageEntry::GetPackageVersionList();
416
 
417
    #
418
    #   Base names on a user supplied value or a default
419
    #
420
    my $vtag = uc( "VERSION$ModePrefix" );
421
    my $guard_name = uc($fname);
422
       $guard_name =~ s~\.~_~g;
423
 
424
    open( VERSIOND, ">$Srcdir/$fname" ) ||
425
        Error( "cannot create $Srcdir/$fname" );
426
 
427
    print VERSIOND
428
        "#ifndef $guard_name\n" .
429
        "#define $guard_name\n" .
430
        "/* Please do not edit this file.\n" .
431
        " * It was auto-generated by Buildlib ($BuildVersion) on $::CurrentTime\n" .
432
        " */\n\n" .
433
        "\n".
434
        "#define ${vtag}_BUILDNAME      \"$BUILDNAME\"\n".
435
        "#define ${vtag}_BUILDDATE      \"$::CurrentTime\"\n".
436
        "\n".
437
        "#define ${vtag}_PACKAGE        \"$BUILDNAME_PACKAGE\"\n".
438
        "#define ${vtag}_VERSION        \"$BUILDNAME_VERSION\"\n".
439
        "#define ${vtag}_MAJOR_STR      \"$major\"\n".
440
        "#define ${vtag}_MINOR_STR      \"$minor\"\n".
441
        "#define ${vtag}_PATCH_STR      \"$patch\"\n".
442
        "#define ${vtag}_BUILD_STR      \"$build\"\n".
443
        "#define ${vtag}_PATCHBUILD_STR \"$raw_patch\"\n".
444
        "#define ${vtag}_PROJECT        \"$BUILDNAME_PROJECT\"\n".
445
        "#define ${vtag}_MAJOR          " . strip_zeros($major) . "\n".
446
        "#define ${vtag}_MINOR          " . strip_zeros($minor) . "\n".
447
        "#define ${vtag}_PATCH          " . strip_zeros($patch) . "\n".
448
        "#define ${vtag}_BUILD          " . strip_zeros($build) . "\n".
449
        "#define ${vtag}_PATCHBUILD     " . strip_zeros($raw_patch) . "\n".
450
        "#define ${vtag}_ALL            \"$BUILDNAME_PACKAGE ($BUILDNAME_VERSION.$BUILDNAME_PROJECT) @PACKAGEVERS\"\n".
451
        "#define ${vtag}_BUILDTIME      " . strip_zeros(time()) . "\n".
452
        "\n".
453
        "#endif /* $guard_name */\n";
454
 
455
    close VERSIOND;
456
}
457
 
458
#-------------------------------------------------------------------------------
229 dpurdie 459
# Function        : BuildVersionProperties
460
#
461
# Description     : Generate a "Java" style version definitions file
462
#                   This is a simple properties file
463
#
464
# Inputs          : $FileName       - Output filename (Optional)
465
#                   $Prefix         - Tag for all generated definitions
466
#
467
# Returns         :
468
#
469
sub BuildVersionProperties
470
{
471
    my ( $fname, $Prefix ) = @_;
472
 
473
    #
474
    #   Default name of the file
475
    #
476
    $fname = 'version.properties' unless $fname;
477
 
478
    #
247 dpurdie 479
    #   Store the files location for use at runtime
480
    #   It will be a file that is 'known' to JATS
481
    #
482
    $fname = ::BuildAddKnownFile ( $Srcdir, $fname );
483
    return if ( $Clobber );      # clobber mode ?
484
 
485
    #
229 dpurdie 486
    #   Generate version properties file
487
    #
488
    #   This file contains ONLY definitions. It may be included by the ANT
489
    #   builds. Its not intended to be imported by the java code
490
 
491
 
492
    #
493
    #   Allow for a user supplied property prefix
494
    #   Not really needed as
495
    #
496
    my $vtag = '';
497
    $vtag = $Prefix . '.' if $Prefix;
498
 
499
 
500
    my ($major, $minor, $patch, $build, $raw_patch) = SplitVersion($BUILDNAME_VERSION);
501
    my @PACKAGEVERS = PackageEntry::GetPackageVersionList();
502
 
503
    #
504
    #   Create properties in the same form as for "C" definitions
505
    #   Note:
506
    #       The 'ALL' is in a format used by other software. Do not change
507
    #
247 dpurdie 508
    open( VERSIOND, ">$fname" ) ||
509
        Error( "cannot create $fname" );
229 dpurdie 510
 
511
    print VERSIOND
512
        "# Please do not edit this file.\n" .
513
        "# It was auto-generated by Buildlib ($BuildVersion) on $::CurrentTime\n" .
514
        "#\n" .
515
        "${vtag}BUILDNAME      = $BUILDNAME\n".
516
        "${vtag}BUILDDATE      = $::CurrentTime\n".
517
        "\n".
518
        "${vtag}PACKAGE        = $BUILDNAME_PACKAGE\n".
519
        "${vtag}VERSION        = $BUILDNAME_VERSION\n".
520
        "${vtag}MAJOR_STR      = $major\n".
521
        "${vtag}MINOR_STR      = $minor\n".
522
        "${vtag}PATCH_STR      = $patch\n".
523
        "${vtag}BUILD_STR      = $build\n".
524
        "${vtag}PATCHBUILD_STR = $raw_patch\n".
525
        "${vtag}PROJECT        = $BUILDNAME_PROJECT\n".
526
        "${vtag}MAJOR          = " . strip_zeros($major) . "\n".
527
        "${vtag}MINOR          = " . strip_zeros($minor) . "\n".
528
        "${vtag}PATCH          = " . strip_zeros($patch) . "\n".
529
        "${vtag}BUILD          = " . strip_zeros($build) . "\n".
530
        "${vtag}PATCHBUILD     = " . strip_zeros($raw_patch) . "\n".
531
        "${vtag}ALL            = $BUILDNAME_PACKAGE ($BUILDNAME_VERSION.$BUILDNAME_PROJECT) @PACKAGEVERS\n".
532
        "${vtag}BUILDTIME      = " . strip_zeros(time()) . "\n".
533
        "\n";
534
    #
535
    #   Create a set of definitions for each dependent package
536
    #
537
    print VERSIOND "# Dependent Packages and Versions\n".
538
                   "#\n";
539
 
540
    foreach my $tag ( PackageEntry::GetPackageList() )
541
    {
542
        my ($name, $version, $type) = PackageEntry::GetPackageData($tag);
543
#        push @attributes, "build=\"true\"" if $type =~ /Build/i;
544
        print VERSIOND "${vtag}PACKAGE.$name=$version\n";
545
    }
546
    close VERSIOND;
547
}
548
 
549
#-------------------------------------------------------------------------------
227 dpurdie 550
# Function        : stip_zeros
551
#
552
# Description     : Remove leading 0's from a string
553
#
554
# Inputs          : A string
555
#
556
# Returns         : A string without leading zeros
557
#
558
sub strip_zeros
559
{
560
    my ($text) = @_;
561
 
562
    $text =~ s~^0*~~;
563
    $text = '0' unless ( $text );
564
    return $text;
565
}
566
 
567
1;