[26092] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 8292 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sat Jul 30 06:05:33 2005

Date: Sat, 30 Jul 2005 03:05:05 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Sat, 30 Jul 2005     Volume: 10 Number: 8292

Today's topics:
    Re: How to return list from Inline::C code? <tlviewerSHRUB@yahooCHENEY.com>
    Re: How to return list from Inline::C code? <sisyphus1@nomail.afraid.org>
    Re: How to return list from Inline::C code? <socyl@987jk.com.invalid>
    Re: Passing vars to a "require"d script <personage@myabode.com>
    Re: Passing vars to a "require"d script <personage@myabode.com>
        PERL vs. Ruby <rstoos@rochester.rr.com>
    Re: Timer/alarm clock module <tassilo.von.parseval@rwth-aachen.de>
    Re: true false ? : expression thingy <jwkenne@attglobal.net>
    Re: true false ? : expression thingy <someone@example.com>
        Where are Inline_Stack_Vars, etc. defined? <socyl@987jk.com.invalid>
    Re: Where are Inline_Stack_Vars, etc. defined? <sisyphus1@nomail.afraid.org>
        Where to ask mysql questions? <BLOCKSPAMfishfry@your-mailbox.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Fri, 29 Jul 2005 22:40:08 GMT
From: "tlviewer" <tlviewerSHRUB@yahooCHENEY.com>
Subject: Re: How to return list from Inline::C code?
Message-Id: <cfyGe.33340$aA5.30032@tornado.socal.rr.com>


"kj" <socyl@987jk.com.invalid> wrote in message =
news:dce677$blb$1@reader2.panix.com...
>=20
>=20
>=20
> I'm attempting to hack the Perl internals, something I know very
> little of.  So I apologize ahead of time for the cluelessness of
> this question.
>=20
> I want to implement a function via Inline::C such that, depending
> on context, it returns either a scalar or a list of two values.
> (This function will access the internals of other variables, and I
> want to make it as fast as possible, hence the decision to code it
> in C).
>=20
> Since C is not capable of optionally returning a scalar or a list,
> I don't even know where to begin with this.
>=20
> Any advice would be much appreciated.  In particular, I'd love to
> look at source code for a simple function (in C) that returns a
> scalar or a list according to calling context.
>=20
> Thanks!
>=20
> kj

In the inline script below, see how I return a perl list
ref from main().

hth,
tlviewer

# begin Chmdump.pl
use Inline C =3D> DATA =3D> LIBS =3D> '-luser32';

my $tStart =3D Win32::GetTickCount();
my $arref;
my ( $in, $out );=20

$|=3D 1;

$in =3D 'i:/temp/Javascript Manual Of Style.chm';  =20
#
$out =3D '/#STRINGS'; =20

my $dir =3D '.';

$arref =3D main($in, $out, $dir );

for my $name (@$arref){
 print $name, "\n";
}=20

=20
# /*  Win32 only way to get the elapsed time */
print "elapsed=3D", ( Win32::GetTickCount() - $tStart ) / 1000, " =
seconds\n";

#
 __END__
 __C__
 /* test  */
#define _WIN32_WINNT 0x0500=20
#include <windows.h>
#include <stdio.h>
#include <limits.h>
#include <errno.h>
#include "chmlib.h"=20

// pass arguments 2 ways to show flexible Ingy style!               =20
AV* main( SV* infname, char* ext_file, char* outdirname)
{ =20
  AV* array =3D newAV(); =20
  ulong length;
  chmfile *c;
  ulong all_len;
  int i;
 =20
  ubyte *outbuf;
  ulong namelen;
  //
  char dirname[255];
  int err;
  int lres;
 =20
  // =20

 fprintf( stdout, "fname=3D %s \n", SvPV(infname, PL_na) );
  c =3D chm_openfile(SvPV(infname, PL_na));     //infname

  if (!c) { =20
   fprintf( stdout, "failed to open %s \n", infname );
    perror("chm_openfile");
    exit(-1);
  } =20
 =20
  //Inline_Stack_Reset;=20
  =20
   for (i =3D 0; i < c->dir->nentries; i++) { =20
    av_push(array, newSVpvf("%s", c->dir->entry[i].name));
    //fprintf(stdout,"%d =3D %s \n", i, c->dir->entry[i].name);=20
 }=20
 //
=20
   fprintf(stdout,"name=3D %s \n", c->dir->entry[3].name);
  //=20
 =20
  fprintf( stdout, "calling getfile \n" );
  lres =3D chm_getfile(c, ext_file , &length, &outbuf);
  if (lres !=3D 0) {=20
   fprintf( stdout, "died in getfile \n" );
  exit(-1);
  }
  //
 =20
  fprintf( stdout, "Length=3D%d \n", length);
  namelen=3D strlen((char*) (outbuf+1));

  // if buffer has embedded nulls, then parse out the tokens (#STRINGS)
  if ( namelen < 15) {
 =20
  strncpy(dirname,outbuf+1, namelen+1);
  fprintf( stdout, "char=3D%s \n", (char*)(outbuf+1));
   =20
  all_len =3D 0;
  while (all_len +2 < length){
   //
     if (namelen>0) fprintf( stdout, "%s\n", (char*)(outbuf+1+all_len)); =

     all_len +=3Dnamelen+1;
 //
 namelen =3D strlen( (char*)(outbuf+all_len+1));=20
  }
  }
  else{
 fprintf( stdout, "file_len=3D%i oblen=3D%i\n", length, strlen(outbuf));
 fwrite( outbuf,1, length, stdout );
  }

  //=20
 =20
 =20
 =20

chm_close(c);=20
 if (outbuf) free(outbuf);=20
  return  array;
} // end main=20

static void  usage(char *pname)
{
  fprintf(stderr, "Usage: %s chmfile outdir\n", pname);
}

// supporting libraries
#include "chmlib.c"=20
#include "lzx.c"



------------------------------

Date: Sat, 30 Jul 2005 11:29:46 +1000
From: "Sisyphus" <sisyphus1@nomail.afraid.org>
Subject: Re: How to return list from Inline::C code?
Message-Id: <42ead83b$0$15938$afc38c87@news.optusnet.com.au>


"kj" <socyl@987jk.com.invalid> wrote in message
news:dce677$blb$1@reader2.panix.com...
>
>
>
> I'm attempting to hack the Perl internals, something I know very
> little of.  So I apologize ahead of time for the cluelessness of
> this question.
>
> I want to implement a function via Inline::C such that, depending
> on context, it returns either a scalar or a list of two values.
> (This function will access the internals of other variables, and I
> want to make it as fast as possible, hence the decision to code it
> in C).
>
> Since C is not capable of optionally returning a scalar or a list,
> I don't even know where to begin with this.
>
> Any advice would be much appreciated.  In particular, I'd love to
> look at source code for a simple function (in C) that returns a
> scalar or a list according to calling context.
>

As William Ahern pointed out, GIMME_V seems to be your friend here:

D:\pscrpt\inline\special>type gimme_v.pl

use warnings;
use Inline C => Config =>
    BUILD_NOISY => 1;

use Inline C => <<'EOC';

void foo() {
     Inline_Stack_Vars;

     if(GIMME_V == G_SCALAR) {
       printf("%s\n", "return scalar");
       Inline_Stack_Reset;
       Inline_Stack_Push(sv_2mortal(newSViv(42)));
       Inline_Stack_Done;
       Inline_Stack_Return(1);
       }

     if(GIMME_V == G_ARRAY) {
       printf("%s\n", "return array");
       Inline_Stack_Reset;
       Inline_Stack_Push(sv_2mortal(newSViv(65537)));
       Inline_Stack_Push(sv_2mortal(newSViv(65539)));
       Inline_Stack_Done;
       Inline_Stack_Return(2);
       }

     if(GIMME_V == G_VOID) {
       printf("Nothing to do ... \n");
       Inline_Stack_Void;
       }

}



EOC

$x = foo();
print $x, "\n\n";

@y = foo();
print "@y\n\n";

foo();

__END__
D:\pscrpt\inline\special>perl gimme_v.pl
return scalar
42

return array
65537 65539

Nothing to do ...

Cheers,
Rob




------------------------------

Date: Sat, 30 Jul 2005 02:30:43 +0000 (UTC)
From: kj <socyl@987jk.com.invalid>
Subject: Re: How to return list from Inline::C code?
Message-Id: <dceooj$b79$1@reader2.panix.com>


Many thanks for all the replies!  I'm in business now.

kj

-- 
NOTE: In my address everything before the first period is backwards;
and the last period, and everything after it, should be discarded.


------------------------------

Date: Sat, 30 Jul 2005 09:42:21 +0100
From: "Bigus" <personage@myabode.com>
Subject: Re: Passing vars to a "require"d script
Message-Id: <42eb3d6c$0$91522$ed2e19e4@ptn-nntp-reader04.plus.net>


"Tad McClellan" <tadmc@augustmail.com> wrote in message 
news:slrndeknir.6b6.tadmc@magna.augustmail.com...
> Bigus <someone@somewhere.com> wrote:
>
>> If I call a separate script from within a CGI script using "require",
>
>
> Then we have entered the Twilight Zone, as what you describe
> is impossible.   :-)
>
> require does not "call" a "separate" program, it "includes" some
> code in the _current_ program.
>
> system(), exec(), backticks or a pipe-open is how truly "separate"
> programs are called from within Perl.

yes, that's what I thought, except I've always managed to get require to do 
the job I want in the cirumstances I've used it until now. I did actually 
try using backticks (though it's a pain having to convert all the forward 
slashes in paths into double back slashes (Windows)) however then the 
require'd script didn't seem to pull in the form data, which I assumed was 
because a system call doesn't maintain the CGI context?

>> is
>> there any (simple) way of passing a variable to it?
>
>
> Yes, but we should first address why you think that you need to do that.
>
> Why do you feel that you need to pass an argument to a require'd file?

Basically, I've got a set of server administration tools. Each tool is a 
separate .pl script (along with a html control form) that is knitted 
together into one web interface by a handler CGI (admin.cgi) script. 
admin.cgi deals with the login and generates a session ticket which I want 
to pass to the tool .pl that I'm requiring.

> Why not simply rewrite the .pl function to take a proper argument,
> and then supply the argument in the main program's function call?

Well, yeah, I could reengineer everything but that involves changing a fair 
few lines.

>> I've tried:
>>
>>     require "/admin/scripts/live/otherscript.pl?123"
>
>
> That indicates that you have an improper mental model of how things
> work. Correcting that will go a long way toward avoiding future 
> confusions.

yeah, you're probably quite correct ;) actually, the admin.cgi I mentioned 
also has an associated admin.pl which is purely a library of subs that I 
call from admin.cgi, and for that matter some of the tool .pl's, so that is 
presumably more like a correct model of usage?

> URL-like methods have no connection whatsoever to Perl, so your thinking
> that that question-mark thing would work indicates your model problem.

I didn't think that would work, but it was the only thing I could think of 
trying. I found an article on "our()" as you mention below, but I didn't 
manage to get it work (largely because the article didn't mention you have 
to also use our() in the receiving script aswell!).

[..]
> If you really really need to "pass" variables (I doubt that you do),
> you can do it thus:
>
> --------------------------
> use warnings;   # foo.pl
> use strict;
> our $foo;
> sub func1 { print $foo }
> 1;
> --------------------------
> #!/usr/bin/perl
> use warnings;  # main program
> use strict;
>
> our $foo = 'foobar';
> require 'foo.pl';
>
> func1();
> --------------------------

thanks.. I'll use that method for now!

Bigus




------------------------------

Date: Sat, 30 Jul 2005 09:44:27 +0100
From: "Bigus" <personage@myabode.com>
Subject: Re: Passing vars to a "require"d script
Message-Id: <42eb3dea$0$91525$ed2e19e4@ptn-nntp-reader04.plus.net>


"Klaus Eichner" <klaus_gb@yahoo.com> wrote in message 
news:42ea5707$0$5043$636a15ce@news.free.fr...
> "Bigus" <someone@somewhere.com> wrote in message
> news:dcdi7n$i4b$1@blackmamba.itd.rl.ac.uk...
>> If I call a separate script from within a CGI script using "require", is
>> there any (simple) way of passing a variable to it?
>>
>> I've tried:
>>
>>     require "/admin/scripts/live/otherscript.pl?123"
>>
>> and trying to pick it up via @ARGV but it comes up with an error saying 
>> it
>> can't find the script. In other words it seems to treat the "?123" as 
>> part
>> of the file name.
>
> You can always define your own variables with "our" to pass values, like:
>
> our @param = ('?', '123');
> require "/admin/scripts/live/otherscript.pl";
>
> Then, inside "/admin/scripts/live/otherscript.pl", you repeat the "our
> @param", but without the "= ('?', '123')". This allows you to access the
> variables inside the "otherscript.pl":
>
> our @param;
> print "\@param = (@param)\n";

thanks, that works nicely :)

I had read an article on our() but it didn't mention you had to use our() 
again in "receiving" script. I thought it must make it global to everything.

Bigus 




------------------------------

Date: Sat, 30 Jul 2005 03:10:06 GMT
From: "Ralph H. Stoos Jr." <rstoos@rochester.rr.com>
Subject: PERL vs. Ruby
Message-Id: <icCGe.616$0m1.326@twister.nyroc.rr.com>

All,

I have taken a company sponsored course in PERL taught by a fellow 
system engineer.  He tried his best but, I am still an old dog and 
well.. that new tricks thing seems to apply.

It seems that all courses I find assume you have other programming 
experience either in C, C++, or Java.  Since I have none of these 
skills, I am hoping to somehow pick up an OOP language.

So, I have folks recommending Ruby over PERL as a good language on which 
  to cut my coding teeth.

Any opinions on the subject would be appreciated.


Please reply to the newsgroup and also to  rstoos@rochester.rr.com so I 
can get it right away.  The next "intermediate" course starts in three 
days.  I will attend it regardless but, would like to know if this is 
the best way to go for my first foray into programming.

Thanks a lot,

Ralph


------------------------------

Date: Sat, 30 Jul 2005 07:52:55 +0200
From: "Tassilo v. Parseval" <tassilo.von.parseval@rwth-aachen.de>
Subject: Re: Timer/alarm clock module
Message-Id: <slrndem5dn.15o.tassilo.von.parseval@localhost.localdomain>

Also sprach Ignoramus27279:

> Is there some perl module for setting alarms? The use I have in mind
> is as follows:
>
> my $times = new AlarmModule( 600, sub { print "Hello" } );
>
> that would make the timer wake up every 600 seconds and print hello.
>
> Any suggestions?

You could use Event::Lib although it might be a bit oversized for that
kind of task:

    use Event::Lib;
    
    $| = 1;
    
    my $timer = timer_new(
	sub { 
	    my $event = shift;
	    print "Hello";
	    $event->add(600); # re-schedule
	}
    );
    $timer->add(600);
    $timer->dispatch;

Tassilo
-- 
use bigint;
$n=71423350343770280161397026330337371139054411854220053437565440;
$m=-8,;;$_=$n&(0xff)<<$m,,$_>>=$m,,print+chr,,while(($m+=8)<=200);


------------------------------

Date: Fri, 29 Jul 2005 23:04:12 -0400
From: "John W. Kennedy" <jwkenne@attglobal.net>
Subject: Re: true false ? : expression thingy
Message-Id: <71CGe.2716$7Q1.1993@fe09.lga>

Ian Wilson wrote:
> Bigus wrote:
> 
>> when you want a
>> 1-line alternative to an if...else.. construct,
> 
> 
> Whilst I quite like
>   $this = condition ? "foo" : "bar";
> 
> What's so horrible about
>   if (condition) {$this="foo";} else {$this="bar"}
> which I find quite readable?

For one thing, you can't use it as an alternative to:

    my $this = condition ? "foo" : "bar";

And it is more economical in a case like:

    $x[$i + $j - 1] = condition ? "foo" : "bar";

-- 
John W. Kennedy
"I want everybody to be smart. As smart as they can be. A world of 
ignorant people is too dangerous to live in."
   -- Garson Kanin. "Born Yesterday"


------------------------------

Date: Sat, 30 Jul 2005 06:12:36 GMT
From: "John W. Krahn" <someone@example.com>
Subject: Re: true false ? : expression thingy
Message-Id: <oTEGe.162969$9A2.73587@edtnps89>

John W. Kennedy wrote:
> Ian Wilson wrote:
>> Bigus wrote:
>>
>>> when you want a
>>> 1-line alternative to an if...else.. construct,
>>
>>
>> Whilst I quite like
>>   $this = condition ? "foo" : "bar";
>>
>> What's so horrible about
>>   if (condition) {$this="foo";} else {$this="bar"}
>> which I find quite readable?
> 
> For one thing, you can't use it as an alternative to:
> 
>    my $this = condition ? "foo" : "bar";
> 
> And it is more economical in a case like:
> 
>    $x[$i + $j - 1] = condition ? "foo" : "bar";

And don't forget you can use it as an lvalue as in:

    ( condition ? $foo : $bar ) = $this;

Or:

    push @{ condition ? \@foo : \@bar }, $this;



John
-- 
use Perl;
program
fulfillment


------------------------------

Date: Sat, 30 Jul 2005 07:36:31 +0000 (UTC)
From: kj <socyl@987jk.com.invalid>
Subject: Where are Inline_Stack_Vars, etc. defined?
Message-Id: <dcfalv$7l0$1@reader2.panix.com>




I'm trying to translate fragments snatched from pp.c into Inline::C
functions.  These fragments use stack-manipulation macros such as
PUTBACK and SPAGAIN.  I'm having a hard time figuring out how to
translate these macros into code that will play well with Inline's
stack manipulation macros.  It would be very helpful for me to see
how the Inline::C macros are defined, but I can't find these
definitions.

Thanks!

kj

-- 
NOTE: In my address everything before the first period is backwards;
and the last period, and everything after it, should be discarded.


------------------------------

Date: Sat, 30 Jul 2005 19:20:50 +1000
From: "Sisyphus" <sisyphus1@nomail.afraid.org>
Subject: Re: Where are Inline_Stack_Vars, etc. defined?
Message-Id: <42eb46a1$0$25201$afc38c87@news.optusnet.com.au>


"kj" <socyl@987jk.com.invalid> wrote in message
news:dcfalv$7l0$1@reader2.panix.com...
>
>
>
> I'm trying to translate fragments snatched from pp.c into Inline::C
> functions.  These fragments use stack-manipulation macros such as
> PUTBACK and SPAGAIN.  I'm having a hard time figuring out how to
> translate these macros into code that will play well with Inline's
> stack manipulation macros.  It would be very helpful for me to see
> how the Inline::C macros are defined, but I can't find these
> definitions.
>
> Thanks!
>

It's all done in Inline.h which gets created whenever you run an Inline::C
script. If you run your Inline::C script with the Config option
CLEAN_AFTER_BUILD => 0 then you'll be able to go into the build directory
and find Inline.h.  (Without that option the build directory gets cleaned up
after the script has successfully compiled.)

Anyway, to save you the trouble, here's what Inline.h looks like:

#define Inline_Stack_Vars dXSARGS
#define Inline_Stack_Items items
#define Inline_Stack_Item(x) ST(x)
#define Inline_Stack_Reset sp = mark
#define Inline_Stack_Push(x) XPUSHs(x)
#define Inline_Stack_Done PUTBACK
#define Inline_Stack_Return(x) XSRETURN(x)
#define Inline_Stack_Void XSRETURN(0)

#define INLINE_STACK_VARS Inline_Stack_Vars
#define INLINE_STACK_ITEMS Inline_Stack_Items
#define INLINE_STACK_ITEM(x) Inline_Stack_Item(x)
#define INLINE_STACK_RESET Inline_Stack_Reset
#define INLINE_STACK_PUSH(x) Inline_Stack_Push(x)
#define INLINE_STACK_DONE Inline_Stack_Done
#define INLINE_STACK_RETURN(x) Inline_Stack_Return(x)
#define INLINE_STACK_VOID Inline_Stack_Void

#define inline_stack_vars Inline_Stack_Vars
#define inline_stack_items Inline_Stack_Items
#define inline_stack_item(x) Inline_Stack_Item(x)
#define inline_stack_reset Inline_Stack_Reset
#define inline_stack_push(x) Inline_Stack_Push(x)
#define inline_stack_done Inline_Stack_Done
#define inline_stack_return(x) Inline_Stack_Return(x)
#define inline_stack_void Inline_Stack_Void

I don't exactly know why those macros were created. Seems to me that one
might just as well use 'dXSARGS',  'items',  'ST(x)',  'sp = mark',
'xPUSHs(x)',  'PUTBACK', 'XSRETURN(x), and 'XSRETURN(0)' instead of the
synonyms provided by Inline.h.

Cheers,
Rob





------------------------------

Date: Fri, 29 Jul 2005 19:55:35 -0700
From: fishfry <BLOCKSPAMfishfry@your-mailbox.com>
Subject: Where to ask mysql questions?
Message-Id: <BLOCKSPAMfishfry-1C4C7F.19553529072005@comcast.dca.giganews.com>

I couldn't find a mysql newsgroup. Where is the appropriate place to ask 
mysql questions that aren't Perl-related?


------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc.  For subscription or unsubscription requests, send
#the single line:
#
#	subscribe perl-users
#or:
#	unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.  

NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice. 

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.

#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V10 Issue 8292
***************************************


home help back first fref pref prev next nref lref last post