in reply to Re^4: XS/Inline::C concat *any* two SVs.
in thread XS/Inline::C concat *any* two SVs.

You're getting the undef warning via the SvPV_nolen macro. If you change that to use sv_setpvn you won't get that anymore. This...
if (!SvOK(sv)) sv_setpvn(sv, "", 0);

... is the XS equivalent of this...

$sv = "" unless defined $sv;
--
Marvin Humphrey
Rectangular Research ― http://www.rectangular.com

Replies are listed 'Best First'.
Re^6: XS/Inline::C concat *any* two SVs.
by BrowserUk (Patriarch) on May 30, 2006 at 17:53 UTC

    Once again thankyou. That does greatly simplify the code and produce the desired results:

    SV* test( SV *a, SV *b ) { if( SvREADONLY( a ) ) a = newSVpv( SvPVX( a ), 0 ); else SvREFCNT_inc( a ); if( !SvOK( a ) ) sv_setpvn( a, "", 0 ); sv_catsv( a, b ); return a; } ... __END__ c:\test>test billfred fred billfred 1fred 1fred1

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      All this emphasis on "*any*" yet you don't care about strings containing "\0" characters (if read-only), tied scalars, nor magic scalars. I'm also curious if SvPVX() can yield you some pointers to interesting things, not strings, for some kinds of scalars, but not enough to try to review the space of all possible scalar types.

      - tye        

        I do care. To quote from the OP.

        What else should I be catering for? (Preferably with hints on how to detect and handle it :).

        And from another post later in the thread:

        Dealing with scalars that might be NVs, IVs, UVs and readonly is only the first part of the exercise. There are also RVs, tied scalars, blessed scalars etc. When I posted, I was hoping for insights into dealing with these also. I never expected to get hung up on dealing with readonly inputs.

        I'm also curious if SvPVX() can yield you some pointers to interesting things, ...

        I think I may be misunderstanding you? I look up SvPVX() and found

        #define SvPVX(sv) ((XPV*) SvANY(sv))->xpv_pv

        And SvANY() is

        #define SvANY(sv) (sv)->sv_any

        Which doesn't clarify much?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        sv_catsv handles "get magic", so overloaded strings shouldn't be a problem. It doesn't handle "set magic", though, so if the first scalar is tied and it does something funny with STORE -- like store an uppercased version of the input -- that won't happen.

        #!/usr/bin/perl package TiedScalar; use strict; use warnings; use base qw( Tie::Scalar ); sub TIESCALAR { my ( $classname, $initial_value ) = @_; return bless \$initial_value, __PACKAGE__; } sub FETCH { return ${ +shift } } sub STORE { my ($self, $value) = @_; $$self = uc($value); } package main; use strict; use warnings; use Inline C => << '__C__', NAME => 'test', CLEAN_AFTER_BUILD => 0; #include <stdio.h> SV* test( SV *a, SV *b ) { if( SvREADONLY( a ) ) a = newSVpv( SvPVX( a ), 0 ); else SvREFCNT_inc( a ); if( !SvOK( a ) ) sv_setpvn( a, "", 0 ); sv_catsv( a, b ); return a; } __C__ my ( $q, $p ); tie $q, 'TiedScalar', "bill"; tie $p, 'TiedScalar', "fred"; print test( $q, $p ) . "\n"; $q .= $p; print "$q\n";

        As for the exotic values via SvPVX, I can't think of an example that would cause any more problems than say, packed ints.

        As for nulls in read-only scalars, I would think sv_catsv would handle that case, no?

        --
        Marvin Humphrey
        Rectangular Research ― http://www.rectangular.com