aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog10
-rw-r--r--awkgram.y66
-rw-r--r--doc/ChangeLog4
-rw-r--r--doc/gawk.110
-rw-r--r--doc/gawk.texi40
5 files changed, 125 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index eda35adf..1f12733a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2012-03-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * awkgram.y (LEX_LOAD): New token to support @load.
+ (grammar): Add rules to support @load.
+ (tokentab): Add "load".
+ (add_srcfile): Improve error message to distinguish between source files
+ and shared libraries.
+ (load_library): New function to load libraries specified with @load.
+ (yylex): Add support for LEX_LOAD (treated the same way as LEX_INCLUDE).
+
2012-03-20 Andrew J. Schorr <aschorr@telemetry-investments.com>
* Makefile.am (EXTRA_DIST): Remove extension.
diff --git a/awkgram.y b/awkgram.y
index a64fff01..0b47568b 100644
--- a/awkgram.y
+++ b/awkgram.y
@@ -52,6 +52,7 @@ static INSTRUCTION *make_assignable(INSTRUCTION *ip);
static void dumpintlstr(const char *str, size_t len);
static void dumpintlstr2(const char *str1, size_t len1, const char *str2, size_t len2);
static int include_source(INSTRUCTION *file);
+static int load_library(INSTRUCTION *file);
static void next_sourcefile(void);
static char *tokexpand(void);
@@ -164,7 +165,7 @@ extern double fmod(double x, double y);
%token LEX_AND LEX_OR INCREMENT DECREMENT
%token LEX_BUILTIN LEX_LENGTH
%token LEX_EOF
-%token LEX_INCLUDE LEX_EVAL
+%token LEX_INCLUDE LEX_EVAL LEX_LOAD
%token NEWLINE
/* Lowest to highest */
@@ -239,6 +240,11 @@ rule
want_source = FALSE;
yyerrok;
}
+ | '@' LEX_LOAD library statement_term
+ {
+ want_source = FALSE;
+ yyerrok;
+ }
;
source
@@ -256,6 +262,21 @@ source
{ $$ = NULL; }
;
+library
+ : FILENAME
+ {
+ if (load_library($1) < 0)
+ YYABORT;
+ efree($1->lextok);
+ bcfree($1);
+ $$ = NULL;
+ }
+ | FILENAME error
+ { $$ = NULL; }
+ | error
+ { $$ = NULL; }
+ ;
+
pattern
: /* empty */
{ $$ = NULL; rule = Rule; }
@@ -1824,6 +1845,7 @@ static const struct token tokentab[] = {
{"int", Op_builtin, LEX_BUILTIN, A(1), do_int},
{"isarray", Op_builtin, LEX_BUILTIN, GAWKX|A(1), do_isarray},
{"length", Op_builtin, LEX_LENGTH, A(0)|A(1), do_length},
+{"load", Op_symbol, LEX_LOAD, GAWKX, 0},
{"log", Op_builtin, LEX_BUILTIN, A(1), do_log},
{"lshift", Op_builtin, LEX_BUILTIN, GAWKX|A(2), do_lshift},
{"match", Op_builtin, LEX_BUILTIN, NOT_OLD|A(2)|A(3), do_match},
@@ -2266,8 +2288,8 @@ add_srcfile(int stype, char *src, SRCFILE *thisfile, int *already_included, int
*errcode = errno_val;
return NULL;
}
- fatal(_("can't open source file `%s' for reading (%s)"),
- src, errno_val ? strerror(errno_val) : _("reason unknown"));
+ fatal(_("can't open %s `%s' for reading (%s)"),
+ ((stype == SRC_EXTLIB) ? "shared library" : "source file"), src, errno_val ? strerror(errno_val) : _("reason unknown"));
}
for (s = srcfiles->next; s != srcfiles; s = s->next) {
@@ -2348,6 +2370,41 @@ include_source(INSTRUCTION *file)
return 0;
}
+/* load_library --- load a shared library */
+
+static int
+load_library(INSTRUCTION *file)
+{
+ SRCFILE *s;
+ char *src = file->lextok;
+ int errcode;
+ int already_included;
+
+ if (do_traditional || do_posix) {
+ error_ln(file->source_line, _("@load is a gawk extension"));
+ return -1;
+ }
+
+ if (strlen(src) == 0) {
+ if (do_lint)
+ lintwarn_ln(file->source_line, _("empty filename after @load"));
+ return 0;
+ }
+
+ s = add_srcfile(SRC_EXTLIB, src, sourcefile, &already_included, &errcode);
+ if (s == NULL) {
+ if (already_included)
+ return 0;
+ error_ln(file->source_line,
+ _("can't open shared library `%s' for reading (%s)"),
+ src, errcode ? strerror(errcode) : _("reason unknown"));
+ return -1;
+ }
+
+ (void) load_ext(s->fullpath, "dlload", NULL);
+ return 0;
+}
+
/* next_sourcefile --- read program from the next source in srcfiles */
static void
@@ -3430,7 +3487,7 @@ retry:
static int warntab[sizeof(tokentab) / sizeof(tokentab[0])];
int class = tokentab[mid].class;
- if ((class == LEX_INCLUDE || class == LEX_EVAL)
+ if ((class == LEX_INCLUDE || class == LEX_LOAD || class == LEX_EVAL)
&& lasttok != '@')
goto out;
@@ -3466,6 +3523,7 @@ retry:
switch (class) {
case LEX_INCLUDE:
+ case LEX_LOAD:
want_source = TRUE;
break;
case LEX_EVAL:
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 3ff659e6..f8f83fca 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,7 @@
+2012-03-21 Andrew J. Schorr <aschorr@telemetry-investments.com>
+
+ * gawk.texi, gawk.1: Document new @load keyword.
+
2012-03-20 Andrew J. Schorr <aschorr@telemetry-investments.com>
* gawk.texi, gawk.1: Add AWKLIBPATH.
diff --git a/doc/gawk.1 b/doc/gawk.1
index cc0ccae2..2e039521 100644
--- a/doc/gawk.1
+++ b/doc/gawk.1
@@ -563,6 +563,9 @@ and optional function definitions.
.RS
.PP
\fB@include "\fIfilename\fB"
+.br
+\fB@load "\fIfilename\fB"
+.br
\fIpattern\fB { \fIaction statements\fB }\fR
.br
\fBfunction \fIname\fB(\fIparameter list\fB) { \fIstatements\fB }\fR
@@ -594,6 +597,13 @@ In addition, lines beginning with
may be used to include other source files into your program,
making library use even easier.
.PP
+Lines beginning with
+.B @load
+may be used to load shared libraries into your program. This is equivalent
+to using the
+.B \-l
+option.
+.PP
The environment variable
.B AWKPATH
specifies a search path to use when finding source files named with
diff --git a/doc/gawk.texi b/doc/gawk.texi
index d0d54121..c3375ce8 100644
--- a/doc/gawk.texi
+++ b/doc/gawk.texi
@@ -356,6 +356,7 @@ particular records in a file and perform operations upon them.
* Other Environment Variables:: The environment variables.
* Exit Status:: @command{gawk}'s exit status.
* Include Files:: Including other files into your program.
+* Loading Shared Libraries:: Loading shared libraries into your program.
* Obsolete:: Obsolete Options and/or features.
* Undocumented:: Undocumented Options and Features.
* Regexp Usage:: How to Use Regular Expressions.
@@ -2905,6 +2906,7 @@ things in this @value{CHAPTER} that don't interest you right now.
* Environment Variables:: The environment variables @command{gawk} uses.
* Exit Status:: @command{gawk}'s exit status.
* Include Files:: Including other files into your program.
+* Loading Shared Libraries:: Loading shared libraries into your program.
* Obsolete:: Obsolete Options and/or features.
* Undocumented:: Undocumented Options and Features.
@end menu
@@ -3191,6 +3193,8 @@ Load a shared library @var{lib}. This searches for the library using the @env{AW
environment variable. The correct library suffix for your platform will be
supplied by default, so it need not be specified in the library name.
The library initialization routine should be named @code{dlload()}.
+An alternative is to use the @samp{@@load} keyword inside the program to load
+a shared library.
@item -L @r{[}value@r{]}
@itemx --lint@r{[}=value@r{]}
@@ -3650,7 +3654,7 @@ The @env{AWKLIBPATH} environment variable is similar to the @env{AWKPATH}
variable, but it is used to search for shared libraries specified
with the @option{-l} option rather than for source files. If the library
is not found, the path is searched again after adding the appropriate
-shared library suffix for the platform. For example, on Linux systems,
+shared library suffix for the platform. For example, on GNU/Linux systems,
the suffix @samp{.so} is used.
@node Other Environment Variables
@@ -3861,6 +3865,40 @@ As mentioned in @ref{AWKPATH Variable}, the current directory is always
searched first for source files, before searching in @env{AWKPATH},
and this also applies to files named with @samp{@@include}.
+@node Loading Shared Libraries
+@section Loading Shared Libraries Into Your Program
+
+This @value{SECTION} describes a feature that is specific to @command{gawk}.
+
+The @samp{@@load} keyword can be used to read external @command{awk} shared
+libraries. This allows you to link in compiled code that may offer superior
+performance and/or give you access to extended capabilities not supported
+by the @command{awk} language. The @env{AWKLIBPATH} variable is used to
+search for the shared library. Using @samp{@@load} is completely equivalent
+to using the @option{-l} command-line option.
+
+If the shared library is not initially found in @env{AWKLIBPATH}, another
+search is conducted after appending the platform's default shared library
+suffix to the filename. For example, on GNU/Linux systems, the suffix
+@samp{.so} is used.
+
+@example
+$ @kbd{awk '@@load "ordchr"; BEGIN @{print chr(65)@}'}
+A
+@end example
+
+@noindent
+This is equivalent to the following example:
+
+@example
+$ @kbd{awk -lordchr 'BEGIN @{print chr(65)@}'}
+A
+@end example
+
+@noindent For command-line usage, the @option{-l} option is more convenient,
+but @samp{@@load} is useful for embedding inside an @command{awk} source file
+that requires access to a shared library.
+
@node Obsolete
@section Obsolete Options and/or Features