Print file name and line number to log - specman

I would like to print file name and line number to log file, similar to __FILE__ and __LINE__ is SV.
Is it possible?
Can I print the stack, as stack() in SV behaves?
Thanks!

In e, there is no "general" syntax to access module name or line number, but there exists a syntax that can be used in define as macros.
For example, you can define a macro like this, to print an expression along with the current line and module name:
define <my'action> "out_with_line_number <exp>" as {
out("<current_line_num> #<current_module_name>: ", <exp>);
};
Regarding the second question, there exists a predefined global method print_stack_trace().

Related

"simple" perl assignment with .txt file

I have an assignment that explains the following:
Write a small Perl program called names.pl reads in a list of first and last names (full name per line) and stores the names in two hashes (%firstNameHash and %lastNameHash). Below is the user interface showing how it should work. Hint, in Perl you can assign 2 variables at once: ($first, $last) = split / /, $line;
File name to read in: myFile.txt
(F) for first name (L) for last name search and (.) to exit: F
Enter first name: Mike
Jonas
(F) for first name (L) for last name search and (.) to exit: L
Enter last name: Jonas
Mike
(F) for first name (L) for last name search and (.) to exit: .
Done!
I find this explanation to be pretty confusing, but I get the interface. I have the test file (myFile.txt) we were assigned, and it looks like this:
Mike Jonas
Mark Jones
Max Tedford
Robbie MacPheson
Alison Bailey
I've watched some videos/read some articles for a couple hours, but when you don't know exactly what to look for, it can be confusing.
Could anyone suggest a possible direction to start in? It would really help.
Thank you in advance!
open can be used to open a file. <$fh> will read a line from the file whose handle is in $fh. chomp can be used to remove the trailing line feed from a variable's value
As for storing the names in two hashes... That doesn't make much sense. Hashes allows one to store values indexed by a string called a key. Should the name be used as a key or value of the hash element? If it's the key, what should be used as the value, and vice-versa. I can't help you with that.
By the way, you should always start your programs with use strict; use warnings;.
($first, $last) should be my ($first, $last).
split / /, $line (splitting on each space) should be split ' ', $line (splitting on whitespace).

Tracing the source of an imported subroutine

I'm modifying a rather large unit test that uses 27 modules before loading the test framework:
use Test::Most;
When the script reaches this line, it outputs the following warning:
mytest.t ........... Subroutine main::explain redefined at mytest.t line 84.
Now I can hide the redefine messages by simply undefining the the subroutine before calling use.
BEGIN {
undef *explain; # Method imported somewhere before. Hide the redefine messages
}
use Test::Most;
However, I'd like to determine which module is importing the other version of explain.
Could use a process of elimination and just comment out everything until I get the warning, but would be nice if there was a more direct route to determining the source.
Inserting use Devel::Peek qw( ); BEGIN { Devel::Peek::Dump(\&foo); } before the line that gives the warning will tell you which package (COMP_STASH) and file name (FILE).
A solution that also gets you the line number is possible. The function's opcode tree could be walked until a nextstate is found (which is probably the very first op of the tree). The file name and line number can be extracted from the op. nextstate ops set the file and line number issued by runtime warnings.
Notes:
#line directives affect both solutions.
If a module exports an imported sub, both solution would give the original package and file of origin, not of the intermediary.
You can use perl's introspection facility (called B) for this:
use B;
my $gv = B::svref_2object(\&explain)->GV;
printf "%s::%s file %s line %s\n", $gv->STASH->NAME, $gv->NAME, $gv->FILE, $gv->LINE;
Test::Most::explain file /usr/share/perl5/Test/Most.pm line 175
(line is the end of the sub, not the beginning)

regarding usage of arrow notation in perl

I've following two statements written in perl :
#m1 = ( [1,2,3],[4,5,6],[7,8,9] ); # It is an array of references.
$mr = [ [1,2,3],[4,5,6],[7,8,9] ]; # It is an anonymous array. $mr holds reference.
When I try to print:
print "$m1[0][1]\n"; # this statement outputs: 2; that is expected.
print "$mr->[0][1]\n"; #this statement outputs: 2; that is expected.
print "$mr[0][1]\n"; #this statement doesn't output anything.
I feel second and third print statements are same. However, I didn't any output with third print statement.
Can anyone let me know what is wrong with third print statement?
This is simple. $mr is a reference. So you use the Arrow Operator to dereference.
Also, if you would use use warnings; use strict;, you would have received a somewhat obvious error message:
Global symbol "#mr" requires explicit package name
$mr is a scalar variable whose value is a reference to a list. It is not a list, and it can't be used as if it was a list. The arrow is needed to access the list it refers to.
But hold on, $m1[0] is also not a list, but a reference to one. You may be wondering why you don't have to write an arrow between the indexes, like $m1[0]->[1]. There's a special rule that says you can omit the arrow when accessing list or hash elements in a list or hash of references, so you can write $mr->[0][1] instead of $mr->[0]->[1] and $m1[0][1] instead of $m1[0]->[1].
$mr holds a reference (conceptually similar to the address of a variable in compiled languages). thus you have an extra level of indirection. replace $mrwith $$mr and you'll be fine.
btw, you can easily check questions like these by browsing for tutorials on perldoc.
You said:
print "$m1[0][1]\n"; # this statement outputs: 2; that is expected.
print "$mr[0][1]\n"; #this statement doesn't output anything.
Notice how you used the same syntax both times.
As you've established by this first line, this syntax accesses the array named: #m1 and #mr. You have no variable named #mr, so you get undef for $mr[0][1].
Maybe you don't realizes that scalar $mr and array #mr have no relation to each other.
Please use use strict; use warnings; to avoid these and many other errors.

Why are there several c files in symbol table of %main::?

'_<perlmain.c' => *{'::_<perlmain.c'},
'_</usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/auto/Data/Dumper/Dumper.so' => *{'::_</usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/auto/Data/Dumper/Dumper.so'},
'_<universal.c' => *{'::_<universal.c'},
'_<xsutils.c' => *{'::_<xsutils.c'},
...
Why are they in the symbol table of %main::,when are they useful?
To repeat the output from the question, run
#! /usr/bin/env perl
use Data::Dumper;
print Dumper \%main::;
The entries you see are inserted in gv_fetchfile_flags:
/* This is where the debuggers %{"::_<$filename"} hash is created */
tmpbuf[0] = '_';
tmpbuf[1] = '<';
memcpy(tmpbuf + 2, name, namelen);
gv = *(GV**)hv_fetch(PL_defstash, tmpbuf, tmplen, TRUE);
if (!isGV(gv)) {
gv_init(gv, PL_defstash, tmpbuf, tmplen, FALSE);
#ifdef PERL_DONT_CREATE_GVSV
GvSV(gv) = newSVpvn(name, namelen);
#else
sv_setpvn(GvSV(gv), name, namelen);
#endif
}
This is called many times by way of newXS as part of the boot process in S_parse_body.
boot_core_PerlIO();
boot_core_UNIVERSAL();
boot_core_mro();
Note that you also see entries for perlio.c, universal.c, and mro.c in the output.
The Debugger Internals section of the perldebguts documentation explains their use:
For example, whenever you call Perl's built-in caller function from the package DB, the arguments that the corresponding stack frame was called with are copied to the #DB::args array. These mechanisms are enabled by calling Perl with the -d switch. Specifically, the following additional features are enabled (cf. $^P in perlvar):
…
Each array #{"_<$filename"} holds the lines of $filename for a file compiled by Perl. The same is also true for evaled strings that contain subroutines, or which are currently being executed. The $filename for evaled strings looks like (eval 34). Code assertions in regexes look like (re_eval 19).
Each hash %{"_<$filename"} contains breakpoints and actions keyed by line number. Individual entries (as opposed to the whole hash) are settable. Perl only cares about Boolean true here, although the values used by perl5db.pl have the form "$break_condition\0$action".
The same holds for evaluated strings that contain subroutines, or which are currently being executed. The $filename for evaled strings looks like (eval 34) or (re_eval 19) .
Each scalar ${"_<$filename"} contains "_<$filename". This is also the case for evaluated strings that contain subroutines, or which are currently being executed. The $filename for evaled strings looks like (eval 34) or (re_eval 19).
After each required file is compiled, but before it is executed, DB::postponed(*{"_<$filename"}) is called if the subroutine DB::postponed exists. Here, the $filename is the expanded name of the required file, as found in the values of %INC.
…
As perl is a interpreter based language, it needs, right, his interpreter, the perl binary. This binary just reads the perl script, and executes the code by translating it in machine code.
Your perl interpreter is compiled with debug symbols, so it contains informations about the source files it build of. Also you see the objects of loaded modules Data::Dumper in your example.
Hope that helps

Finding the path to a Perl module upon loading

I am using a legacy Perl application which loads a library, call it "blah". I need to know where does "blah" resides in my file system.
I am not familiar at all with Perl, and I wonder what is the equivalent way to print the path to the module, along the lines of the special variable __file__ in Python. In other words, the Perl equivalent of the following Python script:
import blah
print blah.__file__
Many thanks.
use blah;
print $INC{'blah.pm'};
use Blah1::Blah2::blah;
print $INC{'Blah1/Blah2/blah.pm'};
The case is significant, even on Windows. use Blah will create an entry for $INC{'Blah.pm'} and use blah will create an entry for $INC{'blah.pm'}.
C:\>perl -MList::util -e "print join $/, keys %INC"
XSLoader.pm
Carp.pm
warnings/register.pm
Exporter.pm
vars.pm
strict.pm
List/util.pm
warnings.pm
To expand on my comment on mob's answer, try a more loose use of %INC to help you:
#!/usr/bin/perl
use strict;
use warnings;
use blah;
foreach (keys %INC) {
if (m'blah.pm') {
print "$_ => $INC{$_}\n";
}
}
The relevant perldoc perlvar on the subject says
%INC
The hash %INC contains entries
for each filename included via the do,
require, or use operators. The key is
the filename you specified (with
module names converted to pathnames),
and the value is the location of the
file found. The require operator uses
this hash to determine whether a
particular file has already been
included.
If the file was loaded via a
hook (e.g. a subroutine reference, see
require for a description of these
hooks), this hook is by default
inserted into %INC in place of a
filename. Note, however, that the hook
may have set the %INC entry by itself
to provide some more specific info.
If even that doesn't help, you may, as the previous document suggests, read about the require command, to help you understand how it is getting to be loaded in the first place. This should help you back it out, perhaps by iterating through #INC, which are the folders that Perl will search for to find files to be required.
I found the following one-liner which solved my problem:
$ perl -MList::Util -e'print $_ . " => " . $INC{$_} . "\n" for keys %INC'
Where -MList::Util stands for the List::Util module (in my case, I used -MBlah)