File Coverage

blib/lib/MDK/Common.pm
Criterion Covered Total %
statement 24 24 100.0
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 32 32 100.0


line stmt bran cond sub pod time code
1             package MDK::Common;
2              
3             =head1 NAME
4              
5             MDK::Common - miscellaneous functions
6              
7             =head1 SYNOPSIS
8              
9             use MDK::Common;
10             # exports all functions, equivalent to
11              
12             use MDK::Common::DataStructure qw(:all);
13             use MDK::Common::File qw(:all);
14             use MDK::Common::Func qw(:all);
15             use MDK::Common::Math qw(:all);
16             use MDK::Common::String qw(:all);
17             use MDK::Common::System qw(:all);
18             use MDK::Common::Various qw(:all);
19              
20             =head1 DESCRIPTION
21              
22             C is a collection of packages containing various simple functions:
23             L,
24             L,
25             L,
26             L,
27             L,
28             L,
29             L.
30              
31             =head1 EXPORTS from MDK::Common::DataStructure.pm
32              
33             =over
34              
35             =item sort_numbers(LIST)
36              
37             numerical sort (small numbers at beginning)
38              
39             =item ikeys(HASH)
40              
41             aka I, as simple as C=E $b } keys>
42              
43             =item add2hash(HASH REF, HASH REF)
44              
45             adds to the first hash the second hash if the key/value is not already there
46              
47             =item add2hash_
48              
49             adds to the first hash the second hash if the key is not already there
50              
51             =item put_in_hash
52              
53             adds to the first hash the second hash, crushing existing key/values
54              
55             =item member(SCALAR, LIST)
56              
57             is the value in the list?
58              
59             =item invbool(SCALAR REF)
60              
61             toggles the boolean value
62              
63             =item listlength(LIST)
64              
65             returns the length of the list. Useful in list (opposed to array) context:
66              
67             sub f { "a", "b" }
68             my $l = listlength f();
69              
70             whereas C would return "b"
71              
72             =item deref(REF)
73              
74             de-reference
75              
76             =item deref_array(REF)
77              
78             de-reference arrays:
79              
80             deref_array [ "a", "b" ] #=> ("a", "b")
81             deref_array "a" #=> "a"
82              
83             =item is_empty_array_ref(SCALAR)
84              
85             is the scalar undefined or is the array empty
86              
87             =item is_empty_hash_ref(SCALAR)
88              
89             is the scalar undefined or is the hash empty
90              
91             =item uniq(LIST)
92              
93             returns the list with no duplicates (keeping the first elements)
94              
95             =item uniq_ { CODE } LIST
96              
97             returns the list with no duplicates according to the scalar results of CODE on each element of LIST (keeping the first elements)
98              
99             uniq_ { $_->[1] } [ 1, "fo" ], [ 2, "fob" ], [ 3, "fo" ], [ 4, "bar" ]
100              
101             gives [ 1, "fo" ], [ 2, "fob" ], [ 4, "bar" ]
102              
103             =item difference2(ARRAY REF, ARRAY REF)
104              
105             returns the first list without the element of the second list
106              
107             =item intersection(ARRAY REF, ARRAY REF, ...)
108              
109             returns the elements which are in all lists
110              
111             =item next_val_in_array(SCALAR, ARRAY REF)
112              
113             finds the value that follow the scalar in the list (circular):
114             C gives C<1>
115             (do not use a list with duplicates)
116              
117             =item group_by2(LIST)
118              
119             interprets the list as an ordered hash, returns a list of [key,value]:
120             C 2, 3 => 4, 5 => 6)> gives C<[1,2], [3,4], [5,6]>
121              
122             =item list2kv(LIST)
123              
124             interprets the list as an ordered hash, returns the keys and the values:
125             C 2, 3 => 4, 5 => 6)> gives C<[1,3,5], [2,4,6]>
126              
127             =back
128              
129             =head1 EXPORTS from MDK::Common::File.pm
130              
131             =over
132              
133             =item dirname(FILENAME)
134              
135             =item basename(FILENAME)
136              
137             returns the dirname/basename of the file name
138              
139             =item cat_(FILES)
140              
141             returns the files contents: in scalar context it returns a single string, in
142             array context it returns the lines.
143              
144             If no file is found, undef is returned
145              
146             =item cat_or_die(FILENAME)
147              
148             same as C but dies when something goes wrong
149              
150             =item cat_utf8(FILES)
151              
152             same as C() but reads utf8 encoded strings
153              
154             =item cat_utf8_or_die(FILES)
155              
156             same as C() but reads utf8 encoded strings
157              
158             =item cat__(FILEHANDLE REF)
159              
160             returns the file content: in scalar context it returns a single string, in
161             array context it returns the lines
162              
163             =item output(FILENAME, LIST)
164              
165             creates a file and outputs the list (if the file exists, it is clobbered)
166              
167             =item output_utf8(FILENAME, LIST)
168              
169             same as C() but writes utf8 encoded strings
170              
171             =item secured_output(FILENAME, LIST)
172              
173             likes output() but prevents insecured usage (it dies if somebody try
174             to exploit the race window between unlink() and creat())
175              
176             =item append_to_file(FILENAME, LIST)
177              
178             add the LIST at the end of the file
179              
180             =item output_p(FILENAME, LIST)
181              
182             just like C but creates directories if needed
183              
184             =item output_with_perm(FILENAME, PERMISSION, LIST)
185              
186             same as C but sets FILENAME permission to PERMISSION (using chmod)
187              
188             =item mkdir_p(DIRNAME)
189              
190             creates the directory (make parent directories as needed)
191              
192             =item rm_rf(FILES)
193              
194             remove the files (including sub-directories)
195              
196             =item cp_f(FILES, DEST)
197              
198             just like "cp -f"
199              
200             =item cp_af(FILES, DEST)
201              
202             just like "cp -af"
203              
204             =item cp_afx(FILES, DEST)
205              
206             just like "cp -afx"
207              
208             =item linkf(SOURCE, DESTINATION)
209              
210             =item symlinkf(SOURCE, DESTINATION)
211              
212             =item renamef(SOURCE, DESTINATION)
213              
214             same as link/symlink/rename but removes the destination file first
215              
216             =item touch(FILENAME)
217              
218             ensure the file exists, set the modification time to current time
219              
220             =item all(DIRNAME)
221              
222             returns all the file in directory (except "." and "..")
223              
224             =item all_files_rec(DIRNAME)
225              
226             returns all the files in directory and the sub-directories (except "." and "..")
227              
228             =item glob_(STRING)
229              
230             simple version of C: doesn't handle wildcards in directory (eg:
231             */foo.c), nor special constructs (eg: [0-9] or {a,b})
232              
233             =item substInFile { CODE } FILENAME
234              
235             executes the code for each line of the file. You can know the end of the file
236             is reached using C
237              
238             =item expand_symlinks(FILENAME)
239              
240             expand the symlinks in the absolute filename:
241             C gives "/usr/bin/Xorg"
242              
243             =item openFileMaybeCompressed(FILENAME)
244              
245             opens the file and returns the file handle. If the file is not found, tries to
246             gunzip the file + .gz
247              
248             =item catMaybeCompressed(FILENAME)
249              
250             cat_ alike. If the file is not found, tries to gunzip the file + .gz
251              
252             =back
253              
254             =head1 EXPORTS from MDK::Common::Func.pm
255              
256             =over
257              
258             =item may_apply(CODE REF, SCALAR)
259              
260             C is C<$f ? $f-E($v) : $v>
261              
262             =item may_apply(CODE REF, SCALAR, SCALAR)
263              
264             C is C<$f ? $f-E($v) : $otherwise>
265              
266             =item if_(BOOL, LIST)
267              
268             special constructs to workaround a missing perl feature:
269             C is C<$b ? ("a", "b") : ()>
270              
271             example of use: C which is not the
272             same as C
273              
274             =item if__(SCALAR, LIST)
275              
276             if_ alike. Test if the value is defined
277              
278             =item fold_left { CODE } LIST
279              
280             if you don't know fold_left (aka foldl), don't use it ;p
281              
282             fold_left { $::a + $::b } 1, 3, 6
283              
284             gives 10 (aka 1+3+6)
285              
286             =item mapn { CODE } ARRAY REF, ARRAY REF, ...
287              
288             map lists in parallel:
289              
290             mapn { $_[0] + $_[1] } [1, 2], [2, 4] # gives 3, 6
291             mapn { $_[0] + $_[1] + $_[2] } [1, 2], [2, 4], [3, 6] gives 6, 12
292              
293             =item mapn_ { CODE } ARRAY REF, ARRAY REF, ...
294              
295             mapn alike. The difference is what to do when the lists have not the same
296             length: mapn takes the minimum common elements, mapn_ takes the maximum list
297             length and extend the lists with undef values
298              
299             =item find { CODE } LIST
300              
301             returns the first element where CODE returns true (or returns undef)
302              
303             find { /foo/ } "fo", "fob", "foobar", "foobir"
304              
305             gives "foobar"
306              
307             =item any { CODE } LIST
308              
309             returns 1 if CODE returns true for an element in LIST (otherwise returns 0)
310              
311             any { /foo/ } "fo", "fob", "foobar", "foobir"
312              
313             gives 1
314              
315             =item every { CODE } LIST
316              
317             returns 1 if CODE returns true for B element in LIST (otherwise returns 0)
318              
319             every { /foo/ } "fo", "fob", "foobar", "foobir"
320              
321             gives 0
322              
323             =item map_index { CODE } LIST
324              
325             just like C, but set C<$::i> to the current index in the list:
326              
327             map_index { "$::i $_" } "a", "b"
328              
329             gives "0 a", "1 b"
330              
331             =item each_index { CODE } LIST
332              
333             just like C, but doesn't return anything
334              
335             each_index { print "$::i $_\n" } "a", "b"
336              
337             prints "0 a", "1 b"
338              
339             =item grep_index { CODE } LIST
340              
341             just like C, but set C<$::i> to the current index in the list:
342              
343             grep_index { $::i == $_ } 0, 2, 2, 3
344              
345             gives (0, 2, 3)
346              
347             =item find_index { CODE } LIST
348              
349             returns the index of the first element where CODE returns true (or throws an exception)
350              
351             find_index { /foo/ } "fo", "fob", "foobar", "foobir"
352              
353             gives 2
354              
355             =item map_each { CODE } HASH
356              
357             returns the list of results of CODE applied with $::a (key) and $::b (value)
358              
359             map_each { "$::a is $::b" } 1=>2, 3=>4
360              
361             gives "1 is 2", "3 is 4"
362              
363             =item grep_each { CODE } HASH
364              
365             returns the hash key/value for which CODE applied with $::a (key) and $::b
366             (value) is true:
367              
368             grep_each { $::b == 2 } 1=>2, 3=>4, 4=>2
369              
370             gives 1=>2, 4=>2
371              
372             =item partition { CODE } LIST
373              
374             alike C, but returns both the list of matching elements and non matching elements
375              
376             my ($greater, $lower) = partition { $_ > 3 } 4, 2, 8, 0, 1
377              
378             gives $greater = [ 4, 8 ] and $lower = [ 2, 0, 1 ]
379              
380             =item before_leaving { CODE }
381              
382             the code will be executed when the current block is finished
383              
384             # create $tmp_file
385             my $b = before_leaving { unlink $tmp_file };
386             # some code that may throw an exception, the "before_leaving" ensures the
387             # $tmp_file will be removed
388              
389             =item cdie(SCALAR)
390              
391             aka I. If a C is catched, the execution continues
392             B the cdie, not where it was catched (as happens with die & eval)
393              
394             If a C is not catched, it mutates in real exception that can be catched
395             with C
396              
397             cdie is useful when you want to warn about something weird, but when you can
398             go on. In that case, you cdie "something weird happened", and the caller
399             decide wether to go on or not. Especially nice for libraries.
400              
401             =item catch_cdie { CODE1 } sub { CODE2 }
402              
403             If a C occurs while executing CODE1, CODE2 is executed. If CODE2
404             returns true, the C is catched.
405              
406             =back
407              
408             =head1 EXPORTS from MDK::Common::Math.pm
409              
410             =over
411              
412             =item $PI
413              
414             the well-known constant
415              
416             =item even(INT)
417              
418             =item odd(INT)
419              
420             is the number even or odd?
421              
422             =item sqr(FLOAT)
423              
424             C gives C<9>
425              
426             =item sign(FLOAT)
427              
428             returns a value in { -1, 0, 1 }
429              
430             =item round(FLOAT)
431              
432             C gives C<1>, C gives C<2>
433              
434             =item round_up(FLOAT, INT)
435              
436             returns the number rounded up to the modulo:
437             C gives C<20>
438              
439             =item round_down(FLOAT, INT)
440              
441             returns the number rounded down to the modulo:
442             C gives C<10>
443              
444             =item divide(INT, INT)
445              
446             integer division (which is lacking in perl). In array context, also returns the remainder:
447             C<($a, $b) = divide(10,3)> gives C<$a is 3> and C<$b is 1>
448              
449             =item min(LIST)
450              
451             =item max(LIST)
452              
453             returns the minimum/maximum number in the list
454              
455             =item or_(LIST)
456              
457             is there a true value in the list?
458              
459             =item and_(LIST)
460              
461             are all values true in the list?
462              
463             =item sum(LIST)
464              
465             =item product(LIST)
466              
467             returns the sum/product of all the element in the list
468              
469             =item factorial(INT)
470              
471             C gives C<24> (4*3*2)
472              
473             =back
474              
475             =head1 OTHER in MDK::Common::Math.pm
476              
477             the following functions are provided, but not exported:
478              
479             =over
480              
481             =item factorize(INT)
482              
483             C gives C<([2,3], [5,1])> as S<40 = 2^3 + 5^1>
484              
485             =item decimal2fraction(FLOAT)
486              
487             C gives C<(4, 3)>
488             ($PRECISION is used to decide which precision to use)
489              
490             =item poly2(a,b,c)
491              
492             Solves the a*x2+b*x+c=0 polynomial:
493             C gives C<(1, -1)>
494              
495             =item permutations(n,p)
496              
497             A(n,p)
498              
499             =item combinaisons(n,p)
500              
501             C(n,p)
502              
503             =back
504              
505             =head1 EXPORTS from MDK::Common::String.pm
506              
507             =over
508              
509             =item bestMatchSentence(STRING, LIST)
510              
511             finds in the list the best corresponding string
512              
513             =item formatList(INT, LIST)
514              
515             if the list size is bigger than INT, replace the remaining elements with "...".
516              
517             formatList(3, qw(a b c d e)) # => "a, b, c, ..."
518              
519             =item formatError(STRING)
520              
521             the string is something like "error at foo.pl line 2" that you get when
522             catching an exception. formatError will remove the "at ..." so that you can
523             nicely display the returned string to the user
524              
525             =item formatTimeRaw(TIME)
526              
527             the TIME is an epoch as returned by C
528              
529             =item formatLines(STRING)
530              
531             remove "\n"s when the next line doesn't start with a space. Otherwise keep
532             "\n"s to keep the indentation.
533              
534             =item formatAlaTeX(STRING)
535              
536             handle carriage return just like LaTeX: merge lines that are not separated by
537             an empty line
538              
539             =item begins_with(STRING, STRING)
540              
541             return true if first argument begins with the second argument. Use this
542             instead of regexps if you don't want regexps.
543              
544             begins_with("hello world", "hello") # => 1
545              
546             =item warp_text(STRING, INT)
547              
548             return a list of lines which do not exceed INT characters
549             (or a string in scalar context)
550              
551             =item warp_text(STRING)
552              
553             warp_text at a default width (80)
554              
555             =back
556              
557             =head1 EXPORTS from MDK::Common::System.pm
558              
559             =over
560              
561             =item %compat_arch
562              
563             architecture compatibility mapping (eg: k6 => i586, k7 => k6 ...)
564              
565             =item %printable_chars
566              
567             7 bit ascii characters
568              
569             =item $sizeof_int
570              
571             sizeof(int)
572              
573             =item $bitof_int
574              
575             $sizeof_int * 8
576              
577             =item arch()
578              
579             return the architecture (eg: i686, ppc, ia64, k7...)
580              
581             =item typeFromMagic(FILENAME, LIST)
582              
583             find the first corresponding magic in FILENAME. eg of LIST:
584              
585             [ 'empty', 0, "\0\0\0\0" ],
586             [ 'grub', 0, "\xEBG", 0x17d, "stage1 \0" ],
587             [ 'lilo', 0x2, "LILO" ],
588             sub { my ($F) = @_;
589             #- standard grub has no good magic (Mageia's grub is patched to have "GRUB" at offset 6)
590             #- so scanning a range of possible places where grub can have its string
591             my ($min, $max, $magic) = (0x176, 0x181, "GRUB \0");
592             my $tmp;
593             sysseek($F, 0, 0) && sysread($F, $tmp, $max + length($magic)) or return;
594             substr($tmp, 0, 2) eq "\xEBH" or return;
595             index($tmp, $magic, $min) >= 0 && "grub";
596             },
597              
598             where each entry is [ magic_name, offset, string, offset, string, ... ].
599              
600             =item list_passwd()
601              
602             return the list of users as given by C (see perlfunc)
603              
604             =item is_real_user()
605              
606             checks whether or not the user is a system user or a real user
607              
608             =item is_real_group()
609              
610             checks whether or not the group is a system group or a real group
611              
612             =item list_home()
613              
614             return the list of home (eg: /home/foo, /home/pixel, ...)
615              
616             =item list_skels()
617              
618             return the directories where we can find dot files: homes, /root and /etc/skel
619              
620             =item list_users()
621              
622             return the list of unprivilegied users (uses the is_real_user function to filter
623             out system users from the full list)
624              
625             =item syscall_(NAME, PARA)
626              
627             calls the syscall NAME
628              
629             =item psizeof(STRING)
630              
631             useful to know the length of a C format string.
632              
633             psizeof("I I I C C S") = 4 + 4 + 4 + 1 + 1 + 2 = 16
634              
635             =item availableMemory()
636              
637             size of swap + memory
638              
639             =item availableRamMB()
640              
641             size of RAM as reported by the BIOS (it is a round number that can be
642             displayed or given as "mem=128M" to the kernel)
643              
644             =item gettimeofday()
645              
646             returns the epoch in microseconds
647              
648             =item unix2dos(STRING)
649              
650             takes care of CR/LF translation
651              
652             =item whereis_binary(STRING)
653              
654             return the first absolute file in $PATH (similar to which(1) and whereis(1))
655              
656             =item getVarsFromSh(FILENAME)
657              
658             returns a hash associating shell variables to their value. useful for config
659             files such as /etc/sysconfig files
660              
661             =item setVarsInSh(FILENAME, HASH REF)
662              
663             write file in shell format association a shell variable + value for each
664             key/value
665              
666             =item setVarsInSh(FILENAME, HASH REF, LIST)
667              
668             restrict the fields that will be printed to LIST
669              
670             =item setVarsInShMode(FILENAME, INT, HASH REF, LIST)
671              
672             like setVarsInSh with INT being the chmod value for the config file
673              
674             =item addVarsInSh(FILENAME, HASH REF)
675              
676             like setVarsInSh but keeping the entries in the file
677              
678             =item addVarsInSh(FILENAME, HASH REF, LIST)
679              
680             like setVarsInSh but keeping the entries in the file
681              
682             =item addVarsInShMode(FILENAME, INT, HASH REF, LIST)
683              
684             like addVarsInShMode but keeping the entries in the file
685              
686             =item setExportedVarsInCsh(FILENAME, HASH REF, LIST)
687              
688             same as C for csh format
689              
690             =item template2file(FILENAME_IN, FILENAME_OUT, HASH)
691              
692             read in a template file, replace keys @@@key@@@ with value, save it in out
693             file
694              
695             =item template2userfile(PREFIX, FILENAME_IN, FILENAME_OUT, BOOL, HASH)
696              
697             read in a template file, replace keys @@@key@@@ with value, save it in every homes.
698             If BOOL is true, overwrite existing files. FILENAME_OUT must be a relative filename
699              
700             =item read_gnomekderc(FILENAME, STRING)
701              
702             reads GNOME-like and KDE-like config files (aka windows-like).
703             You must give a category. eg:
704              
705             read_gnomekderc("/etc/skels/.kderc", 'KDE')
706              
707             =item update_gnomekderc(FILENAME, STRING, HASH)
708              
709             modifies GNOME-like and KDE-like config files (aka windows-like).
710             If the category doesn't exist, it creates it. eg:
711              
712             update_gnomekderc("/etc/skels/.kderc", 'KDE',
713             kfmIconStyle => "Large")
714              
715             =item fuzzy_pidofs(REGEXP)
716              
717             return the list of process ids matching the regexp
718              
719             =back
720              
721             =head1 OTHER in MDK::Common::System.pm
722              
723             =over
724              
725             =item better_arch(ARCH1, ARCH2)
726              
727             is ARCH1 compatible with ARCH2?
728              
729             better_arch('i386', 'ia64') and better_arch('ia64', 'i386') are false
730              
731             better_arch('k7', 'k6') is true and better_arch('k6', 'k7') is false
732              
733             =item compat_arch(STRING)
734              
735             test the architecture compatibility. eg:
736              
737             compat_arch('i386') is false on a ia64
738              
739             compat_arch('k6') is true on a k6 and k7 but false on a i386 and i686
740              
741             =back
742              
743             =head1 EXPORTS from MDK::Common::Various.pm
744              
745             =over
746              
747             =item first(LIST)
748              
749             returns the first value. C is an alternative for C<((XXX)[0])>
750              
751             =item second(LIST)
752              
753             returns the second value. C is an alternative for C<((XXX)[1])>
754              
755             =item top(LIST)
756              
757             returns the last value. C is an alternative for C<$l[$#l]>
758              
759             =item to_bool(SCALAR)
760              
761             returns a value in { 0, 1 }
762              
763             =item to_int(STRING)
764              
765             extracts the number from the string. You could use directly C, but
766             you'll get I. It also handles returns
767             11 for C<"foo 11 bar">
768              
769             =item to_float(STRING)
770              
771             extract a decimal number from the string
772              
773             =item bool2text(SCALAR)
774              
775             returns a value in { "true", "false" }
776              
777             =item bool2yesno(SCALAR)
778              
779             returns a value in { "yes", "no" }
780              
781             =item text2bool(STRING)
782              
783             inverse of C and C
784              
785             =item chomp_(STRING)
786              
787             non-mutable version of chomp: do not modify the argument, returns the chomp'ed
788             value. Also works on lists: C is equivalent to
789             C
790              
791             =item backtrace()
792              
793             returns a string describing the backtrace. eg:
794              
795             sub g { print "oops\n", backtrace() }
796             sub f { &g }
797             f();
798              
799             gives
800              
801             oops
802             main::g() called from /tmp/t.pl:2
803             main::f() called from /tmp/t.pl:4
804              
805              
806             =item internal_error(STRING)
807              
808             another way to C with a nice error message and a backtrace
809              
810             =item noreturn()
811              
812             use this to ensure nobody uses the return value of the function. eg:
813              
814             sub g { print "g called\n"; noreturn }
815             sub f { print "g returns ", g() }
816             f();
817              
818             gives
819              
820             test.pl:3: main::f() expects a value from main::g(), but main::g() doesn't return any value
821              
822             =back
823              
824             =head1 COPYRIGHT
825              
826             Copyright (c) 2001-2005 Mandriva . All rights reserved.
827             This program is free software; you can redistribute it and/or
828             modify it under the same terms as Perl itself.
829              
830             =cut
831              
832              
833 1     1   861 use MDK::Common::DataStructure qw(:all);
  1         2  
  1         203  
834 1     1   275 use MDK::Common::File qw(:all);
  1         2  
  1         161  
835 1     1   7 use MDK::Common::Func qw(:all);
  1         1  
  1         147  
836 1     1   7 use MDK::Common::Math qw(:all);
  1         2  
  1         125  
837 1     1   245 use MDK::Common::String qw(:all);
  1         2  
  1         105  
838 1     1   277 use MDK::Common::System qw(:all);
  1         2  
  1         211  
839 1     1   242 use MDK::Common::Various qw(:all);
  1         2  
  1         115  
840              
841 1     1   7 use Exporter;
  1         1  
  1         91  
842             our @ISA = qw(Exporter);
843             # perl_checker: RE-EXPORT-ALL
844             our @EXPORT = map { @$_ } map { values %{'MDK::Common::' . $_ . 'EXPORT_TAGS'} } grep { /::$/ } keys %MDK::Common::;
845              
846             our $VERSION = "1.2.34.1";
847              
848             1;