The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

File::SmartNL - slurp text files no matter the New Line (NL) sequence

SYNOPSIS

#####
# Subroutine Interface
#
use File::SmartNL qw(config fin fout smartnl);

$old_value = config( $option );
$old_value = config( $option => $new_value);
(@all_options) = config( );

$data          = smart_nl($data);
$data          = fin( $file_name, @options );
$char_count    = fout($file_name, $data, @options);

######
# Object Interface
# 
use File::SmartNL;

$default_options = File::SmartNL->default(@options);

$old_value = $default_options->config( $option );
$old_value = $default_options->config( $option => $new_value);
(@all_options) = $default_options->config( );

$data          = File::SmartNL->smart_nl($data);
$data          = File::SmartNL->fin( $file_name, @options );
$char_count    = File::SmartNL->fout($file_name, $data, @options);

Generally, if a subroutine will process a list of options, @options, that subroutine will also process an array reference, \@options, [@options], or hash reference, \%options, {@options}. If a subroutine will process an array reference, \@options, [@options], that subroutine will also process a hash reference, \%options, {@options}. See the description for a subroutine for details and exceptions.

DESCRIPTION

Different operating systems have different sequences for new-lines. Historically when computers where first being born, one of the mainstays was the teletype. The teletype understood ASCII. The teletype was an automated typewriter that would perform a carriage return when it received an ASCII Carriage Return (CR), \015, character and a new line when it received a Line Feed (LF), \012 character.

After some time came Unix. Unix had a tty driver that had a raw mode that sent data unprocessed to a teletype and a cooked mode that performed all kinds of translations and manipulations. Unix stored data internally using a single NL character at the ends of lines. The tty driver in the cooked mode would translate the New Line (NL) character to a CR,LF sequence. When driving a teletype, the physicall action of performing a carriage return took some time. By always putting the CR before the LF, the teletype would actually still be performing a carriage return when it received the LF and started a line feed.

After some time came DOS. Since the tty driver is actually one of the largest peices of code for UNIX and DOS needed to run in very cramp space, the DOS designers decided, that instead of writing a tailored down tty driver, they would stored a CR,LF in the internal memory. Data internally would be either 'text' data or 'binary' data.

Needless to say, after many years and many operating systems about every conceivable method of storing new lines may be found amoung the various operating systems. This greatly complicates moving files from one operating system to another operating system.

The smart NL methods in this package are designed to take any combination of CR and NL and translate it into the special NL seqeunce used on the site operating system. Thus, by using these methods, the messy problem of moving files between operating systems is mostly hidden in these methods. By using the fin and fout methods, text files may be freely exchanged between operating systems without any other processing.

The one thing not hidden is that the methods need to know if the data is 'text' data or 'binary' data. Normally, the assume the data is 'text' and are overriden by setting the 'binary' option.

Perl 5.6 introduced a built-in smart nl functionality as an IO discipline :crlf. See Programming Perl by Larry Wall, Tom Christiansen and Jon Orwant, page 754, Chapter 29: Functions, open function. For Perl 5.6 or above, the :crlf IO discipline my be preferable over the smart_nl method of this program module.

SUBROUTINES

config

$old_value = config( $option );
$old_value = config( $option => $new_value);
(@all_options) = config( );

When Perl loads the File::SmartNL program module, Perl creates a $File::Drawing::default_options object using the default method.

Using the config as a subroutine

config(@_) 

writes and reads the $File::Drawing::default_options object directly using the Data::Startup::config method. Avoided the config and in multi-threaded environments where separate threads are using File::Drawing. All other subroutines are multi-thread safe. They use override to obtain a copy of the $File::Drawing::default_options and apply any option changes to the copy keeping the original intact.

Using the config as a method,

$options->config(@_)

writes and reads the $options object using the Data::Startup::config method. It goes without saying that that object should have been created using one of the following or equivalent:

$default_options = $class->File::Drawing::defaults(@_);

The underlying object data for the File::SmartNL class of objects is a hash. For object oriented conservative purist, the config subroutine is the accessor function for the underlying object hash.

Since the data are all options whose names and usage is frozen as part of the File::Drawing interface, the more liberal minded, may avoid the config accessor function layer, and access the object data directly.

defaults

The defaults subroutine establish File::Drawing class wide options options as follows:

option                  initial value
--------------------------------------------
warn                      1
binary                    0

fin

$data = fin( $file_name )
$data = fin( $file_name, @options )
$data = fin( $file_name, [@options] )
$data = fin( $file_name, {@options} )

For the binary option, the fin subroutine reads $data from the $file_name as it; otherwise, it converts any CR LF sequence to the the logical Perl \n character for site.

fout

$success = fout($file_name, $data)
$success = fout($file_name, $data, @options)
$success = fout($file_name, $data, [@options])
$success = fout($file_name, $data, {@options})

For the binary option, the fout subroutine writes out the $data to the $file_name as it; otherwise, it converts the logical Perl \n character to th site CR LF sequence for a NL.

smart_nl

$data = smart_nl( $data  )

The smart_nl subroutine converts any combination of CR and LF to the NL of the site operationg system.

REQUIREMENTS

Someday.

DEMONSTRATION

#########
# perl SmartNL.d
###

~~~~~~ Demonstration overview ~~~~~

The results from executing the Perl Code follow on the next lines as comments. For example,

2 + 2
# 4

~~~~~~ The demonstration follows ~~~~~

    use File::Package;
    my $fp = 'File::Package';

    my $uut = 'File::SmartNL';
    my $loaded = '';
    my $expected = '';
    my $data = '';

VO:

##################
# UUT not loaded
# 

$loaded = $fp->is_package_loaded('File::Where')

# ''
#

##################
# Load UUT
# 

my $errors = $fp->load_package($uut, 'config')
$errors

# ''
#
   unlink 'test.pm';
   $expected = "=head1 Title Page\n\nSoftware Version Description\n\nfor\n\n";
   $uut->fout( 'test.pm', $expected, {binary => 1} );

##################
# fout Unix fin
# 

$uut->fin( 'test.pm' )

# '=head1 Title Page

#Software Version Description

#for

#'
#
   unlink 'test.pm';
   $data = "=head1 Title Page\r\n\r\nSoftware Version Description\r\n\r\nfor\r\n\r\n";
   $uut->fout( 'test.pm', $data, {binary => 1} );

##################
# fout Dos Fin
# 

$uut->fin('test.pm')

# '=head1 Title Page

#Software Version Description

#for

#'
#
  unlink 'test.pm';
  $data =   "line1\015\012line2\012\015line3\012line4\015";
  $expected = "line1\nline2\nline3\nline4\n";

##################
# smart_nl
# 

$uut->smart_nl($data)

# 'line1
#line2
#line3
#line4
#'
#

##################
# read configuration
# 

[config('binary')]

# [
#          'binary',
#          0
#        ]
#

##################
# write configuration
# 

[config('binary',1)]

# [
#          'binary',
#          0
#        ]
#

##################
# verify write configuration
# 

[config('binary')]

# [
#          'binary',
#          1
#        ]
#

QUALITY ASSURANCE

Running the test script SmartNL.t verifies the requirements for this module. The tmake.pl cover script for Test::STDmaker automatically generated the SmartNL.t test script, SmartNL.d demo script, and t::File::SmartNL STD program module POD, from the t::File::SmartNL program module contents. The tmake.pl cover script automatically ran the SmartNL.d demo script and inserted the results into the 'DEMONSTRATION' section above. The t::File::SmartNL program module is in the distribution file File-SmartNL-$VERSION.tar.gz.

NOTES

Author

The holder of the copyright and maintainer is

<support@SoftwareDiamonds.com>

Copyrighted (c) 2002 Software Diamonds

All Rights Reserved

Binding Requirements Notice

Binding requirements are indexed with the pharse 'shall[dd]' where dd is an unique number for each header section. This conforms to standard federal government practices, STD490A 3.2.3.6. In accordance with the License, Software Diamonds is not liable for any requirement, binding or otherwise.

License

Software Diamonds permits the redistribution and use in source and binary forms, with or without modification, provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

  3. Commercial installation of the binary or source must visually present to the installer the above copyright notice, this list of conditions intact, that the original source is available at http://softwarediamonds.com and provide means for the installer to actively accept the list of conditions; otherwise, a license fee must be paid to Softwareware Diamonds.

SOFTWARE DIAMONDS, http://www.softwarediamonds.com, PROVIDES THIS SOFTWARE 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWARE DIAMONDS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING USE OF THIS SOFTWARE, EVEN IF ADVISED OF NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE POSSIBILITY OF SUCH DAMAGE.

SEE ALSO

Docs::Site_SVD::File_SmartNL
Test::STDmaker
ExtUtils::SVDmaker