summaryrefslogtreecommitdiff
path: root/usub/README
diff options
context:
space:
mode:
Diffstat (limited to 'usub/README')
-rw-r--r--usub/README110
1 files changed, 110 insertions, 0 deletions
diff --git a/usub/README b/usub/README
new file mode 100644
index 0000000000..ffaefd1ef4
--- /dev/null
+++ b/usub/README
@@ -0,0 +1,110 @@
+This directory contains an example of how you might link in C subroutines
+with perl to make your own special copy of perl. In the perl distribution
+directory, there will be (after make is run) a file called uperl.o, which
+is all of perl except for a single undefined subroutine, named userinit().
+See usersub.c.
+
+The sole purpose of the userinit() routine is to call the initialization
+routines for any modules that you want to link in. In this example, we just
+call init_curses(), which sets up to link in the BSD curses routines.
+You'll find this in the file curses.c, which is the processed output of
+curses.mus.
+
+The magicname() routine adds variable names into the symbol table. Along
+with the name of the variable as Perl knows it, we pass a structure containing
+an index identifying the variable, and the names of two C functions that
+know how to set or evaluate a variable given the index of the variable.
+Our example uses a macro to handle this conveniently.
+
+The init routine calls make_usub() to add user-defined subroutine names
+into the symbol table. The arguments are
+
+ make_usub(subname, subindex, subfunc, filename);
+ char *subname;
+ int subindex;
+ int subfunc();
+ char *filename;
+
+The subname is the name that will be used in the Perl program. The subindex
+will be passed to subfunc() when it is called to tell it which C function
+is desired. subfunc() is a glue routine that translates the arguments
+from Perl internal stack form to the form required by the routine in
+question, calls the desired C function, and then translates any return
+value back into the stack format. The glue routine used by curses just
+has a large switch statement, each branch of which does the processing
+for a particular C function. The subindex could, however, be used to look
+up a function in a dynamically linked library. No example of this is
+provided.
+
+As a help in producing the glue routine, a preprocessor called "mus" lets
+you specify argument and return value types in a tabular format. An entry
+such as:
+
+ CASE int waddstr
+ I WINDOW* win
+ I char* str
+ END
+
+indicates that waddstr takes two input arguments, the first of which is a
+pointer to a window, and the second of which is an ordinary C string. It
+also indicates that an integer is returned. The mus program turns this into:
+
+ case US_waddstr:
+ if (items != 2)
+ fatal("Usage: &waddstr($win, $str)");
+ else {
+ int retval;
+ WINDOW* win = *(WINDOW**) str_get(st[1]);
+ char* str = (char*) str_get(st[2]);
+
+ retval = waddstr(win, str);
+ str_numset(st[0], (double) retval);
+ }
+ return sp;
+
+It's also possible to have output parameters, indicated by O, and input/ouput
+parameters indicated by IO.
+
+The mus program isn't perfect. You'll note that curses.mus has some
+cases which are hand coded. They'll be passed straight through unmodified.
+You can produce similar cases by analogy to what's in curses.c, as well
+as similar routines in the doarg.c, dolist.c and doio.c routines of Perl.
+The mus program is only intended to get you about 90% there. It's not clear,
+for instance, how a given structure should be passed to Perl. But that
+shouldn't bother you--if you've gotten this far, it's already obvious
+that you are totally mad.
+
+Here's an example of how to return an array value:
+
+ case US_appl_errlist:
+ if (!wantarray) {
+ str_numset(st[0], (double) appl_nerr);
+ return sp;
+ }
+ astore(stack, sp + appl_nerr, Nullstr); /* extend stack */
+ st = stack->ary_array + sp; /* possibly realloced */
+ for (i = 0; i < appl_nerr; i++) {
+ tmps = appl_errlist[i];
+ st[i] = str_2mortal(str_make(tmps,strlen(tmps)));
+ }
+ return sp + appl_nerr - 1;
+
+
+In addition, there is a program, man2mus, that will scan a man page for
+function prototypes and attempt to construct a mus CASE entry for you. It has
+to guess about input/output parameters, so you'll have to tidy up after it.
+But it can save you a lot of time if the man pages for a library are
+reasonably well formed.
+
+If you happen to have BSD curses on your machine, you might try compiling
+a copy of curseperl. The "pager" program in this directory is a rudimentary
+start on writing a pager--don't believe the help message, which is stolen
+from the less program.
+
+There is currently no official way to call a Perl routine back from C,
+but we're working on it. It might be easiest to fake up a call to do_eval()
+or do_subr(). This is not for the faint of heart. If you come up with
+such a glue routine, I'll be glad to add it into the distribution.
+
+User-defined subroutines may not currently be called as a signal handler,
+though a signal handler may itself call a user-defined subroutine.