CLI-Popt
view release on metacpan or search on metacpan
_CREATE_PERL_CONST(POPT_ARGFLAG_RANDOM);
_CREATE_PERL_CONST(POPT_ARGFLAG_TOGGLE);
_CREATE_PERL_CONST(POPT_ARGFLAG_OR);
_CREATE_PERL_CONST(POPT_ARGFLAG_AND);
_CREATE_PERL_CONST(POPT_ARGFLAG_XOR);
_CREATE_PERL_CONST(POPT_ARGFLAG_NOT);
}
SV*
_new_xs (const char* classname, SV* name_sv, SV* options_ar )
CODE:
const char *name_const = SvOK(name_sv) ? exs_SvPVbyte_nolen(name_sv) : NULL;
char* name_copy = _copy_str_or_null(aTHX_ name_const);
RETVAL = exs_new_structref(perl_popt_st, classname);
perl_popt_st* perl_popt = exs_structref_ptr(RETVAL);
struct poptOption* options = _create_popt_options(aTHX_ perl_popt, options_ar);
char** faux_argv;
Newxz(faux_argv, 1 + (name_copy ? 1 : 0), char*);
if (name_copy) {
*faux_argv = savepv(name_copy);
}
*perl_popt = (perl_popt_st) {
.name = name_copy,
.pid = getpid(),
.options = options,
.callback_userdata = {
#ifdef MULTIPLICITY
.aTHX = aTHX,
#endif
},
};
_refresh_popt_ctx(aTHX_ perl_popt, name_copy ? 1 : 0, faux_argv);
OUTPUT:
RETVAL
void
DESTROY (SV* self_sv)
CODE:
perl_popt_st* perl_popt = exs_structref_ptr(self_sv);
if (PL_dirty && perl_popt->pid == getpid()) {
warn("DESTROYing %" SVf " at global destruction; memory leak likely!\n", self_sv);
}
poptFreeContext(perl_popt->popt);
if (perl_popt->name) {
Safefree(perl_popt->name);
}
_free_popt_options(aTHX_ perl_popt->options);
void
parse (SV* self_sv, ...)
PPCODE:
perl_popt_st* perl_popt = exs_structref_ptr(self_sv);
// trailing NUL - self_sv = 0
const char* stack_argv[items];
stack_argv[items - 1] = NULL;
for (unsigned i=1; i<items; i++) {
stack_argv[i - 1] = exs_SvPVbyte_nolen(ST(i));
}
char** new_argv = _dup_argv_deep(aTHX_ stack_argv, perl_popt->name);
_refresh_popt_ctx(aTHX_ perl_popt, items - (perl_popt->name ? 0 : 1), new_argv);
struct poptOption* options = perl_popt->options;
HV* named_args = newHV();
perl_popt->callback_userdata.result = named_args;
int rc;
while ((rc = poptGetNextOpt(perl_popt->popt)) >= 0) {
// The compiler should optimize this away:
if (CALLBACK_OPTS) {
struct poptOption* curopt = options + (rc - 1);
_store_opt_in_hv(aTHX_ curopt, named_args);
}
}
if (rc != -1) {
SvREFCNT_dec((SV*) named_args);
const char *opt = poptBadOption(perl_popt->popt, 0);
const char *errdesc = poptStrerror(rc);
SV* args[] = {
newSVpvs("BadOption"),
newSViv(rc),
newSVpv(errdesc, 0),
newSVpv(opt, 0),
NULL,
};
SV* err = exs_call_method_scalar(
newSVpvs_flags(PERL_NS "::X", SVs_TEMP),
"create",
args
);
croak_sv(err);
}
const char** leftovers = poptGetArgs(perl_popt->popt);
unsigned leftovers_count = 0;
const char** curstr_p = leftovers;
if (leftovers != NULL) {
while (*curstr_p++) leftovers_count++;
}
( run in 2.131 seconds using v1.01-cache-2.11-cpan-71847e10f99 )