MDK::Common(3)

NAME
MDK::Common - miscellaneous functions

SYNOPSIS
    use MDK::Common;
    # exports all functions, equivalent to

    use MDK::Common::DataStructure qw(:all);
    use MDK::Common::File qw(:all);
    use MDK::Common::Func qw(:all);
    use MDK::Common::Math qw(:all);
    use MDK::Common::String qw(:all);
    use MDK::Common::System qw(:all);
    use MDK::Common::Various qw(:all);

DESCRIPTION
"MDK::Common" is a collection of packages containing various simple functions: MDK::Common::DataStructure, MDK::Common::File, MDK::Common::Func, MDK::Common::Math, MDK::Common::String, MDK::Common::System, MDK::Common::Various.

EXPORTS from MDK::Common::DataStructure.pm

sort_numbers(LIST)
    numerical sort (small numbers at beginning)

ikeys(HASH)
    aka sorted integer keys, as simple as "sort { $a <=> $b } keys"

add2hash(HASH REF, HASH REF)
    adds to the first hash the second hash if the key/value is not already there

add2hash_
    adds to the first hash the second hash if the key is not already there

put_in_hash
    adds to the first hash the second hash, crushing existing key/values

member(SCALAR, LIST)
    is the value in the list?

invbool(SCALAR REF)
    toggles the boolean value

listlength(LIST)
    returns the length of the list. Useful in list (opposed to array) context:

        sub f { "a", "b" }
        my $l = listlength f();

    whereas "scalar f()" would return "b"

deref(REF)
    de-reference

deref_array(REF)
    de-reference arrays:

        deref_array [ "a", "b" ]    #=> ("a", "b")
        deref_array "a"             #=> "a"

is_empty_array_ref(SCALAR)
    is the scalar undefined or is the array empty

is_empty_hash_ref(SCALAR)
    is the scalar undefined or is the hash empty

uniq(LIST)
    returns the list with no duplicates (keeping the first elements)

uniq_ { CODE } LIST
    returns the list with no duplicates according to the scalar results of CODE on each element of LIST (keeping the first elements)

        uniq_ { $_->[1] } [ 1, "fo" ], [ 2, "fob" ], [ 3, "fo" ], [ 4, "bar" ]

    gives [ 1, "fo" ], [ 2, "fob" ], [ 4, "bar" ]

difference2(ARRAY REF, ARRAY REF)
    returns the first list without the element of the second list

intersection(ARRAY REF, ARRAY REF, ...)
    returns the elements which are in all lists

next_val_in_array(SCALAR, ARRAY REF)
    finds the value that follow the scalar in the list (circular): "next_val_in_array(3, [1, 2, 3])" gives 1 (do not use a list with duplicates)

group_by2(LIST)
    interprets the list as an ordered hash, returns a list of [key,value]: "group_by2(1 =" 2, 3 => 4, 5 => 6)> gives "[1,2], [3,4], [5,6]"

list2kv(LIST)
    interprets the list as an ordered hash, returns the keys and the values: "list2kv(1 =" 2, 3 => 4, 5 => 6)> gives "[1,3,5], [2,4,6]"

EXPORTS from MDK::Common::File.pm

dirname(FILENAME)
basename(FILENAME)
    returns the dirname/basename of the file name

cat_(FILES)
    returns the files contents: in scalar context it returns a single string, in array context it returns the lines.

    If no file is found, undef is returned

cat_or_die(FILENAME)
    same as "cat_" but dies when something goes wrong

cat_utf8(FILES)
    same as C(<cat_>) but reads utf8 encoded strings

cat_utf8_or_die(FILES)
    same as C(<cat_or_die>) but reads utf8 encoded strings

cat__(FILEHANDLE REF)
    returns the file content: in scalar context it returns a single string, in array context it returns the lines

output(FILENAME, LIST)
    creates a file and outputs the list (if the file exists, it is clobbered)

output_utf8(FILENAME, LIST)
    same as C(<output>) but writes utf8 encoded strings

secured_output(FILENAME, LIST)
    likes output() but prevents insecured usage (it dies if somebody try to exploit the race window between unlink() and creat())

append_to_file(FILENAME, LIST)
    add the LIST at the end of the file

output_p(FILENAME, LIST)
    just like "output" but creates directories if needed

output_with_perm(FILENAME, PERMISSION, LIST)
    same as "output_p" but sets FILENAME permission to PERMISSION (using chmod)

mkdir_p(DIRNAME)
    creates the directory (make parent directories as needed)

rm_rf(FILES)
    remove the files (including sub-directories)

cp_f(FILES, DEST)
    just like "cp -f"

cp_af(FILES, DEST)
    just like "cp -af"

cp_afx(FILES, DEST)
    just like "cp -afx"

linkf(SOURCE, DESTINATION)
symlinkf(SOURCE, DESTINATION)
renamef(SOURCE, DESTINATION)
    same as link/symlink/rename but removes the destination file first

touch(FILENAME)
    ensure the file exists, set the modification time to current time

all(DIRNAME)
    returns all the file in directory (except "." and "..")

all_files_rec(DIRNAME)
    returns all the files in directory and the sub-directories (except "." and "..")

glob_(STRING)
    simple version of "glob": doesn't handle wildcards in directory (eg: */foo.c), nor special constructs (eg: [0-9] or {a,b})

substInFile { CODE } FILENAME
    executes the code for each line of the file. You can know the end of the file is reached using "eof"

expand_symlinks(FILENAME)
    expand the symlinks in the absolute filename: "expand_symlinks("/etc/X11/X")" gives "/usr/bin/Xorg"

openFileMaybeCompressed(FILENAME)
    opens the file and returns the file handle. If the file is not found, tries to gunzip the file + .gz

catMaybeCompressed(FILENAME)
    cat_ alike. If the file is not found, tries to gunzip the file + .gz

EXPORTS from MDK::Common::Func.pm

may_apply(CODE REF, SCALAR)
    "may_apply($f, $v)" is "$f ? $f->($v) : $v"

may_apply(CODE REF, SCALAR, SCALAR)
    "may_apply($f, $v, $otherwise)" is "$f ? $f->($v) : $otherwise"

if_(BOOL, LIST)
    special constructs to workaround a missing perl feature: "if_($b, "a", "b")" is "$b ? ("a", "b") : ()"

    example of use: "f("a", if_(arch() =~ /i.86/, "b"), "c")" which is not the same as "f("a", arch()=~ /i.86/ && "b", "c")"

if__(SCALAR, LIST)
    if_ alike. Test if the value is defined

fold_left { CODE } LIST
    if you don't know fold_left (aka foldl), don't use it ;p

        fold_left { $::a + $::b } 1, 3, 6

    gives 10 (aka 1+3+6)

mapn { CODE } ARRAY REF, ARRAY REF, ...
    map lists in parallel:

        mapn { $_[0] + $_[1] } [1, 2], [2, 4] # gives 3, 6
        mapn { $_[0] + $_[1] + $_[2] } [1, 2], [2, 4], [3, 6] gives 6, 12

mapn_ { CODE } ARRAY REF, ARRAY REF, ...
    mapn alike. The difference is what to do when the lists have not the same length: mapn takes the minimum common elements, mapn_ takes the maximum list length and extend the lists with undef values

find { CODE } LIST
    returns the first element where CODE returns true (or returns undef)

        find { /foo/ } "fo", "fob", "foobar", "foobir"

    gives "foobar"

any { CODE } LIST
    returns 1 if CODE returns true for an element in LIST (otherwise returns 0)

        any { /foo/ } "fo", "fob", "foobar", "foobir"

    gives 1

every { CODE } LIST
    returns 1 if CODE returns true for every element in LIST (otherwise returns 0)

        every { /foo/ } "fo", "fob", "foobar", "foobir"

    gives 0

map_index { CODE } LIST
    just like "map", but set $::i to the current index in the list:

        map_index { "$::i $_" } "a", "b"

    gives "0 a", "1 b"

each_index { CODE } LIST
    just like "map_index", but doesn't return anything

        each_index { print "$::i $_\n" } "a", "b"

    prints "0 a", "1 b"

grep_index { CODE } LIST
    just like "grep", but set $::i to the current index in the list:

        grep_index { $::i == $_ } 0, 2, 2, 3

    gives (0, 2, 3)

find_index { CODE } LIST
    returns the index of the first element where CODE returns true (or throws an exception)

        find_index { /foo/ } "fo", "fob", "foobar", "foobir"

    gives 2

map_each { CODE } HASH
    returns the list of results of CODE applied with $::a (key) and $::b (value)

        map_each { "$::a is $::b" } 1=>2, 3=>4

    gives "1 is 2", "3 is 4"

grep_each { CODE } HASH
    returns the hash key/value for which CODE applied with $::a (key) and $::b (value) is true:

        grep_each { $::b == 2 } 1=>2, 3=>4, 4=>2

    gives 1=>2, 4=>2

partition { CODE } LIST
    alike "grep", but returns both the list of matching elements and non matching elements

        my ($greater, $lower) = partition { $_ > 3 } 4, 2, 8, 0, 1

    gives $greater = [ 4, 8 ] and $lower = [ 2, 0, 1 ]

before_leaving { CODE }
    the code will be executed when the current block is finished

        # create $tmp_file
        my $b = before_leaving { unlink $tmp_file };
        # some code that may throw an exception, the "before_leaving" ensures the
        # $tmp_file will be removed

cdie(SCALAR)
    aka conditional die. If a "cdie" is catched, the execution continues after the cdie, not where it was catched (as happens with die & eval)

    If a "cdie" is not catched, it mutates in real exception that can be catched with "eval"

    cdie is useful when you want to warn about something weird, but when you can go on. In that case, you cdie "something weird happened", and the caller decide wether to go on or not. Especially nice for libraries.

catch_cdie { CODE1 } sub { CODE2 }
    If a "cdie" occurs while executing CODE1, CODE2 is executed. If CODE2 returns true, the "cdie" is catched.

EXPORTS from MDK::Common::Math.pm

$PI the well-known constant

even(INT)
odd(INT)
    is the number even or odd?

sqr(FLOAT)
    sqr(3) gives 9

sign(FLOAT)
    returns a value in { -1, 0, 1 }

round(FLOAT)
    "round(1.2)" gives 1, "round(1.6)" gives 2

round_up(FLOAT, INT)
    returns the number rounded up to the modulo: "round_up(11,10)" gives 20

round_down(FLOAT, INT)
    returns the number rounded down to the modulo: "round_down(11,10)" gives 10

divide(INT, INT)
    integer division (which is lacking in perl). In array context, also returns the remainder: "($a, $b) = divide(10,3)" gives "$a is 3" and "$b is 1"

min(LIST)
max(LIST)
    returns the minimum/maximum number in the list

or_(LIST)
    is there a true value in the list?

and_(LIST)
    are all values true in the list?

sum(LIST)
product(LIST)
    returns the sum/product of all the element in the list

factorial(INT)
    factorial(4) gives 24 (4*3*2)

OTHER in MDK::Common::Math.pm
the following functions are provided, but not exported:

factorize(INT)
    "factorize(40)" gives "([2,3], [5,1])" as 40 = 2^3 + 5^1

decimal2fraction(FLOAT)
    "decimal2fraction(1.3333333333)" gives "(4, 3)" ($PRECISION is used to decide which precision to use)

poly2(a,b,c)
    Solves the a*x2+b*x+c=0 polynomial: "poly2(1,0,-1)" gives "(1, -1)"

permutations(n,p)
    A(n,p)

combinaisons(n,p)
    C(n,p)

EXPORTS from MDK::Common::String.pm

bestMatchSentence(STRING, LIST)
    finds in the list the best corresponding string

formatList(INT, LIST)
    if the list size is bigger than INT, replace the remaining elements with "...".

    formatList(3, qw(a b c d e)) # => "a, b, c, ..."

formatError(STRING)
    the string is something like "error at foo.pl line 2" that you get when catching an exception. formatError will remove the "at ..." so that you can nicely display the returned string to the user

formatTimeRaw(TIME)
    the TIME is an epoch as returned by "time", the formatted time looks like "23:59:00"

formatLines(STRING)
    remove "\n"s when the next line doesn't start with a space. Otherwise keep "\n"s to keep the indentation.

formatAlaTeX(STRING)
    handle carriage return just like LaTeX: merge lines that are not separated by an empty line

begins_with(STRING, STRING)
    return true if first argument begins with the second argument. Use this instead of regexps if you don't want regexps.

    begins_with("hello world", "hello") # => 1

warp_text(STRING, INT)
    return a list of lines which do not exceed INT characters (or a string in scalar context)

warp_text(STRING)
    warp_text at a default width (80)

EXPORTS from MDK::Common::System.pm

%compat_arch
    architecture compatibility mapping (eg: k6 => i586, k7 => k6 ...)

%printable_chars
    7 bit ascii characters

$sizeof_int
    sizeof(int)

$bitof_int
    $sizeof_int * 8

arch()
    return the architecture (eg: i686, ppc, ia64, k7...)

typeFromMagic(FILENAME, LIST)
    find the first corresponding magic in FILENAME. eg of LIST:

        [ 'empty', 0, "\0\0\0\0" ],
        [ 'grub', 0, "\xEBG", 0x17d, "stage1 \0" ],
        [ 'lilo', 0x2,  "LILO" ],
        sub { my ($F) = @_;
              #- standard grub has no good magic (Mageia's grub is patched to have "GRUB" at offset 6)
              #- so scanning a range of possible places where grub can have its string
              my ($min, $max, $magic) = (0x176, 0x181, "GRUB \0");
              my $tmp;
              sysseek($F, 0, 0) && sysread($F, $tmp, $max + length($magic)) or return;
              substr($tmp, 0, 2) eq "\xEBH" or return;
              index($tmp, $magic, $min) >= 0 && "grub";
          },

    where each entry is [ magic_name, offset, string, offset, string, ... ].

list_passwd()
    return the list of users as given by "getpwent" (see perlfunc)

is_real_user()
    checks whether or not the user is a system user or a real user

is_real_group()
    checks whether or not the group is a system group or a real group

list_home()
    return the list of home (eg: /home/foo, /home/pixel, ...)

list_skels()
    return the directories where we can find dot files: homes, /root and /etc/skel

list_users()
    return the list of unprivilegied users (uses the is_real_user function to filter out system users from the full list)

syscall_(NAME, PARA)
    calls the syscall NAME

psizeof(STRING)
    useful to know the length of a "pack" format string.

        psizeof("I I I C C S") = 4 + 4 + 4 + 1 + 1 + 2 = 16

availableMemory()
    size of swap + memory

availableRamMB()
    size of RAM as reported by the BIOS (it is a round number that can be displayed or given as "mem=128M" to the kernel)

gettimeofday()
    returns the epoch in microseconds

unix2dos(STRING)
    takes care of CR/LF translation

whereis_binary(STRING)
    return the first absolute file in $PATH (similar to which(1) and whereis(1))

getVarsFromSh(FILENAME)
    returns a hash associating shell variables to their value. useful for config files such as /etc/sysconfig files

setVarsInSh(FILENAME, HASH REF)
    write file in shell format association a shell variable + value for each key/value

setVarsInSh(FILENAME, HASH REF, LIST)
    restrict the fields that will be printed to LIST

setVarsInShMode(FILENAME, INT, HASH REF, LIST)
    like setVarsInSh with INT being the chmod value for the config file

addVarsInSh(FILENAME, HASH REF)
    like setVarsInSh but keeping the entries in the file

addVarsInSh(FILENAME, HASH REF, LIST)
    like setVarsInSh but keeping the entries in the file

addVarsInShMode(FILENAME, INT, HASH REF, LIST)
    like addVarsInShMode but keeping the entries in the file

setExportedVarsInCsh(FILENAME, HASH REF, LIST)
    same as "setExportedVarsInSh" for csh format

template2file(FILENAME_IN, FILENAME_OUT, HASH)
    read in a template file, replace keys @@@key@@@ with value, save it in out file

template2userfile(PREFIX, FILENAME_IN, FILENAME_OUT, BOOL, HASH)
    read in a template file, replace keys @@@key@@@ with value, save it in every homes. If BOOL is true, overwrite existing files. FILENAME_OUT must be a relative filename

read_gnomekderc(FILENAME, STRING)
    reads GNOME-like and KDE-like config files (aka windows-like). You must give a category. eg:

        read_gnomekderc("/etc/skels/.kderc", 'KDE')

update_gnomekderc(FILENAME, STRING, HASH)
    modifies GNOME-like and KDE-like config files (aka windows-like). If the category doesn't exist, it creates it. eg:

        update_gnomekderc("/etc/skels/.kderc", 'KDE',
                          kfmIconStyle => "Large")

fuzzy_pidofs(REGEXP)
    return the list of process ids matching the regexp

OTHER in MDK::Common::System.pm

better_arch(ARCH1, ARCH2)
    is ARCH1 compatible with ARCH2?

    better_arch('i386', 'ia64') and better_arch('ia64', 'i386') are false

    better_arch('k7', 'k6') is true and better_arch('k6', 'k7') is false

compat_arch(STRING)
    test the architecture compatibility. eg:

    compat_arch('i386') is false on a ia64

    compat_arch('k6') is true on a k6 and k7 but false on a i386 and i686

EXPORTS from MDK::Common::Various.pm

first(LIST)
    returns the first value. "first(XXX)" is an alternative for "((XXX)[0])"

second(LIST)
    returns the second value. "second(XXX)" is an alternative for "((XXX)[1])"

top(LIST)
    returns the last value. "top(@l)" is an alternative for $l[$#l]

to_bool(SCALAR)
    returns a value in { 0, 1 }

to_int(STRING)
    extracts the number from the string. You could use directly "int "11 foo"", but you'll get Argument "11 foo" isn't numeric in int. It also handles returns 11 for "foo 11 bar"

to_float(STRING)
    extract a decimal number from the string

bool2text(SCALAR)
    returns a value in { "true", "false" }

bool2yesno(SCALAR)
    returns a value in { "yes", "no" }

text2bool(STRING)
    inverse of "bool2text" and "bool2yesno"

chomp_(STRING)
    non-mutable version of chomp: do not modify the argument, returns the chomp'ed value. Also works on lists: "chomp_($a, $b)" is equivalent to "chomp($a) ; chomp($b) ; ($a,$b)"

backtrace()
    returns a string describing the backtrace. eg:

        sub g { print "oops\n", backtrace() }
        sub f { &g }
        f();

    gives

        oops
        main::g() called from /tmp/t.pl:2
        main::f() called from /tmp/t.pl:4

internal_error(STRING)
    another way to "die" with a nice error message and a backtrace

noreturn()
    use this to ensure nobody uses the return value of the function. eg:

        sub g { print "g called\n"; noreturn }
        sub f { print "g returns ", g() }
        f();

    gives

        test.pl:3: main::f() expects a value from main::g(), but main::g() doesn't return any value

COPYRIGHT
Copyright (c) 2001-2005 Mandriva <pixel@mandriva.com>. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.