Permalink
Switch branches/tags
Find file
Fetching contributors…
Cannot retrieve contributors at this time
336 lines (218 sloc) 6.24 KB
/*
Copyright (C) 2001-2014, Parrot Foundation.
=head1 NAME
src/pmc/env.pmc - Env PMC
=head1 DESCRIPTION
C<Env> is a singleton class which provides access to the system environment.
=head2 Methods
=over 4
=cut
*/
/* 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 */
/* HEADERIZER HFILE: none */
/* HEADERIZER BEGIN: static */
/* HEADERIZER END: static */
static PMC *Env_PMC;
pmclass Env singleton provides hash {
/*
=item C<void *get_pointer()>
=item C<void set_pointer(void *ptr)>
These two functions are part of the singleton creation interface. For more
information see F<src/pmc.c>.
=cut
*/
void class_init() :no_wb {
UNUSED(INTERP)
UNUSED(entry)
Env_PMC = NULL;
}
VTABLE void *get_pointer() :no_wb {
UNUSED(INTERP)
UNUSED(SELF)
return Env_PMC;
}
VTABLE void set_pointer(void *ptr) :no_wb {
UNUSED(INTERP)
UNUSED(SELF)
Env_PMC = (PMC *)ptr;
}
/*
=item C<PMC *get_iter()>
Returns a new iterator for the environment
This method is questionable, as environ is not in ISO-C.
=cut
*/
VTABLE PMC *get_iter() :no_wb {
return Parrot_pmc_new_init(INTERP, enum_class_ArrayIterator, SELF);
}
/*
=item C<INTVAL elements()>
Returns the number of elements in the environment.
This method is questionable, as environ is not in ISO-C.
=cut
*/
VTABLE INTVAL elements() :no_wb {
INTVAL rv = 0;
UNUSED(INTERP)
UNUSED(SELF)
while (environ[rv] != NULL)
++rv;
return rv;
}
/*
=item C<INTVAL get_bool()>
Returns whether the environment has any elements.
=cut
*/
VTABLE INTVAL get_bool() :no_wb {
return SELF.elements() ? 1 : 0;
}
/*
=item C<INTVAL get_integer()>
Returns the size of the hash.
=cut
*/
VTABLE INTVAL get_integer() :no_wb {
return SELF.elements();
}
/*
=item C<FLOATVAL get_number()>
Returns the size of the hash.
=cut
*/
VTABLE FLOATVAL get_number() :no_wb {
return SELF.elements();
}
/*
=item C<STRING *get_string_keyed(PMC *key)>
Returns the Parrot string value for the environment variable C<*key>.
=cut
*/
VTABLE STRING *get_string_keyed_str(STRING *key) :no_wb {
UNUSED(SELF)
if (!STRING_IS_EMPTY(key)) {
STRING * const val = Parrot_getenv(INTERP, key);
if (!STRING_IS_NULL(val)) {
return val;
}
}
return CONST_STRING(INTERP, "");
}
VTABLE STRING *get_string_keyed(PMC *key) :no_wb {
return SELF.get_string_keyed_str(VTABLE_get_string(INTERP, key));
}
/*
=item C<STRING *get_string_keyed_int(PMC *key)>
Returns the Parrot string value for the environment variable at position C<pos>.
Used during iteration.
=cut
*/
VTABLE STRING *get_string_keyed_int(INTVAL pos) :no_wb {
if (pos < 0 || pos >= SELF.elements()) {
return CONST_STRING(INTERP, "");
}
else {
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);
}
}
/*
=item C<STRING *get_pmc_keyed(PMC *key)>
Returns a String PMC for the environment variable C<*key>.
=cut
*/
VTABLE PMC *get_pmc_keyed(PMC *key) :no_wb {
STRING * const keyname = VTABLE_get_string(INTERP, key);
STRING *retval = NULL;
PMC *return_pmc;
UNUSED(SELF);
if (!STRING_IS_EMPTY(keyname)) {
retval = Parrot_getenv(INTERP, keyname);
}
if (STRING_IS_NULL(retval))
retval = CONST_STRING(interp, "");
return_pmc = Parrot_pmc_new(INTERP, enum_class_String);
VTABLE_set_string_native(INTERP, return_pmc, retval);
return return_pmc;
}
/*
=item C<void set_string_keyed(PMC *key, STRING *value)>
Sets the environment variable C<*key> to C<*value>.
=cut
*/
VTABLE void set_string_keyed(PMC *key, STRING *value) :no_wb {
STRING * const keyname = VTABLE_get_string(INTERP, key);
UNUSED(SELF);
if (keyname && value)
Parrot_setenv(INTERP, keyname, value);
}
/*
=item C<void set_pmc_keyed(PMC *key, PMC *value)>
Sets the environment variable C<*key> to C<*value>.
=cut
*/
VTABLE void set_pmc_keyed(PMC *key, PMC *value) :no_wb {
STRING * const keyname = VTABLE_get_string(INTERP, key);
STRING * const str_value = VTABLE_get_string(INTERP, value);
UNUSED(SELF);
if (keyname && str_value)
Parrot_setenv(INTERP, keyname, str_value);
}
/*
=item C<INTVAL exists_keyed(PMC *key)>
Returns whether the environment variable for C<*key> exists.
=cut
*/
VTABLE INTVAL exists_keyed(PMC *pmckey) :no_wb {
STRING * const keyname = VTABLE_get_string(INTERP, pmckey);
UNUSED(SELF);
if (!STRING_IS_EMPTY(keyname)) {
const STRING * const val = Parrot_getenv(INTERP, keyname);
if (!STRING_IS_NULL(val))
return 1;
}
return 0;
}
/*
=item C<void delete_keyed(PMC *key)>
Deletes the environment variable for C<*key>.
=cut
*/
VTABLE void delete_keyed(PMC *key) :no_wb {
STRING * const keyname = VTABLE_get_string(INTERP, key);
UNUSED(SELF);
if (!STRING_IS_EMPTY(keyname)) {
const STRING * const val = Parrot_getenv(INTERP, keyname);
if (!STRING_IS_NULL(val))
Parrot_unsetenv(INTERP, keyname);
}
}
}
/*
=back
=head1 SEE ALSO
PDD -
L<http://docs.parrot.org/parrot/latest/html/docs/pdds/pdd17_pmc.pod.html#Hash_types>
Environment in Perl 6 - L<http://dev.perl.org/perl6/rfc/318.html>
Module for Perl 5 - L<http://search.cpan.org/~stas/Env-C-0.06/>
=cut
*/
/*
* Local variables:
* c-file-style: "parrot"
* End:
* vim: expandtab shiftwidth=4 cinoptions='\:2=2' :
*/