NAME

A2E::Prog

VERSION

This describes version 0.4.4

DESCRIPTION

Basic program elements useful for almost any program, including

  vecho: verbose message
  decho: debugging message
  necho: non-quiet message
  exek: execute a program and return non-null if successful
  exek_open3: like exek, use open3, store stdin/stdout/stderr for later use

SYNOPSIS

use A2E::Prog; $p = new_ready A2E::Prog verbose => 1, dev => '/dev/mapper/perldisk'; $p->vecho('OK') if $p->exek('cryptsetup', 'isLuks', $p->{dev});

DESCRIPTION

Elements common to any program of more than minimal complexity, including output and debugging messages, commandline parsing, configuration, invocation of external programs and capturing of their output.

This is a fairly think wrapper around a series of standard CPAN modules.

This does not comprise database access. To add that, invoke A2E::Daba. A2E::Prog is a base class that most classes at A2E will inherit and most programs will directly or indirectly use.

BUGS, CAVEATS

The documentation effort has just begun.

The routine exek_open3 does not yet do everything it should do.

PREREQUISITES

    AppConfig(3)
    Getopt::Long(3)
    Pod::Usage(3)
    IPC::Open3(3)
    Encode(3)
    Carp(3)
    POSIX(3)
    perl(1)
                                                                               

SEE ALSO

  http://a2e.de/adv/perl/A2E
    A2E::Daba(3)
    perldoc(1)

AUTHOR

    Hartmut Pilch

COPYRIGHT

    Copyright (c) 2007 Hartmut Pilch (phm)

    This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

IMPLEMENTATION

Header: Load Libraries

Echo: Message routines

Function msg

    Subroutine of echo & friends.

Function echo

    Arg 1 is a flag which must be true for anything to happen.
    Arg 2 is the message.
    The remaining arguments are, if present, incorporated into the message by sprintf/hsprintf.

Function vecho

    verbose message

Function debug

Function decho

    debugging message

Function dval

represent perl expressions

Function dmsg

Function dpuc

    Lightweight debugging messages when entering and exiting from a function.

    Maintain a funz stack in the object and push the new function name onto it when starting.

    Use dpop to pop it off when leaving.

Funktion dpop

    Leave a group that was begun by C<dpuc>

Funktion dgot

    $m->dgot(fnom => $fnom, name => $name, mode => $mode, binmode => $opts{binmode});

Function necho

    normal, necessary message.
    Disabled only if quiet option is set.

Functions ustop, pstop, uwarn, pwarn

    User level vs program level error warning/termination.
    
    Wrappers around die, warn, croak, confess, carp and cluck.

Funktion pstop

Funktion deprek_warn

Funktion uwarn

Funktion pwarn

Function koniug

    express a list with a conjuction like 'and', e.g. in debugging messages.

Funktion koniug_et

Function tcek_grup

    If a desired group (i.e. one that should have the writes on the files we write) is set, check whether we are in this group, die if we are not.

Program Time

Function timestamp

    Return a timestamp that can be used for naming of temporary files.

    As arg1, a time template as used by POSIX::strftime can be given.

Function set_timestamp

    Like timestamp, but store the result in $m->{timestamp} and, if it is already there and no argument is given, return it from there.

Various common program elements

Functions ref2list, ref2hash

    Return a list/hash for an object that may or may not be a reference to a list/hash.

Function enclose

    Internal subroutine.

    An elegant way of expressing a frequent text structure in programming language: 

    enclose '( ', ' )', 'abc' ---> '( abc )'

function CamelCase

    synopsis

    $CamelDok = $m->CamelCase($m->{dok});

replace abc_def_en with AbcDefEn. A subroutine used in template transformation operations. Argument 1 is an object property, e.g. 'dok'

File IO

    A thin wrapper around IO::File. 

    Open files for reading/writing in utf-8 mode, store associated info in $m->{f}->{$name} which points to a hash with keys 'name', 'h', and 'mode'.

Function open_fayl

    Open a file arg1 under a shorthand name arg2 in some mode arg3 which is passed to IO::File.

    Options arg4ff include binmode (default C<:utf8>) and lock (default C<0>).

Function lokk_fayl

    lock the file identified by arg 1

Function anlokk_fayl

    unlock file

Function anlokk_faylz

    Unlock all locked files or those in @args.
    This is included in kloz_faylz.

Function fh

Function fn

Function getlini

    Read a line from opened file $_[1] to $_, like perl readline, trailing
    "\n" needed by while loops to determine whether we are at the end of
    the file.

Function xchomp

    extended chomp: remove any blanks, carriage returns or line feeds from
    the end of $_, return the result so as to allow skipping empty lines
    by statements like

    $m->xchomp or next;

Function print_tu_fayl

    Print to file

Function fayl_put_str

    Write a simple string to a file, only once, no bookkeeping of handles etc is done.
    Do nothing and return undef if filename argument is void.

Function fayl2str

    Read complete contents of a file into a string.
    Do nothing and return undef if filename argument is void.

Function kloz_fayl

    Close file handle, remove any lock that may be on it.
    Undef the handle but retain the rest of the info related to the file, so that it can be used for reporting.

Function kloz_faylz

    Close all files given on the command line or all that are still open.

Accessing the Configuration

    wrappers around AppConfig, making us depend less on the underlying module, so that we are freeer to migrate e.g. to something like YAML::AppConfig.

Functions konfget, konfset

Function konfsetif

    Set if proposed value is not null.

Function konfinit

    Set if nothing there yet

Invocation of external programs

Function exek

    execute a system command with arguments and return 1 if execution was successful, 0 otherwise.
    Store the exit value in $m->{err} and the error message in $m->{msg}.

Function make_pipe_sig

    Return a reference to routine that can be given to C<SIG{PIPE}> for invocation when a pipe is broken.

    Used by exek_open3, but it does not seem to be achieving anything there.

    See perldoc perlipc to learn better.

Function exek_open3

    Execute a system command, store stdout and stderr and return success.

    Uses IPC::Open3.  Capturing of STDERR doesn't seem to be working.
    The author may not have fully understood IPC::Open3 and the perlipc manual but is trying to encapsulate what he understood into this command.

    arg is a reference to a list consisting of the program and arguments.
    The remaining arguments are input lines.  The output of the system command is captured into @{$m->{co}}, its error messages into @{$m->{ce}}.  Much like exek, exek_open3 returns 1 if the system command was ended successfully (with 0 exit value), 0 otherwise.

    This is achieved by collecting the exit value resulting from the waitpid call, rather than by the closure function handed to the SIG{PIPE} interrupt.  The latter doesn't seem to be working.

    This is currently used by svn_update.

Function out2sav

    Redirect stdout to the file supplied via the argument or via -o option, unless it is already redirected.

    Append '.tmp' to the file name, so that the intended file will only
    exist after everything has been done successfuly and stdout has been
    restored with sav2out.

Function sav2out

    Restore stdout from copy saved by out2sav.
    Needed only in exceptional cases where stdout must be freed.

Funktion chwd

    In absolutes oder relatives Verzeichnis $1 wechseln und dessen absolute Version in $m->{cwd} speichern.
    Mit Fehler beenden falls es nicht klappt.
    Optionales $2 ist gegenwärtiges Verzeichnis (in idealer Benennung).
    rueckgabewert 2 ist frueheres Verzeichnis.

Funktion cdup

    Step into parent directory, return the child, i.e. the leaf relative to the parent stem into which the program could step to to get back where it came from.

Function mv_non_dir

Move an object out of the way.

Function mkdir_if_neces

Make a directory if it is not there already.

Constructing the Object and reading the configuration

Function new

Simple constructor that creates an object but does not set its configuration options. Deprecated, use new_ready instead.

Function set_debug_system

subroutine of new_ready: set up debugging-related switches based on environment variables DEBUG_BLOKS, DEBUG_PUCPOP_BLOKS, NON_DEBUG_BLOKS and DEBUG

Function new_ready

Make an object ready for use.

Alternative to new and setup, does all the initiating work, offering various parts, especially defvars and lastkonfig, for overloading.

Takes pre-configuration options hash as arguments, with the following options supported in this module:

debug

Debug right from the start, even before the configuration mechanism has been set up.

verbose

Be verbose right from the start

progver

version number of the invoking application. If not provided, the version number is the number of the first prerequisite that has one.

OBSOLETE: see the --progver and --dokprogver options below.

noexec

Do not treat me as an interactively invoked executable, do not parse the commandline.

ATTENTION: you are free to screw the program by setting object properties that you should not meddle with. No checks are performed, because these properties are set only by the programmer, not the end user. Examples of such use are

A2E::SArb(3)

makes heavy use of this in setting properties $m->{funs} and $m->{vars} that are not supported in this module.

A2E::Mktdir(5), mktdir4, mktdir5

uses tratoks to determine the command line. This is clearly a programming option rather than a user interface option.

Function lastkonfig

    Routines at the end of the init process, to be overwritten by inheriting libraries.

    This comes in after the commandline configuration options have been read but before any commandline arguments have been read and before any options have been transferred into object variables.  Parsing of additional configuration files, to be determined by user input, can be done here.

    The arguments are the commandline arguments that have remained after GetOptions.

    Used e.g. in db2auth(1)

Function konfayl

    Add a configuration file.

    An element that every application\'s defvars routine needs.

    Shield applications from the File::Spec package.

Function konfig_define

    do {konfig}->define with somewhat simpler parameters, e.g.

    $m->konfig_define([ 'tmplang', 'T' ], 's', 'multemp');

would map to

    $m->{konfig}->define('tmplang|T=s', { DEFAULT => 'multemp' });

Return the variable name, i.e. in this case 'tmplang'.

Arguments:

    $nom:       variable name(s): item or listref
    $typ:       variable type: '!' for boolean, 'i' integer, 's' string    
    $opts:      options: item or hashref; hashref with DEFAULT key would be same as options argument of konfig->define, anything else would be a value for the DEFAULT key

Function kopi_define

    like konfig_define, additionally store the variable to %{$m->{kopivars}}, so that it will be copied into C<%$m> within the the C<new_ready> initialisation routine (immediately before postkonfig).

    used restrictively for very few central variables that can be allowed to occupy central namespace in $m, any new internal variables should usually be established with C<cache_define> instead.

Function cache_define

    like konfig_define, additionally store the variable in %{$m->{cachevars}}, so that it will be copied into C<%{$m->{cache}}>.  This happens at the end of the initialisation routine C<new_ready> and at arbitrary times via C<kopi_konfigvar>.

    used for internal variables that should not be overwritable by the user by means of template variables.

Function tmplvars_define

    like konfig_define, but additionally store the variable to %{$m->{tmplvars}}, in the same way that C<cache_define> stores it to %{$m->{cache}}, but additionally store '__'.$nom.  The transfer of the values is done in new_ready right before invocation of postkonfig.

Function qre_define

    like konfig_define, but additionally store the variable to %{$m->{qre}}, in the same way that C<cache_define> stores it to %{$m->{cache}}, but in regex-compiled fashion.  The transfer of the values is done in new_ready right before invocation of postkonfig.

Function kopi_konfigvar

    Copy a variable from $m->{konfig} to the internal location where it ultimately resides.

    Something similar is done independently on all variables in new_ready

Function define_prog_vars and the defvars mechanism

    At each application layer, a defvars routine should be defined which again invokes the corresponding routine of its ancestor layer at the beginning, see e.g. define_daba_vars in A2E::Daba(3), define_dokfs_vars in A2E::Dokfs(3), define_mktdir_vars in A2E::Mktdir(3) and define_mktdir5_vars in mktdir5(1).

    Thus each program will invoke 'new', 'defvars', 'setup' and 'process' in sequence.  The mktdir5(1) and dokfs_subdirs(1) can serve as models of minimal application programs.

    Each parent library, also in case of multiple inheritance, has its defvars.  Even a mix-in library like A2E::Lokvars(3) has its lokvars_defvars method, but no setup method.  Moreover, the mixin-type defvars routine does not invoke those of any parents.

OPTIONS

--verbose
--version
--manpage
--help
--quiet
--force
--noexec
--test
--srcfpfx

Prefix of directory-specific source and configuration text files such '_' as found in '_prog', '_dokfs', '_langs' and '_lng.myprog.en.txt'

--konfbas dokfs

Name of library that is used for the minimal configuration file that must be present in each directory so that the source text file name prefix srcfpfx '@' or '_' can be derived from it, e.g. 'dokfs'.

--konfsfx konf

Suffix used in configuration file names invoked in file name templates by '%s' fillable with $m->hsprintf('%b.%s', b => 'dokfs', 's' => 'konf')

--locale|-l de_DE.utf-8

Landessprache festlegen.

Die Landessprache muss vom Betriebssystem unterstützt sein und es sollten Übersetzungen für sie vorliegen.

In Frage kommen derzeit de_DE.utf-8, en_US.utf-8, zh_TW.utf-8, ja_JP.utf-8 und C.

Was ein Unix-Betriebssystem unterstützt, kann man mit dem Befehl locale -a herausfinden.

Voreingestellt ist der Inhalt der Umgebungsvariable LANG.

In der internen Variable $m->{lang} wird der erste Teil von --locale (also 'de', 'en', 'zh' bzw 'ja') abgespeichert.

S. auch perldoc perllocale.

--lang

first 2-3 letters of locale, e.g. 'de', derived therefrom unless separately specified

--hom_konfayl_fnom '.%b_%s'

sprintf template for generating name of user home directory configuration file .prog_konf from elements such as

        b base 'prog'
        s suffix 'konf'
        p prefix '_'
--lok_konfayl_fnom '%p%b'

sprintf template for generating name of local configuration file @prog from elements such as

        b base 'prog'
        s suffix 'konf'
        p prefix '_'
--progver 12035

Current version of software, corresponding to 1.2.35 in PAK.mk. This is used by the creating programs such as mktdir to write dokprogver into the created directory's configuration file aka @dokfs.

--dokprogver

Version of software that the document was created with. Based on this info backward compatibility is enabled or switched off, e.g. with the dokprogverpre function as in

        $m->{tmplvars}->{$nom.'_jungils'} = $val if $m->dokprogverpre(400);

bolean routine. The dokprogver must be preset to a value that represents the lowest allowable progver of the site, so that when a local directory does not have its own dokprogver value this one can be safely used.

--batch

Never ask the user to supply missing information interactively, always use default values instead.

Function hsprintf

Fill in a simple template string with values from a hash.

Simple call-by-value replacement for positional 'sprintf'.

Expand something like

    %p%d.%l.txt 

to sth like

    @perl_pub.de.txt

when invoked by

    $m->hsprintf('%p%d.%l.txt', p => '_', d => 'perl_pub', l => 'de');

TODO: speed up by using pack and unpack and operating on characters rather than using regexps

Function defvars

Define configuration variables and specify configuration files (with the konfayl method) here.

Function ekspand_konfayl

arg1

e.g.

        '/etc/opt/a2e/prog.konf'
result: array of 3 files

e.g.

    '/etc/opt/a2e/prog.konf', '/home/phm/.prog_konf', './@prog'

Subroutine of ekspand_konfaylz

Function ekspand_konfaylz

Subroutine of pars_konfaylz

Expand a list of configuration files like '/etc/opt/a2e/prog.konf' and return list about 3 times as long, consisting of something like

    ('/etc/opt/a2e/prog.konf', "$ENV{HOME}/.prog", '@prog')

in place of each entry.

Function pars_konfaylz

Read configuration files as accumulated in my konfaylz field as well as extra ones optionally supplied as arguments. Void the konfaylz field and instead enter the the names of those files that were found onto the konfaylz_old hash. Never read any file that is already on this hash.

Look for corresponding configuration files also in the user\'s home directory and in the current directory, e.g. if /etc/opt/a2e/mktdir/mktdir.konf is among the configuration files, also read ~/mktdir.konf and ./@mktdir if found.

Function konfig_faylz

Function konfig_optvalz

Part of the new_ready constructor. The argument is a hash with configuration defaults of the current application. This allows any arguments supplied to new_ready to override any options of the same name as found in configuration files, while still allowing users to override this from the commandline.

WARNING: HACK!

The solution relies on internals of AppConfig & AppConfig::State.

We need to directly access the $m->{konfig}->{STATE}->{VARIABLE} hash.

We cannot use the set/get routines on lists and hashes because they perform unwanted parsing.

Function konfig_getopt

read konfig values from commandline.

show help, manpage or version if appropriate.

Function postkonfig

Some final sanity checks and finishing steps to get the object ready for use. To be overwritten by inheriting objects.

Function postkonfig

Functions put_rekonfig, old_ready and plugins: reconfiguration scheme

OBSOLETE?

The original purpose of this scheme was to reset some variables to the original state after a program such as mktdir has been executed so that it can be executed again, e.g. recursively on objects that are subordinate to or referenced by the main object.

Something similar is already implicitely done in the A2E::Mktdir::submktdirs with the statements

    my %tmplvars = %{$m->{tmplvars}};
    my %opts = (tmplvars => \%tmplvars, subopts => { dokdatum => $m->{hodie} });
    foreach my $sem (@subsems) {
        $m->old_ready(%opts);
        [...]
    }

These still use the reconfiguration scheme by invoking old_ready, but they do they still need its full functionality? We need to explore this question as we document the system.

Function put_rekonfig

Register a reconfiguration routine so that it will be invoked during reconfiguration.

Function rekonfig_funvars

Function rekonfig_supobj

Copy variables named in @{$m->{supobj_vars}} from superior object $obj to current one $m. The variables can be of tmplvarsvars or cachevars type; if not found to be so they are assumed to be direct object variables (kopivars).

Function rekonfig_skalvars

Reconfigure scalar variables after one run of the main program, e.g. after mktdir.

Function old_ready

Change initial settings when reinvoking main function without reinvoking new_ready.

This used to be part of postkonfig but it turned out that a separate routine is needed for cases where a top-level function like mktdir is repeatedly invoked with different arguments by one application.

Options supplied as %args include

    supobj
    skalvars
    funvars

They can be plugged in using put_rekonfig, as is done e.g. in A2E::Mktdir(3).

AppConfig subclass functions

These should be moved to a A2E::AppConfig subclass of AppConfig soon.

Function add_alias

add an alias to an existing template variable.

New Functions, To be Classified

Function dokprogverpre

current program version is earlier than the one given

Function get_srcfpfx

Return source file name prefix based on what is found in current directory

ARGS %opts => { bas => 'langs', dir => '/sig/oas' } bas :: base name of file that must be present, e.g. 'dokfs' for '@dokfs', 'langs' for '__langs' RET $pfx :: directory specific source file name prefix $pfx => '_', '__', '@'

Returns '_' as directory-specific source file name prefix if file '_langs' is found in the directory.

TODO use pack and unpack, operate on characters one by one so as to avoid rescanning allow '%%'

Function rtrim_nokoment Remove trailing coments that come after hashmark which is not backslash-escaped and which is followed either by eol or whitespace

Destructors

Function prog_destroy

remove file locks

Function DESTROY

TODO

POD ERRORS

Hey! The above document had some coding errors, which are explained below:

Around line 1055:

Non-ASCII character seen before =encoding in 'gegenwärtiges'. Assuming UTF-8