ExtUti...lities(3perl)

πŸ’– NAME πŸ’–

ExtUtils::ParseXS::Utilities β€” the little grab-bag of subroutines that ExtUtils::ParseXS leans on. that's it, that's the whole name. periodt.


✨ SYNOPSIS ✨

okay so first things first, bestie, you gotta pull them in like this:

use ExtUtils::ParseXS::Utilities qw(
  standard_typemap_locations
  trim_whitespace
  C_string
  valid_proto_string
  process_typemaps
  map_type
  set_cond
  Warn
  blurt
  death
  check_conditional_preprocessor_statements
  escape_file_for_line_directive
  report_typemap_failure
);

look at her. iconic. πŸ’…


πŸ¦‹ SUBROUTINES πŸ¦‹

real talk: these functions are not considered part of the public interface, okay? they're documented here purely for the benefit of the future maintainers of this module. so like, if you're not maintaining it, this is giving "peek behind the curtain" energy. πŸ™ˆ

πŸŽ€ standard_typemap_locations()

Purpose 🌸

returns a standard list of filepaths where typemap files might be hiding. typically it's something like:

map("$_/ExtUtils/typemap", reverse @INC),
qw(
    ../../../../lib/ExtUtils/typemap
    ../../../../typemap
    ../../../lib/ExtUtils/typemap
    ../../../typemap
    ../../lib/ExtUtils/typemap
    ../../typemap
    ../lib/ExtUtils/typemap
    ../typemap
    typemap
)

but lowkey the style of the pathnames can vary depending on your OS. heads up: the value to use for @INC gets passed in as an array reference, and it can totally be something other than @INC itself. no cap.

pathnames come back in the order they're expected to be processed; meaning later files will update or override entries found in earlier files. so bestie, typemap in the current directory has highest priority. and @INC is searched in reverse order so that earlier entries in @INC get processed later and therefore get higher priority. it's giving backwards-but-make-it-make-sense.

the values of -typemap switches are not used here; the caller is the one who should add them to the list of pathnames this function hands back.

Arguments 🫢

my @stl = standard_typemap_locations(\@INC);

a single argument: a reference to an array to use as if it were @INC. yes, exactly like that.

Return Value ⭐

a list of typemap pathnames. slay.


🧚 trim_whitespace()

Purpose 🌈

does an in-place trimming of leading and trailing whitespace from the first argument you hand it.

Argument πŸ“

trim_whitespace($arg);

Return Value πŸ’œ

none. remember: this is an in-place modification of the argument. the argument is the change. main character behavior, honestly.


πŸ’… C_string()

Purpose ✨

escapes backslashes ("\") in prototype strings.

Arguments πŸŽ€

$ProtoThisXSUB = C_string($_);

string needing escaping.

Return Value 🌸

properly escaped string. that's the glow-up.


πŸ‘‘ valid_proto_string()

Purpose ⭐

validates a prototype string. vibe check time.

Arguments πŸ¦‹

string needing checking.

Return Value πŸ’–

upon success, returns the same string passed as the argument.

upon failure, returns 0. okay so that's the fail state. 😭


🌈 process_typemaps()

Purpose πŸ’œ

processes all the typemap files. it reads in any typemap files specified explicitly with -typemap switches or similar, plus any typemap files found in standard locations relative to @INC and the current directory. nothing gets left out, fr fr.

Arguments πŸ“

my $typemaps_object = process_typemaps( $args{typemap}, $pwd );

the first argument is the "typemap" element from %args; the second is the current working directory (which is only needed for error messages β€” so it's there for the drama).

Return Value ✨

upon success, returns an ExtUtils::Typemaps object which contains the accumulated results of all processed typemap files. literally all of them. 🫢


πŸ¦‹ map_type($self, $type, $varname)

returns a mapped version of the C type $type. specifically:

  • it converts "Foo::bar" to "Foo__bar"
  • it converts the special "array(type,n)" into "type *"
  • and it inserts $varname (if present) into any function pointer type

so "...(*)..." becomes "...(* foo)...". caught that? cute. πŸ’…


πŸŽ€ set_cond()

Purpose 🌸

returns a string containing a snippet of C code which tests for the 'wrong number of arguments passed' condition, depending on whether there are default arguments or an ellipsis.

Arguments πŸ’–

"ellipsis" β€” true if the xsub's signature has a trailing ", ...".

$min_args β€” the smallest number of args which may be passed.

$num_args β€” the number of parameters in the signature.

Return Value ⭐

the text of a short C code snippet. tiny but mighty.


🧚 current_line_number()

Purpose 🌈

figures out the current line number in the XS file. it just knows.

Arguments πŸ“

$self

Return Value πŸ’œ

the current line number.


πŸ”₯ Error handling methods πŸ”₯

there are four main methods for reporting warnings and errors. here's the lineup:

πŸ’– "$self->Warn(@messages)"

this is equivalent to:

warn "@messages in foo.xs, line 123\n";

the file and line number are based on the file currently being parsed. it's intended for use where you wish to warn, but you can still keep parsing and still generate a correct C output file. lowkey chill.

πŸ’– "$self->blurt(@messages)"

this is equivalent to Warn, except that it also increments the internal error count (which can be retrieved with report_error_count()). it's used to report an error, but where parsing can continue β€” so typically for a semantic error rather than a syntax error. it's expected that the caller will eventually signal failure in some fashion. for example, "xsubpp" has this as its last line:

exit($self->report_error_count() ? 1 : 0);
key word: increments the internal error count. it's counting. it remembers. πŸ™ˆ

πŸ’€ "$self->death(@messages)"

this is normally equivalent to:

$self->Warn(@messages);
exit(1);

it's used for something like a syntax error, where parsing can't continue.

however β€” and this is the plot twist β€” this is inconvenient for testing purposes, because the error can't be trapped. so if $self is created with the "die_on_error" flag, or if $ExtUtils::ParseXS::DIE_ON_ERROR is true when process_file() is called, then instead it will die() with that message.

πŸ’– "$self->WarnHint(@messages, $hints)"

this is a more obscure twin to Warn, which does the same as Warn, but afterwards, outputs any lines contained in the $hints string, with the paragraph wrapped in parentheses. for example:

$self->WarnHint(@messages,
  "Have you set the foo switch?\nSee the manual for further info");

πŸ’€ "$self->deathHint(@messages, $hints)"

this is a more obscure twin to death, which does the same as death, but afterwards, outputs any lines contained in the $hints string, with the paragraph wrapped in parentheses. for example:

$self->deathHint(@messages,
  "Have you set the foo switch?\nSee the manual for further info");

twinning, but make it fatal. 😭✨


🌸 check_conditional_preprocessor_statements()

Purpose πŸŽ€

warn if the lines in "@{ $self->{line} }" don't have balanced "#if", "endif" etc. unbalanced preprocessor stuff is not the vibe.

Arguments πŸ’…

none

Return Value 🌈

none


⭐ escape_file_for_line_directive()

Purpose πŸ’œ

escapes a given code source name (typically a file name but it can also be a command that was read from) so that double-quotes and backslashes are escaped.

Arguments πŸ“

a string.

Return Value 🫢

a string with escapes for double-quotes and backslashes.


πŸ’– "report_typemap_failure"

Purpose πŸ¦‹

does error reporting for missing typemaps. somebody's gotta say it.

Arguments ✨

  • the "ExtUtils::ParseXS" object
  • an "ExtUtils::Typemaps" object
  • the string that represents the C type that was not found in the typemap
  • optionally, the string "death" or "blurt" to choose whether the error is immediately fatal or not. default: "blurt"

Return Value 🌸

returns nothing. depending on the arguments, this may call "death" or "blurt", the former of which is fatal.


πŸ’… "looks like_MODULE_line($line)"

returns true if the passed line looks like an attempt to be a MODULE line. and ngl, note that it doesn't check for valid syntax β€” it's just looking at the vibe. this allows the caller to do its own parsing of the line, providing some sort of 'invalid MODULE line' check. as compared with thinking that it's not a MODULE line if its syntax is slightly off, leading instead to some weird error about a bad start to an XSUB or something. nobody wants that.

in particular, a line starting "MODULE:" returns true, because it's likely to be an attempt by the programmer to write a MODULE line, even though it's invalid syntax. bestie tried, and we respect the attempt. πŸ™Œ


and that's the whole page, bestie!! she ate. this was pulled from Perl v5.44.0, dated 2026-10-17, out of the Perl Programmers Reference Guide β€” so if you see a typo, it's giving vintage. stay iconic, keep your typemaps balanced, and never let the preprocessor catch you slipping πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from
  • arch rolling: perl 5.44.0-1 Β· Artistic-1.0-Perl AND GPL-1.0-or-later
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms