[21904] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 4108 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Tue Nov 12 18:16:35 2002

Date: Tue, 12 Nov 2002 15:15:19 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Tue, 12 Nov 2002     Volume: 10 Number: 4108

Today's topics:
    Re: Pls recommend me a good Perl programming environmen <reggie_nospam@reggieband.com>
    Re: Question on -B (Walter Roberson)
    Re: Question on -B <rdsmith@sedona.intel.com>
        regexp question <reggie_nospam@reggieband.com>
    Re: regexp question <pinyaj@rpi.edu>
        Socket client/server example not working on Windows 2K (John Ramsden)
    Re: some help with a print statement requested - double <holland@origo.phys.au.dk>
    Re: some help with a print statement requested - double (Tad McClellan)
        some help with a print statement requested - double quo <no_spam@no_spam.com>
    Re: some help with a print statement requested - double <no_spam@no_spam.com>
    Re: Windows and nonblocking IO <goldbb2@earthlink.net>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Tue, 12 Nov 2002 20:20:06 GMT
From: "reggie" <reggie_nospam@reggieband.com>
Subject: Re: Pls recommend me a good Perl programming environment
Message-Id: <WndA9.809236$Ag2.27356925@news2.calgary.shaw.ca>

"Peter Wu" <peterwu@hotmail.com> wrote in message
news:9acc2ac1.0211101952.7acfe2@posting.google.com...
> Can anyone pls recommend me a good Perl programming environment? I
> would like to develop in Perl on Win32 platform and test the program
> on FreeBSD environment.
>
> Any suggestion is appreciated! Thanks!


I like Komodo for an IDE (Win32)

http://www.activestate.com/


regards,
reggie




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

Date: 12 Nov 2002 19:14:29 GMT
From: roberson@ibd.nrc.ca (Walter Roberson)
Subject: Re: Question on -B
Message-Id: <aqrjul$6gu$1@canopus.cc.umanitoba.ca>

In article <3DD14CE9.887CF8A2@sedona.intel.com>,
Ron Smith  <rdsmith@sedona.intel.com> wrote:
:I am working on a file scanning script where I would like to scan
:text-like files, avoiding binary files.  It needs to be
:relatively quick, and it needs to support files that have been gzipped.

:I'd like a quick and *efficient* way to do an "accurate" -B test,
:regardless of whether or not the file is currently gzipped.  (By
:*efficient*, it should be assumed that I do not intend to gunzip the
:file, just to make the test.)

How do you define whether a file is "binary" or text-like? Can
"text-like files":

- contain ^H   (e.g., man FOO > FILE  instead of  man FOO | ul -Tdumb > FILE)
- contain ^G   (e.g., some people put them in /etc/motd)
- contain ^M   ('script')
- contain ^Q and ^S and perhaps escape   (capture of a terminal session)
- contain nulls  (NFS/locking related problems can inject nulls)
- contain small amounts of arbitrary binary (VMS files, Fortran unformatted
- contain ISO9660-1 characters that have the high-bit set
                 output)
- contain unicode
- contain practically anything as long as the first 512 characters
  are "text-like"


I am reminded of the famous 'polyglot' program, which was text
source code that would output "Hello polyglots" when compiled/run
as sh, C, Fortran, a few other languages -- or as a DOS program.
Humans would see it as being pure text, but to DOS it was a binary.


I have seen CVS archives that contained a couple of megabytes of
human-readable text, followed by many megabytes of binary. If you want
to be able to "accurately" classify files as binary, then you have to
be prepared to read the whole file.
--
If a troll and a half can hook a reader and a half in a posting and a half, 
how many readers can six trolls hook in six postings?


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

Date: Tue, 12 Nov 2002 14:54:08 -0700
From: Ron Smith <rdsmith@sedona.intel.com>
Subject: Re: Question on -B
Message-Id: <3DD17880.B26AC3D3@sedona.intel.com>

Walter Roberson wrote:
> 
> In article <3DD14CE9.887CF8A2@sedona.intel.com>,
> Ron Smith  <rdsmith@sedona.intel.com> wrote:
> :I am working on a file scanning script where I would like to scan
> :text-like files, avoiding binary files.  It needs to be
> :relatively quick, and it needs to support files that have been gzipped.
> 
> :I'd like a quick and *efficient* way to do an "accurate" -B test,
> :regardless of whether or not the file is currently gzipped.  (By
> :*efficient*, it should be assumed that I do not intend to gunzip the
> :file, just to make the test.)
> 
> How do you define whether a file is "binary" or text-like?

I'm happy with the perl definition ala -B.  While I appreciate some of
the subtlties you mention below, none of them matter much for the kinds
of files I'm actually going to scan.

            The `-T' and `-B' switches work as follows. The first block
or
            so of the file is examined for odd characters such as
strange
            control codes or characters with the high bit set. If too
many
            odd characters (>30%) are found, it's a `-B' file, otherwise
            it's a `-T' file. Also, any file containing null in the
first
            block is considered a binary file. If `-T' or `-B' is used
on
            a filehandle, the current stdio buffer is examined rather
than
            the first block. Both `-T' and `-B' return TRUE on a null
            file, or a file at EOF when testing a filehandle. Because
you
            have to read a file to do the `-T' test, on most occasions
you
            want to use a `-f' against the file first, as in `next
unless
            -f $file && -T $file'.

> Can "text-like files":
> 
> - contain ^H   (e.g., man FOO > FILE  instead of  man FOO | ul -Tdumb > FILE)
> - contain ^G   (e.g., some people put them in /etc/motd)
> - contain ^M   ('script')
> - contain ^Q and ^S and perhaps escape   (capture of a terminal session)
> - contain nulls  (NFS/locking related problems can inject nulls)
> - contain small amounts of arbitrary binary (VMS files, Fortran unformatted
> - contain ISO9660-1 characters that have the high-bit set
>                  output)
> - contain unicode
> - contain practically anything as long as the first 512 characters
>   are "text-like"
> 
> I am reminded of the famous 'polyglot' program, which was text
> source code that would output "Hello polyglots" when compiled/run
> as sh, C, Fortran, a few other languages -- or as a DOS program.
> Humans would see it as being pure text, but to DOS it was a binary.
> 
> I have seen CVS archives that contained a couple of megabytes of
> human-readable text, followed by many megabytes of binary. If you want
> to be able to "accurately" classify files as binary, then you have to
> be prepared to read the whole file.
> --
> If a troll and a half can hook a reader and a half in a posting and a half,
> how many readers can six trolls hook in six postings?


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

Date: Tue, 12 Nov 2002 20:58:18 GMT
From: "reggie" <reggie_nospam@reggieband.com>
Subject: regexp question
Message-Id: <KXdA9.809262$Ag2.27359019@news2.calgary.shaw.ca>

This one feels easy, but has eluded me.

Given the string:

$text = "Apples are good
food and great
Bananas are yellow
Oranges are
juicy";

I'm trying to grab everything including (apples|oranges|bananas) up to but
excluding the next (apples|oranges|bananas).  So for the above string I end
up with:

@arr = (
    0 => "Apples are good\nfood and great"
    1 => "Bananas are yello"
    2 => "Oranges are\njuict"
)

The terms banana, orange and apple will only ever occur at the beginning of
a line.

So far I've found this to work:

#!usr/bin/perl -w

use strict;

my $text = "Apples are good
food and great
Bananas are yellow
Oranges are
juicy";

my @lines = split /\n/i, $text;

my @result;
for (my $i=0; $i<@lines; $i++){
    if ($lines[$i] =~ /^(apples|oranges|bananas)/i) {
        push @result, $lines[$i];
    } else {
        $result[-1] .= "\n" . $lines[$i];
    }
}

for (@result) {
 print "|";print;print "|";
 print "\n";
}

It splits on newlines then tests each line to see if it begins with the
keyword.  If so, add to result array.  If not, append to last index in
reslult array.

But if feels like it could be much better.  Ideally i'd like to handle this
in one regexp.

Any suggestions?

regards,
reggie.




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

Date: Tue, 12 Nov 2002 17:07:40 -0500
From: Jeff 'japhy' Pinyan <pinyaj@rpi.edu>
To: reggie <reggie@reggieband.com>
Subject: Re: regexp question
Message-Id: <Pine.A41.3.96.1021112165856.53628A-100000@vcmr-104.server.rpi.edu>

[posted & mailed]

On Tue, 12 Nov 2002, reggie wrote:

>$text = "Apples are good
>food and great
>Bananas are yellow
>Oranges are
>juicy";

>@arr = (
>    0 => "Apples are good\nfood and great"
>    1 => "Bananas are yello"
>    2 => "Oranges are\njuict"
>)
>
>The terms banana, orange and apple will only ever occur at the beginning of
>a line.

I would use split() for this, then...

  @arr = split /\n(?=apple|banana|orange)/i, $text;

What this means is "split on a newline that is followed by 'apple',
'banana', or 'orange', case insensitively".

>my @lines = split /\n/i, $text;

That /i is doing you no good here.

>my @result;
>for (my $i=0; $i<@lines; $i++){

That's a C loop.  Use a Perl loop.

>    if ($lines[$i] =~ /^(apples|oranges|bananas)/i) {
>        push @result, $lines[$i];
>    } else {
>        $result[-1] .= "\n" . $lines[$i];
>    }
>}

  my @result;
  for (@lines) {
    if (/^(apple|orange|banana)/i) { push @result, $_ }
    else { $result[-1] .= "\n$_" }
  }

>But if feels like it could be much better.  Ideally i'd like to handle this
>in one regexp.

If you don't want split(), you could do it with:

  my @result = $text =~ m{
    ^                                   # start of a 'line'
    (?: apple | orange | banana )       # one of these words
    .*                                  # the rest of the line
    (?:                                 # this chunk...
      \n                                # a newline
      (?! apple | orange | banana ) .*  # text that doesn't start with
                                        # any of those words
    )*                                  # ...zero or more times
  }gmix;

The /g modifier returns all the matches, the /m modifier makes ^ match at
the beginning of a "line" (thus, at the start of a string, or after a \n),
the /i modifier invokes case-insensitivity, and the /x allows me to have
whitespace and comments like that.

But that's obtuse.  Use my split() example instead of that regex.

-- 
Jeff "japhy" Pinyan      RPI Acacia Brother #734      2002 Acacia Senior Dean
"And I vos head of Gestapo for ten     | Michael Palin (as Heinrich Bimmler)
 years.  Ah!  Five years!  Nein!  No!  | in: The North Minehead Bye-Election
 Oh.  Was NOT head of Gestapo AT ALL!" | (Monty Python's Flying Circus)



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

Date: 12 Nov 2002 11:23:27 -0800
From: john_ramsden@sagitta-ps.com (John Ramsden)
Subject: Socket client/server example not working on Windows 2K
Message-Id: <d27434e.0211121123.4f53c4c6@posting.google.com>

I prepared a short pair of prototype socket client-server
programs, planning to expand them into what is required
for a project I am engaged on at work.

Initially, to test the mechanism, the client just prompts for
a text line, sents it to the server, which displays it and
returns a reply.

On Unix (SunOS) everything works fine with one or more clients
each with a TCP socket connection to the server at once, which
is the intention.

On Windows 2K (using ActiveState Perl v5.6.1 build 631,
MSWin32-x86-multi-thread) the pair work fine with a single
client; but if _two_ clients are started then the server
displays all output from the first client immediately, 
but buffers all output for the second client (and only
displays this when the first client disconnects).

These symptoms may be enough for a guru to know what is
going on. But in case not, or anyone spots any obvious
howlers, or risky /sub-optimal features, in my code this
follows below. (It isn't too long.)

(and yes, I have studied the 'perlipc' man page as best
I can..)

Anyway, I'd be grateful if anyone finds time to to help.


Cheers

John Ramsden  (john_ramsden@sagitta-ps.com)


SERVER:

   use strict;

   use Socket;

   use FileHandle;

   use vars qw
   {
     $wdlog
     $wdport
   };

sub logmsg
{
   my $text = shift;

   open LOG, '>>', $wdlog
     or die "open ('$wdlog', '>>') failed: $!";

   print LOG "$text\n";

   close LOG
     or die "open ('$wdlog', '>>') failed: $!";
}


   STDOUT-> autoflush (1);

   $wdlog = "fred.log";

   $wdport = 9002;                  # hard-coded for now

   my $proto = getprotobyname ('tcp');

   socket (SOCKGEN, PF_INET, SOCK_STREAM, $proto)
     or die "socket: $!";

   setsockopt (SOCKGEN, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) # 'l' is "ell"
     or die "setsockopt: $!";

   bind (SOCKGEN, sockaddr_in ($wdport, INADDR_ANY))   
     or die "bind: $!";

   listen (SOCKGEN, SOMAXCONN)
     or die "listen: $!";

  # multi-threaded server forks off a child version for each incoming request.
  #
   my $paddr;

   my $waitedpid = 0;

   sub REAPER
   {
      $waitedpid = wait;

     # The following line reinstates the signal handler. This is not
     # needed for BSD and POSIX Unix, but may be needed for SysV Unix.
     #
      $SIG{CHLD} = \&REAPER;    # if sigaction(2) is not available
   }

   $SIG{CHLD} = \&REAPER;

  # We assume we are running on a system with non-restartable system
  # calls, and in this case we must use a for-loop that seems slightly
  # more elaborate than necessary, because the act of collecting the
  # zombie child process may cause the accept() call to abort and
  # return _undef_, which in turn aborts the for-loop.
  #
   my $sockclt;

   for ( $waitedpid = 0; 
          ($paddr = accept ($sockclt, SOCKGEN)) or $waitedpid;
            $waitedpid = 0, close $sockclt)
   {
      next if $waitedpid and not $paddr;    # or check $! == EINTR

      my ($cl_port, $iaddr) = sockaddr_in ($paddr);

      my $cl_name = gethostbyaddr ($iaddr, AF_INET);

      my $cl_host = inet_ntoa ($iaddr);

      my $client  = "$cl_name [$cl_host] : $cl_port";

      logmsg "connection from $client";

      my $pid = undef;
 
      if (!defined ($pid = fork))
      {
         logmsg  "cannot fork: $!";

         close $sockclt;
      }

      elsif ($pid)      # in parent
      {

         logmsg "begat $pid";
      }

      else              # in child
      {
         binmode $sockclt;
        
         $sockclt->autoflush (1);

         print "$client connected\n";

         my $line = '';

         while (defined ($line = <$sockclt>))
         {
            chomp $line;

            print "$client sent '$line'\n";

            print $sockclt "got '$line'\n";
         }

         print "$client disconnected\n";

         close $sockclt;
 
         exit;
      }
   }



CLIENT:

   use strict;

   use Socket;

   use FileHandle;

   use vars qw
   {
     $wdlog
     $wdport
   };

   my $naddr = 'localhost';

   my $iaddr = gethostbyname ($naddr)
     or die "gethostbyname ('$naddr') failed: $!";

   my $nproto = 'tcp';

   my $iproto = getprotobyname ($nproto)
     or die "getprotobyname ('$nproto') failed: $!";

   $wdport  = 9002;   # hard-coded for now

   if ($wdport =~ /\D/)  # first character not a digit, e.g. 'watchdog'
   {
      $wdport  =  getservbyname ($wdport, $nproto)
        or die "getservbyname ('$wdport', '$nproto') failed: $!";
   }

   my $paddr = sockaddr_in ($wdport, $iaddr);

   socket (SOCKET, PF_INET, SOCK_STREAM, $iproto)
     or die "socket: $!";

   connect (SOCKET, $paddr)
     or die "connect: $!";

   binmode SOCKET;

   SOCKET->autoflush (1);

   my $line;

   while (1)

   {
      print "type a line: ";

      $line = <STDIN>;

      chomp $line;

      last if ($line =~ /[QqXx]/);

      print "sending server '$line'\n";

      print SOCKET "$line\n";

      $line = <SOCKET>;

      chomp $line;

      print "server replied: '$line'\n";
   }

   close SOCKET
     or die "close (socket) failed: $!";

   exit;


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

Date: 12 Nov 2002 21:32:41 +0100
From: Steve Holland <holland@origo.phys.au.dk>
Subject: Re: some help with a print statement requested - double quotes giving  me trouble!
Message-Id: <w47u1imzfyu.fsf@origo.phys.au.dk>

Paul Spitalny <no_spam@no_spam.com> writes:


> I am trying to print a line and I want quotation marks in the output 
> line. The exact output line I want to print, to the output file, is:
> 
> 	.options probefilename="output.dat"
> 
> I tried to print the line using the following perl code:
> 
> 	print TEMP ".options probefilename="output.dat"\n";
> 
> But,this does not work.
> 
> I can successfully do the following:
> 
> 	print TEMP ".options probefilename='output.dat'\n";
> 
> But, although this will execute, the single quote is not what I want.
> I surmise that the double quotes are confusing the print statement. How 
> can I get around this problem??

     You need to escape the double quotes inside the string that you
wish to print.  In other words, use \" instead of " inside the string.
Here is an example, with less than perfect error checking.

#! /usr/local/bin/perl

use strict;
use warnings;

open(TEMP,">ttt.tmp") || die "$0: unable to open ttt.tmp for writing, $!";
print TEMP ".options probefilename=\"output.dat\"\n";
close(TEMP) || warn "$0: unable to close ttt.tmp, $!";    

=====================================================================
               To find out who and where I am look at:
               http://www.nd.edu/~sholland/index.html
           "An eagle can not fly with a broken left wing."
=====================================================================


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

Date: Tue, 12 Nov 2002 15:46:22 -0600
From: tadmc@augustmail.com (Tad McClellan)
Subject: Re: some help with a print statement requested - double quotes giving  me trouble!
Message-Id: <slrnat2tle.4fq.tadmc@magna.augustmail.com>

Steve Holland <holland@origo.phys.au.dk> wrote:
> Paul Spitalny <no_spam@no_spam.com> writes:
> 
>> I am trying to print a line and I want quotation marks in the output 

>> I surmise that the double quotes are confusing the print statement. How 
>> can I get around this problem??
> 
>      You need to escape the double quotes inside the string that you
> wish to print. 


Or, just use a delimiter other than double quotes for
your double-quoted string:

   print TEMP qq(.options probefilename="output.dat"\n);
or
   print TEMP qq/.options probefilename="output.dat"\n/;


It is easier to see what your output is when you do not have
to mentally filter out all (errr, most) of the backslashes.


-- 
    Tad McClellan                          SGML consulting
    tadmc@augustmail.com                   Perl programming
    Fort Worth, Texas


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

Date: Tue, 12 Nov 2002 11:59:32 -0800
From: Paul Spitalny <no_spam@no_spam.com>
Subject: some help with a print statement requested - double quotes giving me trouble!
Message-Id: <3DD15DA4.4060704@no_spam.com>

Hi,
I am trying to print a line and I want quotation marks in the output 
line. The exact output line I want to print, to the output file, is:

	.options probefilename="output.dat"

I tried to print the line using the following perl code:

	print TEMP ".options probefilename="output.dat"\n";

But,this does not work.

I can successfully do the following:

	print TEMP ".options probefilename='output.dat'\n";

But, although this will execute, the single quote is not what I want.
I surmise that the double quotes are confusing the print statement. How 
can I get around this problem??

Thanks,

Paul



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

Date: Tue, 12 Nov 2002 12:43:58 -0800
From: Paul Spitalny <no_spam@no_spam.com>
Subject: Re: some help with a print statement requested - double quotes giving me trouble!
Message-Id: <3DD1680E.1040400@no_spam.com>

Steve Holland wrote:
> Paul Spitalny <no_spam@no_spam.com> writes:
> 
> 
> 
>>I am trying to print a line and I want quotation marks in the output 
>>line. The exact output line I want to print, to the output file, is:
>>
>>	.options probefilename="output.dat"
>>
>>I tried to print the line using the following perl code:
>>
>>	print TEMP ".options probefilename="output.dat"\n";
>>
>>But,this does not work.
>>
>>I can successfully do the following:
>>
>>	print TEMP ".options probefilename='output.dat'\n";
>>
>>But, although this will execute, the single quote is not what I want.
>>I surmise that the double quotes are confusing the print statement. How 
>>can I get around this problem??
> 
> 
>      You need to escape the double quotes inside the string that you
> wish to print.  In other words, use \" instead of " inside the string.
> Here is an example, with less than perfect error checking.
> 
> #! /usr/local/bin/perl
> 
> use strict;
> use warnings;
> 
> open(TEMP,">ttt.tmp") || die "$0: unable to open ttt.tmp for writing, $!";
> print TEMP ".options probefilename=\"output.dat\"\n";
> close(TEMP) || warn "$0: unable to close ttt.tmp, $!";    
> 
> =====================================================================
>                To find out who and where I am look at:
>                http://www.nd.edu/~sholland/index.html
>            "An eagle can not fly with a broken left wing."
> =====================================================================

Hi Steve,
Thanks, that did the trick!

Much appreciated!

Paul





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

Date: Tue, 12 Nov 2002 14:58:50 -0500
From: Benjamin Goldberg <goldbb2@earthlink.net>
Subject: Re: Windows and nonblocking IO
Message-Id: <3DD15D7A.F96094@earthlink.net>

edgue@web.de wrote:
> 
> Hi,
> 
> > It's never been true -- as long as you didn't try and use pipes for
> > that communication.  For example, you could create a socket for the
> > purpose.
> 
> I tried that (with the piece of code that you posted here some
> month ago.
> 
> The "unblocking" seems to work (with Perl 561) - but no output
> is produces.

Does the program hang, or exit cleanly without printing anything?

If it hangs, where does it hang?

If it exits without printing anything... it shouldn't be able to do
that.  For each port, it should either give you "Error reaching port" or
else print that it's reachable.  Add a bunch of diagnostic print
statements all over the place.

> With Perl 5.8 it tells me "Couldn't set nonblocking:"
> right away.

With nothing in $^E or $! ?  How strange.  Try changing the die
statement to:
   die sprintf "Couldn't set nonblocking:\n" .
               "\t\$! = %d %s\n\t\$^E = %d %s\n\t", $!, $!, $^E, $^E;

-- 
my $n = 2; print +(split //, 'e,4c3H r ktulrnsJ2tPaeh'
 ."\n1oa! er")[map $n = ($n * 24 + 30) % 31, (42) x 26]


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

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.  

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 4108
***************************************


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