Is argv a SAC array of strings, or a traditional C array of strings?
There's CommandLine.sac in the docs, but I have no idea how to use SAC's API.
In version (1.0) you can use the argv(1) function.
$ cat args.sac
use StdIO: all;
use Array: all;
use CommandLine: all;
int main() {
printf("Test: %s\n", argv(1));
return(0);
}
$./args hello
$ Test: hello
SAC does neither (actually worse): SAC provides argv() in the CommandLine module, returning a string with all the arguments concatenated:
$ cat args.sac
use StdIO: all;
use Array: all;
use CommandLine: all;
int main() {
printf("%s\n", argv());
return(0);
}
$ sac2c -o args args.sac
$ ./args a b c
./args a b c
Related
I have Perl code that uses a constant with an initializing block like this:
use constant C => map {
...;
} (0..255);
When I try to set a breakpoint at the ...; line, it does not work, meaning: I can set the breakpoint, but the debugger does not stop there.
I tried:
Start the program with the debugger (perl -d program.pl)
Set the breakpoint in the debugger (b 2)
Reload using R, then run (r) the program
But still the debugger did not stop at the line, just as if I had no breakpoint set.
My Perl is not the latest; it's 5.18.2, just in case it matters...
You are trying to put a break point in a use block.
A use block is in effect a BEGIN block with a require in it.
The Perl debugger by default does not stop in compile phase.
However you can force the Perl debugger into single step mode inside a BEGIN block by setting the variable $DB::single to 1
See Debugging Compile-Time Statements in perldoc perldebug
If you change your code to
use constant C => map {
$DB::single = 1;
...;
} (0..255);
The Perl debugger will stop in the use statement.
You can avoid altering your code if you create a simple module like this (concept originated here):
package StopBegin;
BEGIN {
$DB::single=1;
}
1;
Then, run your code as
perl -I./ -MStopBegin -d test.pl
Pertinent Answer (previous, not-so-pertinent answer is below this one)
If test.pl looks like this:
use constant C => {
map {;
"C$_" => $_;
} 0 .. 255
};
here's what the debug interaction looks like:
% perl -I./ -MStopBegin -d test.pl
Loading DB routines from perl5db.pl version 1.53
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
StopBegin::CODE(0x55db6287dac0)(StopBegin.pm:8):
8: 1;
DB<1> s
main::CODE(0x55db6287db38)(test.pl:5):
5: };
DB<1> -
1 use constant C => {
2: map {;
3: "C$_" => $_;
4 } 0 .. 255
5==> };
DB<2> b 3
DB<3> c
main::CODE(0x55db6287db38)(test.pl:3):
3: "C$_" => $_;
DB<3>
Note the use of the breakpoint to stop inside the map.
Previous, Not-So-Pertinent Answer
If test.pl looks like this:
my $foo;
BEGIN {
$foo = 1;
};
here's what the debug interaction looks like:
% perl -I./ -MStopBegin -d test.pl
Loading DB routines from perl5db.pl version 1.53
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
StopBegin::CODE(0x5567e3d79a80)(StopBegin.pm:8):
8: 1;
DB<1> s
main::CODE(0x5567e40f0db0)(test.pl:4):
4: $foo = 1;
DB<1> s
main::(test.pl:1): my $foo;
DB<1> s
Debugged program terminated. Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.
DB<1>
Note the use of the s command to advance, otherwise it'll skip over the BEGIN block in test.pl
When I run this program:
print(rand*100)
I get values from [0,1) range.
But for this:
print(100*rand)
I get values from [0,100) range.
What is precedence here? and why first expression does not return values from [0,100) range?
rand has two syntax:
rand
rand EXPR
If what follows rand can be the start of an expression (EXPR), Perl assumes you are using the latter form.
* can start an EXPR, so rand*... is parsed as rand EXPR. This means that rand*100 is equivalent to rand(*100).
$ perl -MO=Deparse,-p -wle'print(rand*100)'
BEGIN { $^W = 1; }
BEGIN { $/ = "\n"; $\ = "\n"; }
print(rand(*100));
-e syntax OK
$ perl -wle'print(rand*100)'
Argument "*main::100" isn't numeric in rand at -e line 1.
0.57355563536203
You can always use B::Deparse to see how Perl is parsing an expression.
$ perl -MO=Deparse -e'print(100*rand)'
print 100 * (rand);
-e syntax OK
$ perl -MO=Deparse -e'print(rand*100)'
print rand *100;
-e syntax OK
I want to convert
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He...
to
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
llo.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hell
o.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
...,
where the width is 80 characters.
I firstly thought that I can use sed. (Let me explain with 5 characters instead of 80 characters to clarify.)
echo "longlonglonglonglonglonglonglonglonglonglonglong" | sed 's/\(.\{5\}\)/\1\'$'\n/g'
gives
longl
onglo
nglon
glong
longl
onglo
nglon
glong
longl
ong
as I want. However, I could not use this way when the input string lasts forever.
while true; do; echo -n "Hello."; done | sed 's/\(.\{5\}\)/\1\'$'\n/g'
The above command does not work. I also tried using perl, but in vain. (perl -pe 's/(.{5})/$1\n/g')
So I gave up solving within unix commands and wrote a small programme in C.
#include <stdio.h>
int main(int argc, char *argv[]) {
int i = 0, ch;
while ((ch = fgetc(stdin)) != EOF) {
putchar((char)ch);
i += 1;
if (ch == '\n') {
i = 0;
}
if (i >= 80) {
printf("\n");
i = 0;
}
}
return 0;
}
The programme works nice for me. So the question is, how can I split long long (probably infinite) input string into lines using unix commands?
fold can be your friend:
$ fold -w 80 file
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
llo.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hell
o.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
...
$ fold -w 20 file
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
llo.Hello.Hello.Hell
o.Hello.Hello.Hello.
Hello.Hello.Hello.He
...
From man fold:
fold - wrap each input line to fit in specified width
-w, --width=WIDTH
use WIDTH columns instead of 80
So in fact fold file is the same as fold -w 80 file
You could use perl one liner,
perl -lpe 'BEGIN{ $/ = \80 }' file
From peldoc perlvar
$/
The input record separator, newline by default. [..] Setting $/ to a reference to an integer, scalar containing an integer, or scalar that's convertible to an integer will attempt to read records instead of lines, with the maximum record size being the referenced integer number of characters
try option -u
-u (--unbuffered)
Buffer both input and output as minimally as practical. (This is particularly useful if the input is coming from the likes of ‘tail -f’, and you wish to see the transformed output as soon as possible.)
sed -u 's/\(.\{5\}\)/\1\'$'\n/g'
You could try the below perl code also,
$ perl -0777pe 's/(.{80})/\1\n/g' file
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
llo.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hell
o.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.
Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.Hello.He
...
I am building a module which connects to a camera, takes a picture, and reads the data into a piddle. All of this takes place in an Inline::C command. Using the procedure in the PDL documentation I can create a pdl * and return it. However the camera could fail to take a picture in which case I would like to return 0 as per the usual covention my $pic_pdl = $Camera->TakePicture or die "Failed to take image". This seems to mean that I will need to use the Inline_Stack_Push mechanism but I am not sure how to properly convert the pdl * into an SV*. Also I would like to, if possible, set $! with the error code too. Can this be done in Inline?
The pdl* is converted to an SV by code found in the typemap.
$ cat `perl -E'use PDL::Core::Dev; say PDL_TYPEMAP'`
TYPEMAP
pdl* T_PDL
pdl * T_PDL
Logical T_IV
float T_NV
INPUT
T_PDL
$var = PDL->SvPDLV($arg)
OUTPUT
T_PDL
PDL->SetSV_PDL($arg,$var);
If I read that right, you should be able to do something like:
SV* my_new {
pdl* p = NULL;
...
if (error) {
if (p)
free(p); /* I think */
return &PL_sv_undef;
} else {
SV* rv = newSV(0);
PDL->SetSV_PDL(rv, p);
return rv;
}
}
As for $!, it's simply an interface to C's errno. Simply set errno.
$ perl -E'use Inline C => "void f(int i) { errno = i; }"; f($ARGV[0]); say 0+$!; say $!;' 2
2
No such file or directory
$ perl -E'use Inline C => "void f(int i) { errno = i; }"; f($ARGV[0]); say 0+$!; say $!;' 3
3
No such process
$ perl -E'use Inline C => "void f(int i) { errno = i; }"; f($ARGV[0]); say 0+$!; say $!;' 4
4
Interrupted system call
I use a Perl(loader.vim) script to load VIM modules: (.vimrc) source /whatever/loader.vim
loader.vim:
function! LoadBundles()
perl HERE
while(</root/.vim/bundle/*/plugin/*>) {
my ($path, $fname) =($_ =~ m|^(.+/)(.+?)$|);
#VIM::Msg("$path $fname\n");
VIM::DoCommand("set runtimepath=$path");
VIM::DoCommand("runtime! $fname");
}
HERE
endfunction
call LoadBundles()
I'd like to do something like LoadBundles('/path/to/bundledir') but to do this I need to be able to read a variable from within Perl eg:
function! LoadBundles(path)
let var = a:path
perl HERE
print "$var\n";
How do I do this???
I'd also like to save the runtimepath within perl HERE and then restore it. How do I read runtimepath from within perl HERE?
Here's how you can get at the "runtimepath" option from embedded Perl:
perl VIM::Msg( VIM::Eval('&runtimepath') )
Do the following to get more from the docs:
:help if_perl.txt
Then search for "VIM::Eval". So try:
function! AnExample(arg)
perl << EOF
VIM::Msg( VIM::Eval('a:arg') )
EOF
endfunction
And then to test:
:so %
:call AnExample("hello")