Skip to content

Commit

Permalink
[config] probe for 2 more environ features
Browse files Browse the repository at this point in the history
esp. '_putenv_s' and 'environ' for msvc.
not for the wide _wputenv_s(). we assume it is there
if putenv_s is there also.
  • Loading branch information
Reini Urban committed Jan 26, 2015
1 parent 8f90d48 commit b9a257f
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 39 deletions.
77 changes: 40 additions & 37 deletions config/auto/env.pm
@@ -1,12 +1,12 @@
# Copyright (C) 2001-2009, Parrot Foundation.
# Copyright (C) 2001-2015, Parrot Foundation.

=head1 NAME
config/auto/env.pm - System Environment
config/auto/env.pm - Probe get/setenv functions
=head1 DESCRIPTION
Determining if the C library has C<setenv()> and C<unsetenv()>.
Determining if the C library has C<setenv()>, C<putenv_s()>, C<unsetenv()> and C<environ>.
More information about these functions can be found at
L<http://www.gnu.org/software/libc/manual/html_node/Environment-Access.html>,
Expand All @@ -26,56 +26,59 @@ use Parrot::Configure::Utils ':auto';
sub _init {
my $self = shift;
my %data;
$data{description} = q{Does your C library have setenv / unsetenv};
$data{description} = q{Probe for C library *env functions};
$data{result} = q{};
return \%data;
}

sub runstep {
my ( $self, $conf ) = ( shift, shift );

my ( $setenv, $unsetenv ) = ( 0, 0 );

$conf->cc_gen('config/auto/env/test_setenv_c.in');
eval { $conf->cc_build(); };
unless ( $@ || $conf->cc_run() !~ /ok/ ) {
$setenv = 1;
}
$conf->cc_clean();
$conf->cc_gen('config/auto/env/test_unsetenv_c.in');
eval { $conf->cc_build(); };
unless ( $@ || $conf->cc_run() !~ /ok/ ) {
$unsetenv = 1;
my @probes = qw(setenv unsetenv putenv_s environ);
my $args = {};

for my $f (@probes) {
$args->{$f} = 0;
$conf->cc_gen("config/auto/env/test_${f}_c.in");
eval { $conf->cc_build(); };
unless ( $@ || $conf->cc_run() !~ /ok/ ) {
$args->{$f} = 1;
}
$conf->cc_clean();
}
$conf->cc_clean();

$self->_evaluate_env($conf, $setenv, $unsetenv);

$self->_evaluate_env($conf, $args);
return 1;
}

sub _evaluate_env {
my ($self, $conf, $setenv, $unsetenv) = @_;
$conf->data->set(
setenv => $setenv,
unsetenv => $unsetenv
);

if ( $setenv && $unsetenv ) {
$conf->debug(" (both) ");
$self->set_result('both');
my ($self, $conf, $args) = @_;
$conf->data->set( %$args );
my $result = 0;
my $string = '';

my @probes = sort keys %$args;
for my $f (@probes) {
$conf->debug(" $f => $args->{$f} ");
$result++ if $args->{$f};
$string .= "$f," if $args->{$f};
}
elsif ($setenv) {
$conf->debug(" (setenv) ");
$self->set_result('setenv');
$string = substr($string,0,-1) if $string;

if ($result == @probes) {
$conf->debug(" (all) ");
$self->set_result('all');
}
elsif ($unsetenv) {
$conf->debug(" (unsetenv) ");
$self->set_result('unsetenv');
elsif ($result > 0) {
# only win32 + msvc is supposed to support _putenv_s
if ($^O ne 'MSWin32' and $string eq 'environ,setenv,unsetenv') {
$self->set_result('all');
} else {
$self->set_result($string);
}
}
else {
$conf->debug(" (no) ");
$self->set_result('no');
$conf->debug(" (no) ");
$self->set_result('no');
}
}

Expand Down
45 changes: 45 additions & 0 deletions config/auto/env/test_environ_c.in
@@ -0,0 +1,45 @@
/*
Copyright (C) 2003-2015, Parrot Foundation.

test for environ
*/

#include <stdio.h>
#include <stdlib.h>

/* array of environment variables,
speced in POSIX.1, but not in ISO-C
MS C compilers know about environ, as it is declared in stdlib.h.
OS X doesn't allow access to "environ" from within shared libraries.
*/
#ifndef WIN32
# ifdef __APPLE_CC__
# include <crt_externs.h>
# define environ (*_NSGetEnviron())
# else /* !__APPLE_CC__ */
extern char **environ;
# endif /* __APPLE_CC__ */
#endif /* !WIN32 */

int main(int argc, char **argv)
{

int rv = 0;
while (environ[rv] != NULL)
++rv;

if (rv) {
puts("ok");
}
else {
puts("borken");
}
return 0;
}

/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/
27 changes: 27 additions & 0 deletions config/auto/env/test_putenv_s_c.in
@@ -0,0 +1,27 @@
/*
Copyright (C) 2003-2015, Parrot Foundation.

test for putenv_s
*/

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
if (_putenv_s("PARROT_TEST", "flaf")) {
puts("borken");
}
else {
puts("ok");
}

return 0;
}

/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/
10 changes: 10 additions & 0 deletions config/gen/config_h/feature_h.in
Expand Up @@ -113,6 +113,16 @@ if (@unsetenv@) {
#define PARROT_HAS_UNSETENV 1
END_PRINT
}
if (@putenv_s@) {
print OUT <<'END_PRINT';
#define PARROT_HAS_PUTENV_S 1
END_PRINT
}
if (@environ@) {
print OUT <<'END_PRINT';
#define PARROT_HAS_ENVIRON 1
END_PRINT
}

print OUT <<'END_PRINT';

Expand Down
4 changes: 2 additions & 2 deletions src/pmc/env.pmc
Expand Up @@ -100,7 +100,7 @@ This method is questionable, as environ is not in ISO-C.
UNUSED(INTERP)
UNUSED(SELF)

#ifndef _MSC_VER
#ifdef PARROT_HAS_ENVIRON
while (environ[rv] != NULL)
++rv;
#endif
Expand Down Expand Up @@ -192,7 +192,7 @@ Used during iteration.
return STRINGNULL;
}
else {
#ifndef _MSC_VER
#ifdef PARROT_HAS_ENVIRON
STRING * const envp = Parrot_str_from_platform_cstring(interp, environ[pos]);
const INTVAL delim = STRING_index(interp, envp, CONST_STRING(INTERP, "="), 0);
return STRING_substr(INTERP, envp, 0, delim);
Expand Down

0 comments on commit b9a257f

Please sign in to comment.