Ancient
view release on metacpan or search on metacpan
xs/file/file.c view on Meta::CPAN
XSRETURN_EMPTY;
}
/* ============================================
Callback registry for line processing
Allows C-level predicates for maximum speed
============================================ */
/* Predicate function type for line processing */
typedef bool (*file_line_predicate)(pTHX_ SV *line);
/* Registered callback entry */
typedef struct {
file_line_predicate predicate; /* C function pointer (NULL for Perl-only) */
SV *perl_callback; /* Perl callback (for fallback or custom) */
} FileLineCallback;
/* Global callback registry */
static HV *g_file_callback_registry = NULL;
/* Built-in C predicates */
static bool pred_is_blank(pTHX_ SV *line) {
STRLEN len;
const char *s = SvPV(line, len);
STRLEN i;
for (i = 0; i < len; i++) {
if (s[i] != ' ' && s[i] != '\t' && s[i] != '\r' && s[i] != '\n') {
return FALSE;
}
}
return TRUE;
}
static bool pred_is_not_blank(pTHX_ SV *line) {
return !pred_is_blank(aTHX_ line);
}
static bool pred_is_empty(pTHX_ SV *line) {
return SvCUR(line) == 0;
}
static bool pred_is_not_empty(pTHX_ SV *line) {
return SvCUR(line) > 0;
}
static bool pred_is_comment(pTHX_ SV *line) {
STRLEN len;
const char *s = SvPV(line, len);
/* Skip leading whitespace */
while (len > 0 && (*s == ' ' || *s == '\t')) {
s++;
len--;
}
return len > 0 && *s == '#';
}
static bool pred_is_not_comment(pTHX_ SV *line) {
return !pred_is_comment(aTHX_ line);
}
/* Cleanup callback registry during global destruction */
static void file_cleanup_callback_registry(pTHX_ void *data) {
PERL_UNUSED_ARG(data);
/* During global destruction, just NULL out pointers.
* Perl handles SV cleanup; trying to free them ourselves
* can cause crashes due to destruction order. */
if (PL_dirty) {
g_file_callback_registry = NULL;
return;
}
/* Normal cleanup - not during global destruction */
g_file_callback_registry = NULL;
}
static void file_init_callback_registry(pTHX) {
SV *sv;
FileLineCallback *cb;
if (g_file_callback_registry) return;
g_file_callback_registry = newHV();
/* Register built-in predicates with both naming conventions */
/* blank / is_blank */
Newxz(cb, 1, FileLineCallback);
cb->predicate = pred_is_blank;
cb->perl_callback = NULL;
sv = newSViv(PTR2IV(cb));
hv_store(g_file_callback_registry, "blank", 5, sv, 0);
hv_store(g_file_callback_registry, "is_blank", 8, SvREFCNT_inc(sv), 0);
/* not_blank / is_not_blank */
Newxz(cb, 1, FileLineCallback);
cb->predicate = pred_is_not_blank;
cb->perl_callback = NULL;
sv = newSViv(PTR2IV(cb));
hv_store(g_file_callback_registry, "not_blank", 9, sv, 0);
hv_store(g_file_callback_registry, "is_not_blank", 12, SvREFCNT_inc(sv), 0);
/* empty / is_empty */
Newxz(cb, 1, FileLineCallback);
cb->predicate = pred_is_empty;
cb->perl_callback = NULL;
sv = newSViv(PTR2IV(cb));
hv_store(g_file_callback_registry, "empty", 5, sv, 0);
hv_store(g_file_callback_registry, "is_empty", 8, SvREFCNT_inc(sv), 0);
/* not_empty / is_not_empty */
Newxz(cb, 1, FileLineCallback);
cb->predicate = pred_is_not_empty;
cb->perl_callback = NULL;
sv = newSViv(PTR2IV(cb));
hv_store(g_file_callback_registry, "not_empty", 9, sv, 0);
hv_store(g_file_callback_registry, "is_not_empty", 12, SvREFCNT_inc(sv), 0);
/* comment / is_comment */
Newxz(cb, 1, FileLineCallback);
cb->predicate = pred_is_comment;
cb->perl_callback = NULL;
sv = newSViv(PTR2IV(cb));
hv_store(g_file_callback_registry, "comment", 7, sv, 0);
hv_store(g_file_callback_registry, "is_comment", 10, SvREFCNT_inc(sv), 0);
/* not_comment / is_not_comment */
Newxz(cb, 1, FileLineCallback);
cb->predicate = pred_is_not_comment;
cb->perl_callback = NULL;
sv = newSViv(PTR2IV(cb));
hv_store(g_file_callback_registry, "not_comment", 11, sv, 0);
hv_store(g_file_callback_registry, "is_not_comment", 14, SvREFCNT_inc(sv), 0);
}
xs/file/file.c view on Meta::CPAN
cv_set_call_checker(cv, file_call_checker_2arg, ckobj);
cv = newXS("file::append", xs_append, __FILE__);
ckobj = newSViv(PTR2IV(pp_file_append));
cv_set_call_checker(cv, file_call_checker_2arg, ckobj);
cv = newXS("file::copy", xs_copy, __FILE__);
ckobj = newSViv(PTR2IV(pp_file_copy));
cv_set_call_checker(cv, file_call_checker_2arg, ckobj);
cv = newXS("file::move", xs_move, __FILE__);
ckobj = newSViv(PTR2IV(pp_file_move));
cv_set_call_checker(cv, file_call_checker_2arg, ckobj);
cv = newXS("file::chmod", xs_chmod, __FILE__);
ckobj = newSViv(PTR2IV(pp_file_chmod));
cv_set_call_checker(cv, file_call_checker_2arg, ckobj);
cv = newXS("file::atomic_spew", xs_atomic_spew, __FILE__);
ckobj = newSViv(PTR2IV(pp_file_atomic_spew));
cv_set_call_checker(cv, file_call_checker_2arg, ckobj);
}
/* Functions without custom op optimization */
newXS("file::join", xs_join, __FILE__);
newXS("file::each_line", xs_each_line, __FILE__);
newXS("file::grep_lines", xs_grep_lines, __FILE__);
newXS("file::count_lines", xs_count_lines, __FILE__);
newXS("file::find_line", xs_find_line, __FILE__);
newXS("file::map_lines", xs_map_lines, __FILE__);
newXS("file::register_line_callback", xs_register_line_callback, __FILE__);
newXS("file::list_line_callbacks", xs_list_line_callbacks, __FILE__);
/* File hooks */
newXS("file::register_read_hook", xs_register_read_hook, __FILE__);
newXS("file::register_write_hook", xs_register_write_hook, __FILE__);
newXS("file::clear_hooks", xs_clear_hooks, __FILE__);
newXS("file::has_hooks", xs_has_hooks, __FILE__);
/* Head and tail */
newXS("file::head", xs_head, __FILE__);
newXS("file::tail", xs_tail, __FILE__);
/* Import function */
newXS("file::import", XS_file_import, __FILE__);
/* Memory-mapped files */
newXS("file::mmap_open", xs_mmap_open, __FILE__);
newXS("file::mmap::data", xs_mmap_data, __FILE__);
newXS("file::mmap::sync", xs_mmap_sync, __FILE__);
newXS("file::mmap::close", xs_mmap_close, __FILE__);
newXS("file::mmap::DESTROY", xs_mmap_DESTROY, __FILE__);
/* Line iterators */
newXS("file::lines_iter", xs_lines_iter, __FILE__);
newXS("file::lines::next", xs_lines_iter_next, __FILE__);
newXS("file::lines::eof", xs_lines_iter_eof, __FILE__);
newXS("file::lines::close", xs_lines_iter_close, __FILE__);
newXS("file::lines::DESTROY", xs_lines_iter_DESTROY, __FILE__);
/* Register cleanup for global destruction */
Perl_call_atexit(aTHX_ file_cleanup_callback_registry, NULL);
Perl_xs_boot_epilog(aTHX_ ax);
}
( run in 0.994 second using v1.01-cache-2.11-cpan-df04353d9ac )