Inline-0.53/0000755000076400010400000000000012140067330014323 5ustar sisyphusAdministratorsInline-0.53/C/0000755000076400010400000000000012140070431014501 5ustar sisyphusAdministratorsInline-0.53/C/C-Cookbook.pod0000644000076400010400000012214612115755405017156 0ustar sisyphusAdministrators=head1 NAME Inline::C-Cookbook - A Cornucopia of Inline C Recipes =cut -------------------------------------------------------------------------- =head1 DESCRIPTION It's a lot easier for most of us to cook a meal from a recipe, rather than just throwing things into a pot until something edible forms. So it is with programming as well. C makes C programming for Perl as easy as possible. Having a set of easy to understand samples, makes it simpler yet. This Cookbook is intended to be an evergrowing repository of small yet complete coding examples; each showing how to accomplish a particular task with Inline. Each example is followed by a short discussion, explaining in detail the particular features that are being demonstrated. Many of these recipes are apdapted from email discussions I have had with Inline users around the world. It has been my experience so far, that Inline provides an elegant solution to almost all problems involving Perl and C. Bon Appetit! =cut -------------------------------------------------------------------------- =head1 Appetizers =cut -------------------------------------------------------------------------- =head2 Hello, world =over 4 =item Problem It seems that the first thing any programmer wants to do when he learns a new programming technique is to use it to greet the Earth. How can I do this using Inline? =item Solution use Inline C => <<'END_C'; void greet() { printf("Hello, world\n"); } END_C greet; =item Discussion Nothing too fancy here. We define a single C function C which prints a message to STDOUT. One thing to note is that since the Inline code comes before the function call to C, we can call it as a bareword (no parentheses). =item See Also See L and L for basic info about C. =item Credits Brian Kernigan Dennis Ritchie =back =cut -------------------------------------------------------------------------- =head2 One Liner =over 4 =item Problem A concept is valid in Perl only if it can be shown to work in one line. Can Inline reduce the complexities of Perl/C interaction to a one-liner? =item Solution perl -e 'use Inline C=>q{void greet(){printf("Hello, world\n");}};greet' =item Discussion Try doing that in XS :-) =item See Also My email signature of late is: perl -le 'use Inline C=>q{SV*JAxH(char*x){return newSVpvf("Just Another %s Hacker",x);}};print JAxH+Perl' A bit fancier but a few bytes too long to qualify as a true one liner :-( =item Credits "Eli the Bearded" gave me the idea that I should have an Inline one-liner as a signature. =back =cut -------------------------------------------------------------------------- =head1 Meat & Potatoes =cut -------------------------------------------------------------------------- =head2 Data Types =over 4 =item Problem How do I pass different types of data to and from Inline C functions; like strings, numbers and integers? =item Solution # vowels.pl use Inline C; $filename = $ARGV[0]; die "Usage: perl vowels.pl filename\n" unless -f $filename; $text = join '', <>; # slurp input file $vp = vowel_scan($text); # call our function $vp = sprintf("%03.1f", $vp * 100); # format for printing print "The letters in $filename are $vp% vowels.\n"; __END__ __C__ /* Find percentage of vowels to letters */ double vowel_scan(char* str) { int letters = 0; int vowels = 0; int i = 0; char c; char normalize = 'a' ^ 'A'; /* normalize forces lower case in ASCII; upper in EBCDIC */ char A = normalize | 'a'; char E = normalize | 'e'; char I = normalize | 'i'; char O = normalize | 'o'; char U = normalize | 'u'; char Z = normalize | 'z'; while(c = str[i++]) { c |= normalize; if (c >= A && c <= Z) { letters++; if (c == A || c == E || c == I || c == O || c == U) vowels++; } } return letters ? ((double) vowels / letters) : 0.0; } =item Discussion This script takes a file name from the command line and prints the ratio of vowels to letters in that file. C uses an Inline C function called C, that takes a string argument, and returns the percentage of vowels as a floating point number between 0 and 1. It handles upper and lower case letters, and works with ASCII and EBCDIC. It is also quite fast. Running this script produces: > perl vowels.pl /usr/dict/words The letters in /usr/dict/words are 37.5% vowels. =item See Also The Perl Journal vol #19 has an article about Inline which uses this example. =item Credits This example was reprinted by permission of The Perl Journal. It was edited to work with Inline v0.30 and higher. =back =cut -------------------------------------------------------------------------- =head2 Variable Argument Lists =over 4 =item Problem How do I pass a variable-sized list of arguments to an Inline C function? =item Solution greet(qw(Sarathy Jan Sparky Murray Mike)); use Inline C => <<'END_OF_C_CODE'; void greet(SV* name1, ...) { Inline_Stack_Vars; int i; for (i = 0; i < Inline_Stack_Items; i++) printf("Hello %s!\n", SvPV(Inline_Stack_Item(i), PL_na)); Inline_Stack_Void; } END_OF_C_CODE =item Discussion This little program greets a group of people, such as my coworkers. We use the C ellipsis syntax: "C<...>", since the list can be of any size. Since there are no types or names associated with each argument, we can't expect XS to handle the conversions for us. We'll need to pop them off the B ourselves. Luckily there are two functions (macros) that make this a very easy task. First, we need to begin our function with a "C" statement. This defines a few internal variables that we need to access the B. Now we can use "C", which returns an integer containing the number of arguments passed to us from Perl. B It is important to I use "C" macros when there is an ellipsis (C<...>) in the argument list, I the function has a return type of void. Second, we use the C function to access each argument where "0 <= x < items". B When using a variable length argument list, you have to specify at least one argument before the ellipsis. (On my compiler, anyway.) When XS does it's argument checking, it will complain if you pass in less than the number of I arguments. Therefore, there is currently no way to pass an empty list when a variable length list is expected. =item See Also =item Credits =back =cut -------------------------------------------------------------------------- =head2 Multiple Return Values =over 4 =item Problem How do I return a list of values from a C function? =item Solution print map {"$_\n"} get_localtime(time); use Inline C => <<'END_OF_C_CODE'; #include void get_localtime(int utc) { struct tm *ltime = localtime(&utc); Inline_Stack_Vars; Inline_Stack_Reset; Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_year))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mon))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mday))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_hour))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_min))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_sec))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_isdst))); Inline_Stack_Done; } END_OF_C_CODE =item Discussion Perl is a language where it is common to return a list of values from a subroutine call instead of just a single value. C is not such a language. In order to accomplish this in C we need to manipulate the Perl call stack by hand. Luckily, Inline provides macros to make this easy. This example calls the system C, and returns each of the parts of the time struct; much like the perl builtin C. On each stack push, we are creating a new Perl integer (SVIV) and mortalizing it. The sv_2mortal() call makes sure that the reference count is set properly. Without it, the program would leak memory. NOTE: The C<#include> statement is not really needed, because Inline automatically includes the Perl headers which include almost all standard system calls. =item See Also For more information on the Inline stack macros, see L. =item Credits Richard Anderson contributed the original idea for this snippet. =back =cut -------------------------------------------------------------------------- =head2 Multiple Return Values (Another Way) =over 4 =item Problem How can I pass back more than one value without using the Perl Stack? =item Solution use Inline::Files; use Inline C; my ($foo, $bar); change($foo, $bar); print "\$foo = $foo\n"; print "\$bar = $bar\n"; __C__ int change(SV* var1, SV* var2) { sv_setpvn(var1, "Perl Rocks!", 11); sv_setpvn(var2, "Inline Rules!", 13); return 1; } =item Discussion Most perl function interfaces return values as a list of one or more scalars. Very few like C, will modify an input scalar in place. On the other hand, in C you do this quite often. Values are passed in by reference and modified in place by the called function. It turns out that we can do that with Inline as well. The secret is to use a type of 'C' for each argument that is to be modified. This ensures passing by reference, because no typemapping is needed. The function can then use the Perl5 API to operate on that argument. When control returns to Perl, the argument will retain the value set by the C function. In this example we passed in 2 empty scalars and assigned values directly to them. =item See Also =item Credits Ned Konz brought this behavior to my attention. He also pointed out that he is not the world famous computer cyclist Steve Roberts (http://www.microship.com), but he is close (http://bike-nomad.com). Thanks Ned. =back =cut -------------------------------------------------------------------------- =head2 Using Memory =over 4 =item Problem How should I allocate buffers in my Inline C code? =item Solution print greeting('Ingy'); use Inline C => <<'END_OF_C_CODE'; SV* greeting(SV* sv_name) { return (newSVpvf("Hello %s!\n", SvPV(sv_name, PL_na))); } END_OF_C_CODE =item Discussion In this example we will return the greeting to the caller, rather than printing it. This would seem mighty easy, except for the fact that we need to allocate a small buffer to create the greeting. I would urge you to stay away from Cing your own buffer. Just use Perl's built in memory management. In other words, just create a new Perl string scalar. The function C does just that. And C includes C functionality. The other problem is getting rid of this new scalar. How will the ref count get decremented after we pass the scalar back? Perl also provides a function called C. Mortal variables die when the context goes out of scope. In other words, Perl will wait until the new scalar gets passed back and then decrement the ref count for you, thereby making it eligible for garbage collection. See C. In this example the C call gets done under the hood by XS, because we declared the return type to be C. To view the generated XS code, run the command "C". This will leave the build directory intact and tell you where to find it. =item See Also =item Credits =back =cut -------------------------------------------------------------------------- =head1 Fast Food =cut -------------------------------------------------------------------------- =head2 Inline CGI =over 4 =item Problem How do I use Inline securely in a CGI environment? =item Solution #!/usr/bin/perl use CGI qw(:standard); use Inline (Config => DIRECTORY => '/usr/local/apache/Inline', ); print (header, start_html('Inline CGI Example'), h1(JAxH('Inline')), end_html ); use Inline C => < to a build area on your disk whenever it compiles code. Most CGI scripts don't (and shouldn't) be able to create a directory and write into it. The solution is to explicitly tell Inline which directory to use with the 'use Inline Config => DIRECTORY => ...' line. Then you need to give write access to that directory from the web server (CGI script). If you see this as a security hole, then there is another option. Give write access to yourself, but read-only access to the CGI script. Then run the script once by hand (from the command line). This will cause Inline to precompile the C code. That way the CGI will only need read access to the build directory (to load in the shared library from there). Just remember that whenever you change the C code, you need to precompile it again. =item See Also See L for more information on using the C module. =item Credits =back =cut -------------------------------------------------------------------------- =head2 mod_perl =over 4 =item Problem How do I use Inline with mod_perl? =item Solution package Factorial; use strict; use Inline Config => DIRECTORY => '/usr/local/apache/Inline', ENABLE => 'UNTAINT'; use Inline 'C'; Inline->init; sub handler { my $r = shift; $r->send_http_header('text/plain'); printf "%3d! = %10d\n", $_, factorial($_) for 1..100; return Apache::Constants::OK; } 1; __DATA__ __C__ double factorial(double x) { if (x < 2) return 1; return x * factorial(x - 1) } =item Discussion This is a fully functional mod_perl handler that prints out the factorial values for the numbers 1 to 100. Since we are using Inline under mod_perl, there are a few considerations to , um, consider. First, mod_perl handlers are usually run with C<-T> taint detection. Therefore, we need to enable the UNTAINT option. The next thing to deal with is the fact that this handler will most likely be loaded after Perl's compile time. Since we are using the DATA section, we need to use the special C call. And of course we need to specify a DIRECTORY that mod_perl can compile into. I Other than that, this is a pretty straightforward mod_perl handler, tuned for even more speed! =item See Also See Stas Bekman's upcoming O'Reilly book on mod_perl to which this example was contributed. =item Credits =back =cut -------------------------------------------------------------------------- =head2 Object Oriented Inline =over 4 =item Problem How do I implement Object Oriented programming in Perl using C objects? =item Solution my $obj1 = Soldier->new('Benjamin', 'Private', 11111); my $obj2 = Soldier->new('Sanders', 'Colonel', 22222); my $obj3 = Soldier->new('Matt', 'Sergeant', 33333); for my $obj ($obj1, $obj2, $obj3) { print $obj->get_serial, ") ", $obj->get_name, " is a ", $obj->get_rank, "\n"; } #--------------------------------------------------------- package Soldier; use Inline C => <<'END'; typedef struct { char* name; char* rank; long serial; } Soldier; SV* new(char* class, char* name, char* rank, long serial) { Soldier* soldier; SV* obj_ref = newSViv(0); SV* obj = newSVrv(obj_ref, class); New(42, soldier, 1, Soldier); soldier->name = savepv(name); soldier->rank = savepv(rank); soldier->serial = serial; sv_setiv(obj, (IV)soldier); SvREADONLY_on(obj); return obj_ref; } char* get_name(SV* obj) { return ((Soldier*)SvIV(SvRV(obj)))->name; } char* get_rank(SV* obj) { return ((Soldier*)SvIV(SvRV(obj)))->rank; } long get_serial(SV* obj) { return ((Soldier*)SvIV(SvRV(obj)))->serial; } void DESTROY(SV* obj) { Soldier* soldier = (Soldier*)SvIV(SvRV(obj)); Safefree(soldier->name); Safefree(soldier->rank); Safefree(soldier); } END =item Discussion Damian Conway has given us myriad ways of implementing OOP in Perl. This is one he might not have thought of. The interesting thing about this example is that it uses Perl for all the OO bindings while using C for the attributes and methods. If you examine the Perl code everything looks exactly like a regular OO example. There is a C method and several accessor methods. The familiar 'arrow syntax' is used to invoke them. In the class definition (second part) the Perl C statement is used to name the object class or namespace. But that's where the similarities end Inline takes over. The idea is that we call a C subroutine called C which returns a blessed scalar. The scalar contains a readonly integer which is a C pointer to a Soldier struct. This is our object. The C function needs to malloc the memory for the struct and then copy the initial values into it using C. This also allocates more memory (which we have to keep track of). Note that C doesn't create a reference, but returns a new SV ('obj') and makes 'obj_ref' a reference to it. Ultimately, 'obj_ref' (which is the SV that C returns) holds a reference to the blessed scalar in 'obj', which in turn contains an integer that corresponds to the memory address of the C object. The accessor methods are pretty straightforward. They return the current value of their attribute. The last method C is called automatically by Perl whenever an object goes out of scope. This is where we can free all the memory used by the object. That's it. It's a very simplistic example. It doesn't show off any advanced OO features, but it is pretty cool to see how easy the implementation can be. The important Perl call is C which creates a blessed scalar. =item See Also Read "Object Oriented Perl" by Damian Conway, for more useful ways of doing OOP in Perl. You can learn more Perl calls in L. If you don't have Perl 5.6.0 or higher, visit http://www.perldoc.com/perl5.6/pod/perlapi.html =item Credits =back =cut -------------------------------------------------------------------------- =head1 The Main Course =cut -------------------------------------------------------------------------- =head2 Exposing Shared Libraries =over 4 =item Problem You have this great C library and you want to be able to access parts of it with Perl. =item Solution print get('http://www.axkit.org'); use Inline C => Config => LIBS => '-lghttp'; use Inline C => <<'END_OF_C_CODE'; #include char *get(SV* uri) { SV* buffer; ghttp_request* request; buffer = NEWSV(0,0); request = ghttp_request_new(); ghttp_set_uri(request, SvPV(uri, PL_na)); ghttp_set_header(request, http_hdr_Connection, "close"); ghttp_prepare(request); ghttp_process(request); sv_catpv(buffer, ghttp_get_body(request)); ghttp_request_destroy(request); return SvPV(buffer, PL_na); } END_OF_C_CODE =item Discussion This example fetches and prints the HTML from http://www.axkit.org It requires the GNOME http libraries. http://www.gnome.org One of the most common questions I get is "How can I use Inline to make use of some shared library?". Although it has always been possible to do so, the configuration was ugly, and there were no specific examples. With version 0.30 and higher, you can specify the use of shared libraries easily with something like this: use Inline C => Config => LIBS => '-lghttp'; use Inline C => "code ..."; or use Inline C => "code ...", LIBS => '-lghttp'; To specify a specific library path, use: use Inline C => "code ...", LIBS => '-L/your/lib/path -lyourlib'; To specify an include path use: use Inline C => "code ...", LIBS => '-lghttp', INC => '-I/your/inc/path'; =item See Also The C and C configuration options are formatted and passed into MakeMaker. For more info see L. For more options see L. =item Credits This code was written by Matt Sergeant , author of many CPAN modules. The configuration syntax has been modified for use with Inline v0.30. =back =head2 Automatic Function Wrappers =over 4 =item Problem You have some functions in a C library that you want to access from Perl exactly as you would from C. =item Solution The error function C is probably defined in your standard math library. Annoyingly, Perl does not let you access it. To print out a small table of its values, just say: perl -le 'use Inline C => q{ double erf(double); }, ENABLE => "AUTOWRAP"; print "$_ @{[erf($_)]}" for (0..10)' The excellent C implements Term::ReadLine using the GNU ReadLine library. Here is an easy way to access just C from that library: package MyTerm; use Inline C => Config => ENABLE => AUTOWRAP => LIBS => "-lreadline -lncurses -lterminfo -ltermcap "; use Inline C => q{ char * readline(char *); }; package main; my $x = MyTerm::readline("xyz: "); Note however that it fails to C the memory returned by readline, and that C offers a much richer interface. =item Discussion We access existing functions by merely showing Inline their declarations, rather than a full definition. Of course the function declared must exist, either in a library already linked to Perl or in a library specified using the C option. The first example wraps a function from the standard math library, so Inline requires no additional C directive. The second uses the Config option to specify the libraries that contain the actual compiled C code. This behavior is always disabled by default. You must enable the C option to make it work. =item See Also C, C =item Credits GNU ReadLine was written by Brian Fox and Chet Ramey . Term::ReadLine::Gnu was written by Hiroo Hayashi . Both are far richer than the slim interface given here! The idea of producing wrapper code given only a function declaration is taken from Swig by David M. Beazley . Ingy's inline editorial insight: This entire entry was contributed by Ariel Scolnicov . Ariel also first suggested the idea for Inline to support function declaration processing. =back =cut -------------------------------------------------------------------------- =head2 Complex Data =over 4 =item Problem How do I deal with complex data types like hashes in Inline C? =item Solution use Inline C => <<'END_OF_C_CODE'; void dump_hash(SV* hash_ref) { HV* hash; HE* hash_entry; int num_keys, i; SV* sv_key; SV* sv_val; if (! SvROK(hash_ref)) croak("hash_ref is not a reference"); hash = (HV*)SvRV(hash_ref); num_keys = hv_iterinit(hash); for (i = 0; i < num_keys; i++) { hash_entry = hv_iternext(hash); sv_key = hv_iterkeysv(hash_entry); sv_val = hv_iterval(hash, hash_entry); printf("%s => %s\n", SvPV(sv_key, PL_na), SvPV(sv_val, PL_na)); } return; } END_OF_C_CODE my %hash = ( Author => "Brian Ingerson", Nickname => "INGY", Module => "Inline.pm", Version => "0.30", Language => "C", ); dump_hash(\%hash); =item Discussion The world is not made of scalars alone, although they are definitely the easiest creatures to deal with, when doing Inline stuff. Sometimes we need to deal with arrays, hashes, and code references, among other things. Since Perl subroutine calls only pass scalars as arguments, we'll need to use the argument type C and pass references to more complex types. The above program dumps the key/value pairs of a hash. To figure it out, just curl up with L for a couple hours. Actually, its fairly straight forward once you are familiar with the calls. Note the C function call. This is the proper way to die from your C extensions. =item See Also See L for information about the Perl5 internal API. =item Credits =back =cut -------------------------------------------------------------------------- =head2 Hash of Lists =over 4 =item Problem How do I create a Hash of Lists from C? =item Solution use Inline C; use Data::Dumper; $hash_ref = load_data("./cartoon.txt"); print Dumper $hash_ref; __END__ __C__ static int next_word(char**, char*); SV* load_data(char* file_name) { char buffer[100], word[100], * pos; AV* array; HV* hash = newHV(); FILE* fh = fopen(file_name, "r"); while (fgets(pos = buffer, sizeof(buffer), fh)) { if (next_word(&pos, word)) { hv_store(hash, word, strlen(word), newRV_noinc((SV*)array = newAV()), 0); while (next_word(&pos, word)) av_push(array, newSVpvf("%s", word)); } } fclose(fh); return newRV_noinc((SV*) hash); } static int next_word(char** text_ptr, char* word) { char* text = *text_ptr; while(*text != '\0' && *text <= ' ') text++; if (*text <= ' ') return 0; while(*text != '\0' && *text > ' ') { *word++ = *text++; } *word = '\0'; *text_ptr = text; return 1; } =item Discussion This is one of the larger recipes. But when you consider the number of calories it has, it's not so bad. The function C takes the name of a file as it's input. The file C might look like: flintstones fred barney jetsons george jane elroy simpsons homer marge bart The function will read the file, parsing each line into words. Then it will create a new hash, whereby the first word in a line becomes a hash key and the remaining words are put into an array whose reference becomes the hash value. The output looks like this: $VAR1 = { 'flintstones' => [ 'fred', 'barney' ], 'simpsons' => [ 'homer', 'marge', 'bart' ], 'jetsons' => [ 'george', 'jane', 'elroy' ] }; =item See Also See L for information about the Perl5 internal API. =item Credits Al Danial requested a solution to this on comp.lang.perl.misc. He borrowed the idea from the "Hash of Lists" example in the Camel book. =back =cut -------------------------------------------------------------------------- =head1 Just Desserts =cut -------------------------------------------------------------------------- =head2 Win32 =over 4 =item Problem How do I access Win32 DLL-s using Inline? =item Solution use Inline C => DATA => LIBS => '-luser32'; $text = "@ARGV" || 'Inline.pm works with MSWin32. Scary...'; WinBox('Inline Text Box', $text); __END__ __C__ #include int WinBox(char* Caption, char* Text) { return MessageBoxA(0, Text, Caption, 0); } =item Discussion This example runs on MS Windows. It makes a text box appear on the screen which contains a message of your choice. The important thing is that its proof that you can use Inline to interact with Windows DLL-s. Very scary indeed. 8-o To use Inline on Windows with ActivePerl ( http://www.ActiveState.com ) you'll need MS Visual Studio. You can also use the Cygwin environment, available at http://www.cygwin.com . =item See Also See L for more info on MSWin32 programming with Inline. =item Credits This example was adapted from some sample code written by Garrett Goebel =back =cut -------------------------------------------------------------------------- =head2 Embedding Perl in C =over 4 =item Problem How do I use Perl from a regular C program? =item Solution #!/usr/bin/cpr int main(void) { printf("Using Perl version %s from a C program!\n\n", CPR_eval("use Config; $Config{version};")); CPR_eval("use Data::Dumper;"); CPR_eval("print Dumper \\%INC;"); return 0; } =item Discussion By using CPR. (C Perl Run) This example uses another Inline module, C, available separately on CPAN. When you install this module it also installs a binary interpreter called C. (The path may be different on your system) When you feed a C program to the CPR interpreter, it automatically compiles and runs your code using Inline. This gives you full access to the Perl internals. CPR also provides a set of easy to use C macros for calling Perl internals. This means that you can effectively "run" C source code by putting a CPR hashbang as the first line of your C program. =item See Also See L for more information on using CPR. C can be obtained from http://search.cpan.org/search?dist=Inline-CPR =item Credits Randal Schwartz , Randolph Bentson , Richard Anderson , and Tim Maher helped me figure out how to write a program that would work as a hashbang. =back =cut -------------------------------------------------------------------------- =head1 Entertaining Guests As of version 0.30, Inline has the ability to work in cooperation with other modules that want to expose a C API of their own. The general syntax for doing this is: use Inline with => 'Module'; use Inline C => ... ; This tells C to pass configuration options to Inline. Options like typemaps, include paths, and external libraries, are all resolved automatically so you can just concentrate on writing the functions. =cut -------------------------------------------------------------------------- =head2 Event handling with Event.pm =over 4 =item Problem You need to write a C callback for the C module. Can this be done more easily with Inline? =item Solution use Inline with => 'Event'; Event->timer(desc => 'Timer #1', interval => 2, cb => \&my_callback, ); Event->timer(desc => 'Timer #2', interval => 3, cb => \&my_callback, ); print "Starting...\n"; Event::loop; use Inline C => <<'END'; void my_callback(pe_event* event) { pe_timer * watcher = event->up; printf("%s\n\tEvent priority = %d\n\tWatcher priority = %d\n\n", SvPVX(watcher->base.desc), event->prio, watcher->base.prio ); } END =item Discussion The first line tells Inline to load the C module. Inline then queries C for configuration information. It gets the name and location of Event's header files, typemaps and shared objects. The parameters that C returns look like: INC => "-I $path/Event", TYPEMAPS => "$path/Event/typemap", MYEXTLIB => "$path/auto/Event/Event.$so", AUTO_INCLUDE => '#include "EventAPI.h"', BOOT => 'I_EVENT_API("Inline");', Doing all of this automatically allows you, the programmer, to simply write a function that receives a pointer of type C<'pe_event*'>. This gives you access to the C structure that was passed to you. In this example, I simply print values out of the structure. The Perl code defines 2 timer events which each invoke the same callback. The first one, every two seconds, and the second one, every three seconds. As of this writing, C is the only CPAN module that works in cooperation with Inline. =item See Also Read the C documentation for more information. It contains a tutorial showing several examples of using Inline with C. =item Credits Jochen Stenzel originally came up with the idea of mixing Inline and C. He also authored the C tutorial. Joshua Pritikin is the author of C. =back =cut -------------------------------------------------------------------------- =head1 Food for Thought =cut -------------------------------------------------------------------------- =head2 Calling C from both Perl and C =over 4 =item Problem I'd like to be able to call the same C function from both Perl and C. Also I like to define a C function that B get bound to Perl. How do I do that? =item Solution print "9 + 5 = ", add(9, 5), "\n"; print "SQRT(9^2 + 5^2) = ", pyth(9, 5), "\n"; print "9 * 5 = ", mult(9, 5), "\n"; use Inline C => <<'END_C'; int add(int x, int y) { return x + y; } static int mult(int x, int y) { return x * y; } double pyth(int x, int y) { return sqrt(add(mult(x, x), mult(y, y))); } END_C =item Discussion The program produces: 9 + 5 = 14 SQRT(9^2 + 5^2) = 10.295630140987 Can't locate auto/main/mult.al in @INC ... Every Inline function that is bound to Perl is also callable by C. You don't have to do anything special. Inline arranges it so that all the typemap code gets done by XS and is out of sight. By the time the C function receives control, everything has been converted from Perl to C. Of course if your function manipulates the Perl Stack, you probably don't want to call it from C (unless you I know what you're doing). If you declare a function as C, Inline won't bind it to Perl. That's why we were able to call C from C but the call failed from Perl. =item See Also =item Credits =back =cut -------------------------------------------------------------------------- =head2 Calling Perl from C =over 4 =item Problem So now that I can call C from Perl, how do I call a Perl subroutine from an Inline C function. =item Solution use Inline C; for(1..5) { c_func_1('This is the first line'); c_func_2('This is the second line'); print "\n"; } sub perl_sub_1 { print map "$_\n", @_; } __DATA__ __C__ void c_func_2(SV* text) { dSP; ENTER; SAVETMPS; XPUSHs(sv_2mortal(newSVpvf("Plus an extra line"))); PUTBACK; call_pv("perl_sub_1", G_DISCARD); FREETMPS; LEAVE; } void c_func_1(SV* text) { c_func_2(text); } =item Discussion This demo previously made use of Inline Stack macros only - but that's not the correct way to do it. Instead, base the callbacks on the perlcall documentation (as we're now doing). Actually, this program demonstrates calling a C function which calls another C function which in turn calls a Perl subroutine. The nice thing about Inline C functions is that you can call them from both Perl-space B C-space. That's because Inline creates a wrapper function around each C function. When you use Perl to call C you're actually calling that function's wrapper. The wrapper handles typemapping and Stack management, and then calls your C function. The first time we call C which calls C. The second time we call C directly. C calls the Perl subroutine (C) using the internal C function. It has to put arguments on the stack by hand. Since there is already one argument on the stack when we enter the function, the C ( which is equivalent to an C ) adds a second argument. We iterate through a 'for' loop 5 times just to demonstrate that things still work correctly when we do that. (This was where the previous rendition, making use solely of Inline Stack macros, fell down.) =item See Also See L for more information about Stack macros. See L for more information about the Perl5 internal API. =item Credits =back =cut -------------------------------------------------------------------------- =head2 Evaling C =over 4 =item Problem I've totally lost my marbles and I want to generate C code at run time, and C it into Perl. How do I do this? =item Solution use Inline; use Code::Generator; my $c_code = generate('foo_function'); Inline->bind(C => $c_code); foo_function(1, 2, 3); =item Discussion I can't think of a real life application where you would want to generate C code on the fly, but at least I know how I would do it. :) The C function of Inline let's you bind (compile/load/execute) C functions at run time. It takes all of the same arguments as 'use Inline C => ...'. The nice thing is that once a particular snippet is compiled, it remains cached so that it doesn't need to be compiled again. I can imagine that someday a mad scientist will dream up a self generating modeling system that would run faster and faster over time. If you know such a person, have them drop me a line. =item See Also =item Credits =back =cut -------------------------------------------------------------------------- =head2 Providing a pure perl alternative =over 4 =item Problem I want to write a script that will use a C subroutine if Inline::C is installed, but will otherwise use an equivalent pure perl subroutine if Inline::C is not already installed. How do I do this? =item Solution use strict; use warnings; eval { require Inline; Inline->import (C => Config => BUILD_NOISY => 1); Inline->import (C =><<'EOC'); int foo() { warn("Using Inline\n"); return 42; } EOC }; if($@) { *foo =\&bar; } sub bar { warn("Using Pure Perl Implementation\n"); return 42; } my $x = foo(); print "$x\n"; =item Discussion If Inline::C is installed and functioning properly, the C sub foo is called by the perl code. Otherwise, $@ gets set, and the equivalent pure perl function bar is instead called. Note, too, that the pure perl sub bar can still be explicitly called even if Inline::C is available. =back =cut -------------------------------------------------------------------------- =head2 Accessing Fortran subs using Inline::C =over 4 =item Problem I've been given a neat little sub written in fortran that takes, as its args, two integers and returns their product. And I would like to use that sub as is from Inline::C. By way of example, let's say that the fortran source file is named 'prod.f', and that it looks like this: integer function sqarea(r,s) integer r, s sqarea = r*s return end =item Solution We can't access that code directly, but we can compile it into a library which we *can* then access from Inline::C. Using gcc we could run: gfortran -c prod.f -o prod.o ar cru libprod.a prod.o The function is then accessible as follows: use warnings; use Inline C => Config => LIBS => '-L/full/path/to/libprod_location -lprod -lgfortran'; use Inline C => <<' EOC'; int wrap_sqarea(int a, int b) { return sqarea_(&a, &b); } EOC $x = 15; $y = $x + 3; $ret = wrap_sqarea($x, $y); print "Product of $x and $y is $ret\n"; =item Discussion Note firstly that, although the function is specified as 'sqarea' in the source file, gfortran appends an underscore to the name when the source is compiled. (I don't know if *all* fortran compilers do this.) Therefore Inline::C needs to call the function as 'sqarea_'. Secondly, because fortran subs pass args by reference, we need to pass the *addresses* of the two integer args to sqarea() when we call it from our Inline::C sub. If using g77 instead of gfortran, the only necessary change is that we specify '-lg2c' instead of '-lgfortran' in our 'LIBS' setting. =back =cut -------------------------------------------------------------------------- =head1 SEE ALSO For generic information about Inline, see L. For information about using Inline with C see L. For information on supported languages and platforms see L. For information on writing your own Inline language support module, see L. Inline's mailing list is inline@perl.org To subscribe, send email to inline-subscribe@perl.org =head1 AUTHOR Brian Ingerson =head1 COPYRIGHT Copyright (c) 2001, 2002. Brian Ingerson. Copyright (c) 2008, 2010-2013. Sisyphus. All Rights Reserved. This module is free software. It may be used, redistributed and/or modified under the terms of the Perl Artistic License. See http://www.perl.com/perl/misc/Artistic.html =cut Inline-0.53/C/C.pm0000644000076400010400000006766612140062002015241 0ustar sisyphusAdministratorspackage Inline::C; $Inline::C::VERSION = '0.53'; $Inline::C::VERSION = eval $Inline::C::VERSION; use strict; require Inline; use Config; use Data::Dumper; use Carp; use Cwd qw(cwd abs_path); use File::Spec; @Inline::C::ISA = qw(Inline); #============================================================================== # Register this module as an Inline language support module #============================================================================== sub register { return { language => 'C', # XXX Breaking this on purpose; let's see who screams # aliases => ['c'], type => 'compiled', suffix => $Config{dlext}, }; } #============================================================================== # Validate the C config options #============================================================================== sub usage_validate { my $key = shift; return <{CONFIG}{BUILD_NOISY}; $o->{ILSM} ||= {}; $o->{ILSM}{XS} ||= {}; $o->{ILSM}{MAKEFILE} ||= {}; if (not $o->UNTAINT) { require FindBin; $o->{ILSM}{MAKEFILE}{INC} = "-I\"$FindBin::Bin\"" if not defined $o->{ILSM}{MAKEFILE}{INC}; } $o->{ILSM}{AUTOWRAP} = 0 if not defined $o->{ILSM}{AUTOWRAP}; $o->{ILSM}{XSMODE} = 0 if not defined $o->{ILSM}{XSMODE}; $o->{ILSM}{AUTO_INCLUDE} ||= <{ILSM}{FILTERS} ||= []; $o->{STRUCT} ||= { '.macros' => '', '.xs' => '', '.any' => 0, '.all' => 0, }; while (@_) { my ($key, $value) = (shift, shift); if ($key eq 'PRE_HEAD') { unless( -f $value) { $o->{ILSM}{AUTO_INCLUDE} = $value . "\n" . $o->{ILSM}{AUTO_INCLUDE}; } else { my $insert; open RD, '<', $value or die "Couldn't open $value for reading: $!"; while() {$insert .= $_} close RD or die "Couldn't close $value after reading: $!"; $o->{ILSM}{AUTO_INCLUDE} = $insert . "\n" . $o->{ILSM}{AUTO_INCLUDE}; } next; } if ($key eq 'MAKE' or $key eq 'AUTOWRAP' or $key eq 'XSMODE' ) { $o->{ILSM}{$key} = $value; next; } if ($key eq 'CC' or $key eq 'LD') { $o->{ILSM}{MAKEFILE}{$key} = $value; next; } if ($key eq 'LIBS') { $o->add_list($o->{ILSM}{MAKEFILE}, $key, $value, []); next; } if ($key eq 'INC') { $o->add_string($o->{ILSM}{MAKEFILE}, $key, quote_space($value), ''); next; } if ($key eq 'MYEXTLIB' or $key eq 'OPTIMIZE' or $key eq 'CCFLAGS' or $key eq 'LDDLFLAGS') { $o->add_string($o->{ILSM}{MAKEFILE}, $key, $value, ''); next; } if ($key eq 'CCFLAGSEX') { $o->add_string($o->{ILSM}{MAKEFILE}, 'CCFLAGS', $Config{ccflags} . ' ' . $value, ''); next; } if ($key eq 'TYPEMAPS') { unless(ref($value) eq 'ARRAY') { croak "TYPEMAPS file '$value' not found" unless -f $value; $value = File::Spec->rel2abs($value); } else { for (my $i = 0; $i < scalar(@$value); $i++) { croak "TYPEMAPS file '${$value}[$i]' not found" unless -f ${$value}[$i]; ${$value}[$i] = File::Spec->rel2abs(${$value}[$i]); } } $o->add_list($o->{ILSM}{MAKEFILE}, $key, $value, []); next; } if ($key eq 'AUTO_INCLUDE') { $o->add_text($o->{ILSM}, $key, $value, ''); next; } if ($key eq 'BOOT') { $o->add_text($o->{ILSM}{XS}, $key, $value, ''); next; } if ($key eq 'PREFIX') { croak "Invalid value for 'PREFIX' option" unless ($value =~ /^\w*$/ and $value !~ /\n/); $o->{ILSM}{XS}{PREFIX} = $value; next; } if ($key eq 'FILTERS') { next if $value eq '1' or $value eq '0'; # ignore ENABLE, DISABLE $value = [$value] unless ref($value) eq 'ARRAY'; my %filters; for my $val (@$value) { if (ref($val) eq 'CODE') { $o->add_list($o->{ILSM}, $key, $val, []); } else { eval { require Inline::Filters }; croak "'FILTERS' option requires Inline::Filters to be installed." if $@; %filters = Inline::Filters::get_filters($o->{API}{language}) unless keys %filters; if (defined $filters{$val}) { my $filter = Inline::Filters->new($val, $filters{$val}); $o->add_list($o->{ILSM}, $key, $filter, []); } else { croak "Invalid filter $val specified."; } } } next; } if ($key eq 'STRUCTS') { # A list of struct names if (ref($value) eq 'ARRAY') { for my $val (@$value) { croak "Invalid value for 'STRUCTS' option" unless ($val =~ /^[_a-z][_0-9a-z]*$/i); $o->{STRUCT}{$val}++; } } # Enable or disable elsif ($value =~ /^\d+$/) { $o->{STRUCT}{'.any'} = $value; } # A single struct name else { croak "Invalid value for 'STRUCTS' option" unless ($value =~ /^[_a-z][_0-9a-z]*$/i); $o->{STRUCT}{$value}++; } eval { require Inline::Struct }; croak "'STRUCTS' option requires Inline::Struct to be installed." if $@; $o->{STRUCT}{'.any'} = 1; next; } my $class = ref $o; # handles subclasses correctly. croak "'$key' is not a valid config option for $class\n"; } } sub add_list { my $o = shift; my ($ref, $key, $value, $default) = @_; $value = [$value] unless ref $value eq 'ARRAY'; for (@$value) { if (defined $_) { push @{$ref->{$key}}, $_; } else { $ref->{$key} = $default; } } } sub add_string { my $o = shift; my ($ref, $key, $value, $default) = @_; $value = [$value] unless ref $value; croak usage_validate($key) unless ref($value) eq 'ARRAY'; for (@$value) { if (defined $_) { $ref->{$key} .= ' ' . $_; } else { $ref->{$key} = $default; } } } sub add_text { my $o = shift; my ($ref, $key, $value, $default) = @_; $value = [$value] unless ref $value; croak usage_validate($key) unless ref($value) eq 'ARRAY'; for (@$value) { if (defined $_) { chomp; $ref->{$key} .= $_ . "\n"; } else { $ref->{$key} = $default; } } } #============================================================================== # Return a small report about the C code.. #============================================================================== sub info { my $o = shift; return <{ILSM}{XSMODE}; No information is currently generated when using XSMODE. END my $text = ''; $o->preprocess; $o->parse; if (defined $o->{ILSM}{parser}{data}{functions}) { $text .= "The following Inline $o->{API}{language} function(s) have been successfully bound to Perl:\n"; my $parser = $o->{ILSM}{parser}; my $data = $parser->{data}; for my $function (sort @{$data->{functions}}) { my $return_type = $data->{function}{$function}{return_type}; my @arg_names = @{$data->{function}{$function}{arg_names}}; my @arg_types = @{$data->{function}{$function}{arg_types}}; my @args = map {$_ . ' ' . shift @arg_names} @arg_types; $text .= "\t$return_type $function(" . join(', ', @args) . ")\n"; } } else { $text .= "No $o->{API}{language} functions have been successfully bound to Perl.\n\n"; } $text .= Inline::Struct::info($o) if $o->{STRUCT}{'.any'}; return $text; } sub config { my $o = shift; } #============================================================================== # Parse and compile C code #============================================================================== my $total_build_time; sub build { my $o = shift; if ($o->{CONFIG}{BUILD_TIMERS}) { eval {require Time::HiRes}; croak "You need Time::HiRes for BUILD_TIMERS option:\n$@" if $@; $total_build_time = Time::HiRes::time(); } $o->call('preprocess', 'Build Preprocess'); $o->call('parse', 'Build Parse'); $o->call('write_XS', 'Build Glue 1'); $o->call('write_Inline_headers', 'Build Glue 2'); $o->call('write_Makefile_PL', 'Build Glue 3'); $o->call('compile', 'Build Compile'); if ($o->{CONFIG}{BUILD_TIMERS}) { $total_build_time = Time::HiRes::time() - $total_build_time; printf STDERR "Total Build Time: %5.4f secs\n", $total_build_time; } } sub call { my ($o, $method, $header, $indent) = (@_, 0); my $time; my $i = ' ' x $indent; print STDERR "${i}Starting $header Stage\n" if $o->{CONFIG}{BUILD_NOISY}; $time = Time::HiRes::time() if $o->{CONFIG}{BUILD_TIMERS}; $o->$method(); $time = Time::HiRes::time() - $time if $o->{CONFIG}{BUILD_TIMERS}; print STDERR "${i}Finished $header Stage\n" if $o->{CONFIG}{BUILD_NOISY}; printf STDERR "${i}Time for $header Stage: %5.4f secs\n", $time if $o->{CONFIG}{BUILD_TIMERS}; print STDERR "\n" if $o->{CONFIG}{BUILD_NOISY}; } #============================================================================== # Apply any #============================================================================== sub preprocess { my $o = shift; return if $o->{ILSM}{parser}; $o->get_maps; $o->get_types; $o->{ILSM}{code} = $o->filter(@{$o->{ILSM}{FILTERS}}); } #============================================================================== # Parse the function definition information out of the C code #============================================================================== sub parse { my $o = shift; return if $o->{ILSM}{parser}; return if $o->{ILSM}{XSMODE}; my $parser = $o->{ILSM}{parser} = $o->get_parser; $parser->{data}{typeconv} = $o->{ILSM}{typeconv}; $parser->{data}{AUTOWRAP} = $o->{ILSM}{AUTOWRAP}; Inline::Struct::parse($o) if $o->{STRUCT}{'.any'}; $parser->code($o->{ILSM}{code}) or croak <{API}{language} code passed to Inline at @{[caller(2)]} END } # Create and initialize a parser sub get_parser { my $o = shift; Inline::C::_parser_test("Inline::C::get_parser called\n") if $o->{CONFIG}{_TESTING}; require Inline::C::ParseRecDescent; Inline::C::ParseRecDescent::get_parser($o); } #============================================================================== # Gather the path names of all applicable typemap files. #============================================================================== sub get_maps { my $o = shift; print STDERR "get_maps Stage\n" if $o->{CONFIG}{BUILD_NOISY}; my $typemap = ''; my $file; $file = File::Spec->catfile($Config::Config{installprivlib},"ExtUtils","typemap"); $typemap = $file if -f $file; $file = File::Spec->catfile($Config::Config{privlibexp} ,"ExtUtils","typemap"); $typemap = $file if (not $typemap and -f $file); warn "Can't find the default system typemap file" if (not $typemap and $^W); unshift(@{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}, $typemap) if $typemap; if (not $o->UNTAINT) { require FindBin; $file = File::Spec->catfile($FindBin::Bin,"typemap"); if ( -f $file ) { push(@{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}, $file); } } } #============================================================================== # This routine parses XS typemap files to get a list of valid types to create # bindings to. This code is mostly hacked out of Larry Wall's xsubpp program. #============================================================================== sub get_types { my (%type_kind, %proto_letter, %input_expr, %output_expr); my $o = shift; local $_; croak "No typemaps specified for Inline C code" unless @{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}; my $proto_re = "[" . quotemeta('\$%&*@;') . "]"; foreach my $typemap (@{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}) { next unless -e $typemap; # skip directories, binary files etc. warn("Warning: ignoring non-text typemap file '$typemap'\n"), next unless -T $typemap; open(TYPEMAP, $typemap) or warn ("Warning: could not open typemap file '$typemap': $!\n"), next; my $mode = 'Typemap'; my $junk = ""; my $current = \$junk; while () { next if /^\s*\#/; my $line_no = $. + 1; if (/^INPUT\s*$/) {$mode = 'Input'; $current = \$junk; next} if (/^OUTPUT\s*$/) {$mode = 'Output'; $current = \$junk; next} if (/^TYPEMAP\s*$/) {$mode = 'Typemap'; $current = \$junk; next} if ($mode eq 'Typemap') { chomp; my $line = $_; TrimWhitespace($_); # skip blank lines and comment lines next if /^$/ or /^\#/; my ($type,$kind, $proto) = /^\s*(.*?\S)\s+(\S+)\s*($proto_re*)\s*$/ or warn("Warning: File '$typemap' Line $. '$line' TYPEMAP entry needs 2 or 3 columns\n"), next; $type = TidyType($type); $type_kind{$type} = $kind; # prototype defaults to '$' $proto = "\$" unless $proto; warn("Warning: File '$typemap' Line $. '$line' Invalid prototype '$proto'\n") unless ValidProtoString($proto); $proto_letter{$type} = C_string($proto); } elsif (/^\s/) { $$current .= $_; } elsif ($mode eq 'Input') { s/\s+$//; $input_expr{$_} = ''; $current = \$input_expr{$_}; } else { s/\s+$//; $output_expr{$_} = ''; $current = \$output_expr{$_}; } } close(TYPEMAP); } my %valid_types = map {($_, 1)} grep {defined $input_expr{$type_kind{$_}}} keys %type_kind; my %valid_rtypes = map {($_, 1)} (grep {defined $output_expr{$type_kind{$_}}} keys %type_kind), 'void'; $o->{ILSM}{typeconv}{type_kind} = \%type_kind; $o->{ILSM}{typeconv}{input_expr} = \%input_expr; $o->{ILSM}{typeconv}{output_expr} = \%output_expr; $o->{ILSM}{typeconv}{valid_types} = \%valid_types; $o->{ILSM}{typeconv}{valid_rtypes} = \%valid_rtypes; } sub ValidProtoString ($) { my $string = shift; my $proto_re = "[" . quotemeta('\$%&*@;') . "]"; return ($string =~ /^$proto_re+$/) ? $string : 0; } sub TrimWhitespace { $_[0] =~ s/^\s+|\s+$//go; } sub TidyType { local $_ = shift; s|\s*(\*+)\s*|$1|g; s|(\*+)| $1 |g; s|\s+| |g; TrimWhitespace($_); $_; } sub C_string ($) { (my $string = shift) =~ s|\\|\\\\|g; $string; } #============================================================================== # Write the XS code #============================================================================== sub write_XS { my $o = shift; my $modfname = $o->{API}{modfname}; my $module = $o->{API}{module}; $o->mkpath($o->{API}{build_dir}); open XS, "> ".File::Spec->catfile($o->{API}{build_dir},"$modfname.xs") or croak $!; if ($o->{ILSM}{XSMODE}) { warn <{ILSM}{code} !~ /MODULE\s*=\s*$module\b/; While using Inline XSMODE, your XS code does not have a line with MODULE = $module You should use the Inline NAME config option, and it should match the XS MODULE name. END print XS $o->xs_code; } else { print XS $o->xs_generate; } close XS; } #============================================================================== # Generate the XS glue code (piece together lots of snippets) #============================================================================== sub xs_generate { my $o = shift; return join '', ($o->xs_includes, $o->xs_struct_macros, $o->xs_code, $o->xs_struct_code, $o->xs_bindings, $o->xs_boot, ); } sub xs_includes { my $o = shift; return $o->{ILSM}{AUTO_INCLUDE}; } sub xs_struct_macros { my $o = shift; return $o->{STRUCT}{'.macros'}; } sub xs_code { my $o = shift; return $o->{ILSM}{code}; } sub xs_struct_code { my $o = shift; return $o->{STRUCT}{'.xs'}; } sub xs_boot { my $o = shift; if (defined $o->{ILSM}{XS}{BOOT} and $o->{ILSM}{XS}{BOOT}) { return <{ILSM}{XS}{BOOT} END } return ''; } sub xs_bindings { my $o = shift; my $dir = '_Inline_test'; if($o->{CONFIG}{_TESTING}) { if(! -d $dir) { my $ok = mkdir $dir; warn $! if !$ok; } if(! -f "$dir/void_test") { warn $! if !open(TEST_FH, '>', "$dir/void_test"); warn $! if !close(TEST_FH); } } my ($pkg, $module) = @{$o->{API}}{qw(pkg module)}; my $prefix = (($o->{ILSM}{XS}{PREFIX}) ? "PREFIX = $o->{ILSM}{XS}{PREFIX}" : ''); my $XS = <{ILSM}{parser}; my $data = $parser->{data}; warn("Warning. No Inline C functions bound to Perl in ", $o->{API}{script}, "\n" . "Check your C function definition(s) for Inline compatibility\n\n") if ((not defined$data->{functions}) and ($^W)); for my $function (@{$data->{functions}}) { my $return_type = $data->{function}->{$function}->{return_type}; my @arg_names = @{$data->{function}->{$function}->{arg_names}}; my @arg_types = @{$data->{function}->{$function}->{arg_types}}; $XS .= join '', ("\n$return_type\n$function (", join(', ', @arg_names), ")\n"); for my $arg_name (@arg_names) { my $arg_type = shift @arg_types; last if $arg_type eq '...'; $XS .= "\t$arg_type\t$arg_name\n"; } my $listargs = ''; $listargs = pop @arg_names if (@arg_names and $arg_names[-1] eq '...'); my $arg_name_list = join(', ', @arg_names); if ($return_type eq 'void') { if($o->{CONFIG}{_TESTING}) { $XS .= < ".File::Spec->catfile($o->{API}{build_dir},"INLINE.h") or croak; print HEADER <<'END'; #define Inline_Stack_Vars dXSARGS #define Inline_Stack_Items items #define Inline_Stack_Item(x) ST(x) #define Inline_Stack_Reset sp = mark #define Inline_Stack_Push(x) XPUSHs(x) #define Inline_Stack_Done PUTBACK #define Inline_Stack_Return(x) XSRETURN(x) #define Inline_Stack_Void XSRETURN(0) #define INLINE_STACK_VARS Inline_Stack_Vars #define INLINE_STACK_ITEMS Inline_Stack_Items #define INLINE_STACK_ITEM(x) Inline_Stack_Item(x) #define INLINE_STACK_RESET Inline_Stack_Reset #define INLINE_STACK_PUSH(x) Inline_Stack_Push(x) #define INLINE_STACK_DONE Inline_Stack_Done #define INLINE_STACK_RETURN(x) Inline_Stack_Return(x) #define INLINE_STACK_VOID Inline_Stack_Void #define inline_stack_vars Inline_Stack_Vars #define inline_stack_items Inline_Stack_Items #define inline_stack_item(x) Inline_Stack_Item(x) #define inline_stack_reset Inline_Stack_Reset #define inline_stack_push(x) Inline_Stack_Push(x) #define inline_stack_done Inline_Stack_Done #define inline_stack_return(x) Inline_Stack_Return(x) #define inline_stack_void Inline_Stack_Void END close HEADER; } #============================================================================== # Generate the Makefile.PL #============================================================================== sub write_Makefile_PL { my $o = shift; $o->{ILSM}{xsubppargs} = ''; my $i = 0; for (@{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}) { $o->{ILSM}{xsubppargs} .= "-typemap \"$_\" "; $o->{ILSM}{MAKEFILE}{TYPEMAPS}->[$i++] = fix_space($_); } my %options = ( VERSION => $o->{API}{version} || '0.00', %{$o->{ILSM}{MAKEFILE}}, NAME => $o->{API}{module}, ); open MF, "> ".File::Spec->catfile($o->{API}{build_dir},"Makefile.PL") or croak; print MF <{API}{build_dir}; my $cwd = &cwd; ($cwd) = $cwd =~ /(.*)/ if $o->UNTAINT; chdir $build_dir; # Run these in an eval block, so that we get to chdir back to # $cwd if there's a failure. (Ticket #81375.) eval { $o->call('makefile_pl', '"perl Makefile.PL"', 2); $o->call('make', '"make"', 2); $o->call('make_install', '"make install"', 2); }; chdir $cwd; die if $@; #Die now that we've done the chdir back to $cwd. (#81375) $o->call('cleanup', 'Cleaning Up', 2); } sub makefile_pl { my ($o) = @_; my $perl; -f ($perl = $Config::Config{perlpath}) or ($perl = $^X) or croak "Can't locate your perl binary"; $o->system_call("$perl Makefile.PL", 'out.Makefile_PL'); $o->fix_make; } sub make { my ($o) = @_; my $make = $o->{ILSM}{MAKE} || $Config::Config{make} or croak "Can't locate your make binary"; $o->system_call("$make", 'out.make'); } sub make_install { my ($o) = @_; my $make = $o->{ILSM}{MAKE} || $Config::Config{make} or croak "Can't locate your make binary"; $o->system_call("$make pure_install", 'out.make_install'); } sub cleanup { my ($o) = @_; my ($modpname, $modfname, $install_lib) = @{$o->{API}}{qw(modpname modfname install_lib)}; if ($o->{API}{cleanup}) { $o->rmpath(File::Spec->catdir($o->{API}{directory},'build'), $modpname); my $autodir = File::Spec->catdir($install_lib,'auto',$modpname); unlink (File::Spec->catfile($autodir,'.packlist'), File::Spec->catfile($autodir,'$modfname.bs'), File::Spec->catfile($autodir,'$modfname.exp'), #MSWin32 File::Spec->catfile($autodir,'$modfname.lib'), #MSWin32 ); } } sub system_call { my ($o, $cmd, $output_file) = @_; my $build_noisy = defined $ENV{PERL_INLINE_BUILD_NOISY} ? $ENV{PERL_INLINE_BUILD_NOISY} : $o->{CONFIG}{BUILD_NOISY}; if (not $build_noisy) { $cmd = "$cmd > $output_file 2>&1"; } ($cmd) = $cmd =~ /(.*)/ if $o->UNTAINT; system($cmd) == 0 or croak($o->build_error_message($cmd, $output_file, $build_noisy)); } sub build_error_message { my ($o, $cmd, $output_file, $build_noisy) = @_; my $build_dir = $o->{API}{build_dir}; my $output = ''; if (not $build_noisy and open(OUTPUT, $output_file) ) { local $/; $output = ; close OUTPUT; } return $output . <{API}{language} code. The command that failed was: $cmd The build directory was: $build_dir To debug the problem, cd to the build directory, and inspect the output files. END } #============================================================================== # This routine fixes problems with the MakeMaker Makefile. #============================================================================== my %fixes = ( INSTALLSITEARCH => 'install_lib', INSTALLDIRS => 'installdirs', XSUBPPARGS => 'xsubppargs', INSTALLSITELIB => 'install_lib', ); sub fix_make { use strict; my (@lines, $fix); my $o = shift; $o->{ILSM}{install_lib} = $o->{API}{install_lib}; $o->{ILSM}{installdirs} = 'site'; open(MAKEFILE, '< Makefile') or croak "Can't open Makefile for input: $!\n"; @lines = ; close MAKEFILE; open(MAKEFILE, '> Makefile') or croak "Can't open Makefile for output: $!\n"; for (@lines) { if (/^(\w+)\s*=\s*\S+.*$/ and $fix = $fixes{$1} ) { my $fixed = $o->{ILSM}{$fix}; $fixed = fix_space($fixed) if $fix eq 'install_lib'; print MAKEFILE "$1 = $fixed\n"; } else { print MAKEFILE; } } close MAKEFILE; } sub quote_space { # Do nothing if $ENV{NO_INSANE_DIRNAMES} is set return $_[0] if $ENV{NO_INSANE_DIRNAMES}; # If $_[0] contains one or more doublequote characters, assume # that whitespace has already been quoted as required. Hence, # do nothing other than immediately return $_[0] as is. # We currently don't properly handle tabs either, so we'll # do the same if $_[0] =~ /\t/. return $_[0] if ($_[0] =~ /"/ || $_[0] =~ /\t/); # We want to split on /\s\-I/ not /\-I/ my @in = split /\s\-I/, $_[0]; my $s = @in - 1; my %s; my %q; # First up, let's reinstate the ' ' characters that split # removed for(my $i = 0; $i < $s; $i++) { $in[$i] .= ' '; } # This for{} block dies if it finds that any of the ' -I' # occurrences in $_[0] are part of a directory name. for(my $i = 1; $i < $s; $i++) { my $t = $in[$i + 1]; while($t =~ /\s$/) {chop $t} die "Found a '", $in[$i], "-I", $t, "' directory.", " INC Config argument is ambiguous.", " Please use doublequotes to signify your intentions" if -d ($in[$i] . "-I" . $t); } $s++; # Now the same as scalar(@in) # Remove (but also Keep track of the amount of) whitespace # at the end of each element of @in. for(my $i = 0; $i < $s; $i++) { my $count = 0; while($in[$i] =~ /\s$/) { chop $in[$i]; $count++; } $s{$i} = $count; } # Note which elements of @in still contain whitespace. These # (and only these) elements will be quoted for(my $i = 0; $i < $s; $i++) { $q{$i} = 1 if $in[$i] =~ /\s/; } # Reinstate the occurrences of '-I' that were removed by split(), # insert any quotes that are needed, reinstate the whitespace # that was removed earlier, then join() the array back together # again. for(my $i = 0; $i < $s; $i++) { $in[$i] = '-I' . $in[$i] if $i; $in[$i] = '"' . $in[$i] . '"' if $q{$i}; $in[$i] .= ' ' x $s{$i}; } # Note: If there was no whitespace that needed quoting, the # original argument should not have changed in any way. my $out = join '', @in; $out =~ s/"\-I\s+\//"\-I\//g; $_[0] = $out; } sub fix_space { $_[0] =~ s/ /\\ /g if $_[0] =~ / /; $_[0]; } #============================================================================== # This routine used by C/t/09parser to test that the expected parser is in use #============================================================================== sub _parser_test { my $dir = '_Inline_test'; if(! -d $dir) { my $ok = mkdir $dir; warn $! if !$ok; } warn $! if !open(TEST_FH, '>>', "$dir/parser_id"); print TEST_FH $_[0]; warn $! if !close(TEST_FH); } #======================================================================= # This routine used to cleanup files created by _TESTING (config option) #======================================================================= sub _testing_cleanup { my $dir = '_Inline_test'; if(-f "$dir/parser_id") { warn "Failed to unlink C/$dir/parser_id\n" if !unlink("$dir/parser_id"); } if(-f "$dir/void_test") { warn "Failed to unlink C/$dir/void_test\n" if !unlink("$dir/void_test"); } } 1; __END__ Inline-0.53/C/C.pod0000644000076400010400000004325612052612400015401 0ustar sisyphusAdministrators=head1 NAME Inline::C - Write Perl Subroutines in C =head1 DESCRIPTION C is a module that allows you to write Perl subroutines in C. Since version 0.30 the Inline module supports multiple programming languages and each language has its own support module. This document describes how to use Inline with the C programming language. It also goes a bit into Perl C internals. If you want to start working with programming examples right away, check out L. For more information on Inline in general, see L. =head1 Usage You never actually use C directly. It is just a support module for using C with C. So the usage is always: use Inline C => ...; or bind Inline C => ...; =head1 Function Definitions The Inline grammar for C recognizes certain function definitions (or signatures) in your C code. If a signature is recognized by Inline, then it will be available in Perl-space. That is, Inline will generate the "glue" necessary to call that function as if it were a Perl subroutine. If the signature is not recognized, Inline will simply ignore it, with no complaints. It will not be available from Perl-space, although it I be available from C-space. Inline looks for ANSI/prototype style function definitions. They must be of the form: return-type function-name ( type-name-pairs ) { ... } The most common types are: C, C, C, C, and C. But you can use any type for which Inline can find a typemap. Inline uses the C file distributed with Perl as the default. You can specify more typemaps with the TYPEMAPS configuration option. A return type of C may also be used. The following are examples of valid function definitions. int Foo(double num, char* str) { void Foo(double num, char* str) { void Foo(SV*, ...) { long Foo(int i, int j, ...) { SV* Foo(void) { # 'void' arg invalid with the ParseRecDescent parser. # Works only with the ParseRegExp parser. # See the section on USING (below). SV* Foo() { # Alternative to specifying 'void' arg. Is valid with # both the ParseRecDescent and ParseRegExp parsers. The following definitions would not be recognized: Foo(int i) { # no return type int Foo(float f) { # no (default) typemap for float int Foo(num, str) double num; char* str; { Notice that Inline only looks for function I, not function I. Definitions are the syntax directly preceding a function body. Also Inline does not scan external files, like headers. Only the code passed to Inline is used to create bindings; although other libraries can linked in, and called from C-space. =head1 C Configuration Options For information on how to specify Inline configuration options, see L. This section describes each of the configuration options available for C. Most of the options correspond either to MakeMaker or XS options of the same name. See L and L. =head2 AUTO_INCLUDE Specifies extra statements to automatically included. They will be added onto the defaults. A newline char will be automatically added. use Inline C => Config => AUTO_INCLUDE => '#include "yourheader.h"'; =head2 AUTOWRAP If you 'ENABLE => AUTOWRAP', Inline::C will parse function declarations (prototype statements) in your C code. For each declaration it can bind to, it will create a dummy wrapper that will call the real function which may be in an external library. This is a nice convenience for functions that would otherwise just require an empty wrapper function. This is similar to the base functionality you get from C. It can be very useful for binding to external libraries. =head2 BOOT Specifies C code to be executed in the XS BOOT section. Corresponds to the XS parameter. =head2 CC Specify which compiler to use. =head2 CCFLAGS Specify compiler flags - same as ExtUtils::MakeMaker's CCFLAGS option. Whatever gets specified here replaces the default $Config{ccflags}. Often, you'll want to add an extra flag or two without clobbering the default flags in which case you could instead use CCFLAGSEX (see below) or, iff Config.pm has already been loaded: use Inline C => Config => CCFLAGS => $Config{ccflags} . " -DXTRA -DTOO"; =head2 CCFLAGSEX Extend compiler flags. Sets CCFLAGS to $Config{ccflags} followed by a space, followed by the specified value: use Inline C => Config => CCFLAGSEX => "-DXTRA -DTOO"; =head2 FILTERS Allows you to specify a list of source code filters. If more than one is requested, be sure to group them with an array ref. The filters can either be subroutine references or names of filters provided by the supplementary Inline::Filters module. Your source code will be filtered just before it is parsed by Inline. The MD5 fingerprint is generated before filtering. Source code filters can be used to do things like stripping out POD documentation, pre-expanding #include statements or whatever else you please. For example: use Inline C => DATA => FILTERS => [Strip_POD => \&MyFilter => Preprocess ]; Filters are invoked in the order specified. See L for more information. =head2 INC Specifies an include path to use. Corresponds to the MakeMaker parameter. Expects a fully qualified path. use Inline C => Config => INC => '-I/inc/path'; =head2 LD Specify which linker to use. =head2 LDDLFLAGS Specify which linker flags to use. NOTE: These flags will completely override the existing flags, instead of just adding to them. So if you need to use those too, you must respecify them here. =head2 LIBS Specifies external libraries that should be linked into your code. Corresponds to the MakeMaker parameter. Provide a fully qualified path with the -L switch if the library is in a location where it won't be found automatically. use Inline C => Config => LIBS => '-lyourlib'; or use Inline C => Config => LIBS => '-L/your/path -lyourlib'; =head2 MAKE Specify the name of the 'make' utility to use. =head2 MYEXTLIB Specifies a user compiled object that should be linked in. Corresponds to the MakeMaker parameter. Expects a fully qualified path. use Inline C => Config => MYEXTLIB => '/your/path/yourmodule.so'; =head2 OPTIMIZE This controls the MakeMaker OPTIMIZE setting. By setting this value to C<'-g'>, you can turn on debugging support for your Inline extensions. This will allow you to be able to set breakpoints in your C code using a debugger like gdb. =head2 PREFIX Specifies a prefix that will be automatically stripped from C functions when they are bound to Perl. Useful for creating wrappers for shared library API-s, and binding to the original names in Perl. Also useful when names conflict with Perl internals. Corresponds to the XS parameter. use Inline C => Config => PREFIX => 'ZLIB_'; =head2 PRE_HEAD Specifies code that will precede the inclusion of all files specified in AUTO_INCLUDE (ie EXTERN.h, perl.h, XSUB.h, INLINE.h and anything else that might have been added to AUTO_INCLUDE by the user). If the specified value identifies a file, the contents of that file will be inserted, otherwise the specified value is inserted. use Inline C => Config => PRE_HEAD => $code_or_filename; =head2 TYPEMAPS Specifies extra typemap files to use. These types will modify the behaviour of the C parsing. Corresponds to the MakeMaker parameter. Specify either a fully qualified path or a path relative to the cwd (ie relative to what the cwd is at the time the script is loaded). use Inline C => Config => TYPEMAPS => '/your/path/typemap'; =head2 USING Specifies which parser to use. Default is 'ParseRecDescent', which uses the Parse::RecDescent module. The only other option is 'ParseRegExp', which uses the Inline::C::ParseRegExp module that ships with Inline. use Inline C => Config => USING => 'ParseRegExp'; =head1 C-Perl Bindings This section describes how the C variables get mapped to C variables and back again. First, you need to know how C passes arguments back and forth to subroutines. Basically it uses a stack (also known as the B). When a sub is called, all of the parenthesized arguments get expanded into a list of scalars and pushed onto the B. The subroutine then pops all of its parameters off of the B. When the sub is done, it pushes all of its return values back onto the B. The B is an array of scalars known internally as C's. The B is actually an array of B or C; therefore every element of the B is natively a C. For I about this, read C. So back to variable mapping. XS uses a thing known as "typemaps" to turn each C into a C type and back again. This is done through various XS macro calls, casts and the Perl API. See C. XS allows you to define your own typemaps as well for fancier non-standard types such as C-ed structs. Inline uses the default Perl typemap file for its default types. This file is called C, or something similar, depending on your Perl installation. It has definitions for over 40 types, which are automatically used by Inline. (You should probably browse this file at least once, just to get an idea of the possibilities.) Inline parses your code for these types and generates the XS code to map them. The most commonly used types are: - int - long - double - char* - void - SV* If you need to deal with a type that is not in the defaults, just use the generic C type in the function definition. Then inside your code, do the mapping yourself. Alternatively, you can create your own typemap files and specify them using the C configuration option. A return type of C has a special meaning to Inline. It means that you plan to push the values back onto the B yourself. This is what you need to do to return a list of values. If you really don't want to return anything (the traditional meaning of C) then simply don't push anything back. If ellipsis or C<...> is used at the end of an argument list, it means that any number of Cs may follow. Again you will need to pop the values off of the C yourself. See L<"Examples"> below. =head1 The Inline Stack Macros When you write Inline C, the following lines are automatically prepended to your code (by default): #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "INLINE.h" The file C defines a set of macros that are useful for handling the Perl Stack from your C functions. =over 4 =item Inline_Stack_Vars You'll need to use this one, if you want to use the others. It sets up a few local variables: C, C, C and C, for use by the other macros. It's not important to know what they do, but I mention them to avoid possible name conflicts. NOTE: Since this macro declares variables, you'll need to put it with your other variable declarations at the top of your function. It must come before any executable statements and before any other C macros. =item Inline_Stack_Items Returns the number of arguments passed in on the Stack. =item Inline_Stack_Item(i) Refers to a particular C in the Stack, where C is an index number starting from zero. Can be used to get or set the value. =item Inline_Stack_Reset Use this before pushing anything back onto the Stack. It resets the internal Stack pointer to the beginning of the Stack. =item Inline_Stack_Push(sv) Push a return value back onto the Stack. The value must be of type C. =item Inline_Stack_Done After you have pushed all of your return values, you must call this macro. =item Inline_Stack_Return(n) Return C items on the Stack. =item Inline_Stack_Void A special macro to indicate that you really don't want to return anything. Same as: Inline_Stack_Return(0); Please note that this macro actually B from your function. =back Each of these macros is available in 3 different styles to suit your coding tastes. The following macros are equivalent. Inline_Stack_Vars inline_stack_vars INLINE_STACK_VARS All of this functionality is available through XS macro calls as well. So why duplicate the functionality? There are a few reasons why I decided to offer this set of macros. First, as a convenient way to access the Stack. Second, for consistent, self documenting, non-cryptic coding. Third, for future compatibility. It occured to me that if a lot of people started using XS macros for their C code, the interface might break under Perl6. By using this set, hopefully I will be able to insure future compatibility of argument handling. Of course, if you use the rest of the Perl API, your code will most likely break under Perl6. So this is not a 100% guarantee. But since argument handling is the most common interface you're likely to use, it seemed like a wise thing to do. =head1 Writing C Subroutines The definitions of your C functions will fall into one of the following four categories. For each category there are special considerations. =over 4 =item 1 int Foo(int arg1, char* arg2, SV* arg3) { This is the simplest case. You have a non C return type and a fixed length argument list. You don't need to worry about much. All the conversions will happen automatically. =item 2 void Foo(int arg1, char* arg2, SV* arg3) { In this category you have a C return type. This means that either you want to return nothing, or that you want to return a list. In the latter case you'll need to push values onto the B yourself. There are a few Inline macros that make this easy. Code something like this: int i, max; SV* my_sv[10]; Inline_Stack_Vars; Inline_Stack_Reset; for (i = 0; i < max; i++) Inline_Stack_Push(my_sv[i]); Inline_Stack_Done; After resetting the Stack pointer, this code pushes a series of return values. At the end it uses C to mark the end of the return stack. If you really want to return nothing, then don't use the C macros. If you must use them, then set use C at the end of your function. =item 3 char* Foo(SV* arg1, ...) { In this category you have an unfixed number of arguments. This means that you'll have to pop values off the B yourself. Do it like this: int i; Inline_Stack_Vars; for (i = 0; i < Inline_Stack_Items; i++) handle_sv(Inline_Stack_Item(i)); The return type of C is C. =item 4 void* Foo(SV* arg1, ...) { In this category you have both a C return type and an unfixed number of arguments. Just combine the techniques from Categories 3 and 4. =back =head1 Examples Here are a few examples. Each one is a complete program that you can try running yourself. For many more examples see L. =head2 Example #1 - Greetings This example will take one string argument (a name) and print a greeting. The function is called with a string and with a number. In the second case the number is forced to a string. Notice that you do not need to C<#include >. The C header file which gets included by default, automatically loads the standard C header files for you. use Inline C; greet('Ingy'); greet(42); __END__ __C__ void greet(char* name) { printf("Hello %s!\n", name); } =head2 Example #2 - and Salutations This is similar to the last example except that the name is passed in as a C (pointer to Scalar Value) rather than a string (C). That means we need to convert the C to a string ourselves. This is accomplished using the C function which is part of the C internal API. See C for more info. One problem is that C doesn't automatically convert strings to numbers, so we get a little surprise when we try to greet C<42>. The program segfaults, a common occurence when delving into the guts of Perl. use Inline C; greet('Ingy'); greet(42); __END__ __C__ void greet(SV* sv_name) { printf("Hello %s!\n", SvPVX(sv_name)); } =head2 Example #3 - Fixing the problem We can fix the problem in Example #2 by using the C function instead. This function will stringify the C if it does not contain a string. C returns the length of the string as it's second parameter. Since we don't care about the length, we can just put C there, which is a special variable designed for that purpose. use Inline C; greet('Ingy'); greet(42); __END__ __C__ void greet(SV* sv_name) { printf("Hello %s!\n", SvPV(sv_name, PL_na)); } =head1 SEE ALSO For general information about Inline see L. For sample programs using Inline with C see L. For information on supported languages and platforms see L. For information on writing your own Inline Language Support Module, see L. Inline's mailing list is inline@perl.org To subscribe, send email to inline-subscribe@perl.org =head1 BUGS AND DEFICIENCIES =over 4 =item 1 If you use C function names that happen to be used internally by Perl, you will get a load error at run time. There is currently no functionality to prevent this or to warn you. For now, a list of Perl's internal symbols is packaged in the Inline module distribution under the filename C<'symbols.perl'>. Avoid using these in your code. =back =head1 AUTHOR Brian Ingerson Sisyphus fixed some bugs and is current co-maintainer. =head1 COPYRIGHT Copyright (c) 2000-2002. Brian Ingerson. Copyright (c) 2008, 2010-2012. Sisyphus. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut Inline-0.53/C/Changes0000644000076400010400000002256212140062003015777 0ustar sisyphusAdministratorsRevision history for Perl extension Inline::C. 0.53 Wed 1 May 2013 Version 0.53 released to CPAN Add C/t/23validate.t test script. 0.52_02 Wed 24 Apr 2013 Version 0.52_02 released to CPAN C.pm - Small tweak to setting of $o->{ILSM}{MAKEFILE}{INC} in validate() sub. Thanks, Ian Goodacre. (Ticket #11748.) 0.52_01 Thurs 11 Apr 2013 Version 0.52_01 released to CPAN 0.52 Thurs 07 Mar 2013 Version 0.52 released to CPAN. C-Cookbook.pod - Change the "Object Oriented Inline" example so that it doesn't emit a "print (...) interpreted as function" warning if it's run with warnings enabled. 0.51_03 Wed 28 Nov 2012 Version-0.51_03 released to CPAN. C-Cookbook.pod - Add additional example ("Providing a pure perl alternative"). C.pm - Change sub compile so that it chdirs back to the original cwd before it dies (if the build fails). (Ticket #81375.) 0.51_02 Tues 20 Nov 2012 Version-0.51_02 released to CPAN. Makefile.PL - correct typo. 0.51_01 20 Nov 2012 Version-0.51_01 released to CPAN. C.pm - setting $ENV{NO_INSANE_DIRNAMES} turns quote_space() into a no-op. (This is just an undocumented fallback option in case the quote_space() handling of spaces breaks something for someone who has no need of "space handling" anyway.) - additional tweaks to quote_space sub [Ticket #81172] Makefile.PL - Set EU::MM PREREQ_PM to 6.62, but only if the current version of EU::MM is 6.57_x, and even then only if building with INSTALL_BASE. (Ticket #81094). 0.51 Sat 13 Oct 2012 Version 0.51 released to CPAN. 0.50_03 Mon 8 Oct 2012 Fix Reini's patch (#67053). The original version of quote_space() caused a breakage whenever the INC Config argument contained more than one -I switch. (See #80026.) Also, provide tests for this in the test suite. 0.50_02 Thur 24 May 2012 Version 0.50_02 released to CPAN. 0.50_02 Tues 20 Mar 2012 C.pm - Add CCFLAGSEX and PRE_HEAD config options. C.pod - Document CCGLAGSEX and PRE_HEAD. Add new test files t/15ccflags.t, t/16ccflagsex.t, t/17prehead.t and t/prehead.in. ../MANIFEST - Add new files. 0.50_02 Sun 18 Mar 2012 C.pod - Rewrite CCFLAGS documentation to make it clear that setting it clobbers the existing CCFLAGS (which is $Config{ccflags}). Thanks, BrowserUk. ../Inline-FAQ.pod - Document the C/t/09parser.t test failure that can occur when Cygwin is in need of 'rebaseall' - and what to do about it. Thanks, davido. 0.50_02 Tues 14 Feb 2012 C.pm - Bump version number to 0.50_02 0.50_01 Sun 12 Feb 2012 0.50_01 released to CPAN lib/Inline/C/ParseRegExp.pm - Accommodate 'void' argument. t/14void_arg.t - Test that 'void' arg gets processed as desired. C.pod - Document new standing of 'void' argument. 0.50_01 Wed 8 Feb 2012 C.pm - Bump version number to 0.50_01 0.50 Tues 7 Feb 2012 Version 0.50 released to CPAN C.pm - Bump version number to 0.50 0.49_02 Fri 3 Feb 2012 Version 0.49_02 released to CPAN C.pm - Bring version numbering into line with recommendations made in http://perldoc.perl.org/perlmodstyle.html#Version-numbering 0.49_01 Thurs 02 Feb 2012 Version 0.49_01 released to CPAN. 0.49_01 Sun 25 Dec 2011 C.pm - Bump version to 0.49_01 C.pod - Fix typo. (Ticket 73108) 0.49 Thurs 8 Dec 2011 Version 0.49 released to CPAN. (No changes from 0.48_02). 0.48_02 Mon 5 Dec 2011 Version 0.48_02 released to CPAN. 0.48_02 Fri 9 Sep 2011 - Bump Inline::C version to 0.48_02 - Make a correction and provide some elaboration in the 'Discussion' relating to 'Object Oriented Inline' in C-Cookbook.pod. 0.48_02 Thurs 25 Aug 2011 Add example for accessing fortran code to C-Cookbook. 0.48_01 Mon 11 Apr 2011 Version 0.48_01 released to CPAN. - C/C.pm: [cpan #67053] Space in pwd. Patch from Reini Urban to work with spaces in the current dir. 0.48 Mon 21 Feb 2011 Version 0.48 released to CPAN. (No changes from 0.47_02.) 0.47_02 Tues 1 Feb 2011 Version 0.47_02 released to CPAN. - Change the Test::Warn dependency from 0.22 to 0.21 and specify it in top-level Makefile.PL instead of in C/Makefile.PL. 0.47_01 Sun 30 January 2011 Version 0.47_01 released to CPAN. - Use Test::Warn (on perl-5.8 and later) to check and suppress the warnings produced by C/t/08taint.t during 'make test'. (Ticket #54825.) 0.47 Fri 21 January 2011 Version 0.47 released to CPAN. No changes from 0.46_02 0.46_02 Sat 18 Dec 2010 - Makefile.PL: insert 'return 1 if -e $_[0];' at beginning of find_executable() subroutine. (RT ticket 61218) 0.46_02 Sat 17 Apr 2010 - C-Cookbook.pod: Fix callback example. (RT ticket 56652) 0.46_01 Wed 31 Mar 2010 (and released to CPAN as 0.46_01) - C.pm: local()ise $_ in get_types(). (RT ticket 55607) - C.pm: introduce capability to check that xs_bindings() is working as expected. (Prompted by RT ticket 55543) - C.pm: add _testing_cleanup() to facilitate cleaning up of files created by setting the _TESTING config option - t/08taint.t: Warn the user to expect "Blindly untainting ..." warnings - t/09parser.t: Make use of Inline::C::_testing_cleanup() - add t/10callback.t (mainly in response to RT ticket 55543) and t/11default_readonly.t (in response to RT ticket 55607). 0.46_01 Mon 8 Mar 2010 - Add sub _parser_test() to C.pm (enables us to check which parser is in use). - Add tests (C/t/09parser.t) to check that the expected parser is being used - makes use of '_TESTING' config option. (Involves minor changes to lib/Inline/C/ParseRecDescent.pm and lib/Inline/C/ParseRegExp.pm). 0.46_01 Sun 14 Feb 2010 - Second attempt at accommodating 'ccache cc' compiler (RT ticket 40140) 0.46 Fri 12 Feb 2010 - Same as 0.45_02. 0.45_02 Fri 5 Feb 2010 - Add C/t/08taint.t as part of RT ticket 13084 fix. See top level "Changes" file. 0.45_01 Thurs 28 Jan 2010 - Fix Rt tickets 40140, 45417 and 49419. See top level "Changes" file. 0.45 Sat Nov 22 2008 - No changes from 0.44_01 0.44_01 Tues Oct 11 2008 - In C/C.pm, allow for the calling of multiple typemaps (RT ticket 5639), and have the "No Inline C functions bound to Perl" warning specify the file for which no bindings were found (RT ticket 17774). 0.43 Sun Jul 22 08:15:26 PDT 2001 - Auto add script directory to INC path (-I).. 0.43 Sat Jul 21 12:38:37 PDT 2001 - Added support for XSMODE. 0.43 Fri Jul 20 03:29:08 PDT 2001 - Added OPTIMIZE config parameter for gdb debugging 0.43 Thu Jul 19 17:29:17 PDT 2001 - Use $Config{dlext} instead of $Config{so} 0.43 Sat Jul 7 13:18:36 PDT 2001 - Move the creation of a parser from parse() to get_parser(). This allows Inline::CPP to override only get_parser(). (NEILW) 0.43 Sat Jul 7 12:53:33 PDT 2001 - Break up the generation of XS code into smaller stages which can be overridden in Inline::CPP. Makes the code somewhat longer, but more clear. (NEILW) 0.42 Sun Jun 10 23:50:27 PDT 2001 - Patch that fixes STRUCTS config option being used for explicit structs. 0.42 Sun Jun 10 18:34:36 PDT 2001 - Patch that prevents Inline from creating a nonexistent sitelib Thanks Joey Hess. 0.41 Tue Jun 5 01:49:32 PDT 2001 - Added AUTOWRAP config option 0.40 Sat May 26 13:47:16 PDT 2001 - Added hack to make work with Inline::Files and +w 0.40 Wed May 23 20:21:32 PDT 2001 - 0.40 integration Changed object references Account for no trailing '/' in paths 0.34 Sun May 6 16:56:53 PDT 2001 - Changed the generated Makefile.PL to not create any dependencies between Makefile and Makefile.PL. This was creating a problem on an HP-UX system using AFS. Inline users should never need this dependency anyways. 0.34 Tue May 1 00:05:58 PDT 2001 - Fixed compiler detection bugs in Makefile.PL 0.33 Sat Apr 28 20:20:29 PDT 2001 - Made Inline::C a base class for Inline::CPP 0.33 Sat Apr 28 20:20:29 PDT 2001 - Added support for Inline::Filters. FILTERS config option. 0.33 Sat Apr 28 20:20:29 PDT 2001 - Made installation of Inline::C optional. For those people without a C compiler who may wish to use Java. 0.33 Sat Apr 28 20:20:29 PDT 2001 - Rearranged test harness. Moved all C tests from Inline to Inline::C 0.32 Mon Feb 26 15:36:56 PST 2001 - Added MAKE config option - Changed LDFLAGS to proper name LDDLFLAGS. (MakeMaker) 0.32 Fri Feb 23 03:17:42 PST 2001 - Fixed Debian bug with $Config{installprivlib}. Also added warning if no default typemap, and croak if no typemaps at all. 0.32 Fri Feb 23 03:16:27 PST 2001 - Special case for AIX ($Config{so}) 0.31 Thu Jan 18 22:02:17 PST 2001 - Added the following configuration options: 'CC', 'LD', 'CCFLAGS, 'LDFLAGS'. These are proxies for the MakeMaker options of the same names. 0.31 Sat Jan 13 14:44:28 PST 2001 - Allow relative paths in TYPEMAPS files. - Added a test 't/typemap.t' for this 0.31 Sat Jan 13 12:41:38 PST 2001 - Changed over to new Inline DIRECTORY structure. 0.30 Fri Dec 8 01:55:43 PST 2000 - Created Inline::C. Separated C code from Inline 0.26 Inline-0.53/C/lib/0000755000076400010400000000000012140062610015247 5ustar sisyphusAdministratorsInline-0.53/C/lib/Inline/0000755000076400010400000000000012140062610016465 5ustar sisyphusAdministratorsInline-0.53/C/lib/Inline/C/0000755000076400010400000000000012140062610016647 5ustar sisyphusAdministratorsInline-0.53/C/lib/Inline/C/ParseRecDescent.pm0000644000076400010400000001124412052612400022221 0ustar sisyphusAdministratorspackage Inline::C::ParseRecDescent; use strict; use Carp; sub register { { extends => [qw(C)], overrides => [qw(get_parser)], } } sub get_parser { my $o = shift; Inline::C::_parser_test("Inline::C::ParseRecDescent::get_parser called\n") if $o->{CONFIG}{_TESTING}; eval { require Parse::RecDescent }; croak <new(grammar()) } sub grammar { <<'END'; code: part(s) { return 1; } part: comment | function_definition { my $function = $item[1][0]; $return = 1, last if $thisparser->{data}{done}{$function}++; push @{$thisparser->{data}{functions}}, $function; $thisparser->{data}{function}{$function}{return_type} = $item[1][1]; $thisparser->{data}{function}{$function}{arg_types} = [map {ref $_ ? $_->[0] : '...'} @{$item[1][2]}]; $thisparser->{data}{function}{$function}{arg_names} = [map {ref $_ ? $_->[1] : '...'} @{$item[1][2]}]; } | function_declaration { $return = 1, last unless $thisparser->{data}{AUTOWRAP}; my $function = $item[1][0]; $return = 1, last if $thisparser->{data}{done}{$function}++; my $dummy = 'arg1'; push @{$thisparser->{data}{functions}}, $function; $thisparser->{data}{function}{$function}{return_type} = $item[1][1]; $thisparser->{data}{function}{$function}{arg_types} = [map {ref $_ ? $_->[0] : '...'} @{$item[1][2]}]; $thisparser->{data}{function}{$function}{arg_names} = [map {ref $_ ? ($_->[1] || $dummy++) : '...'} @{$item[1][2]}]; } | anything_else comment: m{\s* // [^\n]* \n }x | m{\s* /\* (?:[^*]+|\*(?!/))* \*/ ([ \t]*)? }x function_definition: rtype IDENTIFIER '(' (s?) ')' '{' { [@item[2,1], $item[4]] } function_declaration: rtype IDENTIFIER '(' (s?) ')' ';' { [@item[2,1], $item[4]] } rtype: rtype1 | rtype2 rtype1: modifier(s?) TYPE star(s?) { $return = $item[2]; $return = join ' ',@{$item[1]},$return if @{$item[1]} and $item[1][0] ne 'extern'; $return .= join '',' ',@{$item[3]} if @{$item[3]}; return undef unless (defined $thisparser->{data}{typeconv} {valid_rtypes}{$return}); } rtype2: modifier(s) star(s?) { $return = join ' ',@{$item[1]}; $return .= join '',' ',@{$item[2]} if @{$item[2]}; return undef unless (defined $thisparser->{data}{typeconv} {valid_rtypes}{$return}); } arg: type IDENTIFIER {[@item[1,2]]} | '...' arg_decl: type IDENTIFIER(s?) {[$item[1], $item[2][0] || '']} | '...' type: type1 | type2 type1: modifier(s?) TYPE star(s?) { $return = $item[2]; $return = join ' ',@{$item[1]},$return if @{$item[1]}; $return .= join '',' ',@{$item[3]} if @{$item[3]}; return undef unless (defined $thisparser->{data}{typeconv} {valid_types}{$return}); } type2: modifier(s) star(s?) { $return = join ' ',@{$item[1]}; $return .= join '',' ',@{$item[2]} if @{$item[2]}; return undef unless (defined $thisparser->{data}{typeconv} {valid_types}{$return}); } modifier: 'unsigned' | 'long' | 'extern' | 'const' star: '*' IDENTIFIER: /\w+/ TYPE: /\w+/ anything_else: /.*/ END } my $hack = sub { # Appease -w using Inline::Files print Parse::RecDescent::IN ''; print Parse::RecDescent::IN ''; print Parse::RecDescent::TRACE_FILE ''; print Parse::RecDescent::TRACE_FILE ''; }; 1; __DATA__ =head1 NAME Inline::C::ParseRecDescent - The Classic Inline::C Parser =head1 SYNOPSIS use Inline C => DATA => USING => ParseRecDescent =head1 DESCRIPTION This module is Inline::C's original Parse::RecDescent based parser. It was previously packaged as Inline::C::grammar. Try Inline::C::ParseRegExp for an alternative. =head2 AUTHOR Brian Ingerson =head1 COPYRIGHT Copyright (c) 2002. Brian Ingerson. Copyright (c) 2008, 2010, 2011. Sisyphus. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut Inline-0.53/C/lib/Inline/C/ParseRegExp.pm0000644000076400010400000001331112052612400021371 0ustar sisyphusAdministratorspackage Inline::C::ParseRegExp; use strict; use Carp; sub register { { extends => [qw(C)], overrides => [qw(get_parser)], } } sub get_parser { Inline::C::_parser_test("Inline::C::ParseRegExp::get_parser called\n") if $_[0]->{CONFIG}{_TESTING}; bless {}, 'Inline::C::ParseRegExp' } sub code { my($self,$code) = @_; # These regular expressions were derived from Regexp::Common v0.01. my $RE_comment_C = q{(?:(?:\/\*)(?:(?:(?!\*\/)[\s\S])*)(?:\*\/))}; my $RE_comment_Cpp = q{(?:\/\*(?:(?!\*\/)[\s\S])*\*\/|\/\/[^\n]*\n)}; my $RE_quoted = (q{(?:(?:\")(?:[^\\\"]*(?:\\.[^\\\"]*)*)(?:\")} .q{|(?:\')(?:[^\\\']*(?:\\.[^\\\']*)*)(?:\'))}); our $RE_balanced_brackets; $RE_balanced_brackets = qr'(?:[{]((?:(?>[^{}]+)|(??{$RE_balanced_brackets}))*)[}])'; our $RE_balanced_parens; $RE_balanced_parens = qr'(?:[(]((?:(?>[^()]+)|(??{$RE_balanced_parens}))*)[)])'; # First, we crush out anything potentially confusing. # The order of these _does_ matter. $code =~ s/$RE_comment_C/ /go; $code =~ s/$RE_comment_Cpp/ /go; $code =~ s/^\#.*(\\\n.*)*//mgo; #$code =~ s/$RE_quoted/\"\"/go; # Buggy, if included. $code =~ s/$RE_balanced_brackets/{ }/go; $self->{_the_code_most_recently_parsed} = $code; # Simplifies debugging. my $normalize_type = sub { # Normalize a type for lookup in a typemap. my($type) = @_; # Remove "extern". # But keep "static", "inline", "typedef", etc, # to cause desirable typemap misses. $type =~ s/\bextern\b//g; # Whitespace: only single spaces, none leading or trailing. $type =~ s/\s+/ /g; $type =~ s/^\s//; $type =~ s/\s$//; # Adjacent "derivative characters" are not separated by whitespace, # but _are_ separated from the adjoining text. # [ Is really only * (and not ()[]) needed??? ] $type =~ s/\*\s\*/\*\*/g; $type =~ s/(?<=[^ \*])\*/ \*/g; return $type; }; # The decision of what is an acceptable declaration was originally # derived from Inline::C::grammar.pm version 0.30 (Inline 0.43). my $re_plausible_place_to_begin_a_declaration = qr { # The beginning of a line, possibly indented. # (Accepting indentation allows for C code to be aligned with # its surrounding perl, and for backwards compatibility with # Inline 0.43). (?m: ^ ) \s* }xo; # Instead of using \s , we dont tolerate blank lines. # This matches user expectation better than allowing arbitrary # vertical whitespace. my $sp = qr{[ \t]|\n(?![ \t]*\n)}; my $re_type = qr {( (?: \w+ $sp* )+? # words (?: \* $sp* )* # stars )}xo; my $re_identifier = qr{ (\w+) $sp* }xo; while($code =~ m{ $re_plausible_place_to_begin_a_declaration ( $re_type $re_identifier $RE_balanced_parens $sp* (\;|\{) ) }xgo) { my($type, $identifier, $args, $what) = ($2,$3,$4,$5); $args = "" if $args =~ /^\s+$/; my $is_decl = $what eq ';'; my $function = $identifier; my $return_type = &$normalize_type($type); my @arguments = split ',', $args; goto RESYNC if $is_decl && !$self->{data}{AUTOWRAP}; goto RESYNC if $self->{data}{done}{$function}; goto RESYNC if !defined $self->{data}{typeconv}{valid_rtypes}{$return_type}; my(@arg_names,@arg_types); my $dummy_name = 'arg1'; foreach my $arg (@arguments) { my $arg_no_space = $arg; $arg_no_space =~ s/\s//g; # If $arg_no_space is 'void', there will be no identifier. if(my($type, $identifier) = $arg =~ /^\s*$re_type(?:$re_identifier)?\s*$/o) { my $arg_name = $identifier; my $arg_type = &$normalize_type($type); if((!defined $arg_name) && ($arg_no_space ne 'void')) { goto RESYNC if !$is_decl; $arg_name = $dummy_name++; } goto RESYNC if ((!defined $self->{data}{typeconv}{valid_types}{$arg_type}) && ($arg_no_space ne 'void')); # Push $arg_name onto @arg_names iff it's defined. Otherwise ($arg_no_space # was 'void'), push the empty string onto @arg_names (to avoid uninitialized # warnings emanating from C.pm). defined($arg_name) ? push(@arg_names,$arg_name) : push(@arg_names, ''); if($arg_name) {push(@arg_types,$arg_type)} else {push(@arg_types,'')} # $arg_no_space was 'void' - this push() avoids 'uninitialized' warnings from C.pm } elsif($arg =~ /^\s*\.\.\.\s*$/) { push(@arg_names,'...'); push(@arg_types,'...'); } else { goto RESYNC; } } # Commit. push @{$self->{data}{functions}}, $function; $self->{data}{function}{$function}{return_type}= $return_type; $self->{data}{function}{$function}{arg_names} = [@arg_names]; $self->{data}{function}{$function}{arg_types} = [@arg_types]; $self->{data}{done}{$function} = 1; next; RESYNC: # Skip the rest of the current line, and continue. $code =~ /\G[^\n]*\n/gc; } return 1; # We never fail. } 1; __DATA__ =head1 NAME Inline::C::ParseRegExp - The New and Improved Inline::C Parser =head1 SYNOPSIS use Inline C => DATA => USING => ParseRegExp; =head1 DESCRIPTION This module is a much faster version of Inline::C's Parse::RecDescent parser. It is based on regular expressions instead. =head2 AUTHOR Mitchell N Charity =head1 COPYRIGHT Copyright (c) 2002. Brian Ingerson. Copyright (c) 2008, 2010-2012. Sisyphus. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut Inline-0.53/C/Makefile.PL0000644000076400010400000000571312052647327016501 0ustar sisyphusAdministratorsuse strict; use ExtUtils::MakeMaker; use Config; use File::Spec; my ($cc, $exe) = @Config{'cc', '_exe'}; $cc =~ s/\s+-.+$//; #remove possible trailing options my $found = 0; my $delim = $Config::Config{path_sep}; if ($cc =~ m|/:\[|) { my $comp = (split /\./, $cc)[0]; $found = -f "$comp$exe"; } # $Config{cc} might be something like 'ccache cc' elsif ($cc =~ m|ccache|) { my @cc = split /\s+/, $cc; $found = 1; for (@cc) { if (!find_executable($_)) { $found = 0; last; } } } else { $found = find_executable($cc); } print < 6.62} : {}; if ($answer =~ /^(y|yes)$/i) { my %h = (NAME => 'Inline::C', clean => {FILES => '_Inline_test'}, PREREQ_PM => $prereq_pm); WriteMakefile(%h); } else { open MF, "> Makefile" or die "Can't open Makefile for output"; print MF <<'END'; all:: test:: clean:: END close MF; } sub find_executable { return 1 if -e $_[0]; my($cc) = @_; my $comp = (split /\./, $cc)[0]; # $Config{cc} might be something like '/some/place/cc' if ($cc =~ m|/|) { return -f "$comp$exe" || -l $cc; } for my $lib (split $delim, $ENV{PATH}) { return 1 if -f File::Spec->catfile($lib,"$comp$exe"); } } # Inline::C is known to not build successfully with EU-MM-6.57_05. # when INSTALL_BASE is set. (Ticket #81094.) sub install_base_problem { return 0 unless $ExtUtils::MakeMaker::VERSION =~ /6\.57/; for my $arg(@ARGV) { if($arg =~ /INSTALL_BASE/) { warn "\n There are problems with some versions of EU-MM-6.57_x and INSTALL_BASE\n", " Setting PREREQ_PM to version 6.62 (which is known to be fine.)\n\n"; return 1; } } return 0; } Inline-0.53/C/README0000644000076400010400000000272712052612400015371 0ustar sisyphusAdministratorsINTRODUCTION: Inline::C - Write Perl subroutines in C. Inline::C is the Inline Language Support Module (ILSM) for C Example: use Inline C => <<'END'; SV* JAxH(char* x) { return newSVpvf ("Just Another %s Hacker",x); } END print JAxH('Inline'), "\n"; When run, this complete program prints: Just Another Inline Hacker ------------------------------------------------------------------------------- INSTALLATION: This module requires the Inline module with which it is distributed. It also requires the appropriate C compiler. (Where appropriate means the one referred to in your Config.pm) Inline::C is packaged with Inline.pm. It is not necessary to install Inline::C to use Inline with some other language, like Java. ------------------------------------------------------------------------------- INFORMATION: = For more infor on Inline, see 'perldoc Inline' and 'perldoc Inline-Support' = For information about Inline::, see 'perldoc Inline::C' and 'perldoc Inline::C-Cookbook' = For information on writing your own Inline extension see 'perldoc Inline-API' = For information about the Perl5 internal C API, see 'perldoc perlapi' or try http://www.perldoc.com/perl5.6/pod/perlapi.html The Inline.pm mailing list is inline@perl.org. Send email to inline-subscribe@perl.org to subscribe. Please send questions and comments to "Brian Ingerson" Copyright (c) 2001, 2002. Brian Ingerson. Copyright (c) 2008, 2010, 2011. Sisyphus. Inline-0.53/C/rt/0000755000076400010400000000000012140062610015126 5ustar sisyphusAdministratorsInline-0.53/C/rt/grammars.t0000644000076400010400000001303012052612400017121 0ustar sisyphusAdministrators# Test both parser implementations to ensure they work the same use strict; use Test; use YAML; use File::Spec; use blib; require Inline::C::ParseRecDescent; require Inline::C::ParseRegExp; # Do all the typemap foo that Inline::C does require Inline::C; use Config; my $typemap = File::Spec->catfile($Config::Config{installprivlib}, 'ExtUtils', 'typemap'); my $o = bless {}, 'Inline::C'; push @{$o->{ILSM}{MAKEFILE}{TYPEMAPS}}, $typemap if -f $typemap; $o->get_types; # Create new instances of each parser my $recdescent = Inline::C::ParseRecDescent->get_parser(); my $regexp = Inline::C::ParseRegExp->get_parser(); $recdescent->{data}{typeconv} = $o->{ILSM}{typeconv}; $regexp->{data}{typeconv} = $o->{ILSM}{typeconv}; my @test_objects = @{YAML::Load($Inline::cases)}; plan(tests => 2 * @test_objects); for my $case (@test_objects) { my $input = $case->{input}; my $expect = $case->{expect}; my @outputs; for ($recdescent, $regexp) { # Without a fresh copy of these objects, the same stuff is parsed over # and over. However, because Parse::RecDescent is sllloooww, we can't # just construct a new object over and over. Hence, new() 'em up top, # and then clone them here. my $parser = deep_clone($_); $parser->code($input); delete $parser->{data}{typeconv}; my $output = YAML::Dump($parser->{data}); $output =~ s/^---.*\n//; push @outputs, $output; } ok($outputs[0], $expect, "ParseRecDescent failed for:$input\n"); ok($outputs[1], $expect, "ParseRegExp failed for:$input\n"); } use Data::Dumper; sub deep_clone { my $VAR1; eval Dumper($_[0]); $VAR1 } BEGIN { ($Inline::cases, undef) = (< 1); ok(1); Inline-0.53/C/t/01syntax.t0000644000076400010400000000233712052612400016625 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; BEGIN { plan(tests => 5, todo => [], onfail => sub {}, ); } use Inline Config => DIRECTORY => '_Inline_test'; # test 1 - Check string syntax ok(add(3, 7) == 10); # test 2 - Check string syntax again ok(subtract(3, 7) == -4); # test 3 - Check DATA syntax ok(multiply(3, 7) == 21); # test 4 - Check DATA syntax again ok(divide(7, -3) == -2); use Inline 'C'; use Inline C => 'DATA'; use Inline C => <<'END_OF_C_CODE'; int add(int x, int y) { return x + y; } int subtract(int x, int y) { return x - y; } END_OF_C_CODE Inline->bind(C => <<'END'); int incr(int x) { return x + 1; } END # test 5 - Test Inline->bind() syntax ok(incr(incr(7)) == 9); __END__ # unused code or maybe AutoLoader stuff sub crap { return 'crap'; } __C__ int multiply(int x, int y) { return x * y; } __C__ int divide(int x, int y) { return x / y; } Inline-0.53/C/t/02config.t0000644000076400010400000000203012052612400016533 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; BEGIN { plan(tests => 3, todo => [], onfail => sub {}, ); } # test 1 - Make sure config options are type checked BEGIN { eval <<'END'; use Inline(C => "void foo(){}", LIBS => {X => 'Y'}, ); END ok(1); # ok($@ =~ /must be a string or an array ref/); } # test 2 - Make sure bogus config options croak BEGIN { eval <<'END'; use Inline(C => "void foo(){}", FOO => 'Bar', ); END ok($@ =~ /not a valid config option/); } # test 3 - Test the PREFIX config option BEGIN { use Inline(C => 'char* XYZ_Howdy(){return "Hello There";}', PREFIX => 'XYZ_', ); ok(Howdy eq "Hello There"); } __END__ Inline-0.53/C/t/03typemap.t0000644000076400010400000000124312052612400016753 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; plan(tests => 1, todo => [], onfail => sub {}, ); use Inline C => DATA => TYPEMAPS => File::Spec->catfile(File::Spec->curdir(),'t','typemap'); # test 1 ok(int((add_em_up(1.2, 3.4) + 0.001) * 10) == 46); __END__ __C__ float add_em_up(float x, float y) { return x + y; } Inline-0.53/C/t/04perlapi.t0000644000076400010400000000116112052612400016730 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; BEGIN { plan(tests => 1, todo => [], onfail => sub {}, ); } use Inline 'C'; $main::myvar = $main::myvar = "myvalue"; # test 1 ok(lookup('main::myvar') eq "myvalue"); __END__ __C__ SV* lookup(char* var) { return perl_get_sv(var, 0); } Inline-0.53/C/t/05xsmode.t0000644000076400010400000000141512052612400016576 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; BEGIN { plan(tests => 1, todo => [], onfail => sub {}, ); } use Inline C => DATA => ENABLE => XSMODE => NAME => 'xsmode'; # test 1 ok(add(5, 10) == 15); __END__ __C__ #include "EXTERN.h" #include "perl.h" #include "XSUB.h" MODULE = xsmode PACKAGE = main int add (x, y) int x int y CODE: RETVAL = x + y; OUTPUT: RETVAL Inline-0.53/C/t/06parseregexp.t0000644000076400010400000000160212052612400017623 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; plan(tests => 1, todo => [], onfail => sub {}, ); use Inline C => Config => USING => 'ParseRegExp'; use Inline C => <<'EOC'; void foo() { printf( "Hello World\n" ); } void foo2() { Inline_Stack_Vars; int i; Inline_Stack_Reset; if(0) printf( "Hello World again\n" ); /* tests balanced quotes bugfix */ for(i = 24; i < 30; ++ i) Inline_Stack_Push(sv_2mortal(newSViv(i))); Inline_Stack_Done; Inline_Stack_Return(6); } EOC my @z = foo2(); ok(scalar(@z) == 6); Inline-0.53/C/t/07typemap_multi.t0000644000076400010400000000251212052612400020171 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; plan(tests => 3, todo => [], onfail => sub {}, ); my $obj = Soldier->new('Benjamin', 'Private', 11111); ok($obj->get_serial == 11111); ok($obj->get_name eq 'Benjamin'); ok($obj->get_rank eq 'Private'); package Soldier; use Inline C => Config => USING => 'ParseRegExp', TYPEMAPS => ['t/typemap', 't/soldier_typemap']; use Inline C => <<'END'; typedef struct { char* name; char* rank; long serial; } Soldier; Soldier * new(char* class, char* name, char* rank, long serial) { Soldier* soldier; New(42, soldier, 1, Soldier); soldier->name = savepv(name); soldier->rank = savepv(rank); soldier->serial = serial; return soldier; } char* get_name(Soldier * obj) { return obj->name; } char* get_rank(Soldier * obj) { return obj->rank; } long get_serial(Soldier * obj) { return obj->serial; } void DESTROY(Soldier* obj) { Safefree(obj->name); Safefree(obj->rank); Safefree(obj); } END Inline-0.53/C/t/08taint.t0000755000076400010400000000214312052612400016423 0ustar sisyphusAdministrators#!perl -T BEGIN { if($] < 5.007) { print "1..1\n"; warn "Skipped for perl 5.6.x\n"; print "ok 1\n"; exit(0); } }; BEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use warnings; use strict; use Test::More tests => 10; use Test::Warn; # Suppress "Set up gcc environment ..." warning. # (Affects ActivePerl only.) $ENV{ACTIVEPERL_CONFIG_SILENT} = 1; my $w1 = 'Blindly untainting tainted fields in %ENV'; my $w2 = 'Blindly untainting Inline configuration file information'; my $w3 = 'Blindly untainting tainted fields in Inline object'; warnings_like {require_taint_1()} [qr/$w1/, qr/$w2/, qr/$w1/, qr/$w3/], 'warn_test 1'; warnings_like {require_taint_2()} [qr/$w1/, qr/$w2/, qr/$w1/, qr/$w3/], 'warn_test 2'; warnings_like {require_taint_3()} [qr/$w1/, qr/$w2/, qr/$w1/, qr/$w3/, qr/$w1/, qr/$w2/, qr/$w1/, qr/$w3/], 'warn_test 3'; sub require_taint_1 { require './t/08taint_1.p'; } sub require_taint_2 { require './t/08taint_2.p'; } sub require_taint_3 { require './t/08taint_3.p'; } Inline-0.53/C/t/08taint_1.p0000644000076400010400000000037112052612400016635 0ustar sisyphusAdministratorsBEGIN {is(${^TAINT}, 1, '1: taint_is_on');}; use Inline Config => UNTAINT => 1, DIRECTORY => '_Inline_test'; use Inline C => <<'END_OF_C_CODE'; int add(int x, int y) { return x + y; } END_OF_C_CODE is(add(7,3), 10, 'add_test'); 1; Inline-0.53/C/t/08taint_2.p0000644000076400010400000000034612052612400016640 0ustar sisyphusAdministratorsBEGIN {is(${^TAINT}, 1, '2: taint_is_on');}; use Inline Config => UNTAINT => 1, DIRECTORY => '_Inline_test'; Inline->bind(C => <<'END'); int incr(int x) { return x + 1; } END is(incr(incr(7)), 9, 'incr_test'); 1; Inline-0.53/C/t/08taint_3.p0000644000076400010400000000060012052612400016632 0ustar sisyphusAdministratorsBEGIN {is(${^TAINT}, 1, '3: taint_is_on');}; use Inline C; use Inline C => 'DATA'; Inline->init() ; use Inline Config => UNTAINT => 1, DIRECTORY => '_Inline_test'; is(multiply(3, 7), 21, 'multiply_test'); is(divide(7, -3), -2, 'divide_test'); 1; __DATA__ __C__ int multiply(int x, int y) { return x * y; } __C__ int divide(int x, int y) { return x / y; } Inline-0.53/C/t/09parser.t0000644000076400010400000001232312052612400016577 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use diagnostics; BEGIN { warn "\nThis test could take a couple of minutes to run\n"; }; print "1..1\n"; #use Inline Config => # DIRECTORY => '_Inline_test', # _TESTING => 1; ########## main:foo_ ######## use Inline C => Config => DIRECTORY => '_Inline_test', FORCE_BUILD => 1, _TESTING => 1, USING => 'ParseRegExp'; use Inline C => <<'EOC'; int foo_() { return -1; } EOC ########## main:_foo_ ######## # Use same Config options as for main::foo() use Inline C => <<'EOC'; int _foo_() { return -3; } EOC ########## main:_foo ######## use Inline C => Config => DIRECTORY => '_Inline_test', FORCE_BUILD => 1, _TESTING => 1, USING => 'ParseRecDescent'; use Inline C => <<'EOC'; int _foo() { return 2; } EOC ########## main:foo ######## use Inline C => Config => DIRECTORY => '_Inline_test', FORCE_BUILD => 1, _TESTING => 1, USING => 'ParseRegExp'; use Inline C => <<'EOC'; int foo() { return 1; } EOC ########## main:bar ######## # No 'USING' value specified here - will use default (ParseRecDescent). use Inline C => Config => DIRECTORY => '_Inline_test', FORCE_BUILD => 1, _TESTING => 1; use Inline C => <<'EOC'; int bar() { return 2; } EOC ########## main:baz ######## use Inline C => Config => DIRECTORY => '_Inline_test', FORCE_BUILD => 1, _TESTING => 1, USING => 'ParseRecDescent'; use Inline C => <<'EOC'; int baz() { return 3; } EOC ########## main:foobar ######## # No 'USING' value specified here - will use default (ParseRecDescent). use Inline C => Config => DIRECTORY => '_Inline_test', FORCE_BUILD => 1, _TESTING => 1; use Inline C => <<'EOC'; int foobar() { return 4; } EOC ########## main:foobarbaz ######## # Use same config options as for main::foobar(). use Inline C => <<'EOC'; int foobarbaz() { return 5; } EOC ########## FOO::foo ######## package FOO; use Inline C => Config => DIRECTORY => '_Inline_test', FORCE_BUILD => 1, _TESTING => 1, USING => 'ParseRecDescent'; use Inline C => <<'EOC'; int foo() { return 6; } EOC ########## BAR::bar ######## package BAR; use Inline C => Config => DIRECTORY => '_Inline_test', FORCE_BUILD => 1, _TESTING => 1; use Inline C => <<'EOC'; int bar() { return 7; } EOC ########## BAZ::baz ######## package BAZ; use Inline C => Config => DIRECTORY => '_Inline_test', FORCE_BUILD => 1, _TESTING => 1, USING => 'ParseRegExp'; use Inline C => <<'EOC'; int baz() { return 8; } EOC ########## BAZ::baz_ ######## # Use same Config options as for BAZ::bar() use Inline C => <<'EOC'; int baz_() { return -2; } EOC ######################################## ######################################## my $ok; my $prod = -483840; my $res = main::foo_() * main::_foo() * main::_foo_() * main::foo() * main::bar() * main::baz() * main::foobar() * main::foobarbaz() * FOO::foo() * BAR::bar() * BAZ::baz() * BAZ::baz_(); if($res == $prod) {$ok .= 'a'} else {warn "1a: Got $res\nExpected $prod\n"} open(RD, '<', '_Inline_test/parser_id') or warn $!; my @p = ; my $lines = 16; if(scalar(@p) == $lines) {$ok .= 'b'} else {warn "1b: Got ", scalar(@p), "\nExpected $lines\n"} if($p[0] eq "Inline::C::ParseRegExp::get_parser called\n") {$ok .= 'c'} else {warn "1c: Got $p[0]\n"} if($p[1] eq "Inline::C::ParseRegExp::get_parser called\n") {$ok .= 'd'} else {warn "1d: Got $p[1]\n"} if($p[2] eq "Inline::C::ParseRecDescent::get_parser called\n") {$ok .= 'e'} else {warn "1e: Got $p[2]\n"} if($p[3] eq "Inline::C::ParseRegExp::get_parser called\n") {$ok .= 'f'} else {warn "1f: Got $p[3]\n"} if($p[4] eq "Inline::C::get_parser called\n") {$ok .= 'g'} else {warn "1g: Got $p[4]\n"} if($p[5] eq "Inline::C::ParseRecDescent::get_parser called\n") {$ok .= 'h'} else {warn "1h: Got $p[5]\n"} if($p[6] eq "Inline::C::ParseRecDescent::get_parser called\n") {$ok .= 'i'} else {warn "1i: Got $p[6]\n"} if($p[7] eq "Inline::C::get_parser called\n") {$ok .= 'j'} else {warn "1j: Got $p[7]\n"} if($p[8] eq "Inline::C::ParseRecDescent::get_parser called\n") {$ok .= 'k'} else {warn "1k: Got $p[8]\n"} if($p[9] eq "Inline::C::get_parser called\n") {$ok .= 'l'} else {warn "1l: Got $p[9]\n"} if($p[10] eq "Inline::C::ParseRecDescent::get_parser called\n") {$ok .= 'm'} else {warn "1m: Got $p[10]\n"} if($p[11] eq "Inline::C::ParseRecDescent::get_parser called\n") {$ok .= 'n'} else {warn "1n: Got $p[11]\n"} if($p[12] eq "Inline::C::get_parser called\n") {$ok .= 'o'} else {warn "1o: Got $p[12]\n"} if($p[13] eq "Inline::C::ParseRecDescent::get_parser called\n") {$ok .= 'p'} else {warn "1p: Got $p[13]\n"} if($p[14] eq "Inline::C::ParseRegExp::get_parser called\n") {$ok .= 'q'} else {warn "1q: Got $p[14]\n"} if($p[15] eq "Inline::C::ParseRegExp::get_parser called\n") {$ok .= 'r'} else {warn "1r: Got $p[15]\n"} close(RD) or warn $!; if($ok eq 'abcdefghijklmnopqr') {print "ok 1\n"} else { warn "\$ok: $ok\n"; print "not ok 1\n"; } Inline::C::_testing_cleanup(); Inline-0.53/C/t/10callback.t0000644000076400010400000001511112052612400017025 0ustar sisyphusAdministrators# Check that basic callbacks are working, and that Inline::C keeps track correctly of whether functions # are truly void or not. (In response to bug #55543.) # This test script plagiarises the perlcall documentation. BEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use diagnostics; print "1..4\n"; use Inline C => Config => FORCE_BUILD => 1, _TESTING => 1, DIRECTORY => '_Inline_test', USING => 'ParseRegExp'; use Inline C => <<'END'; void list_context(int x) { Inline_Stack_Vars; int i = 0; Inline_Stack_Reset; for(i = 1; i < 11; i++) Inline_Stack_Push(sv_2mortal(newSVuv(i * x))); Inline_Stack_Done; Inline_Stack_Return(10); } void call_AddSubtract2(int a, int b) { dSP; I32 ax; int count; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(a))); XPUSHs(sv_2mortal(newSViv(b))); PUTBACK; count = call_pv("AddSubtract", G_ARRAY); SPAGAIN; SP -= count; ax = (SP - PL_stack_base) + 1; if (count != 2) croak("Big trouble\n"); printf ("%d + %d = %d\n", a, b, SvIV(ST(0))); printf ("%d - %d = %d\n", a, b, SvIV(ST(1))); PUTBACK; FREETMPS; LEAVE; } void call_PrintList() { dSP; char * words[] = {"alpha", "beta", "gamma", "delta", NULL}; call_argv("PrintList", G_DISCARD, words); } void call_Inc(int a, int b) { dSP; int count; SV * sva; SV * svb; ENTER; SAVETMPS; sva = sv_2mortal(newSViv(a)); svb = sv_2mortal(newSViv(b)); PUSHMARK(SP); XPUSHs(sva); XPUSHs(svb); PUTBACK; count = call_pv("Inc", G_DISCARD); if (count != 0) croak ("call_Inc: expected 0 values from 'Inc', got %d\n", count); printf ("%d + 1 = %d\n", a, SvIV(sva)); printf ("%d + 1 = %d\n", b, SvIV(svb)); FREETMPS; LEAVE; } void call_AddSubtract(int a, int b) { dSP; int count; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(a))); XPUSHs(sv_2mortal(newSViv(b))); PUTBACK; count = call_pv("AddSubtract", G_ARRAY); SPAGAIN; if (count != 2) croak("Big trouble\n"); printf ("%d - %d = %d\n", a, b, POPi); printf ("%d + %d = %d\n", a, b, POPi); PUTBACK; FREETMPS; LEAVE; } void call_Adder(int a, int b) { dSP; int count; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(a))); XPUSHs(sv_2mortal(newSViv(b))); PUTBACK; count = call_pv("Adder", G_SCALAR); SPAGAIN; if (count != 1) croak("Big trouble\n"); printf ("The sum of %d and %d is %d\n", a, b, POPi); PUTBACK; FREETMPS; LEAVE; } void call_PrintUID() { dSP; PUSHMARK(SP); call_pv("PrintUID", G_DISCARD|G_NOARGS); } void call_LeftString(char *a, int b) { dSP; ENTER; SAVETMPS; PUSHMARK(SP); POPMARK; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVpv(a, 0))); XPUSHs(sv_2mortal(newSViv(b))); PUTBACK; call_pv("LeftString", G_DISCARD); FREETMPS; LEAVE; } void foo(int x) { call_AddSubtract(123, 456); call_LeftString("Hello World !!", x); call_AddSubtract(789,101112); call_AddSubtract2(23,50); call_Inc(22,223); call_PrintList(); call_PrintUID(); call_Adder(7123, 8369); call_LeftString("Hello World !!", x + 1); call_Inc(34,35); call_PrintList(); call_Adder(71231, 83692); call_PrintUID(); call_LeftString("Hello World !!", x + 2); call_AddSubtract2(23,50); } void bar(int x) { dXSARGS; int i = 0; call_LeftString("Hello World !!", x); sp = mark; call_LeftString("Hello World !!", x + 1); for(i = 1; i < 11; i++) XPUSHs(sv_2mortal(newSVuv(i * x))); /* call_LeftString("Hello World !!", x + 2); * /* CRASHES ON RETURN */ PUTBACK; call_LeftString("Hello World !!", x + 3); XSRETURN(10); } END my @list = list_context(17); if(scalar(@list) == 10 && $list[0] == 17) {print "ok 1\n"} else { warn "\nscalar \@list: ", scalar(@list), "\n\$list[0]: $list[0]\n"; print "not ok 1\n"; } call_LeftString("Just testing", 8); foo(7); @list = bar(6); if(scalar(@list) == 10 && $list[0] == 6) {print "ok 2\n"} else { warn "\nscalar \@list: ", scalar(@list), "\n\$list[0]: $list[0]\n"; print "not ok 2\n"; } call_PrintUID(); call_Adder(18, 12345); call_AddSubtract(131415, 161718); call_Inc(102,304); call_PrintList(); call_AddSubtract2(23,50); open RD, '<', '_Inline_test/void_test' or warn "Unable to open _Inline_test/void_test: $!"; my @checks = ; close RD or warn "Unable to close _Inline_test/void_test: $!"; my $expected = 10; if(scalar(@checks == $expected)) {print "ok 3\n"} else { warn "scalar \@checks is ", scalar(@checks), ". Expected $expected\n"; print "not ok 3\n"; } my $ok; if($checks[0] eq "LIST_CONTEXT\n") {$ok .= 'a'} else {warn "4a: Got '$checks[0]', expected 'LIST_CONTEXT'\n"} if($checks[1] eq "TRULY_VOID\n") {$ok .= 'b'} else {warn "4b: Got '$checks[0]', expected 'TRULY_VOID'\n"} if($checks[2] eq "TRULY_VOID\n") {$ok .= 'c'} else {warn "4c: Got '$checks[0]', expected 'TRULY_VOID'\n"} if($checks[3] eq "LIST_CONTEXT\n") {$ok .= 'd'} else {warn "4d: Got '$checks[0]', expected 'LIST_CONTEXT'\n"} if($checks[4] eq "TRULY_VOID\n") {$ok .= 'e'} else {warn "4e: Got '$checks[4]', expected 'TRULY_VOID'\n"} if($checks[5] eq "TRULY_VOID\n") {$ok .= 'f'} else {warn "4f: Got '$checks[5]', expected 'TRULY_VOID'\n"} if($checks[6] eq "TRULY_VOID\n") {$ok .= 'g'} else {warn "4g: Got '$checks[6]', expected 'TRULY_VOID'\n"} if($checks[7] eq "TRULY_VOID\n") {$ok .= 'h'} else {warn "4h: Got '$checks[7]', expected 'TRULY_VOID'\n"} if($checks[8] eq "TRULY_VOID\n") {$ok .= 'i'} else {warn "4i: Got '$checks[8]', expected 'TRULY_VOID'\n"} if($checks[9] eq "TRULY_VOID\n") {$ok .= 'j'} else {warn "4j: Got '$checks[9]', expected 'TRULY_VOID'\n"} if($ok eq 'abcdefghij') {print "ok 4\n"} else { warn "\$ok: $ok\n"; print "not ok 4\n"; } Inline::C::_testing_cleanup(); sub PrintUID { print "UID is $<\n"; } sub LeftString { my($s, $n) = @_; print substr($s, 0, $n), "\n"; } sub Adder { my($a, $b) = @_; $a + $b; } sub AddSubtract { my($a, $b) = @_; ($a+$b, $a-$b); } sub Inc { ++ $_[0]; ++ $_[1]; } sub PrintList { my(@list) = @_; foreach (@list) { print "$_\n" } } Inline-0.53/C/t/11default_readonly.t0000644000076400010400000000165012052612400020616 0ustar sisyphusAdministrators# Checks that Inline's bind function still works when $_ is readonly. (Bug #55607) # Thanks Marty O'Brien. BEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use diagnostics; print "1..1\n"; # The following construct not allowed under # strictures (refs). Hence strictures for # refs have been turned off. { no strict ('refs'); for ('function') { $_->(); } } if(foo(15) == 30) {print "ok 1\n"} else { warn "Expected 30, got ", foo(15), "\n"; print "not ok 1\n"; } sub function { use Inline C => Config => DIRECTORY => '_Inline_test', USING => 'ParseRegExp'; Inline->bind(C => <<'__CODE__'); int foo(SV * x) { return (int)SvIV(x) * 2; } __CODE__ } Inline-0.53/C/t/12taint_old.t0000755000076400010400000000300112052612400017246 0ustar sisyphusAdministrators#!perl -T BEGIN { if($] >= 5.007) { print "1..1\n"; warn "Skipped - applies only to perl 5.6.x\n"; print "ok 1\n"; exit(0); } }; BEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use Test; use diagnostics; use Inline Config => UNTAINT => 1, DIRECTORY => '_Inline_test'; BEGIN { plan(tests => 5, todo => [], onfail => sub {}, ); warn "Expect a number of \"Blindly untainting ...\" warnings - these are intended.\n"; } use Inline Config => UNTAINT => 1, DIRECTORY => '_Inline_test'; # test 1 - Check string syntax ok(add(3, 7) == 10); # test 2 - Check string syntax again ok(subtract(3, 7) == -4); # test 3 - Check DATA syntax ok(multiply(3, 7) == 21); # test 4 - Check DATA syntax again ok(divide(7, -3) == -2); use Inline 'C'; use Inline C => 'DATA'; use Inline C => <<'END_OF_C_CODE'; int add(int x, int y) { return x + y; } int subtract(int x, int y) { return x - y; } END_OF_C_CODE Inline->bind(C => <<'END'); int incr(int x) { return x + 1; } END # test 5 - Test Inline->bind() syntax ok(incr(incr(7)) == 9); __END__ # unused code or maybe AutoLoader stuff sub crap { return 'crap'; } __C__ int multiply(int x, int y) { return x * y; } __C__ int divide(int x, int y) { return x / y; } Inline-0.53/C/t/14void_arg.t0000644000076400010400000000366212052612400017077 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } mkdir('_Inline_test', 0777) unless -e '_Inline_test'; }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use diagnostics; print "1..12\n"; use Inline C => Config => FORCE_BUILD => 1, DIRECTORY => '_Inline_test', USING => 'ParseRegExp'; use Inline C => <<'EOC'; void foo1(void) { printf("Hello from foo1\n"); } int foo2(void) { return 42; } SV * foo3(void) { return newSVnv(42.0); } void foo4() { printf("Hello from foo4\n"); } int foo5() { return 42; } SV * foo6() { return newSVnv(42.0); } void foo7( void ) { printf("Hello from foo7\n"); } int foo8( void ) { return 43; } SV * foo9( void ) { return newSVnv(43.0); } void foo10 ( void ) { printf("Hello from foo10\n"); } int foo11 ( void ) { return 44; } SV * foo12 ( void ) { return newSVnv(44.0); } EOC eval {foo1();}; if($@) { warn "\$\@: $@"; print "not ok 1\n"; } else { print "ok 1\n"} if(42 == foo2()) {print "ok 2\n"} else {print "not ok 2\n"} if(42 == foo3()) {print "ok 3\n"} else {print "not ok 3\n"} eval {foo4();}; if($@) { warn "\$\@: $@"; print "not ok 4\n"; } else { print "ok 4\n"} if(42 == foo5()) {print "ok 5\n"} else {print "not ok 5\n"} if(42 == foo6()) {print "ok 6\n"} else {print "not ok 6\n"} eval {foo7();}; if($@) { warn "\$\@: $@"; print "not ok 7\n"; } else { print "ok 7\n"} if(43 == foo8()) {print "ok 8\n"} else {print "not ok 8\n"} if(43 == foo9()) {print "ok 9\n"} else {print "not ok 9\n"} eval {foo10();}; if($@) { warn "\$\@: $@"; print "not ok 10\n"; } else { print "ok 10\n"} if(44 == foo11()) {print "ok 11\n"} else {print "not ok 11\n"} if(44 == foo12()) {print "ok 12\n"} else {print "not ok 12\n"} Inline-0.53/C/t/15ccflags.t0000644000076400010400000000130212052612400016675 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use diagnostics; use Config; print "1..1\n"; use Inline C => Config => #BUILD_NOISY => 1, FORCE_BUILD => 1, CCFLAGS => $Config{ccflags} . " -DEXTRA_DEFINE=1234", DIRECTORY => '_Inline_test'; use Inline C => <<'EOC'; int foo() { return EXTRA_DEFINE; } EOC my $def = foo(); if($def == 1234) { print "ok 1\n"; } else { warn "\n Expected: 1234\n Got: $def\n"; print "not ok 1\n"; } Inline-0.53/C/t/16ccflagsex.t0000644000076400010400000000126012052612400017236 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use diagnostics; use Config; print "1..1\n"; use Inline C => Config => #BUILD_NOISY => 1, FORCE_BUILD => 1, CCFLAGSEX => "-DEXTRA_DEFINE=1234", DIRECTORY => '_Inline_test'; use Inline C => <<'EOC'; int foo() { return EXTRA_DEFINE; } EOC my $def = foo(); if($def == 1234) { print "ok 1\n"; } else { warn "\n Expected: 1234\n Got: $def\n"; print "not ok 1\n"; } Inline-0.53/C/t/17prehead.t0000644000076400010400000000130512052612400016710 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use diagnostics; use Config; print "1..1\n"; use Inline C => Config => #BUILD_NOISY => 1, #CLEAN_AFTER_BUILD => 0, FORCE_BUILD => 1, PRE_HEAD => 't/prehead.in', DIRECTORY => '_Inline_test'; use Inline C => <<'EOC'; int foo() { return EXTRA_DEFINE; } EOC my $def = foo(); if($def == 1234) { print "ok 1\n"; } else { warn "\n Expected: 1234\n Got: $def\n"; print "not ok 1\n"; } Inline-0.53/C/t/18quote_space.t0000644000076400010400000000743212052612711017625 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use strict; use warnings; use Cwd; require Inline::C; my $t = 10; print "1..$t\n"; my $ok = 1; my $expected; my @t1 = ( '-I/foo -I/bar', ' -I/foo -I/bar -I/baz ', ' -I/foo -I" - I/? ', ' -I/for-Ian -I/for-Ingy -I/for-some-Idiocy ', 'some_crap -I-I-I -I/for-Ian -I/for-Ingy -I/for-some-Idiocy -I/foo -I/bar ', ' -I/foo -I/bar -I/fubar', ); for my $e1(@t1) { $expected = $e1; my $got = Inline::C::quote_space($e1); unless($got eq $expected) { $ok = 0; warn "\nGot: **$got**\n", "Expected: **$expected**\n"; } } if($ok) {print "ok 1\n"} else {print "not ok 1\n"} my @t2 = ( '-I/foo and fu -I/bar', ' -I/foo -I/bar and baa -I/baz ', ' -I/foo and fu -I" - I/? ', ' -I/for-Ian -I/for-Ingy and me -I/for-some-Idiocy ', 'some crap -I-I-I -I/for-Ian -I/for-Ingy -I/for-some Idiocy -I/foo -I/bar ', '-I/foo -I/for-Ian and me -I/for -I/an -I/fu bar', ' -I /foo -I /bar', ); for my $e2 (@t2) {Inline::C::quote_space($e2)} if($t2[0] eq '"-I/foo and fu" -I/bar') {print "ok 2\n"} else { warn "\n2\nGot: **$t2[0]**\n", "Expected: **\"-I/foo and fu\" -I/bar**\n"; print "not ok 2\n"; } if($t2[1] eq ' -I/foo "-I/bar and baa" -I/baz ') {print "ok 3\n"} else { warn "\n3\nGot: **$t2[1]**\n", "Expected: ** -I/foo \"-I/bar and baa\" -I/baz **\n"; print "not ok 3\n"; } if($t2[2] eq ' -I/foo and fu -I" - I/? ') {print "ok 4\n"} else { warn "\n4\nGot: **$t2[2]**\n", "Expected: ** -I/foo and fu -I\" - I/? **\n"; print "not ok 4\n"; } if($t2[3] eq ' -I/for-Ian "-I/for-Ingy and me" -I/for-some-Idiocy ') {print "ok 5\n"} else { warn "\n5\nGot: **$t2[3]**\n", "Expected: ** -I/for-Ian \"-I/for-Ingy and me\" -I/for-some-Idiocy **\n"; print "not ok 5\n"; } if($t2[4] eq '"some crap" -I-I-I -I/for-Ian -I/for-Ingy "-I/for-some Idiocy" -I/foo -I/bar ') {print "ok 6\n"} else { warn "\n6\nGot: **$t2[4]**\n", "Expected: **\"some crap\" -I-I-I -I/for-Ian -I/for-Ingy \"-I/for-some Idiocy\" -I/foo -I/bar **\n"; print "not ok 6\n"; } if($t2[5] eq '-I/foo "-I/for-Ian and me" -I/for -I/an "-I/fu bar"') {print "ok 7\n"} else { warn "\n7\nGot: **$t2[5]**\n", "Expected: **-I/foo \"-I/for-Ian and me\" -I/for -I/an \"-I/fu bar\"**\n"; print "not ok 7\n"; } if($t2[6] eq ' "-I/foo" "-I/bar"') {print "ok 8\n"} else { warn "\n8\nGot: **$t2[6]**\n", "Expected: ** \"-I/foo\" \"-I/bar\"**\n"; print "not ok 8\n"; } $ENV{NO_INSANE_DIRNAMES} = 1; my $got = Inline::C::quote_space('-I/foo and fu -I/bar'); if($got eq '-I/foo and fu -I/bar') {print "ok 9\n"} else { warn "\n9\nGot: **$got**\n", "Expected: **-I/foo and fu -I/bar**\n"; print "not ok 9\n"; } delete $ENV{NO_INSANE_DIRNAMES}; my $have_file_path; my $newdir = Cwd::getcwd(); $newdir .= '/foo -I/'; eval{require File::Path;}; if($@) { warn "\nSkipping remaining tests - couldn't load File::Path\n"; for(10 .. $t) {print "ok $_\n"} exit 0; } else {$have_file_path = 1} unless(File::Path::mkpath($newdir)) { unless(-d $newdir) { warn "\n Skipping remaining tests - couldn't create $newdir directory.\n", "Assuming this platform doesn't support spaces in directory names\n"; for(10 .. $t) {print "ok $_\n"} exit 0; } } my $stest = " -I/here and there -I$newdir -I/foo -I/bar "; eval{Inline::C::quote_space($stest);}; if($@ =~ /\/foo \-I\/' directory\./) {print "ok 10\n"} else { warn "\n\$\@: $@\n"; print "not ok 10\n"; } END { File::Path::rmtree($newdir) if $have_file_path; warn "Failed to remove $newdir" if -d $newdir; }; Inline-0.53/C/t/19INC.t0000644000076400010400000000144012052612400015713 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use warnings; use Cwd; BEGIN { my $cwd = Cwd::getcwd(); my $incdir1 = $cwd . '/t/foo/'; my $incdir2 = $cwd . '/t/bar/'; $main::includes = "-I$incdir1 -I$incdir2"; }; use Inline C => Config => INC => $main::includes, DIRECTORY => '_Inline_test'; use Inline C => <<'EOC'; #include #include SV * foo() { return newSViv(-42); } EOC print "1..1\n"; my $f = foo(); if($f == -42) {print "ok 1\n"} else { warn "\n\$f: $f\n"; print "not ok 1\n"; } Inline-0.53/C/t/20eval.t0000644000076400010400000000230712055363300016231 0ustar sisyphusAdministratorsBEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use strict; use warnings; print "1..5\n"; eval { require Inline; Inline->import(Config => DIRECTORY => '_Inline_test'); Inline->import (C =><<'EOC'); int foo() { return 42; } EOC }; if($@) { *foo =\&bar; } my $x = foo(); if($x == 42) {print "ok 1\n"} else { warn "\n\$x: $x\n"; print "not ok 1\n"; } $x = bar(); if($x == 43) {print "ok 2\n"} else { warn "\n\$x: $x\n"; print "not ok 2\n"; } eval { require Inline; Inline->import(C => Config => DIRECTORY => '_Inline_test', #BUILD_NOISY => 1, CC => 'missing_compiler'); Inline->import (C =><<'EOC'); int fu() { return 44; } EOC }; if($@) { *fu =\&fubar; } $x = fu(); if($x == 45) {print "ok 3\n"} else { warn "\n\$x: $x\n"; print "not ok 3\n"; } $x = fubar(); if($x == 45) {print "ok 4\n"} else { warn "\n\$x: $x\n"; print "not ok 4\n"; } if($@ =~ /missing_compiler/) {print "ok 5\n"} else { warn "\n\$\@ not as expected\n"; print "not ok 5\n"; } sub bar { return 43; } sub fubar { return 45; } Inline-0.53/C/t/21read_DATA.t0000644000076400010400000000137212131373466017021 0ustar sisyphusAdministrators# This file checks that a bug in Inline::read_DATA() has been fixed. # The bug existed up to and including Inline-0.52. BEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use warnings; use Inline C => 'DATA'; print "1..1\n"; my $foo = foo1() + foo2(); if($foo == 15) {print "ok 1\n"} else { warn "\$foo: $foo\n"; print "not ok 1\n"; } __DATA__ __C__ #define __SYMBOL1__ #define __SYMBOL2__ 8 int foo1() { int ret = __SYMBOL2__ - 1; return ret; } int foo2() { return __SYMBOL2__; } Inline-0.53/C/t/22read_DATA_2.t0000644000076400010400000000152512131436245017236 0ustar sisyphusAdministrators# This file checks that a bug in Inline::read_DATA() has been fixed. # The bug existed up to and including Inline-0.52. BEGIN { if (exists $ENV{PERL_INSTALL_ROOT}) { warn "\nIgnoring \$ENV{PERL_INSTALL_ROOT} in $0\n"; delete $ENV{PERL_INSTALL_ROOT}; } }; use File::Spec; use lib (File::Spec->catdir(File::Spec->updir(),'blib','lib'), File::Spec->catdir(File::Spec->curdir(),'blib','lib')); use strict; use warnings; use Inline C => 'DATA'; print "1..1\n"; my $foo = foo1() + foo2(); if($foo == 15) {print "ok 1\n"} else { warn "\$foo: $foo\n"; print "not ok 1\n"; } __DATA__ __C__ #ifndef __Python__ #define __Python__ 8 #endif int foo1() { int ret; if(__Python__ == 8) { ret = __Python__ - 1; } else ret = 7; return ret; } int foo2() { if(__Python__ == 8) return __Python__; else return 8; } Inline-0.53/C/t/23validate.t0000644000076400010400000000246012140067631017101 0ustar sisyphusAdministrators# Check that a small bugfix in Inline::C::validate() (ticket #11748) # is behaving as expected. use warnings; use strict; print "1..5\n"; require Inline::C; # Next 2 lines are for the benefit of 5.8.8. my (%o1, %o2, %o3); my($o1, $o2, $o3) = (\%o1, \%o2,\ %o3); $o1->{FOOBAR}{STUFF} = 1; $o2->{FOOBAR}{STUFF} = 1; $o2->{ILSM}{MAKEFILE}{INC} = '-I/foo -I/bar'; $o3->{FOOBAR}{STUFF} = 1; bless($o1, 'Inline::C'); bless($o2, 'Inline::C'); bless($o3, 'Inline::C'); Inline::C::validate($o1); if($o1->{ILSM}{MAKEFILE}{INC}) {print "ok 1\n"} else {print "not ok 1\n"} Inline::C::validate($o2); if($o2->{ILSM}{MAKEFILE}{INC} eq '-I/foo -I/bar') {print "ok 2\n"} else { warn "INC: ", $o2->{ILSM}{MAKEFILE}{INC}, "\n"; print "not ok 2\n"; } Inline::C::validate($o2, 'INC', '-I/baz'); if($o2->{ILSM}{MAKEFILE}{INC} =~ / \-I\/baz/) {print "ok 3\n"} else { warn "INC: ", $o2->{ILSM}{MAKEFILE}{INC}, "\n"; print "not ok 3\n"; } if($o2->{ILSM}{MAKEFILE}{INC} eq '-I/foo -I/bar -I/baz') {print "ok 4\n"} else { warn "INC: ", $o2->{ILSM}{MAKEFILE}{INC}, "\n"; print "not ok 4\n"; } Inline::C::validate($o3, 'INC', '-I/baz'); if($o3->{ILSM}{MAKEFILE}{INC} =~ / \-I\/baz/ && $o3->{ILSM}{MAKEFILE}{INC} ne ' -I/baz' ) {print "ok 5\n"} else { warn "INC: ", $o3->{ILSM}{MAKEFILE}{INC}, "\n"; print "not ok 5\n"; } Inline-0.53/C/t/bar/0000755000076400010400000000000012140062610015510 5ustar sisyphusAdministratorsInline-0.53/C/t/bar/find_me_in_bar.h0000644000076400010400000000002412052612400020570 0ustar sisyphusAdministrators#include Inline-0.53/C/t/foo/0000755000076400010400000000000012140062610015527 5ustar sisyphusAdministratorsInline-0.53/C/t/foo/find_me_in_foo.h0000644000076400010400000000002312052612400020625 0ustar sisyphusAdministrators#include Inline-0.53/C/t/prehead.in0000644000076400010400000000013012052612400016676 0ustar sisyphusAdministrators#ifndef EXTRA_DEFINE #define EXTRA_DEFINE 1234 #else #define SOMETHING_ELSE 1234 #endif Inline-0.53/C/t/soldier_typemap0000644000076400010400000000037612052612400020075 0ustar sisyphusAdministratorsSoldier * SOLDIER INPUT SOLDIER $var = INT2PTR($type, SvIV(SvRV($arg))) OUTPUT SOLDIER $arg = newSViv(0); sv_setiv(newSVrv($arg, \"Soldier\"), (IV)$var); SvREADONLY_on(SvRV($arg)); $arg;Inline-0.53/C/t/typemap0000644000076400010400000000015212052612400016344 0ustar sisyphusAdministratorsfloat T_FLOAT INPUT T_FLOAT $var = (float)SvNV($arg) OUTPUT T_FLOAT sv_setnv($arg, (double)$var); Inline-0.53/Changes0000644000076400010400000005216412140062002015615 0ustar sisyphusAdministrators# Revision history for Perl extension Inline. --- version 0.53 date Wed 1 May 2013 Version 0.53 released to CPAN --- version 0.52_02 date Wed 24 Apr 2013 Version 0.52_02 released to CPAN --- version 0.52_01 date Thurs 11 Apr 2013 Version 0.52_01 released to CPAN Inline.pm - in sub read_DATA() replace: @{$DATA{$pkg}} = split /(?m)(__\S+?__\n)/, $data with: @{$DATA{$pkg}} = split /(?m)^[ \t]{0,}(__\S+?__\n)/, $data; Otherwise some non-markers can be treated as markers. Thanks to Chris Nighswonger and Stefan Seifert. Added C/t/21read_DATA.t and C/t/22read_DATA_2.t as the test cases. NOTE: This is not a complete fix - it's still possible to write code (albeit in an unorthodox fashion) such that a non-marker can be treated as a marker. --- version 0.52 date Thurs 07 Mar 2013 Version 0.52 released to CPAN --- version 0.51_03 date Wed 28 Nov 2012 Version 0.51_03 released to CPAN --- version 0.51_02 date Tues 20 Nov 2012 Version 0.51_02 released to CPAN --- version 0.51_01 date Tues 20 Nov 2012 Version 0.51_01 released to CPAN --- version 0.51 date Sat 13 Oct 2012 Version 0.51 released to CPAN. --- version 0.50_03 date Mon 8 Oct 2012 Version 0.50_03 released to CPAN. --- version 0.50_02 date Thurs 24 May 2012 Version 0.50_02 released to CPAN. Makefile.PL - Provide special handling of the Digest::MD5 dependency For pre-5.8.1 versions of perl. Inline.pm - Replace "$lexwarn" with its actual value of "no warnings;". Inline.pod - Document use of "Inline->init();" for Inline modules. Inline-FAQ.pod - Document use of "Inline->init();" for Inline modules. --- version 0.50_02 date Mon 14 May 2012 Inline-FAQ.pod - Mention that the behaviour being documented in the first FAQ can be overridden by either the DIRECTORY config option or the PERL_INLINE_DIRECTORY environemnt variable. --- version 0.50_02 date Tues 14 Feb 2012 Inline.pm - Bump version number to 0.50_02 --- version 0.50_01 date Sun 12 Feb 2012 Version 0.50_01 released to CPAN --- version 0.50_01 date Wed 8 Feb 2012 Inline.pm - Add a warning prior to croaking with M62_invalid_config_file(). That way, we'll at least see what $config contains. This is in response to FAIL report: http://www.cpantesters.org/cpan/report/3287249c-5151-11e1-9dba-4238887bd19e - Bump version number to 0.50_01 --- version 0.50 date Tues 7 Feb 2012 Version 0.50 released to CPAN Inline.pm - Bump version number to 0.50 --- version 0.49_02 date Fri 3 Feb 2012 Version 0.49_02 released to CPAN Inline.pm - Bring version numbering into line with recommendations made in http://perldoc.perl.org/perlmodstyle.html#Version-numbering --- version 0.49_01 date Thurs 2 Feb 2012 Version 0.49_01 released to CPAN. Inline.pm - Rename create_config_file()'s private @INC to @_inc. (This is just to avoid any confusion that we might be messing with @INC.) - In creating @_inc, we now additionally grep for the location of Parse::RecDescent - in case it's in a different PERL5LIB location to Inline (as generally happens with cpan smokers - but could happen anywhere). - Update copyright dates throughout. --- version 0.49_01 date Mon 23 Jan 2012 C/t - Make alterations to all of the '.t' files in C/t (except for 00init.t). This is in reponse to ticket 73448, which raised the possibility that Inline may get built with the PERL_INSTALL_ROOT environment variable set. Inline.pod - mention the need to make provision for the PERL_INSTALL_ROOT environment variable iff it has been set. --- version 0.49_01 date Sun 25 Dec 2011 As the result of input from David Oswald: Inline.pod - Changes relating to "CONFIGURE_REQUIRES" and fix typo reported in ticket 73108. Inline-FAQ.pod - Changes relating to "CONFIGURE_REQUIRES" Inline.pm - Bump version to 0.49_01 lib/Inline/MakeMaker.pm - Bump version to 0.49_01 --- version 0.49 date: Thurs 8 Dec 2011 Version 0.49 released to CPAN Inline.pm - small alteration to M19_usage_language error message --- version 0.48_02 date: Mon 5 Dec 2011 Version 0.48_02 released to CPAN Inline.pm - Have the config file re-created *before* we croak with M19_usage_language(). (Re-creating the config file should alleviate the need to croak, thus allowing the script to complete successfully.) Thanks to Patrick LeBoutillier for the patch, and to David Oswald for pursuing this. --- version 0.48_02 date: Fri 9 Sept 2011 Bump Inline version to 0.48_02 --- version 0.48_01 date: Mon 11 Apr 2011 Version 0.48_01 released to CPAN t/05files.t - Have t/05files.t provide a reason for skipping the tests. Inline.pm - Create REWRITE_CONFIG_FILE config option. Makefile.PL - Test::Warn 0.23 or later needed for perl-5.13 and later. (Older perls need 0.21 or later). --- version: 0.48 date: Mon 21 Feb 2011 Version 0.48 released to CPAN. (No changes from 0.47_02.) --- version: 0.47_02 date: Tues 1 Feb 2011 Version 0.47_02 released to CPAN. Makefile.PL - Change the Test::Warn dependency from 0.22 to 0.21 and specify it in top-level Makefile.PL instead of in C/Makefile.PL. --- version: 0.47_01 date: Sun 30 January 2011 Version 0.47_01 released to CPAN. Changes only to Inline::C test suite - see C/Changes. --- version: 0.47 date: Fri 21 January 2011 Version 0.47 released to CPAN. No changes from 0.46_02 --- version: 0.46_02 date: Wed 29 December 2010 lib/Inline/MakeMaker.pm - apply patch from Raymond Mroz to accommodate the modern h2xs directory structure. Bump Inline::MakeMaker version to 0.45. --- version: 0.46_01 date: Wed 31 March 2010 (and released to CPAN as 0.46_01) Inline.pm - warn about untainting of Inline configuration info (where applicable) - quieten non-numeric warnings in relation to devel releases - quieten uninitialized warning regarding $ENV{WIN64} that can occur in certain circumstances on MS Windows Inline.pod - Documentation change relating to introduction of further _TESTING capabilities in Inline::C --- version: 0.46_01 date: Mon 8 March 2010 Inline.pm - add '_TESTING' config option - hide the 'redefined' warning introduced by the fix to ticket 49669, by placing the offending code in a 'no warnings "redefine";' block. - bump require from 5.005 to 5.006 --- version: 0.46_01 date: Sun 14 feb 2010 Inline.pm - add archname and perlversion number to config filename. C/C.pm - Second attempt at accommodating 'ccache cc' compiler (RT ticket 40140). --- version: 0.46 date: Fri Feb 12 2010 Same as 0.45_02 (plus some minor doc alterations in Inline.pod). --- version: 0.45_02 date: Fri Feb 5 2010 Changes to Inline.pm, denter.pm, and Inline.pod relating to "fixing" untainting (to the extent that untainting of -T inline scripts works as documented). Many thanks to Patrick LeBoutillier. Also added C/t/08taint.t (which contains -T on the shebang line) as a basic test of untainting. (RT ticket 13084) --- version: 0.45_01 date: Thurs Jan 28 2010 C/C.pod - document that *fully qualified* paths for LIBS, INC, TYPEMAPS and MYEXTLIB are needed. (RT ticket 5207) Inline.pm - remove "defined" from "defined %main::Inline::Config::" as that usage causes a deprecation warning with perl-5.11 and later. (RT ticket 53227) Inline.pm - fix sub push_overrides (RT ticket 49669) This change responsible for "Subroutine Inline::C::get_parser redefined" warnings that can occur during build stage under certain circumstances. denter.pm - local()ise $_ (in four places) (RT ticket 16801) Inline.pod - doc correction (thanks Alejandro Ochoa). C/Makefile.PL - accommodate 'ccache cc' (RT ticket 40140) - accommodate ActivePerl-5.10.1 and later (RT ticket 49419) C/Cookbook.pod - typo fixes (thanks Brad Barber) - Change "NAME" from "C Cookbook ..." to "Inline::C-Cookbook ...". (RT ticket 45417) --- version: 0.45 date: Sat Nov 22 2008 No changes from 0.44_01 --- version: 0.44_01 date: Tues Oct 11 2008 changes: - Apply patch to Inline.pm that addresses a problem with whitespace occurring in the name of the build directory. (RT ticket 4150) - Fix ParseRegExp.pm. (RT ticket 6327) - Fix (in Inline.pm) problem regarding the calling of the same script from different builds of perl. (RT ticket 29326) - Allow Inline::install() subroutine to apply to languages other than C and CPP. (RT ticket 35517) - Fix C/Makefile.PL so that the C compiler can still be found when $Config{cc} reports something like /some/place/cc. (RT ticket 8251) - In C/C.pm, allow for the calling of multiple typemaps (RT ticket 5639), and have the "No Inline C functions bound to Perl" warning specify the file for which no bindings were found (RT ticket 17774). - Minor doc fixes. --- version: 0.44 date: Mon Oct 28 10:31:51 PST 2002 changes: - Doc fixes. Thanks Mitchell. - Put all current ILSMs in doc and Makefile.PL --- version: 0.44 date: Sun Oct 27 23:34:50 PST 2002 changes: - Applied some patches from Patrick LeBoutillier, including one to make things work out of the box on Win95 and friends. Rob helped too. - Added a warning to help debug why certain ILSMs might be failing. --- version: 0.44 date: Fri Oct 25 10:12:16 PDT 2002 changes: - Changes to Inline-FAQ --- version: 0.44 date: Thu Oct 24 16:17:27 PDT 2002 changes: - Fixed ParseRecDescent to handle 'unsigned foo()' and 'long foo()' - Updated README - Fixed %INC problem --- version: 0.44 date: Wed Oct 23 10:27:41 PDT 2002 changes: - Used File::Spec::Unix for %INC keys (which are always in Unix form) --- version: 0.44 date: Mon Oct 21 16:49:54 PDT 2002 changes: - Applied Mitchell's patch for Inline::C::ParseRegExp --- version: 0.44 date: Mon Oct 21 00:17:22 PDT 2002 changes: - Updated pod docs --- version: 0.44 date: Thu Oct 17 20:00:46 PDT 2002 changes: - Shortened BUILD_TIMER precision, per Leon Brocard's suggestion. - Applied Mitchell Charity's patch to fix Piers Harding's CPP problem. - Fixed bug with USING keyword --- version: 0.44 date: Fri Oct 11 18:09:03 PDT 2002 changes: - Added the USING keyword. This allows you to specify a list of modules which can override certain parts of the Inline process. - Added Inline::C::ParseRecDescent and Inline::C::ParseRegExp to provide two (hopefully) functionally identical C parsers. You use one of these by saying 'use Inline C => DATA => USING => "ParseRegExp"'. Big thanks to Mitchell Charity for ParseRegExp. It's over two orders of magnitude faster than ParseRecDescent. - Added the more diagnostics to BUILD_NOISY. - Added BUILD_TIMERS for benchmarking the Inline build process. --- version: 0.44 date: Wed Oct 9 19:03:34 PDT 2002 changes: - Applied a (BIG) patch to the Inline distribution to use File::Spec to manipulate all file paths. Thanks Mitchell Charity! --- version: 0.44 date: Tue Oct 8 11:47:39 PDT 2002 changes: - Fixed a bug in OS X. Inline::C was being required even if the object was cached. That's because Inline.pm wasn't checking for .bundle. --- version: 0.44 date: Tue Oct 8 10:33:13 PDT 2002 changes: - Added an option to Inline::C called BUILD_NOISY. Setting this to true will cause the build process to dump output to the screen instead of to a file. You can set it with 'BUILD_NOISY => 1,' or 'ENABLE => "BUILD_NOISY"'. - Honor the PERL_INLINE_BUILD_NOISY environment variable, to do the same as above. Environment variable has higher precedence. - Print the contents of 'out.make' to the screen on failure. This will happen when BUILD_NOISY is off. When its on, you'll see the messages in real time, but they won't go to 'out.make'. - Provide the NOISY shortcut so you can say 'perl -MInline=force,noisy foo.pl'. - Inline::MakeMaker uses the NOISY shortcut for its build command. This way module builds are noisy like they should be. --- version: 0.44 date: Thu Oct 3 17:40:27 PDT 2002 changes: - Integrated the new improved Inline::MakeMaker - WriteInlineMakefile is deprecated for WriteMakefile --- version: 0.44 date: Thu Oct 3 17:09:20 PDT 2002 changes: - Added a patch by Rafael Garcia-Suarez to use $^X when $Config::Config{perlpath} is wrong. (It happens) --- version: 0.44 date: Thu Oct 3 16:51:39 PDT 2002 changes: - Refactored the Parse::RecDescent grammar - Moved grammar module to Inline::C::recdescent - Support 'const' in types. Requested by Nicholas Clark - Other modifiers seemed to be busted. Like 'unsigned'. Got them working. - Started integrating Mitchell Charity's parser. Don't know how to turn it on yet. It's currently in Inline::C::charity --- version: 0.44 date: Thu Oct 3 16:20:56 PDT 2002 changes: - Allow C++ based modules to be installed as well as C ones. Requested by Piers Harding. --- version: 0.44 date: Wed Oct 2 21:04:13 PDT 2002 changes: - Call validate() for interpreted ILSMs even on load(). This patch is dedicated to the very patient Mark Fowler who waited almost a year for it. I hope that never happens again. 0.43 Sat Jul 21 14:58:46 PDT 2001 - Removed *old* deprecated functionality. 0.43 Sat Jul 21 14:53:33 PDT 2001 - Inline now works with *all* Perl release versions 5.005 and above. 0.43 Thu Jul 19 17:29:17 PDT 2001 - I was comparing a version number to a md5 hash. Oops. Thanks Marcel. 0.43 Thu Jul 19 17:29:17 PDT 2001 - Changed M51 error message which was causing confusion. It would often come up in places I didn't anticipate. 0.43 Thu Jul 19 17:29:17 PDT 2001 - Use $Config{dlext} instead of $Config{so}. Thanks Marcel. 0.42 Sun Jun 10 18:21:06 PDT 2001 - Re-fixed config generator path bug prevents ILSMs like I::Python and I::Tcl from installing. (NEILW) 0.41 Tue Jun 5 00:23:46 PDT 2001 - Don't install .inline or .inl files with Inline::MakeMaker. Require object name to be same as package name for installation. Put hack in INIT block to fix Sarathy's patch ;) 0.41 Sat Jun 2 19:53:58 PDT 2001 - Fixed config generator path bug that would prevent other ILSMs from installing. Thanks Patrick. 0.41 Sat Jun 2 19:53:58 PDT 2001 - Applied patch to (hopefully) handle CRLF variations properly. Thanks Binkley 0.40 Sun May 27 18:59:59 PDT 2001 - Bugfix. NAME not set right without AUTONAME. 0.40 Sat May 26 13:41:18 PDT 2001 - TRIAL8 of Inline-0.40 Added option to distribute binary PPM modules with or without source. Got UNTAINT to work again. 0.40 Wed May 23 18:19:16 PDT 2001 - TRIAL7 of Inline-0.40 Fixed path bus for MacOS. Thanks Marcel. 'with' works again (with Event) Inline::MakeMaker adds WriteMakefile dependency for Inline 0.40 0.40 Wed May 23 01:14:23 PDT 2001 - TRIAL6 of Inline-0.40 Made Denter YAML compliant Croak on usage of SITE_INSTALL Update Inline.pod for 0.40 features Detect and croak on old config files 0.40 Mon May 21 18:06:30 PDT 2001 - TRIAL5 of Inline-0.40 Added alpha support for Inline::Files Made all internal path names canonical 0.40 Sun May 13 23:38:26 PDT 2001 - Finished TRIAL1 version of Inline-0.40 Short object names Safer config generation AUTONAME support Reinstituted AutoLoading Put all messages into subroutines inside Inline.pm 0.40 Wed May 9 11:14:47 PDT 2001 - Completely reorganized the Inline internal object into major groups: API - Contract space for the ILSMs. Guaranteed backwards compatible after Inline 1.00. ILSM - Private space for ILSMs INLINE - Private Inline space. Subject to constant change. CONFIG - Config options. Not for use by ILSMs MATCH - Matching criteria for the object. STRUCT - Reserved for Inline::Struct 0.40 Wed May 9 11:14:47 PDT 2001 - Added command proxy logic for Inline::MakeMaker utilities: INSTALL, MAKEDIST, MAKEPPD 0.40 Wed May 9 11:14:47 PDT 2001 - Got _INSTALL_ option working with Inline::MakeMaker 0.40 Sun Apr 29 13:58:40 PDT 2001 - Replaced Inline's use of Data::Dumper with Inline::Denter. This is a stripped down version of Data::Denter. This change makes Inline more secure because it doesn't need to eval() untrusted code. Also removes the dependency on Safe.pm which has known security flaws. Yay! 0.33 Sat Apr 28 20:20:29 PDT 2001 - 'require FindBin' instead of 'use FindBin' for mod_perl. 0.33 Sat Apr 28 20:20:29 PDT 2001 - Fixed Win32 bug. Drive letter 'c:' can be lower case. 0.33 Sat Apr 28 20:20:29 PDT 2001 - Changed 'make install' to 'make pure_install' 0.33 Sat Apr 28 20:20:29 PDT 2001 - Fixed bug of assuminh ':' for PATH separator. (Windows bug) 0.33 Sat Apr 28 20:20:29 PDT 2001 - Rearranged test harness. Removed dependency on C for tests. Invented Inline::Foo for testing. 0.33 Sat Apr 28 20:20:29 PDT 2001 - Added ENABLE and DISABLE config modifiers. 0.33 Sat Apr 28 20:20:29 PDT 2001 - Changed the way ILSMs are detected. 0.32 Mon Feb 26 07:44:34 PST 2001 - Add DIRECTORY path to applicable warnings and error msgs 0.32 Mon Feb 26 07:42:32 PST 2001 - Warn if UNTAINT && SAFEMODE && ! DIRECTORY (croak if root) 0.32 Mon Feb 26 01:07:15 PST 2001 - Added GLOBAL_LOAD option with GLOBAL shortcut. 0.32 Mon Feb 26 01:00:00 PST 2001 - Added SAFEMODE option. - Safe->reval(DIRECTORY/config) if SAFE. - Blindly untaint all %ENV variables for UNTAINT. 0.32 Fri Feb 23 03:20:19 PST 2001 - Fixed MSWin32 bug of getting full path parts in dll name. 0.32 Thu Feb 22 02:35:04 PST 2001 - Fixed the "cut & paste" bug. (DOS line endings in Unix.) 0.32 Thu Feb 22 02:10:07 PST 2001 - Fixed detection of using Inline::Config. 0.32 Wed Feb 21 23:40:33 PST 2001 - Added UNTAINT option, which lets you use Inline with Perl's -T flag. 0.31 Fri Jan 19 00:13:31 PST 2001 - Changed doc instances of 'C' to 'Inline'. 0.31 Sat Jan 13 11:49:14 PST 2001 - Reorganized the internal structure of the Inline DIRECTORY - Shortened install path to .Inline/lib/auto/... - Lengthened the build path to .Inline/build/... 0.31 Sat Jan 13 11:18:22 PST 2001 - Changed BLIB option to DIRECTORY - Changed default DIRECTORY from blib_I to _Inline or .Inline 0.30 Fri Dec 8 02:00:17 PST 2000 - Major reworking of Inline.pm Sweeping changes to: - Configuaration - Syntax - Language integration Too much to list here. See ToDo 0.26 Thu Sep 14 20:51:11 PDT 2000 - localize $/ and $\ to shield them from things like 'perl -l'. Thanks Michael Schwern. 0.25 Fri Sep 1 10:07:33 PDT 2000 - Use MD5 on unmodified code only. User must force recompile if auto_headers change. This would have caused existing installs to break. 0.25 Fri Sep 1 10:04:14 PDT 2000 - Don't determine build path unless really needed, since a blib_I might be created. This might be annoying for someone who is only *using* an Inline extension module. 0.25 Fri Sep 1 08:35:53 PDT 2000 - Mangle $VERSION into object name for modules 0.25 Thu Aug 31 22:46:25 PDT 2000 - Support Inline->import(C=>); syntax 0.25 Sun Aug 20 20:52:24 PDT 2000 - Return an empty list when the C function is of type void and doesn't use any stack manipulating macros. (ie dXSARGS) It used to return whatever was passed in on the stack. :-( 0.25 Fri Aug 18 18:45:24 PDT 2000 - Force rebuild when SITE_INSTALL option is set. 0.25 Fri Aug 18 18:15:34 PDT 2000 - Figured out what was actually causing the 0.23 AutoLoader bug. Can't autoload from "./blib" (relative path) when chdir() has been used. Fixed properly now. Can AutoLoad fix_make() again. :-) 0.24 Fri Aug 18 03:03:06 PDT 2000 - Fixed Autoload bug found during "make test" of Inline installation. 0.23 Wed Aug 16 18:10:07 PDT 2000 - Added support for MSWin32 operating systems which use the Microsoft Visual C++ compiler. 0.22 Wed Aug 9 18:55:54 PDT 2000 - First alpha release to CPAN 0.01 Mon Jul 24 11:23:25 2000 - original version; created by h2xs 1.19 Inline-0.53/Inline-API.pod0000644000076400010400000003145212052612400016655 0ustar sisyphusAdministrators=head1 NAME Inline-API - How to bind a programming language to Perl using Inline.pm =head1 SYNOPSIS #!/usr/bin/perl use Inline Foo; say_it('foo'); # Use Foo to print "Hello, Foo" __Foo__ foo-sub say_it { foo-my $foo = foo-shift; foo-print "Hello, $foo\n"; } =head1 DESCRIPTION So you think Inline C is pretty cool, but what you really need is for Perl to work with the brand new programming language "Foo". Well you're in luck. C has support for adding your own Inline Language Support Module (B), like C. Inline has always been intended to work with lots of different programming languages. Many of the details can be shared between implementations, so that C has a similar interface to C. All of the common code is in C. Language specific modules like C are subclasses of C. They can inherit as much of the common behaviour as they want, and provide specific behaviour of their own. This usually comes in the form of Configuration Options and language specific compilation. The Inline C support is probably the best boilerplate to copy from. Since version 0.30 all C support was isolated into the module C and the parsing grammar is further broken out into C. All of these components come with the Inline distribution. This POD gives you all the details you need for implementing an ILSM. For further assistance, contact inline@perl.org See L<"SEE ALSO"> below. We'll examine the joke language Inline::Foo which is distributed with Inline. It actually is a full functioning ILSM. I use it in Inline's test harness to test base Inline functionality. It is very short, and can help you get your head wrapped around the Inline API. =head1 A Skeleton For the remainder of this tutorial, let's assume we're writing an ILSM for the ficticious language C. We'll call it C. Here is the entire (working) implementation. package Inline::Foo; use strict; $Inline::Foo::VERSION = '0.01'; @Inline::Foo::ISA = qw(Inline); require Inline; use Carp; #=========================================================== # Register Foo as an Inline Language Support Module (ILSM) #=========================================================== sub register { return { language => 'Foo', aliases => ['foo'], type => 'interpreted', suffix => 'foo', }; } #=========================================================== # Error messages #=========================================================== sub usage_config { my ($key) = @_; "'$key' is not a valid config option for Inline::Foo\n"; } sub usage_config_bar { "Invalid value for Inline::Foo config option BAR"; } #=========================================================== # Validate the Foo Config Options #=========================================================== sub validate { my $o = shift; $o->{ILSM}{PATTERN} ||= 'foo-'; $o->{ILSM}{BAR} ||= 0; while (@_) { my ($key, $value) = splice @_, 0, 2; if ($key eq 'PATTERN') { $o->{ILSM}{PATTERN} = $value; next; } if ($key eq 'BAR') { croak usage_config_bar unless $value =~ /^[01]$/; $o->{ILSM}{BAR} = $value; next; } croak usage_config($key); } } #=========================================================== # Parse and compile Foo code #=========================================================== sub build { my $o = shift; my $code = $o->{API}{code}; my $pattern = $o->{ILSM}{PATTERN}; $code =~ s/$pattern//g; $code =~ s/bar-//g if $o->{ILSM}{BAR}; sleep 1; # imitate compile delay { package Foo::Tester; eval $code; } croak "Foo build failed:\n$@" if $@; my $path = "$o->{API}{install_lib}/auto/$o->{API}{modpname}"; my $obj = $o->{API}{location}; $o->mkpath($path) unless -d $path; open FOO_OBJ, "> $obj" or croak "Can't open $obj for output\n$!"; print FOO_OBJ $code; close \*FOO_OBJ; } #=========================================================== # Only needed for interpreted languages #=========================================================== sub load { my $o = shift; my $obj = $o->{API}{location}; open FOO_OBJ, "< $obj" or croak "Can't open $obj for output\n$!"; my $code = join '', ; close \*FOO_OBJ; eval "package $o->{API}{pkg};\n$code"; croak "Unable to load Foo module $obj:\n$@" if $@; } #=========================================================== # Return a small report about the Foo code. #=========================================================== sub info { my $o = shift; my $text = <<'END'; This is a small report about the Foo code. Perhaps it contains information about the functions the parser found which will be bound to Perl. It will get included in the text produced by the Inline 'INFO' command. END return $text; } 1; Except for C, the subroutines in this code are mandatory for an ILSM. What they do is described below. A few things to note: =over 4 =item 1 C must be a subclass of Inline. This is accomplished with: @Inline::Foo::ISA = qw(Inline); =item 2 The line 'C' is not necessary. But it is there to remind you not to say 'C'. This will not work. =item 3 Remember, it is not valid for a user to say: use Inline::Foo; C will detect such usage for you in its C method, which is automatically inherited since C is a subclass. =item 4 In the build function, you normally need to parse your source code. Inline::C uses Parse::RecDescent to do this. Inline::Foo simply uses eval. (After we strip out all occurances of 'foo-'). An alternative parsing method that works well for many ILSMs (like Java and Python) is to use the language's compiler itself to parse for you. This works as long as the compiler can be made to give back parse information. =back =head1 The Inline API This section is a more formal specification of what functionality you'll need to provide to implement an ILSM. When Inline determines that some C code needs to be compiled it will automatically load your ILSM module. It will then call various subroutines which you need to supply. We'll call these subroutines "callbacks". You will need to provide the following 5 callback subroutines. =head2 The register() Callback This subroutine receives no arguments. It returns a reference to a hash of ILSM meta-data. Inline calls this routine only when it is trying to detect new ILSM-s that have been installed on a given system. Here is an example of the has ref you would return for Foo: { language => 'Foo', aliases => ['foo'], type => 'interpreted', suffix => 'foo', }; The meta-data items have the following meanings: =over 4 =item language This is the proper name of the language. It is usually implemented as C for a given language 'X'. =item aliases This is a reference to an array of language name aliases. The proper name of a language can only contain word characters. [A-Za-z0-9_] An alias can contain any characters except whitespace and quotes. This is useful for names like 'C++' and 'C#'. =item type Must be set to 'compiled' or 'interpreted'. Indicates the category of the language. =item suffix This is the file extension for the cached object that will be created. For 'compiled' languages, it will probably be 'so' or 'dll'. The appropriate value is in C. For interpreted languages, this value can be whatever you want. Python uses C. Foo uses C. =back =head2 The validate() Callback This routine gets passed all configuration options that were not already handled by the base Inline module. The options are passed as key/value pairs. It is up to you to validate each option and store its value in the Inline object (which is also passed in). If a particular option is invalid, you should croak with an appropriate error message. =head2 The build() Callback This subroutine is responsible for doing the parsing and compilation of the Foo source code. The Inline object is passed as the only argument. All pertinent information will be stored in this object. C is required to create a cache object of a specific name, or to croak with an appropriate error message. This is the meat of your ILSM. Since it will most likely be quite complicated, it is probably best that you study an existing ILSM like C. =head2 The load() Callback This method only needs to be provided for interpreted languages. It's responsibility is to start the interpreter. For compiled languages, the load routine from C is called which uses C to load the shared object or DLL. =head2 The info() Callback This method is called when the user makes use of the C shortcut. You should return a string containing a small report about the Inlined code. =head1 The Inline Object C creates a hash based Perl object for each section of Inlined source code it receives. This object contains lots of information about the code, the environment, and the configuration options used. This object is a hash that is broken into several subhashes. The only two subhashes that an ILSM should use at all are $o->{API} and $o->{ILSM}. The first one contains all of the information that Inline has gather for you in order for you to create/load a cached object of your design. The second one is a repository where your ILSM can freely store data that it might need later on. This section will describe all of the Inline object "API" attributes. =head2 The code Attribute This the actual source code passed in by the user. It is stored as one long string. =head2 The language Attribute The proper name of the language being used. =head2 The language_id Attribute The language name specified by the user. Could be 'C++' instead of 'CPP'. =head2 The module Attribute This is the shared object's file name. =head2 The modfname Attribute This is the shared object's file name. =head2 The modpname Attribute This is the shared object's installation path extension. =head2 The version Attribute The version of C being used. =head2 The pkg Attribute The Perl package from which this invocation pf Inline was called. =head2 The install_lib Attribute This is the directory to write the shared object into. =head2 The build_dir Attribute This is the directory under which you should write all of your build related files. =head2 The script Attribute This is the name of the script that invoked Inline. =head2 The location Attribute This is the full path name of the executable object in question. =head2 The suffix Attribute This is the shared library extension name. (Usually 'so' or 'dll'). =over 4 =back =head1 The Inline Namespace C has been set up so that anyone can write their own language support modules. It further allows anyone to write a different implementation of an existing Inline language, like C for instance. You can distribute that module on the CPAN. If you have plans to implement and distribute an Inline module, I would ask that you please work with the Inline community. We can be reached at the Inline mailing list: inline@perl.org (Send mail to inline-subscribe@perl.org to subscribe). Here you should find the advice and assistance needed to make your module a success. The Inline community will decide if your implementation of COBOL will be distributed as the official C or should use an alternate namespace. In matters of dispute, I (Brian Ingerson) retain final authority. (and I hope not to need use of it :-) Actually modules@perl.org retains the B authority. But even if you want to work alone, you are free and welcome to write and distribute Inline language support modules on CPAN. You'll just need to distribute them under a different package name. =head1 SEE ALSO For generic information about Inline, see L. For information about using Inline with C see L. For information on supported languages and platforms see L. Inline's mailing list is inline@perl.org To subscribe, send email to inline-subscribe@perl.org =head1 AUTHOR Brian Ingerson =head1 COPYRIGHT Copyright (c) 2000-2002. Brian Ingerson. Copyright (c) 2008, 2010, 2011. Sisyphus. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut Inline-0.53/Inline-FAQ.pod0000644000076400010400000001552512052612400016656 0ustar sisyphusAdministrators=head1 NAME Inline-FAQ - The Inline FAQ =head1 DESCRIPTION Welcome to the official Inline FAQ. In this case, B means: Formerly Answered Questions This is a collection of old, long-winded emails that myself and others have sent to the Inline mailing list. (inline@perl.org) They have been reviewed and edited for general Inline edification. Some of them may be related to a specific language. They are presented here in a traditional FAQ layout. =head1 General Inline Since there is only a handful of content so far, all FAQs are currently under this heading. =head2 How disposable is a .Inline or _Inline directory? I probably need to be more emphatic about the roll of _Inline/ cache directories. Since they are created automatically, they are completely disposable. I delete them all the time. And it is fine to have a different one for each project. In fact as long as you don't have ~/.Inline/ defined, Inline will create a new ./_Inline directory (unless, you've done something to override this automatic process - such as using the DIRECTORY config option, or using the PERL_INLINE_DIRECTORY environment variable). You can move that to ./.Inline and it will continue to work if you want togive it more longevity and hide it from view. There is a long complicated list of rules about how [_.]Inline/ directories are used/created. But it was designed to give you the most flexibility/ease-of-use. Never be afraid to nuke 'em. They'll just pop right back next time they're needed. :) =head2 Whatever happened to the SITE_INSTALL option? SITE_INSTALL is gone. I was going to leave it in and change the semantics, but thought it better to remove it, so people wouldn't try to use it the old way. There is now _INSTALL_ (but you're not supposed to know that :). It works magically through the use of Inline::MakeMaker. I explained this earlier but it's worth going through again because it's the biggest change for 0.40. Here's how to 'permanently' install an Inline extension (Inline based module) with 0.40: 1) Create a module with Inline. 2) Test it using the normal/local _Inline/ cache. 3) Create a Makefile.PL (like the one produced by h2xs) 4) Change 'use ExtUtils::MakeMaker' to 'use Inline::MakeMaker' 5) In the Makefile.PL's WriteMakefile() insert: CONFIGURE_REQUIRES => { 'Inline::MakeMaker' => 0.45, 'ExtUtils::MakeMaker' => 6.52, }, (See the "Writing Modules with Inline" section of Inline.pod for an explanation/elaboration.) 6) Change your 'use Inline C => DATA' to 'use Inline C => DATA => NAME => Foo => VERSION => 1.23' 7) Make sure NAME matches your package name ('Foo'), or begins with 'Foo::'. 8) If you want to quiet a harmless warning that will appear when the module is loaded via "require", do "Inline->init();". See "Writing Modules with Inline" in the Inline pod for details. 9) Make sure VERSION matches $Foo::VERSION. This must be a string (not a number) matching /^\d\.\d\d$/ 10) Do the perl/make/test/install dance (thanks binkley :) With Inline 0.41 (or thereabouts) you can skip steps 3 & 4, and just say 'perl -MInline=INSTALL ./Foo.pm'. This will work for non-Inline modules too. It will become the defacto standard (since there is no easy standard) way of installing a Perl module. It will allow Makefile.PL parameters 'perl -MInline=INSTALL ./Foo.pm - PREFIX=/home/ingy/perl' and things like that. It will also make use of a MANIFEST if you provide one. =head2 How do I create a binary distribution using Inline? I've figured out how to create and install a PPM binary distribution; with or without distributing the C code! And I've decided to share it with all of you :) NOTE: Future versions of Inline will make this process a one line command. But for now just use this simple recipe. --- The Inline 0.40 distribution comes with a sample extension module called Math::Simple. Theoretically you could distribute this module on CPAN. It has all the necessary support for installation. You can find it in Inline-0.40/modules/Math/Simple/. Here are the steps for converting this into a binary distribution *without* C source code. NOTE: The recipient of this binary distribution will need to have the PPM.pm module installed. This module requires a lot of other CPAN modules. ActivePerl (available for Win32, Linux, and Solaris) has all of these bundled. While ActivePerl isn't required, it makes things (a lot) easier. 1) cd Inline-0.40/Math/Simple/ 2) Divide Simple.pm into two files: ---8<--- (Simple.pm) package Math::Simple; use strict; require Exporter; @Math::Simple::ISA = qw(Exporter); @Math::Simple::EXPORT = qw(add subtract); $Math::Simple::VERSION = '1.23'; use Inline (C => 'src/Simple.c' => NAME => 'Math::Simple', VERSION => '1.23', ); 1; ---8<--- ---8<--- (src/Simple.c) int add (int x, int y) { return x + y; } int subtract (int x, int y) { return x - y; } ---8<--- So now you have the Perl in one file and the C in the other. The C code must be in a subdirectory. 3) Note that I also changed the term 'DATA' to the name of the C file. This will work just as if the C were still inline. 4) Run 'perl Makefile.PL' 5) Run 'make test' 6) Get the MD5 key from 'blib/arch/auto/Math/Simple/Simple.inl' 7) Edit 'blib/lib/Math/Simple.pm'. Change 'src/Simple.c' to '02c61710cab5b659efc343a9a830aa73' (the MD5 key) 8) Run 'make ppd' 9) Edit 'Math-Simple.ppd'. Fill in AUTHOR and ABSTRACT if you wish. Then change: to 10) Run: tar cvf Math-Simple.tar blib gzip --best Math-Simple.tar 11) Run: tar cvf Math-Simple-1.23.tar Math-Simple.ppd Math-Simple.tar.gz gzip --best Math-Simple-1.23.tar 12) Distribute Math-Simple-1.23.tar.gz with the following instructions: A) Run: gzip -d Math-Simple-1.23.tar.gz tar xvzf Math-Simple-1.23.tar B) Run 'ppm install Math-Simple.ppd' C) Delete Math-Simple.tar and Math-Simple.ppd. D) Test with: perl -MMath::Simple -le 'print add(37, 42)' --- That's it. The process should also work with zip instead of tar, but I haven't tried it. The recipient of the binary must have Perl built with a matching architecture. Luckily, ppm will catch this. For a binary dist *with* C source code, simply omit steps 2, 3, 6, and 7. If this seems too hard, then in a future version you should be able to just type: make ppm =head2 Why does C/t/09parser.t fail on Cygwin ? It doesn't always fail on Cygwin, but if you find that it produces "unable to remap .... to same address as parent" errors during the build phase, then it's time for you to run rebaseall. See http://cygwin.com/faq/faq-nochunks.html#faq.using.fixing-fork-failures and, if needed, seek further help from the Cygwin mailing list. =cut Inline-0.53/Inline-Support.pod0000644000076400010400000000656212052612400017724 0ustar sisyphusAdministrators=head1 NAME Inline-Support - Support Information for Inline.pm and related modules. =head1 DESCRIPTION This document contains all of the latest support information for C and the recognized Inline Language Support Modules (ILSMs) available on CPAN. =head1 SUPPORTED LANGUAGES The most important language that Inline supports is C. That is because Perl itself is written in C. By giving a your Perl scripts access to C, you in effect give them access to the entire glorious internals of Perl. (Caveat scriptor :-) As of this writing, Inline also supports: - C++ - Java - Python - Tcl - Assembly - CPR - And even Inline::Foo! :) Projects that I would most like to see happen in the year 2001 are: - Fortran - Ruby - Lisp - Guile - Bash - Perl4 =head1 SUPPORTED PLATFORMS C should work anywhere that CPAN extension modules (those that use XS) can be installed, using the typical install format of: perl Makefile.PL make make test make install It has been tested on many Unix and Windows variants. B: C requires Perl 5.005 or higher because C requires it. (Something to do with the C operator) Inline has been successfully tested at one time or another on the following platforms: Linux Solaris SunOS HPUX AIX FreeBSD OpenBSD BeOS OS X WinNT Win2K WinME Win98 Cygwin The Microsoft tests deserve a little more explanation. I used the following: Windows NT 4.0 (service pack 6) Perl 5.005_03 (ActiveState build 522) MS Visual C++ 6.0 The "nmake" make utility (distributed w/ Visual C++) C pulls all of its base configuration (including which C utility to use) from C. Since your MSWin32 version of Perl probably came from ActiveState (as a binary distribution) the C will indicate that C is the system's C utility. That is because ActiveState uses Visual C++ to compile Perl. To install C (or any other CPAN module) on MSWin32 w/ Visual C++, use these: perl Makefile.PL nmake nmake test nmake install Inline has also been made to work with Mingw32/gcc on all Windows platforms. This is a free compiler for Windows. You must also use a perl built with that compiler. The "Cygwin" test was done on a Windows 98 machine using the Cygwin Unix/Win32 porting layer software from Cygnus. The C binary on this machine was also compiled using the Cygwin tool set (C). This software is freely available from http://sources.redhat.com/cygwin/ If you get Inline to work on a new platform, please send me email email. If it doesn't work, let me know as well and I'll see what can be done. =head1 SEE ALSO For general information about Inline see L. For information about using Inline with C see L. For sample programs using Inline with C see L. For information on writing your own Inline Language Support Module, see L. Inline's mailing list is inline@perl.org To subscribe, send email to inline-subscribe@perl.org =head1 AUTHOR Brian Ingerson =head1 COPYRIGHT Copyright (c) 2000-2002. Brian Ingerson. Copyright (c) 2008, 2010, 2011. Sisyphus. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut Inline-0.53/Inline.pm0000644000076400010400000016231012140062002016071 0ustar sisyphusAdministratorspackage Inline; use strict; require 5.006; $Inline::VERSION = '0.53'; $Inline::VERSION = eval $Inline::VERSION; use AutoLoader 'AUTOLOAD'; use Inline::denter; use Config; use Carp; use Cwd qw(abs_path cwd); use File::Spec; use File::Spec::Unix; my %CONFIG = (); my @DATA_OBJS = (); my $INIT = 0; my $version_requested = 0; my $version_printed = 0; my $untaint = 0; my $safemode = 0; $Inline::languages = undef; #needs to be global for AutoLoaded error messages our $did = '_Inline'; # Default Inline Directory # This is the config file written by create_config_file(). our $configuration_file = 'config-' . $Config::Config{'archname'} . '-' . $]; my %shortcuts = ( NOCLEAN => [CLEAN_AFTER_BUILD => 0], CLEAN => [CLEAN_BUILD_AREA => 1], FORCE => [FORCE_BUILD => 1], INFO => [PRINT_INFO => 1], VERSION => [PRINT_VERSION => 1], REPORTBUG => [REPORTBUG => 1], UNTAINT => [UNTAINT => 1], SAFE => [SAFEMODE => 1], UNSAFE => [SAFEMODE => 0], GLOBAL => [GLOBAL_LOAD => 1], NOISY => [BUILD_NOISY => 1], TIMERS => [BUILD_TIMERS => 1], NOWARN => [WARNINGS => 0], _INSTALL_ => [_INSTALL_ => 1], SITE_INSTALL => undef, # No longer supported. ); my $default_config = { NAME => '', AUTONAME => -1, VERSION => '', DIRECTORY => '', WITH => [], USING => [], CLEAN_AFTER_BUILD => 1, CLEAN_BUILD_AREA => 0, FORCE_BUILD => 0, PRINT_INFO => 0, PRINT_VERSION => 0, REPORTBUG => 0, UNTAINT => 0, NO_UNTAINT_WARN => 0, REWRITE_CONFIG_FILE => 0, SAFEMODE => -1, GLOBAL_LOAD => 0, BUILD_NOISY => 0, BUILD_TIMERS => 0, WARNINGS => 1, _INSTALL_ => 0, _TESTING => 0, }; sub UNTAINT {$untaint} sub SAFEMODE {$safemode} #============================================================================== # This is where everything starts. #============================================================================== sub import { local ($/, $") = ("\n", ' '); local ($\, $,); my $o; my ($pkg, $script) = caller; # Not sure what this is for. Let's see what breaks. # $pkg =~ s/^.*[\/\\]//; my $class = shift; if ($class ne 'Inline') { croak M01_usage_use($class) if $class =~ /^Inline::/; croak M02_usage(); } $CONFIG{$pkg}{template} ||= $default_config; return unless @_; &create_config_file(), return 1 if $_[0] eq '_CONFIG_'; goto &maker_utils if $_[0] =~ /^(install|makedist|makeppd)$/i; my $control = shift; if ($control eq 'with') { return handle_with($pkg, @_); } elsif ($control eq 'Config') { return handle_global_config($pkg, @_); } elsif (exists $shortcuts{uc($control)}) { handle_shortcuts($pkg, $control, @_); $version_requested = $CONFIG{$pkg}{template}{PRINT_VERSION}; return; } elsif ($control =~ /^\S+$/ and $control !~ /\n/) { my $language_id = $control; my $option = shift || ''; my @config = @_; my $next = 0; for (@config) { next if $next++ % 2; croak M02_usage() if /[\s\n]/; } $o = bless {}, $class; $o->{INLINE}{version} = $Inline::VERSION; $o->{API}{pkg} = $pkg; $o->{API}{script} = $script; $o->{API}{language_id} = $language_id; if ($option =~ /^(FILE|BELOW)$/ or not $option and defined $INC{File::Spec::Unix->catfile('Inline','Files.pm')} and Inline::Files::get_filename($pkg) ) { $o->read_inline_file; $o->{CONFIG} = handle_language_config(@config); } elsif ($option eq 'DATA' or not $option) { $o->{CONFIG} = handle_language_config(@config); push @DATA_OBJS, $o; return; } elsif ($option eq 'Config') { $CONFIG{$pkg}{$language_id} = handle_language_config(@config); return; } else { $o->receive_code($option); $o->{CONFIG} = handle_language_config(@config); } } else { croak M02_usage(); } $o->glue; } #============================================================================== # Run time version of import (public method) #============================================================================== sub bind { local ($/, $") = ("\n", ' '); local ($\, $,); my ($code, @config); my $o; my ($pkg, $script) = caller; my $class = shift; croak M03_usage_bind() unless $class eq 'Inline'; $CONFIG{$pkg}{template} ||= $default_config; my $language_id = shift or croak M03_usage_bind(); croak M03_usage_bind() unless ($language_id =~ /^\S+$/ and $language_id !~ /\n/); $code = shift or croak M03_usage_bind(); @config = @_; my $next = 0; for (@config) { next if $next++ % 2; croak M03_usage_bind() if /[\s\n]/; } $o = bless {}, $class; $o->{INLINE}{version} = $Inline::VERSION; $o->{API}{pkg} = $pkg; $o->{API}{script} = $script; $o->{API}{language_id} = $language_id; $o->receive_code($code); $o->{CONFIG} = handle_language_config(@config); $o->glue; } #============================================================================== # Process delayed objects that don't have source code yet. #============================================================================== # This code is an ugly hack because of the fact that you can't use an # INIT block at "run-time proper". So we kill the warning and tell users # to use an Inline->init() call if they run into problems. (rare) eval <read_DATA; $o->glue; } } sub END { warn M51_unused_DATA() if @DATA_OBJS; print_version() if $version_requested && not $version_printed; } #============================================================================== # Print a small report about the version of Inline #============================================================================== sub print_version { return if $version_printed++; print STDERR <{API}}{qw(pkg language_id)}; my @config = (%{$CONFIG{$pkg}{template}}, %{$CONFIG{$pkg}{$language_id} || {}}, %{$o->{CONFIG} || {}}, ); @config = $o->check_config(@config); $o->fold_options; $o->check_installed; $o->env_untaint if UNTAINT; if (not $o->{INLINE}{object_ready}) { $o->check_config_file; # Final DIRECTORY set here. push @config, $o->with_configs; my $language = $o->{API}{language}; croak M04_error_nocode($language_id) unless $o->{API}{code}; $o->check_module; } $o->env_untaint if UNTAINT; $o->obj_untaint if UNTAINT; print_version() if $version_requested; $o->reportbug() if $o->{CONFIG}{REPORTBUG}; if (not $o->{INLINE}{object_ready} or $o->{CONFIG}{PRINT_INFO} ) { eval "require $o->{INLINE}{ILSM_module}"; croak M05_error_eval('glue', $@) if $@; $o->push_overrides; bless $o, $o->{INLINE}{ILSM_module}; $o->validate(@config); } else { $o->{CONFIG} = {(%{$o->{CONFIG}}, @config)}; } $o->print_info if $o->{CONFIG}{PRINT_INFO}; unless ($o->{INLINE}{object_ready} or not length $o->{INLINE}{ILSM_suffix}) { $o->build(); $o->write_inl_file() unless $o->{CONFIG}{_INSTALL_}; } if ($o->{INLINE}{ILSM_suffix} ne 'so' and $o->{INLINE}{ILSM_suffix} ne 'dll' and $o->{INLINE}{ILSM_suffix} ne 'bundle' and ref($o) eq 'Inline' ) { eval "require $o->{INLINE}{ILSM_module}"; croak M05_error_eval('glue', $@) if $@; $o->push_overrides; bless $o, $o->{INLINE}{ILSM_module}; $o->validate(@config); } $o->load; $o->pop_overrides; } #============================================================================== # Set up the USING overrides #============================================================================== sub push_overrides { my ($o) = @_; my ($language_id) = $o->{API}{language_id}; my ($ilsm) = $o->{INLINE}{ILSM_module}; for (@{$o->{CONFIG}{USING}}) { my $using_module = /^::/ ? "Inline::$language_id$_" : /::/ ? $_ : "Inline::${language_id}::$_"; eval "require $using_module"; croak "Invalid module '$using_module' in USING list:\n$@" if $@; my $register; eval "\$register = $using_module->register"; croak "Invalid module '$using_module' in USING list:\n$@" if $@; for my $override (@{$register->{overrides}}) { no strict 'refs'; next if defined $o->{OVERRIDDEN}{$ilsm . "::$override"}; $o->{OVERRIDDEN}{$ilsm . "::$override"} = \&{$ilsm . "::$override"}; { no warnings 'redefine'; *{$ilsm . "::$override"} = \&{$using_module . "::$override"}; } } } } #============================================================================== # Restore the modules original methods #============================================================================== sub pop_overrides { my $nowarn = $] >= 5.006 ? "no warnings 'redefine';" : ''; eval ($nowarn . 'my ($o) = @_; for my $override (keys %{$o->{OVERRIDDEN}}) { no strict "refs"; *{$override} = $o->{OVERRIDDEN}{$override}; } delete $o->{OVERRIDDEN};') } #============================================================================== # Get source from the DATA filehandle #============================================================================== my (%DATA, %DATA_read); sub read_DATA { require Socket; my ($marker, $marker_tag); my $o = shift; my ($pkg, $language_id) = @{$o->{API}}{qw(pkg language_id)}; unless ($DATA_read{$pkg}++) { no strict 'refs'; *Inline::DATA = *{$pkg . '::DATA'}; local ($/); my ($CR, $LF) = (&Socket::CR, &Socket::LF); (my $data = ) =~ s/$CR?$LF/\n/g; @{$DATA{$pkg}} = split /(?m)^[ \t]{0,}(__\S+?__\n)/, $data; shift @{$DATA{$pkg}} unless ($ {$DATA{$pkg}}[0] || '') =~ /__\S+?__\n/; } ($marker, $o->{API}{code}) = splice @{$DATA{$pkg}}, 0, 2; croak M08_no_DATA_source_code($language_id) unless defined $marker; ($marker_tag = $marker) =~ s/__(\S+?)__\n/$1/; croak M09_marker_mismatch($marker, $language_id) unless $marker_tag eq $language_id; } #============================================================================== # Validate and store the non language-specific config options #============================================================================== sub check_config { my $o = shift; my @others; while (@_) { my ($key, $value) = (shift, shift); if (defined $default_config->{$key}) { if ($key =~ /^(WITH|USING)$/) { croak M10_usage_WITH_USING() if (ref $value and ref $value ne 'ARRAY'); $value = [$value] unless ref $value; $o->{CONFIG}{$key} = $value; next; } $o->{CONFIG}{$key} = $value, next if not $value; if ($key eq 'DIRECTORY') { croak M11_usage_DIRECTORY($value) unless (-d $value); $value = abs_path($value); } elsif ($key eq 'NAME') { croak M12_usage_NAME($value) unless $value =~ /^[a-zA-Z_](\w|::)*$/; } elsif ($key eq 'VERSION') { croak M13_usage_VERSION($value) unless $value =~ /^\d\.\d\d*$/; } $o->{CONFIG}{$key} = $value; } else { push @others, $key, $value; } } return (@others); } #============================================================================== # Set option defaults based on current option settings. #============================================================================== sub fold_options { my $o = shift; # The following small section of code seems, to me, to be unnecessary - which is the # reason that I've commented it out. I've left it here (including its associated comments) # in case it later becomes evident that there *is* good reason to include it. --sisyphus # ## This bit tries to enable UNTAINT automatically if required when running the test suite. # my $env_ha = $ENV{HARNESS_ACTIVE} || 0 ; # my ($harness_active) = $env_ha =~ /(.*)/ ; # if (($harness_active)&&(! $o->{CONFIG}{UNTAINT})){ # eval { # require Scalar::Util; # $o->{CONFIG}{UNTAINT} = # (Scalar::Util::tainted(Cwd::cwd()) ? 1 : 0) ; ## Disable SAFEMODE in the test suite, we know what we are doing... # $o->{CONFIG}{SAFEMODE} = 0 ; # warn "\n-[tT] enabled for test suite. #Automatically setting UNTAINT=1 and SAFEMODE=0.\n" # unless $Inline::_TAINT_WARNING_ ; # $Inline::_TAINT_WARNING_ = 1 ; # } ; # } ## $untaint = $o->{CONFIG}{UNTAINT} || 0; $safemode = (($o->{CONFIG}{SAFEMODE} == -1) ? ($untaint ? 1 : 0) : $o->{CONFIG}{SAFEMODE} ); if (UNTAINT and SAFEMODE and not $o->{CONFIG}{DIRECTORY}) { croak M49_usage_unsafe(1) if ($< == 0 or $> == 0); warn M49_usage_unsafe(0) if $^W; } if ($o->{CONFIG}{AUTONAME} == -1) { $o->{CONFIG}{AUTONAME} = length($o->{CONFIG}{NAME}) ? 0 : 1; } $o->{API}{cleanup} = ($o->{CONFIG}{CLEAN_AFTER_BUILD} and not $o->{CONFIG}{REPORTBUG}); } #============================================================================== # Check if Inline extension is preinstalled #============================================================================== sub check_installed { my $o = shift; $o->{INLINE}{object_ready} = 0; unless ($o->{API}{code} =~ /^[A-Fa-f0-9]{32}$/) { require Digest::MD5; $o->{INLINE}{md5} = Digest::MD5::md5_hex($o->{API}{code}); } else { $o->{INLINE}{md5} = $o->{API}{code}; } return if $o->{CONFIG}{_INSTALL_}; return unless $o->{CONFIG}{VERSION}; croak M26_error_version_without_name() unless $o->{CONFIG}{NAME}; my @pkgparts = split(/::/, $o->{API}{pkg}); my $realname = File::Spec->catfile(@pkgparts) . '.pm'; my $realname_unix = File::Spec::Unix->catfile(@pkgparts) . '.pm'; my $realpath = $INC{$realname_unix} or croak M27_module_not_indexed($realname_unix); my ($volume,$dir,$file) = File::Spec->splitpath($realpath); my @dirparts = File::Spec->splitdir($dir); pop @dirparts unless $dirparts[-1]; push @dirparts, $file; my @endparts = splice(@dirparts, 0 - @pkgparts); $dirparts[-1] = 'arch' if $dirparts[-2] eq 'blib' && $dirparts[-1] eq 'lib'; File::Spec->catfile(@endparts) eq $realname or croak M28_error_grokking_path($realpath); $realpath = File::Spec->catpath($volume,File::Spec->catdir(@dirparts),""); $o->{API}{version} = $o->{CONFIG}{VERSION}; $o->{API}{module} = $o->{CONFIG}{NAME}; my @modparts = split(/::/,$o->{API}{module}); $o->{API}{modfname} = $modparts[-1]; $o->{API}{modpname} = File::Spec->catdir(@modparts); my $suffix = $Config{dlext}; my $obj = File::Spec->catfile($realpath,'auto',$o->{API}{modpname}, "$o->{API}{modfname}.$suffix"); croak M30_error_no_obj($o->{CONFIG}{NAME}, $o->{API}{pkg}, $realpath) unless -f $obj; @{$o->{CONFIG}}{qw( PRINT_INFO REPORTBUG FORCE_BUILD _INSTALL_ )} = (0, 0, 0, 0); $o->{install_lib} = $realpath; $o->{INLINE}{ILSM_type} = 'compiled'; $o->{INLINE}{ILSM_module} = 'Inline::C'; $o->{INLINE}{ILSM_suffix} = $suffix; $o->{INLINE}{object_ready} = 1; } #============================================================================== # Dynamically load the object module #============================================================================== sub load { my $o = shift; if ($o->{CONFIG}{_INSTALL_}) { my $inline = "$o->{API}{modfname}.inl"; open INLINE, "> $inline" or croak M24_open_for_output_failed($inline); print INLINE "*** AUTOGENERATED by Inline.pm ***\n\n"; print INLINE "This file satisfies the make dependency for "; print INLINE "$o->{API}{modfname}.pm\n"; close INLINE; return; } my ($pkg, $module) = @{$o->{API}}{qw(pkg module)}; croak M42_usage_loader() unless $o->{INLINE}{ILSM_type} eq 'compiled'; require DynaLoader; @Inline::ISA = qw(DynaLoader); my $global = $o->{CONFIG}{GLOBAL_LOAD} ? '0x01' : '0x00'; my $version = $o->{API}{version} || '0.00'; eval <bootstrap; END croak M43_error_bootstrap($module, $@) if $@; } #============================================================================== # Process the config options that apply to all Inline sections #============================================================================== sub handle_global_config { my $pkg = shift; while (@_) { my ($key, $value) = (shift, shift); croak M02_usage() if $key =~ /[\s\n]/; $key = $value if $key =~ /^(ENABLE|DISABLE)$/; croak M47_invalid_config_option($key) unless defined $default_config->{$key}; if ($key eq 'ENABLE') { $CONFIG{$pkg}{template}{$value} = 1; } elsif ($key eq 'DISABLE') { $CONFIG{$pkg}{template}{$value} = 0; } else { $CONFIG{$pkg}{template}{$key} = $value; } } } #============================================================================== # Process the config options that apply to a particular language #============================================================================== sub handle_language_config { my @values; while (@_) { my ($key, $value) = (shift, shift); croak M02_usage() if $key =~ /[\s\n]/; if ($key eq 'ENABLE') { push @values, $value, 1; } elsif ($key eq 'DISABLE') { push @values, $value, 0; } else { push @values, $key, $value; } } return {@values}; } #============================================================================== # Validate and store shortcut config options #============================================================================== sub handle_shortcuts { my $pkg = shift; for my $option (@_) { my $OPTION = uc($option); if ($OPTION eq 'SITE_INSTALL') { croak M58_site_install(); } elsif ($shortcuts{$OPTION}) { my ($method, $arg) = @{$shortcuts{$OPTION}}; $CONFIG{$pkg}{template}{$method} = $arg; } else { croak M48_usage_shortcuts($option); } } } #============================================================================== # Process the with command #============================================================================== sub handle_with { my $pkg = shift; croak M45_usage_with() unless @_; for (@_) { croak M02_usage() unless /^[\w:]+$/; eval "require $_;"; croak M46_usage_with_bad($_) . $@ if $@; push @{$CONFIG{$pkg}{template}{WITH}}, $_; } } #============================================================================== # Perform cleanup duties #============================================================================== sub DESTROY { my $o = shift; $o->clean_build if $o->{CONFIG}{CLEAN_BUILD_AREA}; } # Comment out the next 2 lines to stop autoloading of subroutines (testing) 1; __END__ #============================================================================== # Get the source code #============================================================================== sub receive_code { my $o = shift; my $code = shift; croak M02_usage() unless (defined $code and $code); if (ref $code eq 'CODE') { $o->{API}{code} = &$code; } elsif (ref $code eq 'ARRAY') { $o->{API}{code} = join '', @$code; } elsif ($code =~ m|[/\\:]| and $code =~ m|^[/\\:\w.\-\ \$\[\]<>]+$|) { if (-f $code) { local ($/, *CODE); open CODE, "< $code" or croak M06_code_file_failed_open($code); $o->{API}{code} = ; } else { croak M07_code_file_does_not_exist($code); } } else { $o->{API}{code} = $code; } } #============================================================================== # Get the source code from an Inline::Files filehandle #============================================================================== sub read_inline_file { my $o = shift; my ($lang, $pkg) = @{$o->{API}}{qw(language_id pkg)}; my $langfile = uc($lang); croak M59_bad_inline_file($lang) unless $langfile =~ /^[A-Z]\w*$/; croak M60_no_inline_files() unless (defined $INC{File::Spec::Unix->catfile("Inline","Files.pm")} and $Inline::Files::VERSION =~ /^\d\.\d\d$/ and $Inline::Files::VERSION ge '0.51'); croak M61_not_parsed() unless $lang = Inline::Files::get_filename($pkg); { no strict 'refs'; local $/; $Inline::FILE = \*{"${pkg}::$langfile"}; # open $Inline::FILE; $o->{API}{code} = <$Inline::FILE>; # close $Inline::FILE; } } #============================================================================== # Read the cached config file from the Inline directory. This will indicate # whether the Language code is valid or not. #============================================================================== sub check_config_file { my ($DIRECTORY, %config); my $o = shift; croak M14_usage_Config() if %main::Inline::Config::; croak M63_no_source($o->{API}{pkg}) if $o->{INLINE}{md5} eq $o->{API}{code}; # First make sure we have the DIRECTORY if ($o->{CONFIG}{_INSTALL_}) { croak M15_usage_install_directory() if $o->{CONFIG}{DIRECTORY}; my $cwd = Cwd::cwd(); $DIRECTORY = $o->{INLINE}{DIRECTORY} = File::Spec->catdir($cwd, $did); if (not -d $DIRECTORY) { _mkdir($DIRECTORY, 0777) or croak M16_DIRECTORY_mkdir_failed($DIRECTORY); } } else { $DIRECTORY = $o->{INLINE}{DIRECTORY} = $o->{CONFIG}{DIRECTORY} || $o->find_temp_dir; } if($o->{CONFIG}{REWRITE_CONFIG_FILE}) { if(-e File::Spec->catfile($DIRECTORY, $configuration_file)) { my $unlink = unlink(File::Spec->catfile($DIRECTORY, $configuration_file)); if(!$unlink) {warn "REWRITE_CONFIG_FILE is set, but removal of config file failed"} else {warn "config file removal successful\n" if $o->{CONFIG}{_TESTING}} } } my $load_cfg = sub { $o->create_config_file($DIRECTORY) if not -e File::Spec->catfile($DIRECTORY, $configuration_file); open CONFIG, "< ".File::Spec->catfile($DIRECTORY,$configuration_file) or croak M17_config_open_failed($DIRECTORY); my $config = join '', ; close CONFIG; unless($config =~ /^version :/) { warn "\$load_cfg sub: \$config: *${config}*\n"; croak M62_invalid_config_file(File::Spec->catfile($DIRECTORY,$configuration_file)); } if(UNTAINT) { warn "In Inline::check_config_file(): Blindly untainting Inline configuration file information.\n" unless $o->{CONFIG}{NO_UNTAINT_WARN}; ($config) = $config =~ /(.*)/s; } %config = Inline::denter->new()->undent($config); } ; $load_cfg->() ; if (! defined $config{languages}->{$o->{API}{language_id}}){ my $unlink = unlink(File::Spec->catfile($DIRECTORY, $configuration_file)); if(!$unlink) {warn "Failed to remove config file"} else {warn "config file removed\n" if $o->{CONFIG}{_TESTING}} $load_cfg->() ; } $Inline::languages = $config{languages}; { no warnings ('numeric'); # These warnings were a pain with devel releases. # If there's a problem with the version number, the # error message will output $config{version} anyway. croak M18_error_old_version($config{version}, $DIRECTORY) unless (defined $config{version} and $config{version} =~ /TRIAL/ or $config{version} >= 0.40); } # numeric warnings re-enabled. croak M19_usage_language($o->{API}{language_id}, $DIRECTORY) unless defined $config{languages}->{$o->{API}{language_id}}; $o->{API}{language} = $config{languages}->{$o->{API}{language_id}}; if ($o->{API}{language} ne $o->{API}{language_id}) { if (defined $o->{$o->{API}{language_id}}) { $o->{$o->{API}{language}} = $o->{$o->{API}{language_id}}; delete $o->{$o->{API}{language_id}}; } } $o->{INLINE}{ILSM_type} = $config{types}->{$o->{API}{language}}; $o->{INLINE}{ILSM_module} = $config{modules}->{$o->{API}{language}}; $o->{INLINE}{ILSM_suffix} = $config{suffixes}->{$o->{API}{language}}; } #============================================================================== # Auto-detect installed Inline language support modules #============================================================================== sub create_config_file { my ($o, $dir) = @_; # This subroutine actually fires off another instance of perl. # with arguments that make this routine get called again. # That way the queried modules don't stay loaded. if (defined $o) { ($dir) = $dir =~ /(.*)/s if UNTAINT; my $perl = $Config{perlpath}; $perl = $^X unless -f $perl; ($perl) = $perl =~ /(.*)/s if UNTAINT; local $ENV{PERL5LIB} if defined $ENV{PERL5LIB}; local $ENV{PERL5OPT} if defined $ENV{PERL5OPT}; my $inline = $INC{'Inline.pm'}; $inline ||= File::Spec->curdir(); my($v,$d,$f) = File::Spec->splitpath($inline); $f = "" if $f eq 'Inline.pm'; $inline = File::Spec->catpath($v,$d,$f); # P::RD may be in a different PERL5LIB dir to Inline (as happens with cpan smokers). # Therefore we need to grep for it - otherwise, if P::RD *is* in a different PERL5LIB # directory the ensuing rebuilt @INC will not include that directory and attempts to use # Inline::CPP (and perhaps other Inline modules) will fail because P::RD isn't found. my @_inc = map { "-I$_" } ($inline, grep {(-d File::Spec->catdir($_,"Inline") or -d File::Spec->catdir($_,"auto","Inline") or -e File::Spec->catdir($_,"Parse/RecDescent.pm"))} @INC); system $perl, @_inc, "-MInline=_CONFIG_", "-e1", "$dir" and croak M20_config_creation_failed($dir); return; } my ($lib, $mod, $register, %checked, %languages, %types, %modules, %suffixes); LIB: for my $lib (@INC) { next unless -d File::Spec->catdir($lib,"Inline"); opendir LIB, File::Spec->catdir($lib,"Inline") or warn(M21_opendir_failed(File::Spec->catdir($lib,"Inline"))), next; while ($mod = readdir(LIB)) { next unless $mod =~ /\.pm$/; $mod =~ s/\.pm$//; next LIB if ($checked{$mod}++); if ($mod eq 'Config') { # Skip Inline::Config warn M14_usage_Config(); next; } next if $mod =~ /^(MakeMaker|denter|messages)$/; eval "require Inline::$mod;"; warn($@), next if $@; eval "\$register=&Inline::${mod}::register"; next if $@; my $language = ($register->{language}) or warn(M22_usage_register($mod)), next; for (@{$register->{aliases}}) { warn(M23_usage_alias_used($mod, $_, $languages{$_})), next if defined $languages{$_}; $languages{$_} = $language; } $languages{$language} = $language; $types{$language} = $register->{type}; $modules{$language} = "Inline::$mod"; $suffixes{$language} = $register->{suffix}; } closedir LIB; } my $file = File::Spec->catfile($ARGV[0], $configuration_file); open CONFIG, "> $file" or croak M24_open_for_output_failed($file); flock(CONFIG, LOCK_EX); print CONFIG Inline::denter->new() ->indent(*version => $Inline::VERSION, *languages => \%languages, *types => \%types, *modules => \%modules, *suffixes => \%suffixes, ); flock(CONFIG, LOCK_UN); close CONFIG; exit 0; } #============================================================================== # Check to see if code has already been compiled #============================================================================== sub check_module { my ($module, $module2); my $o = shift; return $o->install if $o->{CONFIG}{_INSTALL_}; if ($o->{CONFIG}{NAME}) { $module = $o->{CONFIG}{NAME}; } elsif ($o->{API}{pkg} eq 'main') { $module = $o->{API}{script}; my($v,$d,$file) = File::Spec->splitpath($module); $module = $file; $module =~ s|\W|_|g; $module =~ s|^_+||; $module =~ s|_+$||; $module = 'FOO' if $module =~ /^_*$/; $module = "_$module" if $module =~ /^\d/; } else { $module = $o->{API}{pkg}; } $o->{API}{suffix} = $o->{INLINE}{ILSM_suffix}; $o->{API}{directory} = $o->{INLINE}{DIRECTORY}; my $auto_level = 2; while ($auto_level <= 5) { if ($o->{CONFIG}{AUTONAME}) { $module2 = $module . '_' . substr($o->{INLINE}{md5}, 0, 2 + $auto_level); $auto_level++; } else { $module2 = $module; $auto_level = 6; # Don't loop on non-autoname objects } $o->{API}{module} = $module2; my @modparts = split /::/, $module2; $o->{API}{modfname} = $modparts[-1]; $o->{API}{modpname} = File::Spec->catdir(@modparts); $o->{API}{build_dir} = File::Spec->catdir($o->{INLINE}{DIRECTORY}, 'build',$o->{API}{modpname}); $o->{API}{install_lib} = File::Spec->catdir($o->{INLINE}{DIRECTORY}, 'lib'); my $inl = File::Spec->catfile($o->{API}{install_lib},"auto", $o->{API}{modpname},"$o->{API}{modfname}.inl"); $o->{API}{location} = File::Spec->catfile($o->{API}{install_lib},"auto",$o->{API}{modpname}, "$o->{API}{modfname}.$o->{INLINE}{ILSM_suffix}"); last unless -f $inl; my %inl; { local ($/, *INL); open INL, $inl or croak M31_inline_open_failed($inl); %inl = Inline::denter->new()->undent(); } next unless ($o->{INLINE}{md5} eq $inl{md5}); next unless ($inl{inline_version} ge '0.40'); next unless ($inl{Config}{version} eq $Config::Config{version}); next unless ($inl{Config}{archname} eq $Config::Config{archname}); unless (-f $o->{API}{location}) { warn <{API}{location} For Inline file: $inl END next; } $o->{INLINE}{object_ready} = 1 unless $o->{CONFIG}{FORCE_BUILD}; last; } unshift @::INC, $o->{API}{install_lib}; } #============================================================================== # Set things up so that the extension gets installed into the blib/arch. # Then 'make install' will do the right thing. #============================================================================== sub install { my ($module, $DIRECTORY); my $o = shift; croak M64_install_not_c($o->{API}{language_id}) unless uc($o->{API}{language_id}) =~ /^(C|CPP|Java|Python|Ruby|Lisp|Pdlpp)$/ ; croak M36_usage_install_main() if ($o->{API}{pkg} eq 'main'); croak M37_usage_install_auto() if $o->{CONFIG}{AUTONAME}; croak M38_usage_install_name() unless $o->{CONFIG}{NAME}; croak M39_usage_install_version() unless $o->{CONFIG}{VERSION}; croak M40_usage_install_badname($o->{CONFIG}{NAME}, $o->{API}{pkg}) unless $o->{CONFIG}{NAME} eq $o->{API}{pkg}; # $o->{CONFIG}{NAME} =~ /^$o->{API}{pkg}::\w(\w|::)+$/ # ); my ($mod_name, $mod_ver, $ext_name, $ext_ver) = ($o->{API}{pkg}, $ARGV[0], @{$o->{CONFIG}}{qw(NAME VERSION)}); croak M41_usage_install_version_mismatch($mod_name, $mod_ver, $ext_name, $ext_ver) unless ($mod_ver eq $ext_ver); $o->{INLINE}{INST_ARCHLIB} = $ARGV[1]; $o->{API}{version} = $o->{CONFIG}{VERSION}; $o->{API}{module} = $o->{CONFIG}{NAME}; my @modparts = split(/::/,$o->{API}{module}); $o->{API}{modfname} = $modparts[-1]; $o->{API}{modpname} = File::Spec->catdir(@modparts); $o->{API}{suffix} = $o->{INLINE}{ILSM_suffix}; $o->{API}{build_dir} = File::Spec->catdir($o->{INLINE}{DIRECTORY},'build', $o->{API}{modpname}); $o->{API}{directory} = $o->{INLINE}{DIRECTORY}; my $cwd = Cwd::cwd(); $o->{API}{install_lib} = File::Spec->catdir($cwd,$o->{INLINE}{INST_ARCHLIB}); $o->{API}{location} = File::Spec->catfile($o->{API}{install_lib},"auto",$o->{API}{modpname}, "$o->{API}{modfname}.$o->{INLINE}{ILSM_suffix}"); unshift @::INC, $o->{API}{install_lib}; $o->{INLINE}{object_ready} = 0; } #============================================================================== # Create the .inl file for an object #============================================================================== sub write_inl_file { my $o = shift; my $inl = File::Spec->catfile($o->{API}{install_lib},"auto",$o->{API}{modpname}, "$o->{API}{modfname}.inl"); open INL, "> $inl" or croak "Can't create Inline validation file $inl: $!"; my $apiversion = $Config{apiversion} || $Config{xs_apiversion}; print INL Inline::denter->new() ->indent(*md5, $o->{INLINE}{md5}, *name, $o->{API}{module}, *version, $o->{CONFIG}{VERSION}, *language, $o->{API}{language}, *language_id, $o->{API}{language_id}, *installed, $o->{CONFIG}{_INSTALL_}, *date_compiled, scalar localtime, *inline_version, $Inline::VERSION, *ILSM, { map {($_, $o->{INLINE}{"ILSM_$_"})} (qw( module suffix type )) }, *Config, { (map {($_,$Config{$_})} (qw( archname osname osvers cc ccflags ld so version ))), (apiversion => $apiversion), }, ); close INL; } #============================================================================== # Get config hints #============================================================================== sub with_configs { my $o = shift; my @configs; for my $mod (@{$o->{CONFIG}{WITH}}) { my $ref = eval { no strict 'refs'; &{$mod . "::Inline"}($o->{API}{language}); }; croak M25_no_WITH_support($mod, $@) if $@; push @configs, %$ref; } return @configs; } #============================================================================== # Blindly untaint tainted fields in %ENV. #============================================================================== sub env_untaint { my $o = shift; warn "In Inline::env_untaint() : Blindly untainting tainted fields in %ENV.\n" unless $o->{CONFIG}{NO_UNTAINT_WARN}; { no warnings ('uninitialized'); # In case $ENV{$_} is set to undef. for (keys %ENV) { ($ENV{$_}) = $ENV{$_} =~ /(.*)/; } } $ENV{PATH} = $^O eq 'MSWin32' ? join ';', grep {not /^\./ and -d $_ } split /;/, $ENV{PATH} : join ':', grep {not /^\./ and -d $_ and not ((stat($_))[2] & 0022) } split /:/, $ENV{PATH}; map {($_) = /(.*)/} @INC; } #============================================================================== # Blindly untaint tainted fields in Inline object. #============================================================================== sub obj_untaint { my $o = shift; warn "In Inline::obj_untaint() : Blindly untainting tainted fields in Inline object.\n" unless $o->{CONFIG}{NO_UNTAINT_WARN}; ($o->{INLINE}{ILSM_module}) = $o->{INLINE}{ILSM_module} =~ /(.*)/; ($o->{API}{build_dir}) = $o->{API}{build_dir} =~ /(.*)/; ($o->{CONFIG}{DIRECTORY}) = $o->{CONFIG}{DIRECTORY} =~ /(.*)/; ($o->{API}{install_lib}) = $o->{API}{install_lib} =~ /(.*)/; ($o->{API}{modpname}) = $o->{API}{modpname} =~ /(.*)/; ($o->{API}{modfname}) = $o->{API}{modfname} =~ /(.*)/; ($o->{API}{language}) = $o->{API}{language} =~ /(.*)/; ($o->{API}{pkg}) = $o->{API}{pkg} =~ /(.*)/; ($o->{API}{module}) = $o->{API}{module} =~ /(.*)/; } #============================================================================== # Clean the build directory from previous builds #============================================================================== sub clean_build { use strict; my ($prefix, $dir); my $o = shift; $prefix = $o->{INLINE}{DIRECTORY}; opendir(BUILD, $prefix) or croak "Can't open build directory: $prefix for cleanup $!\n"; while ($dir = readdir(BUILD)) { my $maybedir = File::Spec->catdir($prefix,$dir); if (($maybedir and -d $maybedir) and ($dir =~ /\w{36,}/)) { $o->rmpath($prefix,$dir); } } close BUILD; } #============================================================================== # Apply a list of filters to the source code #============================================================================== sub filter { my $o = shift; my $new_code = $o->{API}{code}; for (@_) { croak M52_invalid_filter($_) unless ref; if (ref eq 'CODE') { $new_code = $_->($new_code); } else { $new_code = $_->filter($o, $new_code); } } return $new_code; } #============================================================================== # User wants to report a bug #============================================================================== sub reportbug { use strict; my $o = shift; return if $o->{INLINE}{reportbug_handled}++; print STDERR < REPORTBUG mode in effect. Your Inline $o->{API}{language_id} code will be processed in the build directory: $o->{API}{build_dir} A perl-readable bug report including your perl configuration and run-time diagnostics will also be generated in the build directory. When the program finishes please bundle up the above build directory with: tar czf Inline.REPORTBUG.tar.gz $o->{API}{build_dir} and send "Inline.REPORTBUG.tar.gz" as an email attachment to the author of the offending Inline::* module with the subject line: REPORTBUG: Inline.pm Include in the email, a description of the problem and anything else that you think might be helpful. Patches are welcome! :-\) <-----------------------End of REPORTBUG Section------------------------------> END my %versions; { no strict 'refs'; %versions = map {eval "use $_();"; ($_, $ {$_ . '::VERSION'})} qw (Digest::MD5 Parse::RecDescent ExtUtils::MakeMaker File::Path FindBin Inline ); } $o->mkpath($o->{API}{build_dir}); open REPORTBUG, "> ".File::Spec->catfile($o->{API}{build_dir},"REPORTBUG") or croak M24_open_for_output_failed (File::Spec->catfile($o->{API}{build_dir},"REPORTBUG")); %Inline::REPORTBUG_Inline_Object = (); %Inline::REPORTBUG_Perl_Config = (); %Inline::REPORTBUG_Module_Versions = (); print REPORTBUG Inline::denter->new() ->indent(*REPORTBUG_Inline_Object, $o, *REPORTBUG_Perl_Config, \%Config::Config, *REPORTBUG_Module_Versions, \%versions, ); close REPORTBUG; } #============================================================================== # Print a small report if PRINT_INFO option is set. #============================================================================== sub print_info { use strict; my $o = shift; print STDERR < Information about the processing of your Inline $o->{API}{language_id} code: END print STDERR <{INLINE}{object_ready}); Your module is already compiled. It is located at: $o->{API}{location} END print STDERR <{INLINE}{object_ready} and $o->{CONFIG}{FORCE_BUILD}); But the FORCE_BUILD option is set, so your code will be recompiled. I\'ll use this build directory: $o->{API}{build_dir} and I\'ll install the executable as: $o->{API}{location} END print STDERR <{INLINE}{object_ready}); Your source code needs to be compiled. I\'ll use this build directory: $o->{API}{build_dir} and I\'ll install the executable as: $o->{API}{location} END eval { print STDERR $o->info; }; print $@ if $@; print STDERR < END } #============================================================================== # Hand off this invokation to Inline::MakeMaker #============================================================================== sub maker_utils { require Inline::MakeMaker; goto &Inline::MakeMaker::utils; } #============================================================================== # Utility subroutines #============================================================================== #============================================================================== # Make a path #============================================================================== sub mkpath { use strict; my ($o, $mkpath) = @_; my($volume,$dirs,$nofile) = File::Spec->splitpath($mkpath,1); my @parts = File::Spec->splitdir($dirs); my @done; foreach (@parts){ push(@done,$_); my $path = File::Spec->catpath($volume,File::Spec->catdir(@done),""); -d $path || _mkdir($path, 0777); } croak M53_mkdir_failed($mkpath) unless -d $mkpath; } #============================================================================== # Nuke a path (nicely) #============================================================================== sub rmpath { use strict; my ($o, $prefix, $rmpath) = @_; # Nuke the target directory _rmtree(File::Spec->catdir($prefix ? ($prefix,$rmpath) : ($rmpath))); # Remove any empty directories underneath the requested one my @parts = File::Spec->splitdir($rmpath); while (@parts){ $rmpath = File::Spec->catdir($prefix ? ($prefix,@parts) : @parts); ($rmpath) = $rmpath =~ /(.*)/ if UNTAINT; rmdir $rmpath or last; # rmdir failed because dir was not empty pop @parts; } } sub _rmtree { my($roots) = @_; $roots = [$roots] unless ref $roots; my($root); foreach $root (@{$roots}) { if ( -d $root ) { my(@names,@paths); if (opendir MYDIR, $root) { @names = readdir MYDIR; closedir MYDIR; } else { croak M21_opendir_failed($root); } my $dot = File::Spec->curdir(); my $dotdot = File::Spec->updir(); foreach my $name (@names) { next if $name eq $dot or $name eq $dotdot; my $maybefile = File::Spec->catfile($root,$name); push(@paths,$maybefile),next if $maybefile and -f $maybefile; push(@paths,File::Spec->catdir($root,$name)); } _rmtree(\@paths); ($root) = $root =~ /(.*)/ if UNTAINT; rmdir($root) or croak M54_rmdir_failed($root); } else { ($root) = $root =~ /(.*)/ if UNTAINT; unlink($root) or croak M55_unlink_failed($root); } } } #============================================================================== # Find the 'Inline' directory to use. #============================================================================== my $TEMP_DIR; sub find_temp_dir { return $TEMP_DIR if $TEMP_DIR; my ($temp_dir, $home, $bin, $cwd, $env); $temp_dir = ''; $env = $ENV{PERL_INLINE_DIRECTORY} || ''; $home = $ENV{HOME} ? abs_path($ENV{HOME}) : ''; if ($env and -d $env and -w $env) { $temp_dir = $env; } elsif ($cwd = abs_path('.') and $cwd ne $home and -d File::Spec->catdir($cwd,".Inline") and -w File::Spec->catdir($cwd,".Inline")) { $temp_dir = File::Spec->catdir($cwd,".Inline"); } else { require FindBin ; if ($bin = $FindBin::Bin and -d File::Spec->catdir($bin,".Inline") and -w File::Spec->catdir($bin,".Inline")) { $temp_dir = File::Spec->catdir($bin,".Inline"); } elsif ($home and -d File::Spec->catdir($home,".Inline") and -w File::Spec->catdir($home,".Inline")) { $temp_dir = File::Spec->catdir($home,".Inline"); } elsif (defined $cwd and $cwd and -d File::Spec->catdir($cwd, $did) and -w File::Spec->catdir($cwd, $did)) { $temp_dir = File::Spec->catdir($cwd, $did); } elsif (defined $bin and $bin and -d File::Spec->catdir($bin, $did) and -w File::Spec->catdir($bin, $did)) { $temp_dir = File::Spec->catdir($bin, $did); } elsif (defined $cwd and $cwd and -d $cwd and -w $cwd and _mkdir(File::Spec->catdir($cwd, $did), 0777)) { $temp_dir = File::Spec->catdir($cwd, $did); } elsif (defined $bin and $bin and -d $bin and -w $bin and _mkdir(File::Spec->catdir($bin, $did), 0777)) { $temp_dir = File::Spec->catdir($bin, $did); } } croak M56_no_DIRECTORY_found() unless $temp_dir; return $TEMP_DIR = abs_path($temp_dir); } sub _mkdir { my $dir = shift; my $mode = shift || 0777; ($dir) = ($dir =~ /(.*)/) if UNTAINT; $dir =~ s|[/\\:]$||; return mkdir($dir, $mode); } # Comment out the next 2 lines to stop autoloading of messages (for testing) #1; #__END__ #============================================================================== # Error messages are autoloaded #============================================================================== sub M01_usage_use { my ($module) = @_; return < "source-string", config-pair-list; use Inline language => "source-file", config-pair-list; use Inline language => [source-line-list], config-pair-list; use Inline language => 'DATA', config-pair-list; use Inline language => 'Config', config-pair-list; use Inline Config => config-pair-list; use Inline with => module-list; use Inline shortcut-list; END # This is broken ???????????????????????????????????????????????????? $usage .= <bind() function. Valid usages are: Inline->bind(language => "source-string", config-pair-list); Inline->bind(language => "source-file", config-pair-list); Inline->bind(language => [source-line-list], config-pair-list); END $usage .= <catfile(${dir}, $configuration_file); return <catfile(${dir}, $configuration_file); return < '$mod'" but '$mod' does not work with Inline. $err END } sub M26_error_version_without_name { return < 'module1', 'module2', ..., 'moduleN'; END } sub M46_usage_with_bad { my $mod = shift; return < "$mod";'. '$mod' could not be found. END } sub M47_invalid_config_option { my ($option) = @_; return < for support information. =head2 Why Inline? Do you want to know "Why would I use other languages in Perl?" or "Why should I use Inline to do it?"? I'll try to answer both. =over 4 =item Why would I use other languages in Perl? The most obvious reason is performance. For an interpreted language, Perl is very fast. Many people will say "Anything Perl can do, C can do faster". (They never mention the development time :-) Anyway, you may be able to remove a bottleneck in your Perl code by using another language, without having to write the entire program in that language. This keeps your overall development time down, because you're using Perl for all of the non-critical code. Another reason is to access functionality from existing API-s that use the language. Some of this code may only be available in binary form. But by creating small subroutines in the native language, you can "glue" existing libraries to your Perl. As a user of the CPAN, you know that code reuse is a good thing. So why throw away those Fortran libraries just yet? If you are using Inline with the C language, then you can access the full internals of Perl itself. This opens up the floodgates to both extreme power and peril. Maybe the best reason is "Because you want to!". Diversity keeps the world interesting. TMTOWTDI! =item Why should I use Inline to do it? There are already two major facilities for extending Perl with C. They are XS and SWIG. Both are similar in their capabilities, at least as far as Perl is concerned. And both of them are quite difficult to learn compared to Inline. There is a big fat learning curve involved with setting up and using the XS environment. You need to get quite intimate with the following docs: * perlxs * perlxstut * perlapi * perlguts * perlmod * h2xs * xsubpp * ExtUtils::MakeMaker With Inline you can be up and running in minutes. There is a C Cookbook with lots of short but complete programs that you can extend to your real-life problems. No need to learn about the complicated build process going on in the background. You don't even need to compile the code yourself. Inline takes care of every last detail except writing the C code. Perl programmers cannot be bothered with silly things like compiling. "Tweak, Run, Tweak, Run" is our way of life. Inline does all the dirty work for you. Another advantage of Inline is that you can use it directly in a script. You can even use it in a Perl one-liner. With XS and SWIG, you always set up an entirely separate module. Even if you only have one or two functions. Inline makes easy things easy, and hard things possible. Just like Perl. Finally, Inline supports several programming languages (not just C and C++). As of this writing, Inline has support for C, C++, Java, Python, Ruby, Tcl, Assembler, Basic, Guile, Befunge, Octave, Awk, BC, TT (Template Toolkit), WebChat and even PERL. New Inline Language Support Modules (ILSMs) are regularly being added. See L for details on how to create your own ILSM. =back =head1 Using the Inline.pm Module Inline is a little bit different than most of the Perl modules that you are used to. It doesn't import any functions into your namespace and it doesn't have any object oriented methods. Its entire interface (with two minor exceptions) is specified through the C<'use Inline ...'> command. This section will explain all of the different ways to C. If you want to begin using C with Inline immediately, see L. =head2 The Basics The most basic form for using Inline is: use Inline X => "X source code"; where 'X' is one of the supported Inline programming languages. The second parameter identifies the source code that you want to bind to Perl. The source code can be specified using any of the following syntaxes: =over 4 =item The DATA Keyword. use Inline Java => 'DATA'; # Perl code goes here ... __DATA__ __Java__ /* Java code goes here ... */ The easiest and most visually clean way to specify your source code in an Inline Perl program is to use the special C keyword. This tells Inline to look for a special marker in your C filehandle's input stream. In this example the special marker is C<__Java__>, which is the programming language surrounded by double underscores. In case you've forgotten, the C pseudo file is comprised of all the text after the C<__END__> or C<__DATA__> section of your program. If you're working outside the C
package, you'd best use the C<__DATA__> marker or else Inline will not find your code. Using this scheme keeps your Perl code at the top, and all the ugly Java stuff down below where it belongs. This is visually clean and makes for more maintainable code. An excellent side benefit is that you don't have to escape any characters like you might in a Perl string. The source code is verbatim. For these reasons, I prefer this method the most. The only problem with this style is that since Perl can't read the C filehandle until runtime, it obviously can't bind your functions until runtime. The net effect of this is that you can't use your Inline functions as barewords (without predeclaring them) because Perl has no idea they exist during compile time. =item The FILE and BELOW keywords. use Inline::Files; use Inline Java => 'FILE'; # Perl code goes here ... __JAVA__ /* Java code goes here ... */ This is the newest method of specifying your source code. It makes use of the Perl module C written by Damian Conway. The basic style and meaning are the same as for the C keyword, but there are a few syntactic and semantic twists. First, you must say 'use Inline::Files' before you 'use Inline' code that needs those files. The special 'C' keyword is replaced by either 'C' or 'C'. This allows for the bad pun idiom of: use Inline C => 'BELOW'; You can omit the C<__DATA__> tag now. Inline::Files is a source filter that will remove these sections from your program before Perl compiles it. They are then available for Inline to make use of. And since this can all be done at compile time, you don't have to worry about the caveats of the 'DATA' keyword. This module has a couple small gotchas. Since Inline::Files only recognizes file markers with capital letters, you must specify the capital form of your language name. Also, there is a startup time penalty for using a source code filter. At this point Inline::Files is alpha software and use of it is experimental. Inline's integration of this module is also fledgling at the time being. One of things I plan to do with Inline::Files is to get line number info so when an extension doesn't compile, the error messages will point to the correct source file and line number. My best advice is to use Inline::Files for testing (especially as support for it improves), but use DATA for production and distributed/CPAN code. =item Strings use Inline Java => <<'END'; /* Java code goes here ... */ END # Perl code goes here ... You also just specify the source code as a single string. A handy way to write the string is to use Perl's "here document" style of quoting. This is ok for small functions but can get unwieldy in the large. On the other hand, the string variant probably has the least startup penalty and all functions are bound at compile time. If you wish to put the string into a scalar variable, please be aware that the C statement is a compile time directive. As such, all the variables it uses must also be set at compile time, C the 'use Inline' statement. Here is one way to do it: my $code; BEGIN { $code = < $code; # Perl code goes here ... =item The bind() Function An alternative to using the BEGIN block method is to specify the source code at run time using the 'Inline->bind()' method. (This is one of the interface exceptions mentioned above) The C method takes the same arguments as C<'use Inline ...'>. my $code = <bind(Java => $code); You can think of C as a way to C code in other programming languages. Although bind() is a powerful feature, it is not recommended for use in Inline based modules. In fact, it won't work at all for installable modules. See instructions below for creating modules with Inline. =item Other Methods The source code for Inline can also be specified as an external filename, a reference to a subroutine that returns source code, or a reference to an array that contains lines of source code. (Note that if the external source file is in the current directory it must be specified with a leading './' - ie './file.ext' instead of simply 'file.ext'.) These methods are less frequently used but may be useful in some situations. =item Shorthand If you are using the 'DATA' or 'FILE' methods described above B there are no extra parameters, you can omit the keyword altogether. For example: use Inline 'Java'; # Perl code goes here ... __DATA__ __Java__ /* Java code goes here ... */ or use Inline::Files; use Inline 'Java'; # Perl code goes here ... __JAVA__ /* Java code goes here ... */ =back =head2 More about the DATA Section If you are writing a module, you can also use the DATA section for POD and AutoLoader subroutines. Just be sure to put them before the first Inline marker. If you install the helper module C, you can even use POD inside your Inline code. You just have to specify a filter to strip it out. You can also specify multiple Inline sections, possibly in different programming languages. Here is another example: # The module Foo.pm package Foo; use AutoLoader; use Inline C; use Inline C => DATA => FILTERS => 'Strip_POD'; use Inline Python; 1; __DATA__ sub marine { # This is an autoloaded subroutine } =head1 External subroutines =cut __C__ /* First C section */ __C__ /* Second C section */ =head1 My C Function Some POD doc. =cut __Python__ """A Python Section""" An important thing to remember is that you need to have one "use Inline Foo => 'DATA'" for each "__Foo__" marker, and they must be in the same order. This allows you to apply different configuration options to each section. =head2 Configuration Options Inline trys to do the right thing as often as possible. But sometimes you may need to override the default actions. This is easy to do. Simply list the Inline configuration options after the regular Inline parameters. All congiguration options are specified as (key, value) pairs. use Inline (C => 'DATA', DIRECTORY => './inline_dir', LIBS => '-lfoo', INC => '-I/foo/include', PREFIX => 'XXX_', WARNINGS => 0, ); You can also specify the configuration options on a separate Inline call like this: use Inline (C => Config => DIRECTORY => './inline_dir', LIBS => '-lfoo', INC => '-I/foo/include', PREFIX => 'XXX_', WARNINGS => 0, ); use Inline C => <<'END_OF_C_CODE'; The special keyword C<'Config'> tells Inline that this is a configuration-only call. No source code will be compiled or bound to Perl. If you want to specify global configuration options that don't apply to a particular language, just leave the language out of the call. Like this: use Inline Config => WARNINGS => 0; The Config options are inherited and additive. You can use as many Config calls as you want. And you can apply different options to different code sections. When a source code section is passed in, Inline will apply whichever options have been specified up to that point. Here is a complex configuration example: use Inline (Config => DIRECTORY => './inline_dir', ); use Inline (C => Config => LIBS => '-lglobal', ); use Inline (C => 'DATA', # First C Section LIBS => ['-llocal1', '-llocal2'], ); use Inline (Config => WARNINGS => 0, ); use Inline (Python => 'DATA', # First Python Section LIBS => '-lmypython1', ); use Inline (C => 'DATA', # Second C Section LIBS => [undef, '-llocal3'], ); The first C applies to all subsequent calls. The second C applies to all subsequent C sections (but not C sections). In the first C section, the external libraries C, C and C are used. (Most options allow either string or array ref forms, and do the right thing.) The C section does not use the C library, but does use the same C, and has warnings turned off. The second C section only uses the C library. That's because a value of C resets the additive behavior. The C and C options are generic Inline options. All other options are language specific. To find out what the C options do, see C. =head2 On and Off If a particular config option has value options of 1 and 0, you can use the ENABLE and DISABLE modifiers. In other words, this: use Inline Config => FORCE_BUILD => 1, CLEAN_AFTER_BUILD => 0; could be reworded as: use Inline Config => ENABLE => FORCE_BUILD, DISABLE => CLEAN_AFTER_BUILD; =head2 Playing 'with' Others Inline has a special configuration syntax that tells it to get more configuration options from other Perl modules. Here is an example: use Inline with => 'Event'; This tells Inline to load the module C and ask it for configuration information. Since C has a C API of its own, it can pass Inline all of the information it needs to be able to use C C callbacks seamlessly. That means that you don't need to specify the typemaps, shared libraries, include files and other information required to get this to work. You can specify a single module or a list of them. Like: use Inline with => qw(Event Foo Bar); Currently, C is the only module that works I Inline. =head2 Inline Shortcuts Inline lets you set many configuration options from the command line. These options are called 'shortcuts'. They can be very handy, especially when you only want to set the options temporarily, for say, debugging. For instance, to get some general information about your Inline code in the script C, use the command: perl -MInline=INFO Foo.pl If you want to force your code to compile, even if its already done, use: perl -MInline=FORCE Foo.pl If you want to do both, use: perl -MInline=INFO -MInline=FORCE Foo.pl or better yet: perl -MInline=INFO,FORCE Foo.pl =head2 The Inline DIRECTORY Inline needs a place to build your code and to install the results of the build. It uses a single directory named C<'.Inline/'> under normal circumstances. If you create this directory in your home directory, the current directory or in the directory where your program resides, Inline will find and use it. You can also specify it in the environment variable C or directly in your program, by using the C keyword option. If Inline cannot find the directory in any of these places it will create a C<'_Inline/'> directory in either your current directory or the directory where your script resides. One of the key factors to using Inline successfully, is understanding this directory. When developing code it is usually best to create this directory (or let Inline do it) in your current directory. Remember that there is nothing sacred about this directory except that it holds your compiled code. Feel free to delete it at any time. Inline will simply start from scratch and recompile your code on the next run. If you have several programs that you want to force to recompile, just delete your C<'.Inline/'> directory. It is probably best to have a separate C<'.Inline/'> directory for each project that you are working on. You may want to keep stable code in the <.Inline/> in your home directory. On multi-user systems, each user should have their own C<'.Inline/'> directories. It could be a security risk to put the directory in a shared place like C. =head2 Debugging Inline Errors All programmers make mistakes. When you make a mistake with Inline, like writing bad C code, you'll get a big error report on your screen. This report tells you where to look to do the debugging. Some languages may also dump out the error messages generated from the build. When Inline needs to build something it creates a subdirectory under your C directory. This is where it writes all the components it needs to build your extension. Things like XS files, Makefiles and output log files. If everything goes OK, Inline will delete this subdirectory. If there is an error, Inline will leave the directory intact and print its location. The idea is that you are supposed to go into that directory and figure out what happened. Read the doc for your particular Inline Language Support Module for more information. =head2 The 'config' Registry File Inline keeps a cached file of all of the Inline Language Support Module's meta data in a file called C. This file can be found in your C directory. If the file does not exist, Inline creates a new one. It will search your system for any module beginning with C. It will then call that module's C method to get useful information for future invocations. Whenever you add a new ILSM, you should delete this file so that Inline will auto-discover your newly installed language module. (This should no longer be necessary as of Inline-0.49.) =head1 Configuration Options This section lists all of the generic Inline configuration options. For language specific configuration, see the doc for that language. =head2 DIRECTORY The C config option is the directory that Inline uses to both build and install an extension. Normally Inline will search in a bunch of known places for a directory called C<'.Inline/'>. Failing that, it will create a directory called C<'_Inline/'> If you want to specify your own directory, use this configuration option. Note that you must create the C directory yourself. Inline will not do it for you. =head2 NAME You can use this option to set the name of your Inline extension object module. For example: use Inline C => 'DATA', NAME => 'Foo::Bar'; would cause your C code to be compiled in to the object: lib/auto/Foo/Bar/Bar.so lib/auto/Foo/Bar/Bar.inl (The .inl component contains dependency information to make sure the source code is in sync with the executable) If you don't use NAME, Inline will pick a name for you based on your program name or package name. In this case, Inline will also enable the AUTONAME option which mangles in a small piece of the MD5 fingerprint into your object name, to make it unique. =head2 AUTONAME This option is enabled whenever the NAME parameter is not specified. To disable it say: use Inline C => 'DATA', DISABLE => 'AUTONAME'; AUTONAME mangles in enough of the MD5 fingerprint to make your module name unique. Objects created with AUTONAME will never get replaced. That also means they will never get cleaned up automatically. AUTONAME is very useful for small throw away scripts. For more serious things, always use the NAME option. =head2 VERSION Specifies the version number of the Inline extension object. It is used B for modules, and it must match the global variable $VERSION. Additionally, this option should used if (and only if) a module is being set up to be installed permanently into the Perl sitelib tree. Inline will croak if you use it otherwise. The presence of the VERSION parameter is the official way to let Inline know that your code is an installable/installed module. Inline will never generate an object in the temporary cache (_Inline/ directory) if VERSION is set. It will also never try to recompile a module that was installed into someone's Perl site tree. So the basic rule is develop without VERSION, and deliver with VERSION. =head2 WITH C can also be used as a configuration option instead of using the special 'with' syntax. Do this if you want to use different sections of Inline code I different modules. (Probably a very rare usage) use Event; use Inline C => DATA => WITH => 'Event'; Modules specified using the config form of C will B be automatically required. You must C them yourself. =head2 GLOBAL_LOAD This option is for compiled languages only. It tells Inline to tell DynaLoader to load an object file in such a way that its symbols can be dynamically resolved by other object files. May not work on all platforms. See the C shortcut below. =head2 UNTAINT You can use this option whenever you use Perl's C<-T> switch, for taint checking. This option tells Inline to blindly untaint all tainted variables. (This is generally considerd to be an appallingly insecure thing to do, and not to be recommended - but the option is there for you to use if you want. Please consider using something other than Inline for scripts that need taint checking.) It also turns on SAFEMODE by default. See the C shortcut below. You will see warnings about blindly untainting fields in both %ENV and Inline objects. If you want to silence these warnings, set the Config option NO_UNTAINT_WARN => 1. There can be some problems untainting Inline scripts where older versions of Cwd, such as those that shipped with early versions of perl-5.8 (and earlier), are installed. Updating Cwd will probably solve these problems. =head2 SAFEMODE Perform extra safety checking, in an attempt to thwart malicious code. This option cannot guarantee security, but it does turn on all the currently implemented checks. (Currently, the only "currently implemented check" is to ensure that the C option has also been used.) There is a slight startup penalty by using SAFEMODE. Also, using UNTAINT automatically turns this option on. If you need your code to start faster under C<-T> (taint) checking, you'll need to turn this option off manually. Only do this if you are not worried about security risks. See the C shortcut below. =head2 FORCE_BUILD Makes Inline build (compile) the source code every time the program is run. The default is 0. See the C shortcut below. =head2 BUILD_NOISY Tells ILSMs that they should dump build messages to the terminal rather than be silent about all the build details. =head2 BUILD_TIMERS Tells ILSMs to print timing information about how long each build phase took. Usually requires C. =head2 CLEAN_AFTER_BUILD Tells Inline to clean up the current build area if the build was successful. Sometimes you want to DISABLE this for debugging. Default is 1. See the C shortcut below. =head2 CLEAN_BUILD_AREA Tells Inline to clean up the old build areas within the entire Inline DIRECTORY. Default is 0. See the C shortcut below. =head2 PRINT_INFO Tells Inline to print various information about the source code. Default is 0. See the C shortcut below. =head2 PRINT_VERSION Tells Inline to print Version info about itself. Default is 0. See the C shortcut below. =head2 REPORTBUG Puts Inline into 'REPORTBUG' mode, which is what you want if you desire to report a bug. =head2 REWRITE_CONFIG_FILE Default is 0, but setting 'REWRITE_CONFIG_FILE => 1' will mean that the existing configuration file in the Inline DIRECTORY will be overwritten. (This is useful if the existing config file is not up to date as regards supported languages.) =head2 WARNINGS This option tells Inline whether to print certain warnings. Default is 1. =head1 Inline Configuration Shortcuts This is a list of all the shorcut configuration options currently available for Inline. Specify them from the command line when running Inline scripts. perl -MInline=NOCLEAN inline_script.pl or perl -MInline=Info,force,NoClean inline_script.pl You can specify multiple shortcuts separated by commas. They are not case sensitive. You can also specify shorcuts inside the Inline program like this: use Inline 'Info', 'Force', 'Noclean'; NOTE: If a C<'use Inline'> statement is used to set shortcuts, it can not be used for additional purposes. =over 4 =item CLEAN Tells Inline to remove any build directories that may be lying around in your build area. Normally these directories get removed immediately after a successful build. Exceptions are when the build fails, or when you use the NOCLEAN or REPORTBUG options. =item FORCE Forces the code to be recompiled, even if everything is up to date. =item GLOBAL Turns on the GLOBAL_LOAD option. =item INFO This is a very useful option when you want to know what's going on under the hood. It tells Inline to print helpful information to C. Among the things that get printed is a list of which Inline functions were successfully bound to Perl. =item NOCLEAN Tells Inline to leave the build files after compiling. =item NOISY Use the BUILD_NOISY option to print messages during a build. =item REPORTBUG Puts Inline into 'REPORTBUG' mode, which does special processing when you want to report a bug. REPORTBUG also automatically forces a build, and doesn't clean up afterwards. This is so that you can tar and mail the build directory to me. REPORTBUG will print exact instructions on what to do. Please read and follow them carefully. NOTE: REPORTBUG informs you to use the tar command. If your system does not have tar, please use the equivalent C command. =item SAFE Turns SAFEMODE on. UNTAINT will turn this on automatically. While this mode performs extra security checking, it does not guarantee safety. =item SITE_INSTALL This parameter used to be used for creating installable Inline modules. It has been removed from Inline altogether and replaced with a much simpler and more powerful mechanism, C. See the section below on how to create modules with Inline. =item _TESTING Used internally by C/t/09parser.t and C/t/10callback.t(in the Inline::C test suite). Setting this option with Inline::C will mean that files named 'parser_id' and 'void_test' are created in the ./Inline_test directory, creating that directory if it doesn't already exist. The files (but not the ./Inline_test directory) are cleaned up by calling Inline::C::_testing_cleanup(). Also used by t/06rewrite_config.t to trigger a warning. =item TIMERS Turn on BUILD_TIMERS to get extra diagnostic info about builds. =item UNSAFE Turns SAFEMODE off. Use this in combination with UNTAINT for slightly faster startup time under C<-T>. Only use this if you are sure the environment is safe. =item UNTAINT Turn the UNTAINT option on. Used with C<-T> switch. In terms of secure practices, this is definitely *not* a recommended way of dealing with taint checking, but it's the *only* option currently available with Inline. Use it at your own risk. =item VERSION Tells Inline to report its release version. =back =head1 Writing Modules with Inline Writing CPAN modules that use C code is easy with Inline. Let's say that you wanted to write a module called C. Start by using the following command: h2xs -PAXn Math::Simple This will generate a bunch of files that form a skeleton of what you need for a distributable module. (Read the h2xs manpage to find out what the options do) Next, modify the C file to look like this: package Math::Simple; $VERSION = '1.23'; use base 'Exporter'; @EXPORT_OK = qw(add subtract); use strict; use Inline C => 'DATA', VERSION => '1.23', NAME => 'Math::Simple'; # The following Inline->init() call is optional - see below for more info. #Inline->init(); 1; __DATA__ =pod =cut __C__ int add(int x, int y) { return x + y; } int subtract(int x, int y) { return x - y; } The important things to note here are that you B specify a C and C parameter. The C must match your module's package name. The C parameter must match your module's C<$VERSION> variable and they must be of the form C. NOTE: These are Inline's sanity checks to make sure you know what you're doing before uploading your code to CPAN. They insure that once the module has been installed on someone's system, the module would not get automatically recompiled for any reason. This makes Inline based modules work in exactly the same manner as XS based ones. Finally, you need to modify the Makefile.PL. Simply change: use ExtUtils::MakeMaker; to use Inline::MakeMaker; And, in order that the module build work correctly in the cpan shell, add the following directive to the Makefile.PL's WriteMakefile(): CONFIGURE_REQUIRES => { 'Inline::MakeMaker' => 0.45, 'ExtUtils::MakeMaker' => 6.52, }, This "CONFIGURE_REQUIRES" directive ensures that the cpan shell will install Inline on the user's machine (if it's not already present) before building your Inline-based module. Specifying of "ExtUtils::MakeMaker => 6.52," is optional, and can be omitted if you like. It ensures only that some harmless warnings relating to the "CONFIGURE_REQUIRES" directive won't be emitted during the building of the module. It also means, of course, that ExtUtils::Makemaker will first be updated on the user's machine unless the user already has version 6.52 or later. If the "Inline->init();" is not done then, having installed Math::Simple, a warning that "One or more DATA sections were not processed by Inline" will appear when (and only when) Math::Simple is loaded by a "require call. It's a harmless warning - and if you're prepared to live with it, then there's no need to make the "Inline->init();" call. When the person installing C does a "C", the generated Makefile will invoke Inline in such a way that the C code will be compiled and the executable code will be placed into the C<./blib> directory. Then when a "C" is done, the module will be copied into the appropriate Perl sitelib directory (which is where an installed module should go). Now all you need to do is: perl Makefile.PL make dist That will generate the file C which is a distributable package. (It will also generate some harmless warnings in relation to "CONFIGURE_REQUIRES" unless the version of your ExtUtils::MakeMaker is 6.52 or later.) That's all there is to it. IMPORTANT NOTE: Although the above steps will produce a workable module, you still have a few more responsibilities as a budding new CPAN author. You need to write lots of documentation and write lots of tests. Take a look at some of the better CPAN modules for ideas on creating a killer test harness. Actually, don't listen to me, go read these: perldoc perlnewmod http://www.cpan.org/modules/04pause.html http://www.cpan.org/modules/00modlist.long.html =head1 How Inline Works In reality, Inline just automates everything you would need to do if you were going to do it by hand (using XS, etc). Inline performs the following steps: =over 4 =item 1) Receive the Source Code Inline gets the source code from your script or module with a statements like the following: use Inline C => "Source-Code"; or use Inline; bind Inline C => "Source-Code"; where C is the programming language of the source code, and C is a string, a file name, an array reference, or the special C<'DATA'> keyword. Since Inline is coded in a "C" statement, everything is done during Perl's compile time. If anything needs to be done that will affect the C, it needs to be done in a C block that is I the "C" statement. If you really need to specify code to Inline at runtime, you can use the C method. Source code that is stowed in the C<'DATA'> section of your code, is read in by an C subroutine in Inline. That's because the C filehandle is not available at compile time. =item 2) Check if the Source Code has been Built Inline only needs to build the source code if it has not yet been built. It accomplishes this seemingly magical task in an extremely simple and straightforward manner. It runs the source text through the C module to produce a 128-bit "fingerprint" which is virtually unique. The fingerprint along with a bunch of other contingency information is stored in a C<.inl> file that sits next to your executable object. For instance, the C code from a script called C might create these files: example_pl_3a9a.so example_pl_3a9a.inl If all the contingency information matches the values stored in the C<.inl> file, then proceed to step 8. (No compilation is necessary) =item 3) Find a Place to Build and Install At this point Inline knows it needs to build the source code. The first thing to figure out is where to create the great big mess associated with compilation, and where to put the object when it's done. By default Inline will try to build and install under the first place that meets one of the following conditions: A) The DIRECTORY= config option; if specified B) The PERL_INLINE_DIRECTORY environment variable; if set C) .Inline/ (in current directory); if exists and $PWD != $HOME D) bin/.Inline/ (in directory of your script); if exists E) ~/.Inline/; if exists F) ./_Inline/; if exists G) bin/_Inline; if exists H) Create ./_Inline/; if possible I) Create bin/_Inline/; if possible Failing that, Inline will croak. This is rare and easily remedied by just making a directory that Inline will use. If the PERL_INSTALL_ROOT Environment Variable has been set, you will need to make special provision for that if the 'make install' phase of your Inline scripts are to succeed. If the module option is being compiled for permanent installation, then Inline will only use C<./_Inline/> to build in, and the C<$Config{installsitearch}> directory to install the executable in. This action is caused by Inline::MakeMaker, and is intended to be used in modules that are to be distributed on the CPAN, so that they get installed in the proper place. =item 4) Parse the Source for Semantic Cues Inline::C uses the module C to parse through your chunks of C source code and look for things that it can create run-time bindings to. In C it looks for all of the function definitions and breaks them down into names and data types. These elements are used to correctly bind the C function to a C subroutine. Other Inline languages like Python and Java actually use the C and C modules to parse the Inline code. =item 5) Create the Build Environment Now Inline can take all of the gathered information and create an environment to build your source code into an executable. Without going into all the details, it just creates the appropriate directories, creates the appropriate source files including an XS file (for C) and a C. =item 6) Build the Code and Install the Executable The planets are in alignment. Now for the easy part. Inline just does what you would do to install a module. "C". If something goes awry, Inline will croak with a message indicating where to look for more info. =item 7) Tidy Up By default, Inline will remove all of the mess created by the build process, assuming that everything worked. If the build fails, Inline will leave everything intact, so that you can debug your errors. Setting the C shortcut option will also stop Inline from cleaning up. =item 8) DynaLoad the Executable For C (and C++), Inline uses the C method to pull your external module into C space. Now you can call all of your external functions like Perl subroutines. Other languages like Python and Java, provide their own loaders. =back =head1 SEE ALSO For information about using Inline with C see L. For sample programs using Inline with C see L. For "Formerly Answered Questions" about Inline, see L. For information on supported languages and platforms see L. For information on writing your own Inline Language Support Module, see L. Inline's mailing list is inline@perl.org To subscribe, send email to inline-subscribe@perl.org =head1 BUGS AND DEFICIENCIES When reporting a bug, please do the following: - Put "use Inline REPORTBUG;" at the top of your code, or use the command line option "perl -MInline=REPORTBUG ...". - Run your code. - Follow the printed directions. =head1 AUTHOR Brian Ingerson Neil Watkiss is the author of C, C, C, C, C and C. He is known in the innermost Inline circles as the "Boy Wonder". Sisyphus fixed some bugs and is current co-maintainer. =head1 COPYRIGHT Copyright (c) 2000-2002. Brian Ingerson. Copyright (c) 2008, 2010-2013. Sisyphus. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://www.perl.com/perl/misc/Artistic.html =cut Inline-0.53/kobes.log0000644000076400010400000000070312140067330016131 0ustar sisyphusAdministratorsInline: Unable to remove blibadditional Inline: Unable to remove blib56 Inline: Unable to remove blib58 Inline: Unable to remove blib510 Inline: Unable to remove blib514 Inline: Unable to remove blibblead Inline: Unable to remove blibblead_64int Inline: Unable to remove blib516_x86_64int Inline: Unable to remove blib510_x64 Inline: Unable to remove blib512_x64 Inline: Unable to remove blib514_x64 Inline: Unable to remove blibblead_x64 Inline-0.53/lib/0000755000076400010400000000000012140062610015065 5ustar sisyphusAdministratorsInline-0.53/lib/Inline/0000755000076400010400000000000012140062610016303 5ustar sisyphusAdministratorsInline-0.53/lib/Inline/denter.pm0000644000076400010400000002242712052612400020131 0ustar sisyphusAdministratorspackage Inline::denter; use strict; use Carp; use AutoLoader 'AUTOLOAD'; sub new { my $class = shift; bless {width => 4, comma => " : ", level => 0, tabwidth => 8, }, $class; } # Prevent a taint exception being thrown by AutoLoader.pm. # Serves no other purpose. sub DESTROY { } sub undent { local $/ = "\n"; my ($o, $text) = @_; my ($comma) = $o->{comma}; my $package = caller; $package = caller(1) if $package eq 'Inline::denter'; %{$o->{xref}} = (); @{$o->{objects}} = (); @{$o->{context}} = (); my $glob = ''; chomp $text; @{$o->{lines}} = split $/, $text; $o->{level} = 0; $o->{line} ||= 1; $o->_setup_line; while (not $o->{done}) { if ($o->{level} == 0 and $o->{content} =~ /^(\w+)\s*$comma\s*(.*)$/) { $o->{content} = $2; no strict 'refs'; push @{$o->{objects}}, "$1"; } push @{$o->{objects}}, $o->_undent_data; } return @{$o->{objects}}; } sub _undent_data { my $o = shift; my ($obj, $class) = ('', ''); my @refs; my %refs; while ($o->{content} =~ s/^\\(?:\((\w+)\))?((\%|\@|\$|\\).*)/$2/) { push @refs, $1; $refs{$1} = scalar @refs; } if ($o->{content} =~ /^([\%\@\$]) (\w(?:\w|::)*)? \s*$/x ) { my $foo; $obj = ($1 eq '%') ? {} : ($1 eq '@') ? [] : \$foo; $class = $2 || ''; if ($1 eq '%') { %$obj = $o->_undent_hash; } elsif ($1 eq '@') { @$obj = $o->_undent_array; } else { $$obj = $o->_undent_scalar; } bless $obj, $class if length $class; } elsif ($o->{content} =~ /^\?\s*$/) { $obj = $o->_undent_undef; } else { $obj = $o->_undent_value; } while (@refs) { my $ref = pop @refs; my $copy = $obj; $obj = \ $copy; $o->{xref}{$ref} = $obj if $ref; } return $obj; } sub _undent_value { my $o = shift; my $value = ''; if ($o->{content} =~ /^\<\<(\w+)(\-?)\s*$/) { my ($marker, $chomp) = ($1, $2); my $line = $o->{line}; $o->_next_line; while (not $o->{done} and $o->{lines}[0] ne $marker) { $value .= $o->{lines}[0] . "\n"; $o->_next_line; } croak M03_no_value_end_marker($marker, $line) if $o->{done}; chomp $value if $chomp; } elsif ($o->{content} =~ /^\"/) { croak $o->M04_mismatched_quotes unless $o->{content} =~ /^\".*\"\s*$/; ($value = $o->{content}) =~ s/^\"|\"\s*$//g; } else { $value = $o->{content}; } $o->_next_line; $o->_setup_line; return $value; } sub _undent_hash { my @values; my $o = shift; my $level = $o->{level} + 1; $o->_next_line; $o->_setup_line; while ($o->{level} == $level) { my ($key, $value) = split $o->{comma}, $o->{content}; croak $o->M05_invalid_key_value unless (defined $key and defined $value); $o->{content} = $value; push @values, $o->_get_key($key), $o->_undent_data;; } croak $o->M06_invalid_indent_level if $o->{level} > $level; return @values; } sub _get_key { my ($o, $key) = @_; return $key unless $key =~ /^\<\<(\w+)(\-?)/; my ($marker, $chomp) = ($1, $2); $key = ''; my $line = $o->{line}; $o->_next_line; while (not $o->{done} and $o->{lines}[0] ne $marker) { $key .= $o->{lines}[0] . "\n"; $o->_next_line; } croak M02_no_key_end_marker($marker, $line) if $o->{done}; chomp $key if $chomp; $o->_next_line; $o->_setup_line; return $key; } sub _undent_array { my @values; my $o = shift; my $level = $o->{level} + 1; $o->_next_line; $o->_setup_line; while ($o->{level} == $level) { push @values, $o->_undent_data; } croak $o->M06_invalid_indent_level if $o->{level} > $level; return @values; } sub _undent_scalar { my $values; my $o = shift; my $level = $o->{level} + 1; $o->_next_line; $o->_setup_line; croak $o->M06_invalid_indent_level if $o->{level} != $level; croak $o->M07_invalid_scalar_value if $o->{content} =~ /^[\%\@\$\\]/; return $o->_undent_undef if $o->{content} =~ /^\?/; return $o->_undent_value; } sub _undent_undef { my $o = shift; $o->_next_line; $o->_setup_line; return undef; } sub _next_line { my $o = shift; $o->{done}++, $o->{level} = -1, return unless @{$o->{lines}}; local $_ = shift @{$o->{lines}}; $o->{line}++; } sub _setup_line { my $o = shift; $o->{done}++, $o->{level} = -1, return unless @{$o->{lines}}; my ($width, $tabwidth) = @{$o}{qw(width tabwidth)}; while (1) { local $_ = $o->{lines}[0]; # expand tabs in leading whitespace; $o->next_line, next if /^(\s*$|\#)/; # skip comments and blank lines while (s{^( *)(\t+)} {' ' x (length($1) + length($2) * $tabwidth - length($1) % $tabwidth)}e){} croak $o->M01_invalid_indent_width unless /^(( {$width})*)(\S.*)$/; $o->{level} = length($1) / $width; $o->{content} = $3; last; } } 1; __END__ sub indent { my $o = shift; my $package = caller; $package = caller(1) if $package eq 'Inline::denter'; my $stream = ''; $o->{key} = ''; while (@_) { local $_ = shift; $stream .= $o->indent_name($_, shift), next if (/^\*$package\::\w+$/); $stream .= $o->indent_data($_); } return $stream; } sub indent_data { my $o = shift; local $_ = shift; return $o->indent_undef($_) if not defined; return $o->indent_value($_) if (not ref); return $o->indent_hash($_) if (ref eq 'HASH' and not /=/ or /=HASH/); return $o->indent_array($_) if (ref eq 'ARRAY' and not /=/ or /=ARRAY/); return $o->indent_scalar($_) if (ref eq 'SCALAR' and not /=/ or /=SCALAR/); return $o->indent_ref($_) if (ref eq 'REF'); return "$_\n"; } sub indent_value { my ($o, $data) = @_; my $stream; if ($data =~ /\n/) { my $marker = 'EOV'; $marker++ while $data =~ /^$marker$/m; my $chomp = ($data =~ s/\n\Z//) ? '' : '-'; $stream = "<<$marker$chomp\n"; $stream .= $o->{key}, $o->{key} = '' if $o->{key}; $stream .= "$data\n$marker\n"; } elsif ($data =~ /^[\s\%\@\$\\?\"]|\s$/ or $data =~ /\Q$o->{comma}\E/ or $data =~ /[\x00-\x1f]/ or $data eq '') { $stream = qq{"$data"\n}; $stream .= $o->{key}, $o->{key} = '' if $o->{key}; } else { $stream = "$data\n"; $stream .= $o->{key}, $o->{key} = '' if $o->{key}; } return $stream; } sub indent_hash { my ($o, $data) = @_; my $stream = $o->_print_ref($data, '%', 'HASH'); return $$stream if ref $stream; my $indent = ++$o->{level} * $o->{width}; for my $key (sort keys %$data) { my $key_out = $key; if ($key =~ /\n/ or $key =~ /\Q$o->{comma}\E/) { my $marker = 'EOK'; $marker++ while $key =~ /^$marker$/m; my $chomp = (($o->{key} = $key) =~ s/\n\Z//m) ? '' : '-'; $o->{key} .= "\n$marker\n"; $key_out = "<<$marker$chomp"; } elsif ($data =~ /^[\s\%\@\$\\?\"]|\s$/) { $key_out = qq{"$key"}; } $stream .= ' ' x $indent . $key_out . $o->{comma}; $stream .= $o->indent_data($data->{$key}); } $o->{level}--; return $stream; } sub indent_array { my ($o, $data) = @_; my $stream = $o->_print_ref($data, '@', 'ARRAY'); return $$stream if ref $stream; my $indent = ++$o->{level} * $o->{width}; for my $datum (@$data) { $stream .= ' ' x $indent; $stream .= $o->indent_data($datum); } $o->{level}--; return $stream; } sub indent_scalar { my ($o, $data) = @_; my $stream = $o->_print_ref($data, q{$}, 'SCALAR'); return $$stream if ref $stream; my $indent = ($o->{level} + 1) * $o->{width}; $stream .= ' ' x $indent; $stream .= $o->indent_data($$data); return $stream; } sub indent_ref { my ($o, $data) = @_; my $stream = $o->_print_ref($data, '\\', 'SCALAR'); return $$stream if ref $stream; chomp $stream; return $stream . $o->indent_data($$data); } sub indent_undef { my ($o, $data) = @_; my $stream = "?\n"; $stream .= $o->{key}, $o->{key} = '' if $o->{key}; return $stream; } sub indent_name { my ($o, $name, $value) = @_; $name =~ s/^.*:://; my $stream = $name . $o->{comma}; $stream .= $o->indent_data($value); return $stream; } sub _print_ref { my ($o, $data, $symbol, $type) = @_; $data =~ /^(([\w:]+)=)?$type\(0x([0-9a-f]+)\)$/ or croak "Invalid reference: $data\n"; my $stream = $symbol; $stream .= $2 if defined $2; $o->{xref}{$3}++; croak "Inline::denter does not handle duplicate references" if $o->{xref}{$3} > 1; $stream .= "\n"; $stream .= $o->{key}, $o->{key} = '' if $o->{key}; return $stream; } # Undent error messages sub M01_invalid_indent_width { my $o = shift; "Invalid indent width detected at line $o->{line}\n"; } sub M02_no_key_end_marker { my ($marker, $line) = @_; "No terminating marker '$marker' found for key at line $line\n"; } sub M03_no_value_end_marker { my ($marker, $line) = @_; "No terminating marker '$marker' found for value at line $line\n"; } sub M04_mismatched_quotes { my $o = shift; "Mismatched double quotes for value at line $o->{line}\n"; } sub M05_invalid_key_value { my $o = shift; "Missing or invalid hash key/value pair at $o->{line}\n"; } sub M06_invalid_indent_level { my $o = shift; "Invalid indentation level at $o->{line}\n"; } sub M07_invalid_scalar_value { my $o = shift; "Invalid value for scalar ref context at $o->{line}\n"; } 1; __END__ Inline-0.53/lib/Inline/Foo.pm0000644000076400010400000000333412052612400017367 0ustar sisyphusAdministratorspackage Inline::Foo; $VERSION = '0.01'; require Inline; @ISA = qw(Inline); use strict; use Carp; use File::Spec; sub register { return { language => 'Foo', aliases => ['foo'], type => 'interpreted', suffix => 'foo', }; } sub usage_config { my $key = shift; "'$key' is not a valid config option for Inline::Foo\n"; } sub usage_config_bar { "Invalid value for Inline::Foo config option BAR"; } sub validate { my $o = shift; $o->{ILSM}{PATTERN} ||= 'foo-'; $o->{ILSM}{BAR} ||= 0; while (@_) { my ($key, $value) = splice @_, 0, 2; if ($key eq 'PATTERN') { $o->{ILSM}{PATTERN} = $value; next; } if ($key eq 'BAR') { croak usage_config_bar unless $value =~ /^[01]$/; $o->{ILSM}{BAR} = $value; next; } croak usage_config($key); } } sub build { my $o = shift; my $code = $o->{API}{code}; my $pattern = $o->{ILSM}{PATTERN}; $code =~ s/$pattern//g; $code =~ s/bar-//g if $o->{ILSM}{BAR}; sleep 1; # imitate compile delay { package Foo::Tester; eval $code; } croak "Foo build failed:\n$@" if $@; my $path = File::Spec->catdir($o->{API}{install_lib},'auto',$o->{API}{modpname}); my $obj = $o->{API}{location}; $o->mkpath($path) unless -d $path; open FOO_OBJ, "> $obj" or croak "Can't open $obj for output\n$!"; print FOO_OBJ $code; close \*FOO_OBJ; } sub load { my $o = shift; my $obj = $o->{API}{location}; open FOO_OBJ, "< $obj" or croak "Can't open $obj for output\n$!"; my $code = join '', ; close \*FOO_OBJ; eval "package $o->{API}{pkg};\n$code"; croak "Unable to load Foo module $obj:\n$@" if $@; } sub info { my $o = shift; } 1; __END__ Inline-0.53/lib/Inline/MakeMaker/0000755000076400010400000000000012140062610020140 5ustar sisyphusAdministratorsInline-0.53/lib/Inline/MakeMaker/Changes0000644000076400010400000000464612140062002021440 0ustar sisyphusAdministratorsRevision history for Perl extension Inline::MakeMaker. --- version 0.53 date Wed 1 May 2013 version 0.53 released to CPAN --- version 0.52_02 date Wed 24 Apr 2013 version 0.52_02 released to CPAN --- version 0.52_01 date Thurs 11 Apr 2013 version 0.52_01 released to CPAN --- version 0.52 date Thurs 07 Mar 2013 version 0.52 released to CPAN --- version 0.51_03 date: Wed 28 Nov 2012 Version 0.51_03 released to CPAN. --- version 0.51_02 date: Tues 20 Nov 2012 Version 0.51_02 released to CPAN. --- version 0.51_01 date: Tues 20 Nov 2012 Version 0.51_01 released to CPAN. --- version 0.51 date: Sat 13 Oct 2012 Version 0.51 released to CPAN. --- version 0.50_03 date: Mon 8 Oct 2012 Version 0.50_03 released to CPAN. --- version 0.50_02 date: Thur 24 May 2012 Version 0.50_02 released to CPAN. --- version: 0.50_02 date: Tues 14 Feb 2012 MakeMaker.pm - Bump version number to 0.50_02 --- version: 0.50_01 date: Sun 12 Feb 2012 Version 0.50_01 released to CPAN. --- version: 0.50_01 date: Wed 8 Feb 2012 Makemaker.pm - Bump version number to 0.50_01 --- version: 0.50 date: Tues 7 Feb 2012 Version 0.50 released to CPAN Makemaker.pm - Bump version number to 0.50 --- version: 0.49_02 date: Fri 3 Feb 2012 - Bring version numbering into line with recommendations made in http://perldoc.perl.org/perlmodstyle.html#Version-numbering --- version: 0.44 date: Tue Oct 8 11:54:10 PDT 2002 changes: - Made Inline module builds be noisy (show all compiler messages). --- version: 0.44 date: Tue Oct 8 11:54:10 PDT 2002 changes: - Rewrote the whole module. Much simpler and flexible now. 0.41 Tue Jun 5 02:59:53 PDT 2001 - Made dependencies more make like. Works very nice in trees. 0.41 Sun Jun 3 20:34:49 PDT 2001 - Fixed bug. Needed to stack versions as well as names. 0.41 Sun Jun 3 20:34:49 PDT 2001 - Allow MY::postamble in non Inline Makefile.PLs Thanks David Coppit 0.41 Sat Jun 2 19:53:58 PDT 2001 - Fixed to work properly in Makefile.PL hierarchies. Thanks Brett. 0.40 Sun May 13 23:30:02 PDT 2001 - First version of Inline::MakeMaker. Supports installing Inline extensions like regular XS ones. 0.01 Mon May 7 22:30:09 2001 - original version; created by h2xs 1.21 with options -PAXn Inline::MakeMaker Inline-0.53/lib/Inline/MakeMaker.pm0000644000076400010400000000364112140062002020475 0ustar sisyphusAdministratorspackage Inline::MakeMaker; $Inline::MakeMaker::VERSION = '0.53'; $Inline::MakeMaker::VERSION = eval $Inline::MakeMaker::VERSION; @EXPORT = qw(WriteMakefile WriteInlineMakefile); use strict; use base 'Exporter'; use ExtUtils::MakeMaker(); use Carp; sub WriteInlineMakefile { # warn <parse_version($args{VERSION_FROM}) or croak "Can't determine version for $name\n"; } croak < "_Inline $object.inl" } unless defined $args{clean}; # Add Inline to the dependencies $args{PREREQ_PM}{Inline} = '0.44' unless defined $args{PREREQ_PM}{Inline}; &ExtUtils::MakeMaker::WriteMakefile(%args); open MAKEFILE, '>> Makefile' or croak "Inline::MakeMaker::WriteMakefile can't append to Makefile:\n$!"; print MAKEFILE < 5.013 ? 0.23 : 0.21; my $prereq_pm = $] > 5.007 ? { Data::Dumper => 2.09, Digest::MD5 => 2.09, Parse::RecDescent => 1.80, File::Spec => 0.8, Test::Warn => $twv, } : { Data::Dumper => 2.09, Digest::MD5 => 2.09, Parse::RecDescent => 1.80, File::Spec => 0.8, }; WriteMakefile( NAME => 'Inline', VERSION_FROM => 'Inline.pm', PREREQ_PM => $prereq_pm, clean => {FILES => '_Inline_test _Inline .Inline'}, ); if ($^O =~ /Win32/i) { print "Fixing Makefile for MSWin32\n"; open MAKEFILE, "< Makefile" or die "Can't open Makefile for reading"; my @lines = ; close MAKEFILE; open MAKEFILE, "> Makefile" or die "Can't open Makefile for writing"; for (@lines) { print MAKEFILE unless /^\s*((\@\[)|(\]))\s*$/; } close MAKEFILE; } Inline-0.53/MANIFEST0000644000076400010400000000227112140062002015445 0ustar sisyphusAdministratorsC/C-Cookbook.pod C/C.pm C/C.pod C/Changes C/Makefile.PL C/README C/lib/Inline/C/ParseRecDescent.pm C/lib/Inline/C/ParseRegExp.pm C/rt/grammars.t C/t/00init.t C/t/01syntax.t C/t/02config.t C/t/03typemap.t C/t/04perlapi.t C/t/05xsmode.t C/t/06parseregexp.t C/t/07typemap_multi.t C/t/08taint.t C/t/08taint_1.p C/t/08taint_2.p C/t/08taint_3.p C/t/09parser.t C/t/10callback.t C/t/11default_readonly.t C/t/12taint_old.t C/t/14void_arg.t C/t/15ccflags.t C/t/16ccflagsex.t C/t/17prehead.t C/t/18quote_space.t C/t/19INC.t C/t/20eval.t C/t/21read_DATA.t C/t/22read_DATA_2.t C/t/23validate.t C/t/prehead.in C/t/soldier_typemap C/t/typemap C/t/foo/find_me_in_foo.h C/t/bar/find_me_in_bar.h Changes Inline-API.pod Inline-FAQ.pod Inline-Support.pod Inline.pm Inline.pod MANIFEST Makefile.PL README ToDo lib/Inline/Foo.pm lib/Inline/MakeMaker/Changes lib/Inline/MakeMaker.pm lib/Inline/denter.pm modules/Math/Simple/Simple.pm modules/Math/Simple/Makefile.PL modules/Math/Simple/test.pl modules/Math/Simple/Changes modules/Math/Simple/MANIFEST symbols.perl t/00init.t t/01usages.t t/02config.t t/03errors.t t/04create.t t/05files.t t/06rewrite_config.t t/06rewrite_config.p t/07rewrite2_config.t t/07rewrite2_config.p t/file Inline-0.53/modules/0000755000076400010400000000000012140062610015767 5ustar sisyphusAdministratorsInline-0.53/modules/Math/0000755000076400010400000000000012140062610016660 5ustar sisyphusAdministratorsInline-0.53/modules/Math/Simple/0000755000076400010400000000000012140062610020111 5ustar sisyphusAdministratorsInline-0.53/modules/Math/Simple/Changes0000644000076400010400000000016512052612400021406 0ustar sisyphusAdministratorsRevision history for Perl extension Math::Simple. 1.23 Sun May 6 22:07:57 2001 - Sample CPAN module using Inline Inline-0.53/modules/Math/Simple/Makefile.PL0000644000076400010400000000017312052612400022064 0ustar sisyphusAdministratorsuse Inline::MakeMaker; WriteMakefile( NAME => 'Math::Simple', VERSION_FROM => 'Simple.pm', ); Inline-0.53/modules/Math/Simple/MANIFEST0000644000076400010400000000005712052612400021244 0ustar sisyphusAdministratorsChanges MANIFEST Makefile.PL Simple.pm test.pl Inline-0.53/modules/Math/Simple/Simple.pm0000644000076400010400000000047012052612400021701 0ustar sisyphusAdministratorspackage Math::Simple; $VERSION = '1.23'; use base 'Exporter'; @EXPORT_OK = qw(add subtract); use strict; use Inline C => 'DATA', VERSION => '1.23', NAME => 'Math::Simple'; 1; __DATA__ __C__ int add (int x, int y) { return x + y; } int subtract (int x, int y) { return x - y; } Inline-0.53/modules/Math/Simple/test.pl0000644000076400010400000000026112052612400021424 0ustar sisyphusAdministratorsuse strict; use Test; BEGIN { plan(tests => 2, todo => [], onfail => sub {}, ); } use Math::Simple qw(add subtract); ok(add(5, 7) == 12); ok(subtract(5, 7) == -2); Inline-0.53/README0000644000076400010400000001650612052612400015207 0ustar sisyphusAdministratorsINTRODUCTION: Inline.pm - Write Perl subroutines in other programming languages. Inline lets you write Perl subroutines in other programming languages like C, C++, Java, Python, Tcl and even Assembly. You don't need to compile anything. All the details are handled transparently so you can just run your Perl script like normal. Example: use Inline::Files; use Inline C; print JAxH('Inline'), "\n"; __C__ SV* JAxH(char* x) { return newSVpvf ("Just Another %s Hacker",x); } When run, this complete program prints: Just Another Inline Hacker The one line version is: perl -le 'use Inline C=>q{SV*JAxH(char*x){return newSVpvf("Just Another %s Hacker",x);}};print JAxH+Inline' ------------------------------------------------------------------------------- FEATURES: Inline version 0.44 is a semi-major release: + This version is intended to be backwards compatible with 0.43. + Fixed many bugs reported since 0.43 + Sped up parsing of C with 'USING => ParseRegExp' + Added BUILD_NOISY and BUILD_TIMERS options + Use File::Spec for all path operations. First step in porting to all platforms. + Always call ILSM->validate() + Allow C++ modules to be written with Inline + New improved Inline::MakeMaker Inline version 0.43 is a minor release: + Added XSMODE for using Inline directly with XS + Now works with *all* Perl release versions over 5.005 (5.005_02, etc) + Removed old deprecated funstionality + Works on Mac OS X + Added support for ILSMs who don't want to invoke a build + Added script's working directory to the #include path for C + Tighter integration between Inline::C and Inline::CPP + Bug fixes reported on the mailing list. Inline version 0.42 is a minor release: + Applied a couple patches. Python and Tcl now install properly. Inline version 0.41 is a minor release: + Added the AUTOWRAP feature for C - Inline can now create wrappers from C function *declarations* alone. + Made Inline::MakeMaker work correctly in nested Makefile.PL trees. + Fixed bug preventing other Inline::* modules from installing in some cases. + Fixed platform dependent CRLF issues. Inline version 0.40 is a major upgrade. It includes: + Inline::MakeMaker + Rock solid support for writing CPAN extension modules + Short file names. + No more _Inline/lib/auto/Foo_C_3cee729d1d942c6792ca5a741dc21879/Foo_C_3cee729d1d942c6792ca5a741dc21879.so + Now it's _Inline/lib/auto/Foo/Foo.so + Support for creating binary distributions. + Can even do it without shipping C source code. + Support for Damian Conway's Inline::Files + No more __END__ markers. + Safe new config and caching format. + Similar to Data::Denter format + New Inline-FAQ.pod. Inline version 0.34 fixes 2 minor bugs: + Makefile.PL got confused on $Config::Config{cc} with full pathnames or flags + Makefile.PL/Makefile dependency caused a problem in one rare case. Inline version 0.33 is a minor upgrade with the following changes: + Support for Inline::Struct and Inline::Filters + Added ENABLE and DISABLE configuration modifiers. + C installation is optional + Test harness reworked. Faster testing. + Fixed all reported (and some unreported) bugs. + Documentation enhancements. Inline version 0.32 is a minor upgrade with the following changes: + Addition of UNTAINT, SAFEMODE, GLOBAL_LOAD, MAKE, and LDDLFLAGS configuration options. + Fixed all reported (and some unreported) bugs. + Documentation enhancements. Inline version 0.31 is a minor upgrade with the following changes: + "use Inline C;" is now a synonym for "use Inline C => DATA;" + Default build/install directory changed from "blib_I/" to ".Inline/" + Build/Install directory structure simplified. + Short install paths. + Build areas in ".Inline/build/" subdirectory. + Added 'CC', 'CCFLAGS', 'LD', and 'LDFLAGS' config options to C. + More recipes in Cookbook. Inline version 0.30 is a major upgrade from previous verions. It includes: + Integrated support for typemap files in C. + All the recognized types now come *only* from typemaps. + The default types come from the default typemap installed with core Perl. + Typemaps are used to modify the Parse::RecDescent grammar for parsing C. + This means you can easily use your existing typemaps. + Language support completely separated from base Inline code. + Beta supoort for C (Inline::C, included) + Alpha support for C++ (Inline::CPP, available separately) + Alpha support for Python (Inline::Python, available separately) + Support for 'embedding' Perl in C with my new programming language, CPR. (Inline::CPR, available separately) This one may warp your mind :^) + Simple API for adding your own language support. + Write your own Inline::Foo + Write your own implementation of Inline::C, or just modify Inline::C::grammar. + Support for interpreted languages in addition to compiled ones. + Autodetection of new Inline language modules. + Much easier and more powerful configuration syntax. + More XS and MakeMaker features exposed for configuration (for C and C++). + Flexible new syntax for specifying source code. + Use DATA section for AutoLoader, Inline, and POD simultaneously. + Support for using Inline 'with' other modules. + "use Inline with 'Event';" lets Event.pm pass config info to Inline.pm. + Event.pm 0.80 has built in support for Inline.pm 0.30 and higher. + Write Event callbacks in C with extreme ease. + More documentation + perldoc Inline + perldoc Inline-FAQ + perldoc Inline-API + perldoc Inline::C + perldoc Inline::C-Cookbook + Better error messages and easier debugging. + Mailing list: inline@perl.org Other features of Inline.pm include: = Automatically compiles your source code and caches the shared object. = Automatically DynaLoads the shared object and binds it to Perl. = Recompiles only when the C code changes. = Changing the Perl code will not cause a recompile of the C code. = Support for writing extension modules, suitable for distributing to the CPAN. = Support for generating and binding Inline subs at run time. = Works on all Unix and MS Windows configurations. ------------------------------------------------------------------------------- INSTALLATION: This module requires the Digest::MD5 and Parse::RecDescent modules. It also requires the appropriate C compiler. (Where appropriate means the one referred to in your Config.pm) To install Inline do this: perl Makefile.PL make make test make install On ActivePerl for MSWin32, use nmake instead of make. Or just use: ppm install Inline For convenience, Inline::C is packaged with Inline, and will be automatically installed as well. ------------------------------------------------------------------------------- INFORMATION: = For more information on Inline, see 'perldoc Inline' and 'perldoc Inline-FAQ' = For information about Inline::, see 'perldoc Inline::C' and 'perldoc Inline::C-Cookbook' = For information on writing your own Inline extension see 'perldoc Inline-API' = For information about the Perl5 internal C API, see 'perldoc perlapi' or try http://www.perldoc.com/perl5.6/pod/perlapi.html = The Fall 2000 edition of The Perl Journal has an article about Inline The Inline.pm mailing list is inline@perl.org. Send email to inline-subscribe@perl.org to subscribe. Please send questions and comments to "Brian Ingerson" Copyright (c) 2000-2002. Brian Ingerson. Copyright (c) 2008, 2010, 2011. Sisyphus. Inline-0.53/symbols.perl0000644000076400010400000007616512052612400016712 0ustar sisyphusAdministratorsBases.663 LastError Letext PL_AMG_names PL_No PL_Yes PL_check PL_curinterp PL_do_undump PL_fold PL_fold_locale PL_force_link_funcs PL_freq PL_hexdigit PL_no_aelem PL_no_dir_func PL_no_func PL_no_helem PL_no_mem PL_no_modify PL_no_myglob PL_no_security PL_no_sock_func PL_no_symref PL_no_usym PL_no_wrongref PL_op_desc PL_op_mutex PL_op_name PL_opargs PL_patleave PL_ppaddr PL_regkind PL_sig_name PL_sig_num PL_simple PL_thr_key PL_utf8skip PL_uuemap PL_varies PL_vtbl_amagic PL_vtbl_amagicelem PL_vtbl_arylen PL_vtbl_backref PL_vtbl_bm PL_vtbl_collxfrm PL_vtbl_dbline PL_vtbl_defelem PL_vtbl_env PL_vtbl_envelem PL_vtbl_fm PL_vtbl_glob PL_vtbl_isa PL_vtbl_isaelem PL_vtbl_mglob PL_vtbl_nkeys PL_vtbl_pack PL_vtbl_packelem PL_vtbl_pos PL_vtbl_regdata PL_vtbl_regdatum PL_vtbl_regexp PL_vtbl_sig PL_vtbl_sigelem PL_vtbl_substr PL_vtbl_sv PL_vtbl_taint PL_vtbl_uvar PL_vtbl_vec PL_warn_nl PL_warn_nosemi PL_warn_reserved PL_warn_uninit PerlIO_init PerlIO_sprintf PerlIO_tmpfile PerlIO_vsprintf Perl_GNo_ptr Perl_GYes_ptr Perl_Gcurinterp_ptr Perl_Gdo_undump_ptr Perl_Ghexdigit_ptr Perl_Gop_mutex_ptr Perl_Gpatleave_ptr Perl_Gthr_key_ptr Perl_Gv_AMupdate Perl_IArgv_ptr Perl_ICmd_ptr Perl_IDBcv_ptr Perl_IDBgv_ptr Perl_IDBline_ptr Perl_IDBsignal_ptr Perl_IDBsingle_ptr Perl_IDBsub_ptr Perl_IDBtrace_ptr Perl_Iamagic_generation_ptr Perl_Ian_ptr Perl_Iargvgv_ptr Perl_Iargvout_stack_ptr Perl_Iargvoutgv_ptr Perl_Ibasetime_ptr Perl_Ibeginav_ptr Perl_Ibitcount_ptr Perl_Ibufend_ptr Perl_Ibufptr_ptr Perl_Icheckav_ptr Perl_Icollation_ix_ptr Perl_Icollation_name_ptr Perl_Icollation_standard_ptr Perl_Icollxfrm_base_ptr Perl_Icollxfrm_mult_ptr Perl_Icompcv_ptr Perl_Icompiling_ptr Perl_Icomppad_name_fill_ptr Perl_Icomppad_name_floor_ptr Perl_Icomppad_name_ptr Perl_Icomppad_ptr Perl_Icop_seqmax_ptr Perl_Icopline_ptr Perl_Icshlen_ptr Perl_Icshname_ptr Perl_Icurcopdb_ptr Perl_Icurstname_ptr Perl_Idbargs_ptr Perl_Idebstash_ptr Perl_Idebug_ptr Perl_Idefgv_ptr Perl_Idiehook_ptr Perl_Idoextract_ptr Perl_Idoswitches_ptr Perl_Idowarn_ptr Perl_Ie_script_ptr Perl_Iegid_ptr Perl_Iendav_ptr Perl_Ienvgv_ptr Perl_Ierrgv_ptr Perl_Ierror_count_ptr Perl_Ieuid_ptr Perl_Ieval_root_ptr Perl_Ieval_start_ptr Perl_Ievalseq_ptr Perl_Iexit_flags_ptr Perl_Iexitlist_ptr Perl_Iexitlistlen_ptr Perl_Iexpect_ptr Perl_Ifdpid_ptr Perl_Ifilemode_ptr Perl_Iforkprocess_ptr Perl_Iformfeed_ptr Perl_Igeneration_ptr Perl_Igensym_ptr Perl_Igid_ptr Perl_Iglob_index_ptr Perl_Iglobalstash_ptr Perl_Ihe_arenaroot_ptr Perl_Ihe_root_ptr Perl_Ihintgv_ptr Perl_Ihints_ptr Perl_Iin_clean_all_ptr Perl_Iin_clean_objs_ptr Perl_Iin_my_ptr Perl_Iin_my_stash_ptr Perl_Iincgv_ptr Perl_Iinitav_ptr Perl_Iinplace_ptr Perl_Ilast_lop_op_ptr Perl_Ilast_lop_ptr Perl_Ilast_swash_hv_ptr Perl_Ilast_swash_key_ptr Perl_Ilast_swash_klen_ptr Perl_Ilast_swash_slen_ptr Perl_Ilast_swash_tmps_ptr Perl_Ilast_uni_ptr Perl_Ilastfd_ptr Perl_Ilaststatval_ptr Perl_Ilaststype_ptr Perl_Ilex_brackets_ptr Perl_Ilex_brackstack_ptr Perl_Ilex_casemods_ptr Perl_Ilex_casestack_ptr Perl_Ilex_defer_ptr Perl_Ilex_dojoin_ptr Perl_Ilex_expect_ptr Perl_Ilex_formbrack_ptr Perl_Ilex_inpat_ptr Perl_Ilex_inwhat_ptr Perl_Ilex_op_ptr Perl_Ilex_repl_ptr Perl_Ilex_starts_ptr Perl_Ilex_state_ptr Perl_Ilex_stuff_ptr Perl_Ilineary_ptr Perl_Ilinestart_ptr Perl_Ilinestr_ptr Perl_Ilocalpatches_ptr Perl_Imain_cv_ptr Perl_Imain_root_ptr Perl_Imain_start_ptr Perl_Imax_intro_pending_ptr Perl_Imaxo_ptr Perl_Imaxsysfd_ptr Perl_Imess_sv_ptr Perl_Imin_intro_pending_ptr Perl_Iminus_F_ptr Perl_Iminus_a_ptr Perl_Iminus_c_ptr Perl_Iminus_l_ptr Perl_Iminus_n_ptr Perl_Iminus_p_ptr Perl_Imodglobal_ptr Perl_Imulti_close_ptr Perl_Imulti_end_ptr Perl_Imulti_open_ptr Perl_Imulti_start_ptr Perl_Imultiline_ptr Perl_Inexttoke_ptr Perl_Inexttype_ptr Perl_Inextval_ptr Perl_Inice_chunk_ptr Perl_Inice_chunk_size_ptr Perl_Inomemok_ptr Perl_Inullstash_ptr Perl_Inumeric_local_ptr Perl_Inumeric_name_ptr Perl_Inumeric_radix_ptr Perl_Inumeric_standard_ptr Perl_Iofmt_ptr Perl_Ioldbufptr_ptr Perl_Ioldname_ptr Perl_Ioldoldbufptr_ptr Perl_Iop_mask_ptr Perl_Iop_seqmax_ptr Perl_Iorigalen_ptr Perl_Iorigargc_ptr Perl_Iorigargv_ptr Perl_Iorigenviron_ptr Perl_Iorigfilename_ptr Perl_Iors_ptr Perl_Iorslen_ptr Perl_Iosname_ptr Perl_Ipad_reset_pending_ptr Perl_Ipadix_floor_ptr Perl_Ipadix_ptr Perl_Ipatchlevel_ptr Perl_Ipending_ident_ptr Perl_Iperl_destruct_level_ptr Perl_Iperldb_ptr Perl_Ipidstatus_ptr Perl_Ipreambleav_ptr Perl_Ipreambled_ptr Perl_Ipreprocess_ptr Perl_Iprofiledata_ptr Perl_Ipsig_name_ptr Perl_Ipsig_ptr_ptr Perl_Iptr_table_ptr Perl_Ireplgv_ptr Perl_Irsfp_filters_ptr Perl_Irsfp_ptr Perl_Irunops_ptr Perl_Isawampersand_ptr Perl_Ish_path_ptr Perl_Isighandlerp_ptr Perl_Isplitstr_ptr Perl_Isrand_called_ptr Perl_Istatusvalue_ptr Perl_Istderrgv_ptr Perl_Istdingv_ptr Perl_Istrtab_ptr Perl_Isub_generation_ptr Perl_Isublex_info_ptr Perl_Isubline_ptr Perl_Isubname_ptr Perl_Isv_arenaroot_ptr Perl_Isv_count_ptr Perl_Isv_no_ptr Perl_Isv_objcount_ptr Perl_Isv_root_ptr Perl_Isv_undef_ptr Perl_Isv_yes_ptr Perl_Itainting_ptr Perl_Itokenbuf_ptr Perl_Iuid_ptr Perl_Iunsafe_ptr Perl_Iutf8_alnum_ptr Perl_Iutf8_alnumc_ptr Perl_Iutf8_alpha_ptr Perl_Iutf8_ascii_ptr Perl_Iutf8_cntrl_ptr Perl_Iutf8_digit_ptr Perl_Iutf8_graph_ptr Perl_Iutf8_lower_ptr Perl_Iutf8_mark_ptr Perl_Iutf8_print_ptr Perl_Iutf8_punct_ptr Perl_Iutf8_space_ptr Perl_Iutf8_tolower_ptr Perl_Iutf8_totitle_ptr Perl_Iutf8_toupper_ptr Perl_Iutf8_upper_ptr Perl_Iutf8_xdigit_ptr Perl_Iuudmap_ptr Perl_Iwarnhook_ptr Perl_Iwidesyscalls_ptr Perl_Ixiv_arenaroot_ptr Perl_Ixiv_root_ptr Perl_Ixnv_arenaroot_ptr Perl_Ixnv_root_ptr Perl_Ixpv_arenaroot_ptr Perl_Ixpv_root_ptr Perl_Ixpvav_arenaroot_ptr Perl_Ixpvav_root_ptr Perl_Ixpvbm_arenaroot_ptr Perl_Ixpvbm_root_ptr Perl_Ixpvcv_arenaroot_ptr Perl_Ixpvcv_root_ptr Perl_Ixpvhv_arenaroot_ptr Perl_Ixpvhv_root_ptr Perl_Ixpviv_arenaroot_ptr Perl_Ixpviv_root_ptr Perl_Ixpvlv_arenaroot_ptr Perl_Ixpvlv_root_ptr Perl_Ixpvmg_arenaroot_ptr Perl_Ixpvmg_root_ptr Perl_Ixpvnv_arenaroot_ptr Perl_Ixpvnv_root_ptr Perl_Ixrv_arenaroot_ptr Perl_Ixrv_root_ptr Perl_Iyychar_ptr Perl_Iyydebug_ptr Perl_Iyyerrflag_ptr Perl_Iyylval_ptr Perl_Iyynerrs_ptr Perl_Iyyval_ptr Perl_TSv_ptr Perl_TXpv_ptr Perl_Tav_fetch_sv_ptr Perl_Tbodytarget_ptr Perl_Tbostr_ptr Perl_Tchopset_ptr Perl_Tcolors_ptr Perl_Tcolorset_ptr Perl_Tcurcop_ptr Perl_Tcurpad_ptr Perl_Tcurpm_ptr Perl_Tcurstack_ptr Perl_Tcurstackinfo_ptr Perl_Tcurstash_ptr Perl_Tdefoutgv_ptr Perl_Tdefstash_ptr Perl_Tdelaymagic_ptr Perl_Tdirty_ptr Perl_Tdumpindent_ptr Perl_Tefloatbuf_ptr Perl_Tefloatsize_ptr Perl_Terrors_ptr Perl_Textralen_ptr Perl_Tfirstgv_ptr Perl_Tformtarget_ptr Perl_Thv_fetch_ent_mh_ptr Perl_Thv_fetch_sv_ptr Perl_Tin_eval_ptr Perl_Tlast_in_gv_ptr Perl_Tlastgotoprobe_ptr Perl_Tlastscream_ptr Perl_Tlocalizing_ptr Perl_Tmainstack_ptr Perl_Tmarkstack_max_ptr Perl_Tmarkstack_ptr Perl_Tmarkstack_ptr_ptr Perl_Tmaxscream_ptr Perl_Tmodcount_ptr Perl_Tna_ptr Perl_Tnrs_ptr Perl_Tofs_ptr Perl_Tofslen_ptr Perl_Top_ptr Perl_Treg_call_cc_ptr Perl_Treg_curpm_ptr Perl_Treg_eval_set_ptr Perl_Treg_flags_ptr Perl_Treg_ganch_ptr Perl_Treg_leftiter_ptr Perl_Treg_magic_ptr Perl_Treg_maxiter_ptr Perl_Treg_oldcurpm_ptr Perl_Treg_oldpos_ptr Perl_Treg_oldsaved_ptr Perl_Treg_oldsavedlen_ptr Perl_Treg_poscache_ptr Perl_Treg_poscache_size_ptr Perl_Treg_re_ptr Perl_Treg_start_tmp_ptr Perl_Treg_start_tmpl_ptr Perl_Treg_starttry_ptr Perl_Treg_sv_ptr Perl_Treg_whilem_seen_ptr Perl_Tregbol_ptr Perl_Tregcc_ptr Perl_Tregcode_ptr Perl_Tregcomp_parse_ptr Perl_Tregcomp_rx_ptr Perl_Tregcompp_ptr Perl_Tregdata_ptr Perl_Tregdummy_ptr Perl_Tregendp_ptr Perl_Tregeol_ptr Perl_Tregexecp_ptr Perl_Tregflags_ptr Perl_Tregfree_ptr Perl_Tregindent_ptr Perl_Treginput_ptr Perl_Tregint_start_ptr Perl_Tregint_string_ptr Perl_Treginterp_cnt_ptr Perl_Treglastparen_ptr Perl_Tregnarrate_ptr Perl_Tregnaughty_ptr Perl_Tregnpar_ptr Perl_Tregprecomp_ptr Perl_Tregprev_ptr Perl_Tregprogram_ptr Perl_Tregsawback_ptr Perl_Tregseen_ptr Perl_Tregsize_ptr Perl_Tregstartp_ptr Perl_Tregtill_ptr Perl_Tregxend_ptr Perl_Trestartop_ptr Perl_Tretstack_ix_ptr Perl_Tretstack_max_ptr Perl_Tretstack_ptr Perl_Trs_ptr Perl_Tsavestack_ix_ptr Perl_Tsavestack_max_ptr Perl_Tsavestack_ptr Perl_Tscopestack_ix_ptr Perl_Tscopestack_max_ptr Perl_Tscopestack_ptr Perl_Tscreamfirst_ptr Perl_Tscreamnext_ptr Perl_Tsecondgv_ptr Perl_Tseen_evals_ptr Perl_Tseen_zerolen_ptr Perl_Tsortcop_ptr Perl_Tsortcxix_ptr Perl_Tsortstash_ptr Perl_Tstack_base_ptr Perl_Tstack_max_ptr Perl_Tstack_sp_ptr Perl_Tstart_env_ptr Perl_Tstatbuf_ptr Perl_Tstatcache_ptr Perl_Tstatgv_ptr Perl_Tstatname_ptr Perl_Ttainted_ptr Perl_Ttimesbuf_ptr Perl_Ttmps_floor_ptr Perl_Ttmps_ix_ptr Perl_Ttmps_max_ptr Perl_Ttmps_stack_ptr Perl_Ttop_env_ptr Perl_Ttoptarget_ptr Perl_Twatchaddr_ptr Perl_Twatchok_ptr Perl_amagic_call Perl_any_dup Perl_append_elem Perl_append_list Perl_apply Perl_av_clear Perl_av_delete Perl_av_exists Perl_av_extend Perl_av_fake Perl_av_fetch Perl_av_fill Perl_av_len Perl_av_make Perl_av_pop Perl_av_push Perl_av_reify Perl_av_shift Perl_av_store Perl_av_undef Perl_av_unshift Perl_avhv_delete_ent Perl_avhv_exists_ent Perl_avhv_fetch_ent Perl_avhv_iternext Perl_avhv_iterval Perl_avhv_keys Perl_avhv_store_ent Perl_bind_match Perl_block_end Perl_block_gimme Perl_block_start Perl_boot_core_UNIVERSAL Perl_boot_core_xsutils Perl_call_argv Perl_call_atexit Perl_call_list Perl_call_method Perl_call_pv Perl_call_sv Perl_cando Perl_cast_i32 Perl_cast_iv Perl_cast_ulong Perl_cast_uv Perl_ck_anoncode Perl_ck_bitop Perl_ck_concat Perl_ck_defined Perl_ck_delete Perl_ck_eof Perl_ck_eval Perl_ck_exec Perl_ck_exists Perl_ck_exit Perl_ck_ftst Perl_ck_fun Perl_ck_fun_locale Perl_ck_glob Perl_ck_grep Perl_ck_index Perl_ck_join Perl_ck_lengthconst Perl_ck_lfun Perl_ck_listiob Perl_ck_match Perl_ck_method Perl_ck_null Perl_ck_open Perl_ck_repeat Perl_ck_require Perl_ck_rfun Perl_ck_rvconst Perl_ck_sassign Perl_ck_scmp Perl_ck_select Perl_ck_shift Perl_ck_sort Perl_ck_spair Perl_ck_split Perl_ck_subr Perl_ck_svconst Perl_ck_trunc Perl_convert Perl_croak Perl_croak_nocontext Perl_cv_ckproto Perl_cv_clone Perl_cv_const_sv Perl_cv_undef Perl_cx_dump Perl_cx_dup Perl_cxinc Perl_debop Perl_debprofdump Perl_delimcpy Perl_deprecate Perl_die Perl_die_nocontext Perl_die_where Perl_dirp_dup Perl_do_aexec Perl_do_aexec5 Perl_do_binmode Perl_do_chomp Perl_do_chop Perl_do_close Perl_do_eof Perl_do_exec Perl_do_exec3 Perl_do_execfree Perl_do_gv_dump Perl_do_gvgv_dump Perl_do_hv_dump Perl_do_ipcctl Perl_do_ipcget Perl_do_join Perl_do_kv Perl_do_magic_dump Perl_do_msgrcv Perl_do_msgsnd Perl_do_op_dump Perl_do_open Perl_do_open9 Perl_do_pipe Perl_do_pmop_dump Perl_do_print Perl_do_readline Perl_do_seek Perl_do_semop Perl_do_shmio Perl_do_sprintf Perl_do_sv_dump Perl_do_sysseek Perl_do_tell Perl_do_trans Perl_do_vecget Perl_do_vecset Perl_do_vop Perl_dofile Perl_dounwind Perl_dowantarray Perl_dump_all Perl_dump_eval Perl_dump_form Perl_dump_indent Perl_dump_packsubs Perl_dump_sub Perl_dump_vindent Perl_eval_pv Perl_eval_sv Perl_fbm_compile Perl_fbm_instr Perl_filter_add Perl_filter_del Perl_filter_read Perl_find_script Perl_fold_constants Perl_force_list Perl_form Perl_form_nocontext Perl_fp_dup Perl_fprintf_nocontext Perl_free_tmps Perl_gen_constant_list Perl_get_av Perl_get_context Perl_get_cv Perl_get_hv Perl_get_no_modify Perl_get_op_descs Perl_get_op_names Perl_get_opargs Perl_get_ppaddr Perl_get_sv Perl_get_vtbl Perl_getenv_len Perl_gp_dup Perl_gp_free Perl_gp_ref Perl_gv_AVadd Perl_gv_HVadd Perl_gv_IOadd Perl_gv_autoload4 Perl_gv_check Perl_gv_dump Perl_gv_efullname Perl_gv_efullname3 Perl_gv_fetchfile Perl_gv_fetchmeth Perl_gv_fetchmethod Perl_gv_fetchmethod_autoload Perl_gv_fetchpv Perl_gv_fullname Perl_gv_fullname3 Perl_gv_init Perl_gv_stashpv Perl_gv_stashpvn Perl_gv_stashsv Perl_he_dup Perl_huge Perl_hv_clear Perl_hv_delayfree_ent Perl_hv_delete Perl_hv_delete_ent Perl_hv_exists Perl_hv_exists_ent Perl_hv_fetch Perl_hv_fetch_ent Perl_hv_free_ent Perl_hv_iterinit Perl_hv_iterkey Perl_hv_iterkeysv Perl_hv_iternext Perl_hv_iternextsv Perl_hv_iterval Perl_hv_ksplit Perl_hv_magic Perl_hv_store Perl_hv_store_ent Perl_hv_undef Perl_ibcmp Perl_ibcmp_locale Perl_ingroup Perl_init_debugger Perl_init_i18nl10n Perl_init_i18nl14n Perl_init_stacks Perl_instr Perl_intro_my Perl_invert Perl_io_close Perl_is_gv_magical Perl_is_uni_alnum Perl_is_uni_alnum_lc Perl_is_uni_alnumc Perl_is_uni_alnumc_lc Perl_is_uni_alpha Perl_is_uni_alpha_lc Perl_is_uni_ascii Perl_is_uni_ascii_lc Perl_is_uni_cntrl Perl_is_uni_cntrl_lc Perl_is_uni_digit Perl_is_uni_digit_lc Perl_is_uni_graph Perl_is_uni_graph_lc Perl_is_uni_idfirst Perl_is_uni_idfirst_lc Perl_is_uni_lower Perl_is_uni_lower_lc Perl_is_uni_print Perl_is_uni_print_lc Perl_is_uni_punct Perl_is_uni_punct_lc Perl_is_uni_space Perl_is_uni_space_lc Perl_is_uni_upper Perl_is_uni_upper_lc Perl_is_uni_xdigit Perl_is_uni_xdigit_lc Perl_is_utf8_alnum Perl_is_utf8_alnumc Perl_is_utf8_alpha Perl_is_utf8_ascii Perl_is_utf8_char Perl_is_utf8_cntrl Perl_is_utf8_digit Perl_is_utf8_graph Perl_is_utf8_idfirst Perl_is_utf8_lower Perl_is_utf8_mark Perl_is_utf8_print Perl_is_utf8_punct Perl_is_utf8_space Perl_is_utf8_upper Perl_is_utf8_xdigit Perl_jmaybe Perl_keyword Perl_leave_scope Perl_lex_end Perl_lex_start Perl_linklist Perl_list Perl_listkids Perl_load_module Perl_load_module_nocontext Perl_localize Perl_looks_like_number Perl_magic_clear_all_env Perl_magic_clearenv Perl_magic_clearpack Perl_magic_clearsig Perl_magic_dump Perl_magic_existspack Perl_magic_freeregexp Perl_magic_get Perl_magic_getarylen Perl_magic_getdefelem Perl_magic_getglob Perl_magic_getnkeys Perl_magic_getpack Perl_magic_getpos Perl_magic_getsig Perl_magic_getsubstr Perl_magic_gettaint Perl_magic_getuvar Perl_magic_getvec Perl_magic_killbackrefs Perl_magic_len Perl_magic_nextpack Perl_magic_regdata_cnt Perl_magic_regdatum_get Perl_magic_set Perl_magic_set_all_env Perl_magic_setamagic Perl_magic_setarylen Perl_magic_setbm Perl_magic_setcollxfrm Perl_magic_setdbline Perl_magic_setdefelem Perl_magic_setenv Perl_magic_setfm Perl_magic_setglob Perl_magic_setisa Perl_magic_setmglob Perl_magic_setnkeys Perl_magic_setpack Perl_magic_setpos Perl_magic_setsig Perl_magic_setsubstr Perl_magic_settaint Perl_magic_setuvar Perl_magic_setvec Perl_magic_sizepack Perl_magic_wipepack Perl_magicname Perl_markstack_grow Perl_mem_collxfrm Perl_mess Perl_mess_nocontext Perl_mg_clear Perl_mg_copy Perl_mg_dup Perl_mg_find Perl_mg_free Perl_mg_get Perl_mg_length Perl_mg_magical Perl_mg_set Perl_mg_size Perl_mod Perl_mode_from_discipline Perl_moreswitches Perl_my Perl_my_atof Perl_my_attrs Perl_my_exit Perl_my_failure_exit Perl_my_fflush_all Perl_my_lstat Perl_my_pclose Perl_my_popen Perl_my_setenv Perl_my_stat Perl_my_unexec Perl_newANONATTRSUB Perl_newANONHASH Perl_newANONLIST Perl_newANONSUB Perl_newASSIGNOP Perl_newATTRSUB Perl_newAV Perl_newAVREF Perl_newBINOP Perl_newCONDOP Perl_newCONSTSUB Perl_newCVREF Perl_newFORM Perl_newFOROP Perl_newGVOP Perl_newGVREF Perl_newGVgen Perl_newHV Perl_newHVREF Perl_newHVhv Perl_newIO Perl_newLISTOP Perl_newLOGOP Perl_newLOOPEX Perl_newLOOPOP Perl_newMYSUB Perl_newNULLLIST Perl_newOP Perl_newPADOP Perl_newPMOP Perl_newPROG Perl_newPVOP Perl_newRANGE Perl_newRV Perl_newRV_noinc Perl_newSLICEOP Perl_newSTATEOP Perl_newSUB Perl_newSV Perl_newSVOP Perl_newSVREF Perl_newSViv Perl_newSVnv Perl_newSVpv Perl_newSVpvf Perl_newSVpvf_nocontext Perl_newSVpvn Perl_newSVrv Perl_newSVsv Perl_newSVuv Perl_newUNOP Perl_newWHILEOP Perl_newXS Perl_new_collate Perl_new_ctype Perl_new_numeric Perl_new_stackinfo Perl_nextargv Perl_ninstr Perl_oopsAV Perl_oopsCV Perl_oopsHV Perl_op_const_sv Perl_op_dump Perl_op_free Perl_package Perl_pad_alloc Perl_pad_allocmy Perl_pad_findmy Perl_pad_free Perl_pad_leavemy Perl_pad_reset Perl_pad_sv Perl_pad_swipe Perl_peep Perl_pidgone Perl_pmflag Perl_pmop_dump Perl_pmruntime Perl_pmtrans Perl_pop_return Perl_pop_scope Perl_pp_aassign Perl_pp_abs Perl_pp_accept Perl_pp_add Perl_pp_aelem Perl_pp_aelemfast Perl_pp_alarm Perl_pp_and Perl_pp_andassign Perl_pp_anoncode Perl_pp_anonhash Perl_pp_anonlist Perl_pp_aslice Perl_pp_atan2 Perl_pp_av2arylen Perl_pp_backtick Perl_pp_bind Perl_pp_binmode Perl_pp_bit_and Perl_pp_bit_or Perl_pp_bit_xor Perl_pp_bless Perl_pp_caller Perl_pp_chdir Perl_pp_chmod Perl_pp_chomp Perl_pp_chop Perl_pp_chown Perl_pp_chr Perl_pp_chroot Perl_pp_close Perl_pp_closedir Perl_pp_complement Perl_pp_concat Perl_pp_cond_expr Perl_pp_connect Perl_pp_const Perl_pp_cos Perl_pp_crypt Perl_pp_dbmclose Perl_pp_dbmopen Perl_pp_dbstate Perl_pp_defined Perl_pp_delete Perl_pp_die Perl_pp_divide Perl_pp_dofile Perl_pp_dump Perl_pp_each Perl_pp_egrent Perl_pp_ehostent Perl_pp_enetent Perl_pp_enter Perl_pp_entereval Perl_pp_enteriter Perl_pp_enterloop Perl_pp_entersub Perl_pp_entertry Perl_pp_enterwrite Perl_pp_eof Perl_pp_eprotoent Perl_pp_epwent Perl_pp_eq Perl_pp_eservent Perl_pp_exec Perl_pp_exists Perl_pp_exit Perl_pp_exp Perl_pp_fcntl Perl_pp_fileno Perl_pp_flip Perl_pp_flock Perl_pp_flop Perl_pp_fork Perl_pp_formline Perl_pp_ftatime Perl_pp_ftbinary Perl_pp_ftblk Perl_pp_ftchr Perl_pp_ftctime Perl_pp_ftdir Perl_pp_fteexec Perl_pp_fteowned Perl_pp_fteread Perl_pp_ftewrite Perl_pp_ftfile Perl_pp_ftis Perl_pp_ftlink Perl_pp_ftmtime Perl_pp_ftpipe Perl_pp_ftrexec Perl_pp_ftrowned Perl_pp_ftrread Perl_pp_ftrwrite Perl_pp_ftsgid Perl_pp_ftsize Perl_pp_ftsock Perl_pp_ftsuid Perl_pp_ftsvtx Perl_pp_fttext Perl_pp_fttty Perl_pp_ftzero Perl_pp_ge Perl_pp_gelem Perl_pp_getc Perl_pp_getlogin Perl_pp_getpeername Perl_pp_getpgrp Perl_pp_getppid Perl_pp_getpriority Perl_pp_getsockname Perl_pp_ggrent Perl_pp_ggrgid Perl_pp_ggrnam Perl_pp_ghbyaddr Perl_pp_ghbyname Perl_pp_ghostent Perl_pp_glob Perl_pp_gmtime Perl_pp_gnbyaddr Perl_pp_gnbyname Perl_pp_gnetent Perl_pp_goto Perl_pp_gpbyname Perl_pp_gpbynumber Perl_pp_gprotoent Perl_pp_gpwent Perl_pp_gpwnam Perl_pp_gpwuid Perl_pp_grepstart Perl_pp_grepwhile Perl_pp_gsbyname Perl_pp_gsbyport Perl_pp_gservent Perl_pp_gsockopt Perl_pp_gt Perl_pp_gv Perl_pp_gvsv Perl_pp_helem Perl_pp_hex Perl_pp_hslice Perl_pp_i_add Perl_pp_i_divide Perl_pp_i_eq Perl_pp_i_ge Perl_pp_i_gt Perl_pp_i_le Perl_pp_i_lt Perl_pp_i_modulo Perl_pp_i_multiply Perl_pp_i_ncmp Perl_pp_i_ne Perl_pp_i_negate Perl_pp_i_subtract Perl_pp_index Perl_pp_int Perl_pp_ioctl Perl_pp_iter Perl_pp_join Perl_pp_keys Perl_pp_kill Perl_pp_last Perl_pp_lc Perl_pp_lcfirst Perl_pp_le Perl_pp_leave Perl_pp_leaveeval Perl_pp_leaveloop Perl_pp_leavesub Perl_pp_leavesublv Perl_pp_leavetry Perl_pp_leavewrite Perl_pp_left_shift Perl_pp_length Perl_pp_lineseq Perl_pp_link Perl_pp_list Perl_pp_listen Perl_pp_localtime Perl_pp_lock Perl_pp_log Perl_pp_lslice Perl_pp_lstat Perl_pp_lt Perl_pp_mapstart Perl_pp_mapwhile Perl_pp_match Perl_pp_method Perl_pp_method_named Perl_pp_mkdir Perl_pp_modulo Perl_pp_msgctl Perl_pp_msgget Perl_pp_msgrcv Perl_pp_msgsnd Perl_pp_multiply Perl_pp_ncmp Perl_pp_ne Perl_pp_negate Perl_pp_next Perl_pp_nextstate Perl_pp_not Perl_pp_null Perl_pp_oct Perl_pp_open Perl_pp_open_dir Perl_pp_or Perl_pp_orassign Perl_pp_ord Perl_pp_pack Perl_pp_padany Perl_pp_padav Perl_pp_padhv Perl_pp_padsv Perl_pp_pipe_op Perl_pp_pop Perl_pp_pos Perl_pp_postdec Perl_pp_postinc Perl_pp_pow Perl_pp_predec Perl_pp_preinc Perl_pp_print Perl_pp_prototype Perl_pp_prtf Perl_pp_push Perl_pp_pushmark Perl_pp_pushre Perl_pp_qr Perl_pp_quotemeta Perl_pp_rand Perl_pp_range Perl_pp_rcatline Perl_pp_read Perl_pp_readdir Perl_pp_readline Perl_pp_readlink Perl_pp_recv Perl_pp_redo Perl_pp_ref Perl_pp_refgen Perl_pp_regcmaybe Perl_pp_regcomp Perl_pp_regcreset Perl_pp_rename Perl_pp_repeat Perl_pp_require Perl_pp_reset Perl_pp_return Perl_pp_reverse Perl_pp_rewinddir Perl_pp_right_shift Perl_pp_rindex Perl_pp_rmdir Perl_pp_rv2av Perl_pp_rv2cv Perl_pp_rv2gv Perl_pp_rv2hv Perl_pp_rv2sv Perl_pp_sassign Perl_pp_scalar Perl_pp_schomp Perl_pp_schop Perl_pp_scmp Perl_pp_scope Perl_pp_seek Perl_pp_seekdir Perl_pp_select Perl_pp_semctl Perl_pp_semget Perl_pp_semop Perl_pp_send Perl_pp_seq Perl_pp_setpgrp Perl_pp_setpriority Perl_pp_setstate Perl_pp_sge Perl_pp_sgrent Perl_pp_sgt Perl_pp_shift Perl_pp_shmctl Perl_pp_shmget Perl_pp_shmread Perl_pp_shmwrite Perl_pp_shostent Perl_pp_shutdown Perl_pp_sin Perl_pp_sle Perl_pp_sleep Perl_pp_slt Perl_pp_sne Perl_pp_snetent Perl_pp_socket Perl_pp_sockpair Perl_pp_sort Perl_pp_splice Perl_pp_split Perl_pp_sprintf Perl_pp_sprotoent Perl_pp_spwent Perl_pp_sqrt Perl_pp_srand Perl_pp_srefgen Perl_pp_sselect Perl_pp_sservent Perl_pp_ssockopt Perl_pp_stat Perl_pp_stringify Perl_pp_stub Perl_pp_study Perl_pp_subst Perl_pp_substcont Perl_pp_substr Perl_pp_subtract Perl_pp_symlink Perl_pp_syscall Perl_pp_sysopen Perl_pp_sysread Perl_pp_sysseek Perl_pp_system Perl_pp_syswrite Perl_pp_tell Perl_pp_telldir Perl_pp_threadsv Perl_pp_tie Perl_pp_tied Perl_pp_time Perl_pp_tms Perl_pp_trans Perl_pp_truncate Perl_pp_uc Perl_pp_ucfirst Perl_pp_umask Perl_pp_undef Perl_pp_unlink Perl_pp_unpack Perl_pp_unshift Perl_pp_unstack Perl_pp_untie Perl_pp_utime Perl_pp_values Perl_pp_vec Perl_pp_wait Perl_pp_waitpid Perl_pp_wantarray Perl_pp_warn Perl_pp_xor Perl_pregcomp Perl_pregexec Perl_pregfree Perl_prepend_elem Perl_ptr_table_fetch Perl_ptr_table_new Perl_ptr_table_split Perl_ptr_table_store Perl_push_return Perl_push_scope Perl_pv_display Perl_qerror Perl_re_dup Perl_re_intuit_start Perl_re_intuit_string Perl_ref Perl_refkids Perl_regdump Perl_regexec_flags Perl_reginitcolors Perl_regnext Perl_regprop Perl_repeatcpy Perl_report_closed_fh Perl_report_uninit Perl_require_pv Perl_rninstr Perl_rsignal Perl_rsignal_restore Perl_rsignal_save Perl_rsignal_state Perl_runops_debug Perl_runops_standard Perl_rxres_free Perl_rxres_restore Perl_rxres_save Perl_safesyscalloc Perl_safesysfree Perl_safesysmalloc Perl_safesysrealloc Perl_save_I16 Perl_save_I32 Perl_save_I8 Perl_save_aelem Perl_save_alloc Perl_save_aptr Perl_save_ary Perl_save_clearsv Perl_save_delete Perl_save_destructor Perl_save_destructor_x Perl_save_freeop Perl_save_freepv Perl_save_freesv Perl_save_generic_pvref Perl_save_generic_svref Perl_save_gp Perl_save_hash Perl_save_helem Perl_save_hints Perl_save_hptr Perl_save_int Perl_save_item Perl_save_iv Perl_save_list Perl_save_long Perl_save_nogv Perl_save_op Perl_save_pptr Perl_save_re_context Perl_save_scalar Perl_save_sptr Perl_save_svref Perl_save_threadsv Perl_save_vptr Perl_savepv Perl_savepvn Perl_savestack_grow Perl_sawparens Perl_scalar Perl_scalarkids Perl_scalarseq Perl_scalarvoid Perl_scan_bin Perl_scan_hex Perl_scan_num Perl_scan_oct Perl_scope Perl_screaminstr Perl_set_context Perl_set_numeric_local Perl_set_numeric_radix Perl_set_numeric_standard Perl_setdefout Perl_setenv_getix Perl_share_hek Perl_sharepvn Perl_si_dup Perl_sighandler Perl_ss_dup Perl_stack_grow Perl_start_subparse Perl_str_to_version Perl_sub_crush_depth Perl_sv_2bool Perl_sv_2cv Perl_sv_2io Perl_sv_2iv Perl_sv_2mortal Perl_sv_2nv Perl_sv_2pv Perl_sv_2pv_nolen Perl_sv_2pvbyte Perl_sv_2pvbyte_nolen Perl_sv_2pvutf8 Perl_sv_2pvutf8_nolen Perl_sv_2uv Perl_sv_add_arena Perl_sv_backoff Perl_sv_bless Perl_sv_catpv Perl_sv_catpv_mg Perl_sv_catpvf Perl_sv_catpvf_mg Perl_sv_catpvf_mg_nocontext Perl_sv_catpvf_nocontext Perl_sv_catpvn Perl_sv_catpvn_mg Perl_sv_catsv Perl_sv_catsv_mg Perl_sv_chop Perl_sv_clean_all Perl_sv_clean_objs Perl_sv_clear Perl_sv_cmp Perl_sv_cmp_locale Perl_sv_collxfrm Perl_sv_compile_2op Perl_sv_dec Perl_sv_derived_from Perl_sv_dump Perl_sv_dup Perl_sv_eq Perl_sv_force_normal Perl_sv_free Perl_sv_free_arenas Perl_sv_gets Perl_sv_grow Perl_sv_inc Perl_sv_insert Perl_sv_isa Perl_sv_isobject Perl_sv_iv Perl_sv_len Perl_sv_len_utf8 Perl_sv_magic Perl_sv_mortalcopy Perl_sv_newmortal Perl_sv_newref Perl_sv_nv Perl_sv_peek Perl_sv_pos_b2u Perl_sv_pos_u2b Perl_sv_pv Perl_sv_pvbyte Perl_sv_pvbyten Perl_sv_pvbyten_force Perl_sv_pvn Perl_sv_pvn_force Perl_sv_pvutf8 Perl_sv_pvutf8n Perl_sv_pvutf8n_force Perl_sv_reftype Perl_sv_replace Perl_sv_report_used Perl_sv_reset Perl_sv_rvweaken Perl_sv_setiv Perl_sv_setiv_mg Perl_sv_setnv Perl_sv_setnv_mg Perl_sv_setpv Perl_sv_setpv_mg Perl_sv_setpvf Perl_sv_setpvf_mg Perl_sv_setpvf_mg_nocontext Perl_sv_setpvf_nocontext Perl_sv_setpviv Perl_sv_setpviv_mg Perl_sv_setpvn Perl_sv_setpvn_mg Perl_sv_setref_iv Perl_sv_setref_nv Perl_sv_setref_pv Perl_sv_setref_pvn Perl_sv_setsv Perl_sv_setsv_mg Perl_sv_setuv Perl_sv_setuv_mg Perl_sv_taint Perl_sv_tainted Perl_sv_true Perl_sv_unmagic Perl_sv_unref Perl_sv_untaint Perl_sv_upgrade Perl_sv_usepvn Perl_sv_usepvn_mg Perl_sv_utf8_decode Perl_sv_utf8_downgrade Perl_sv_utf8_encode Perl_sv_utf8_upgrade Perl_sv_uv Perl_sv_vcatpvf Perl_sv_vcatpvf_mg Perl_sv_vcatpvfn Perl_sv_vsetpvf Perl_sv_vsetpvf_mg Perl_sv_vsetpvfn Perl_swash_fetch Perl_swash_init Perl_taint_env Perl_taint_proper Perl_tmps_grow Perl_to_uni_lower Perl_to_uni_lower_lc Perl_to_uni_title Perl_to_uni_title_lc Perl_to_uni_upper Perl_to_uni_upper_lc Perl_to_utf8_lower Perl_to_utf8_title Perl_to_utf8_upper Perl_unshare_hek Perl_unsharepvn Perl_utf16_to_utf8 Perl_utf16_to_utf8_reversed Perl_utf8_distance Perl_utf8_hop Perl_utf8_to_uv Perl_utilize Perl_uv_to_utf8 Perl_vcroak Perl_vdie Perl_vform Perl_vivify_defelem Perl_vivify_ref Perl_vload_module Perl_vmess Perl_vnewSVpvf Perl_vwarn Perl_vwarner Perl_wait4pid Perl_warn Perl_warn_nocontext Perl_warner Perl_warner_nocontext Perl_watch Perl_whichsig Perl_yyerror Perl_yylex Perl_yyparse Perl_yywarn S_add_data S_ao S_apply_attrs S_asIV S_asUV S_avhv_index S_avhv_index_sv S_bad_type S_cache_re S_call_body S_call_list_body S_check_uni S_checkcomma S_checkposixcc S_cl_and S_cl_anything S_cl_init S_cl_init_zero S_cl_is_anything S_cl_or S_cop_free S_cv_clone2 S_cv_dump S_debprof S_del_he S_del_xiv S_del_xnv S_del_xpv S_del_xpvav S_del_xpvbm S_del_xpvcv S_del_xpvhv S_del_xpviv S_del_xpvlv S_del_xpvmg S_del_xpvnv S_del_xrv S_depcom S_div128 S_do_maybe_phash S_do_oddball S_do_trans_CC_complex S_do_trans_CC_count S_do_trans_CC_simple S_do_trans_CU_simple S_do_trans_CU_trivial S_do_trans_UC_simple S_do_trans_UC_trivial S_do_trans_UU_complex S_do_trans_UU_count S_do_trans_UU_simple S_docatch S_docatch_body S_doencodes S_doeval S_dofindlabel S_doform S_doopen_pmc S_doparseform S_dopoptoeval S_dopoptolabel S_dopoptoloop S_dopoptosub S_dopoptosub_at S_dumpuntil S_dup_attrlist S_emulate_eaccess S_filter_gets S_find_beginning S_find_byclass S_forbid_setid S_force_ident S_force_next S_force_version S_force_word S_free_closures S_get_db_sub S_gv_ename S_gv_init_sv S_hfreeentries S_hsplit S_hv_magic_check S_incl_perldb S_incline S_incpush S_init_ids S_init_interp S_init_lexer S_init_main_stash S_init_perllib S_init_postdump_symbols S_init_predump_symbols S_intuit_method S_intuit_more S_is_an_int S_is_handle_constructor S_isa_lookup S_list_assignment S_lop S_magic_methcall S_magic_methpack S_mess_alloc S_method_common S_missingterm S_modkids S_more_he S_more_sv S_more_xiv S_more_xnv S_more_xpv S_more_xpvav S_more_xpvbm S_more_xpvcv S_more_xpvhv S_more_xpviv S_more_xpvlv S_more_xpvmg S_more_xpvnv S_more_xrv S_mul128 S_my_exit_jump S_my_kid S_newDEFSVOP S_new_constant S_new_he S_new_logop S_new_xiv S_new_xnv S_new_xpv S_new_xpvav S_new_xpvbm S_new_xpvcv S_new_xpvhv S_new_xpviv S_new_xpvlv S_new_xpvmg S_new_xpvnv S_new_xrv S_nextchar S_no_bareword_allowed S_no_fh_allowed S_no_op S_not_a_number S_nuke_stacks S_null S_op_clear S_open_script S_pad_addlex S_pad_findlex S_parse_body S_put_byte S_qsortsv S_re_croak2 S_refto S_reg S_reg_node S_reganode S_regatom S_regbranch S_regclass S_regclassutf8 S_regcp_set_to S_regcppop S_regcppush S_regcurly S_reghop S_reghopmaybe S_reginclass S_reginclassutf8 S_reginsert S_regmatch S_regoptail S_regpiece S_regpposixcc S_regrepeat S_regrepeat_hard S_regtail S_regtry S_reguni S_regwhite S_run_body S_save_hek S_save_lines S_save_magic S_save_scalar_at S_scalar_mod_type S_scalarboolean S_scan_commit S_scan_const S_scan_formline S_scan_heredoc S_scan_ident S_scan_inputsymbol S_scan_pat S_scan_str S_scan_subst S_scan_trans S_scan_word S_seed S_set_csh S_simplify_sort S_skipspace S_study_chunk S_sublex_done S_sublex_push S_sublex_start S_sv_add_backref S_sv_del_backref S_sv_unglob S_tokeq S_too_few_arguments S_too_many_arguments S_usage S_validate_suid S_visit SaveError XS_DynaLoader_dl_error XS_DynaLoader_dl_find_symbol XS_DynaLoader_dl_install_xsub XS_DynaLoader_dl_load_file XS_DynaLoader_dl_undef_symbols XS_DynaLoader_dl_unload_file XS_UNIVERSAL_VERSION XS_UNIVERSAL_can XS_UNIVERSAL_isa XS_attributes__fetch_attrs XS_attributes__guess_stash XS_attributes__modify_attrs XS_attributes__warn_reserved XS_attributes_bootstrap XS_attributes_reftype _DYNAMIC _GLOBAL_OFFSET_TABLE_ _IO_getc _IO_stdin_used __CTOR_END__ __CTOR_LIST__ __DTOR_END__ __DTOR_LIST__ __EH_FRAME_BEGIN__ __FRAME_END__ __bss_start __ctype_b __ctype_tolower __ctype_toupper __data_start __deregister_frame_info __do_global_ctors_aux __do_global_dtors_aux __environ __errno_location __fxstat64 __gmon_start__ __h_errno_location __libc_start_main __lxstat64 __rawmemchr __register_frame_info __sigsetjmp __strtod_internal __strtol_internal __strtoul_internal __xstat64 _edata _end _exit _fini _fp_hw _init _start accept access alarm amagic_cmp amagic_cmp_locale amagic_i_ncmp amagic_ncmp autolen.565 autoload.564 bases.662 bind boot_DynaLoader chdir chmod chown chroot clear_re clearerr close closedir completed.4 connect crypt data_start dayname.870 dgd.627 dl_generic_private_init dl_nonlazy dl_private_init dl_unload_all_files dlclose dlerror dlopen dlsym do_clean_all do_clean_named_objs do_clean_objs do_report_used drand48 dup dup2 endgrent endhostent endnetent endprotoent endpwent endservent endspent environ execl execv execvp exit fchmod fchown fclose fcntl fdopen feof ferror fflush fileno fini_dummy flock fopen64 force_to_data fork fprintf fputc fputs frame_dummy fread free frexp fseeko64 ftello64 ftruncate64 fwrite gcc2_compiled. gcvt getegid getenv geteuid getgid getgrent getgrgid getgrnam getgroups gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr getnetbyname getnetent getpeername getpgid getpid getppid getpriority getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid getservbyname getservbyport getservent getsockname getsockopt getspent getspnam gettimeofday getuid gmtime ident_too_long init_dummy ioctl isatty kill killpg link listen local_patches localeconv localtime lseek64 main malloc maxima.664 memcpy memmove memset misc_env.540 mkdir modf modify_SV_attributes monname.871 msgctl msgget msgrcv msgsnd must_have_label.671 my_perl null10.891 nullstr.1044 number_too_long.660 nvshift.661 object.11 open64 opendir p.3 parens.570 pause perl_alloc perl_clone perl_construct perl_destruct perl_free perl_parse perl_run pipe prefix.615 printf pthread_getspecific pthread_key_create pthread_mutex_destroy pthread_mutex_init pthread_mutex_lock pthread_mutex_unlock pthread_setspecific qsort read read_e_script readdir64 readlink realloc recvfrom reg_off_by_arg regarglen rename restore_magic restore_pos restore_rsfp rewinddir rmdir run_user_filter seekdir select semctl semget semop send sendto setegid seteuid setgrent setgroups sethostent setlinebuf setlocale setnetent setpgid setpriority setprotoent setpwent setregid setresgid setresuid setreuid setservent setsockopt setspent shmat shmctl shmdt shmget shutdown sig_sv sigaction sigemptyset siglongjmp sleep socket socketpair sortcv sortcv_stacked sortcv_xsub space10.892 sprintf srand48 stderr stdin stdout strcat strchr strcmp strcpy strerror strncmp strncpy strrchr strxfrm sv_i_ncmp sv_ncmp symlink syscall telldir time times tmpfile64 tmpfp too_deep.664 truncate64 uiv_2buf umask ungetc unlink unwind_handler_stack usage_msg.603 utf8compare utime vfprintf vsprintf waitpid write xs_init yycheck yydefred yydestruct yydgoto yygindex yylen yylhs yyrindex yysccsid yysindex yytable zero_but_true zero_scan_data Inline-0.53/t/0000755000076400010400000000000012140062610014562 5ustar sisyphusAdministratorsInline-0.53/t/00init.t0000644000076400010400000000014712052612400016054 0ustar sisyphusAdministratorsuse strict; use Test; mkdir('_Inline_test', 0777) unless -e '_Inline_test'; plan(tests => 1); ok(1); Inline-0.53/t/01usages.t0000644000076400010400000000300212052612400016372 0ustar sisyphusAdministratorsuse File::Spec; use lib (File::Spec->catdir(File::Spec->curdir(),'blib','lib'), File::Spec->curdir()); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; BEGIN { plan(tests => 7, todo => [], onfail => sub {}, ); } use Inline Config => DIRECTORY => '_Inline_test'; # test 1 # Make sure that the syntax for reading external files works. use Inline Foo => File::Spec->catfile(File::Spec->curdir(),'t','file'); ok(test1('test1')); # test 2 & 3 # Make sure that data files work use Inline Foo => 'DATA'; ok(test2('test2')); use Inline 'Foo'; ok(not test3('test3')); # test 4 # Make sure string form works ok(test4('test4')); use Inline Foo => <<'END_OF_FOO'; foo-sub test4 { foo-return $_[0] foo-eq 'test4'; } END_OF_FOO # test 5 # Make sure language name aliases work ('foo' instead of 'Foo') ok(test5('test5')); use Inline foo => <<'END_OF_FOO'; foo-sub test5 { foo-return $_[0] foo-eq 'test5'; } END_OF_FOO # test 6 # Make sure Inline->init works eval <<'END'; use Inline Foo => 'DATA'; Inline->init; ok(add(3, 7) == 10); END print "$@\nnot ok 1\n" if $@; # test 7 # Make sure bind works eval <<'END'; Inline->bind(Foo => <<'EOFOO'); foo-sub subtract { foo-return $_[0] foo-- $_[1]; } EOFOO ok(subtract(3, 7) == -4); END print "$@\nnot ok 2\n" if $@; __END__ __Foo__ # Inline Foo file foo-sub test2 { foo-return $_[0] foo-eq 'test2'; } __Foo__ foo-sub test3 { foo-return $_[0] foo-eq 'yrlnry'; } __Foo__ foo-sub add { foo-return $_[0] foo-+ $_[1]; } Inline-0.53/t/02config.t0000644000076400010400000000122312052612400016354 0ustar sisyphusAdministratorsuse File::Spec; use lib (File::Spec->catdir(File::Spec->curdir(),'blib','lib'), File::Spec->curdir()); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; BEGIN { plan(tests => 2, todo => [], onfail => sub {}, ); } # test 1 # Make sure ENABLE works ok(test1('test1')); use Inline Foo => <<'END_OF_FOO', ENABLE => 'BAR'; foo-sub test1 { bar-return $_[0] bar-eq 'test1'; } END_OF_FOO # test 2 # Make sure PATTERN works ok(test2('test2')); use Inline Foo => Config => ENABLE => 'BAR'; use Inline Foo => <<'END_OF_FOO', PATTERN => 'gogo-'; gogo-sub test2 { bar-return $_[0] gogo-eq 'test2'; } END_OF_FOO Inline-0.53/t/03errors.t0000644000076400010400000000150112052612400016423 0ustar sisyphusAdministratorsuse File::Spec; use lib (File::Spec->catdir(File::Spec->curdir(),'blib','lib'), File::Spec->curdir()); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; BEGIN { plan(tests => 3, todo => [], onfail => sub {}, ); } # test 1 # Bad first parameter BEGIN { eval <<'END'; use Inline 'Bogus' => 'code'; END ok($@ =~ /\QYou have specified 'Bogus' as an Inline programming language. I currently only know about the following languages:/); } # test 2 # Bad shortcut BEGIN { eval <<'END'; use Inline 'force', 'hocum'; END ok($@ =~ /\Q${\ Inline::M48_usage_shortcuts('hocum')}/); } # test 3 # Bad config option BEGIN { eval <<'END'; require Inline::Foo; use Inline Foo => 'xxx' => ENABLE => 'BOGUM'; END ok($@ =~ Inline::Foo::usage_config('BOGUM')); } Inline-0.53/t/04create.t0000644000076400010400000000075112052612400016361 0ustar sisyphusAdministratorsuse File::Spec; use lib (File::Spec->catdir(File::Spec->curdir(),'blib','lib'), File::Spec->curdir()); use strict; use Test; use diagnostics; BEGIN { plan(tests => 1, todo => [], onfail => sub {}, ); delete $ENV{PERL_INLINE_DIRECTORY}; delete $ENV{HOME}; } # test 1 # Make sure Inline can generate a new _Inline/ directory. # (But make sure it's in our own space.) use Inline 'Foo'; ok(add(3, 7) == 10); __END__ __Foo__ foo-sub add { foo-return $_[0] + $_[1]; } Inline-0.53/t/05files.t0000644000076400010400000000124012052612400016213 0ustar sisyphusAdministratorsuse File::Spec; use lib (File::Spec->catdir(File::Spec->curdir(),'blib','lib'), File::Spec->curdir()); use strict; use Test; use diagnostics; use Inline Config => DIRECTORY => '_Inline_test'; BEGIN { eval "require Inline::Files"; if($@) { warn "Skipping - couldn't load the Inline::Files module\n"; print "1..1\nok 1\n"; exit 0; } } use Inline::Files; BEGIN { plan(tests => 1, todo => [], onfail => sub {}, ); } use Inline Config => DIRECTORY => '_Inline_test'; # test 1 # Make sure that Inline::Files support works use Inline Foo => 'BELOW'; ok(test1('test1')); __FOO__ foo-sub test1 { foo-return $_[0] foo-eq 'test1'; } Inline-0.53/t/06rewrite_config.p0000644000076400010400000000036112052612400020117 0ustar sisyphusAdministratorsInline->init() ; use Inline Config => DIRECTORY => '_Inline_test', _TESTING => 1, REWRITE_CONFIG_FILE => 1; use Inline 'Foo'; is(add(3, 7), 10, 'foo test'); 1; __DATA__ __Foo__ foo-sub add { foo-return $_[0] + $_[1]; } Inline-0.53/t/06rewrite_config.t0000644000076400010400000000073212052612400020125 0ustar sisyphusAdministratorsBEGIN { if($] < 5.007) { print "1..1\n"; warn "Skipped for perl 5.6.x\n"; print "ok 1\n"; exit(0); } }; use warnings; use strict; use Test::More tests => 2; use Test::Warn; # Suppress "Set up gcc environment ..." warning. # (Affects ActivePerl only.) $ENV{ACTIVEPERL_CONFIG_SILENT} = 1; my $w = 'config file removal successful'; warnings_like {require_rewrite()} [qr/$w/], 'warn_test'; sub require_rewrite { require './t/06rewrite_config.p'; } Inline-0.53/t/07rewrite2_config.p0000644000076400010400000000021012052612400020173 0ustar sisyphusAdministratorsInline->init() ; use Inline Config => DIRECTORY => '_Inline_test', _TESTING => 1; use Inline Bogus => <<'EOB'; foo(){} EOB Inline-0.53/t/07rewrite2_config.t0000644000076400010400000000077012052612400020212 0ustar sisyphusAdministratorsBEGIN { if($] < 5.007) { print "1..1\n"; warn "Skipped for perl 5.6.x\n"; print "ok 1\n"; exit(0); } }; use warnings; use strict; use Test::More tests => 2; use Test::Warn; # Suppress "Set up gcc environment ..." warning. # (Affects ActivePerl only.) $ENV{ACTIVEPERL_CONFIG_SILENT} = 1; my $w = 'config file removed'; warnings_like {require_rewrite()} [qr/$w/], 'warn_test'; ok($@, '"Inline Bogus" test'); sub require_rewrite { eval {require './t/07rewrite2_config.p';}; } Inline-0.53/t/file0000644000076400010400000000011212052612400015416 0ustar sisyphusAdministrators# Inline Foo file foo-sub test1 { foo-return $_[0] foo-eq 'test1'; } Inline-0.53/ToDo0000644000076400010400000000557012052612400015116 0ustar sisyphusAdministrators# 0.44 To Do List done: - Mark Fowler fix: > This fix involves calling validate() even when build() is not called. It affects only the interpreted ILSMs - Fix grammars to handle 'const' etc. - Allow other module languages besides C. (Esp C++) - Inline::MakeMaker replacement: > This rewrite is completed for the core Inline. Should be easy to bring over. - Add a patch from Rafael Garcia-Suarez that uses $^X when $Config{perlpath} is wrong. (0.44/patch4) - Test the recursive build suite - Change the way that error output is displayed. - use File::Spec: > It is top priority to turn all file path operations under the control of File::Spec, so that Inline can be ported to other platforms. - Apply Mitchell's File::Spec patch - Copy Regex::Common regexps to charity.pm - Mitchell Charity patch: > Mitchell wrote a drop in replacement for the Parse::RecDescent one. This needs to be moved to Inline::C::ParserRegexp - Add USING parameter to specify a list of classes for Inline to inherit replacement functionality to. - Add a WARNINGS option (default to 1) - Add more build warnings for NOISY - Add BUILD_TIMERS (TIMERS) - Email Mark Fowler with typemap idea - Change the precision of Time::HiRes messages. - INFO option causes parse to fail - Documentation review High priority: * Fix installation problem with lesser ILSMs reported by Mitchell. - Patch perlcall example in Cookbook to be safer. This requires calls outside the Inline Stack Macros. - Allow *.h typemap *.c from cwd() to work without full pathnames - Support COPY_TO_BUILD => [ '*.c', 'typemap', 'foo.h' ] - Warn when non-static functions don't bind. - Warn if no functions were bound at all - int foo(...) hack - add 'int foo(void) {' - Support the types that Nicholas reported - Allow spaces in path names Medium Priority: - Add an Inline typemap to replace the Ext::Utils one - Redo the test suite to be faster. Eliminate duplicate tests. - Apply user patches - Regression tests: > These can be run outside of make test. They can use YAML, etc. - Investigate not needing the .inl files for dummy targets in Inline::MakeMaker - Try to support lib/ in Inline::MakeMaker - Eliminate Inline::denter with a simple regexp parser and heredoc emitter Lower Priority: - Relative paths need to be resolved in relation to the cwd rather than the Inline build directory. - Inline/Inline::Devel/Inline::Build split: This needs to happen soon. Maybe in 0.45. - Remove the 'config' complexity - Make #line numbers resolve to Perl code. Bugs: Next Release: - Rewrite the Inline API macros: - Possible cross-compatibility with Python/Ruby - Support Attribute::Handlers - Inline::TT/WebChat have install probs: The following fixes it: #local $ENV{PERL5LIB} if defined $ENV{PERL5LIB};