/* VMS::DCLsym - manipulate DCL symbols * * Version: 1.0 * Author: Charles Bailey bailey@newman.upenn.edu * Revised: 17-Aug-1995 * * * Revision History: * * 1.0 17-Aug-1995 Charles Bailey bailey@newman.upenn.edu * original production version */ #include #include #include #include #include #include "EXTERN.h" #include "perl.h" #include "XSUB.h" MODULE = VMS::DCLsym PACKAGE = VMS::DCLsym void _getsym(name) SV * name PPCODE: { struct dsc$descriptor_s namdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}, valdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,0}; STRLEN namlen; int tbltype; unsigned long int retsts; SETERRNO(0,SS$_NORMAL); if (!name) { PUSHs(sv_newmortal()); SETERRNO(EINVAL,LIB$_INVARG); return; } namdsc.dsc$a_pointer = SvPV(name,namlen); namdsc.dsc$w_length = (unsigned short int) namlen; retsts = lib$get_symbol(&namdsc,&valdsc,0,&tbltype); if (retsts & 1) { PUSHs(sv_2mortal(newSVpv(valdsc.dsc$w_length ? valdsc.dsc$a_pointer : "",valdsc.dsc$w_length))); EXTEND(sp,2); /* just in case we're at the end of the stack */ if (tbltype == LIB$K_CLI_LOCAL_SYM) PUSHs(sv_2mortal(newSVpv("LOCAL",5))); else PUSHs(sv_2mortal(newSVpv("GLOBAL",6))); _ckvmssts(lib$sfree1_dd(&valdsc)); } else { /* error - we'll return an empty list */ switch (retsts) { case LIB$_NOSUCHSYM: break; /* nobody home */; case LIB$_INVSYMNAM: /* user errors; set errno return undef */ case LIB$_INSCLIMEM: case LIB$_NOCLI: set_errno(EVMSERR); set_vaxc_errno(retsts); break; default: /* bail out */ { _ckvmssts(retsts); } } } } void _setsym(name,val,typestr="LOCAL") SV * name SV * val char * typestr CODE: { struct dsc$descriptor_s namdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}, valdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; STRLEN slen; int type; unsigned long int retsts; SETERRNO(0,SS$_NORMAL); if (!name || !val) { SETERRNO(EINVAL,LIB$_INVARG); XSRETURN_UNDEF; } namdsc.dsc$a_pointer = SvPV(name,slen); namdsc.dsc$w_length = (unsigned short int) slen; valdsc.dsc$a_pointer = SvPV(val,slen); valdsc.dsc$w_length = (unsigned short int) slen; type = strNE(typestr,"GLOBAL") ? LIB$K_CLI_LOCAL_SYM : LIB$K_CLI_GLOBAL_SYM; retsts = lib$set_symbol(&namdsc,&valdsc,&type); if (retsts & 1) { XSRETURN_YES; } else { switch (retsts) { case LIB$_AMBSYMDEF: /* user errors; set errno and return */ case LIB$_INSCLIMEM: case LIB$_INVSYMNAM: case LIB$_NOCLI: set_errno(EVMSERR); set_vaxc_errno(retsts); XSRETURN_NO; break; /* NOTREACHED */ default: /* bail out */ { _ckvmssts(retsts); } } } } void _delsym(name,typestr="LOCAL") SV * name char * typestr CODE: { struct dsc$descriptor_s namdsc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_S,0}; STRLEN slen; int type; unsigned long int retsts; SETERRNO(0,SS$_NORMAL); if (!name || !typestr) { SETERRNO(EINVAL,LIB$_INVARG); XSRETURN_UNDEF; } namdsc.dsc$a_pointer = SvPV(name,slen); namdsc.dsc$w_length = (unsigned short int) slen; type = strNE(typestr,"GLOBAL") ? LIB$K_CLI_LOCAL_SYM : LIB$K_CLI_GLOBAL_SYM; retsts = lib$delete_symbol(&namdsc,&type); if (retsts & 1) { XSRETURN_YES; } else { switch (retsts) { case LIB$_INVSYMNAM: /* user errors; set errno and return */ case LIB$_NOCLI: case LIB$_NOSUCHSYM: set_errno(EVMSERR); set_vaxc_errno(retsts); XSRETURN_NO; break; /* NOTREACHED */ default: /* bail out */ { _ckvmssts(retsts); } } } }