00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "awk.h"
00031
00032 #ifdef DYNAMIC
00033
00034 #include <dlfcn.h>
00035
00036 #ifdef __GNUC__
00037 static unsigned long long dummy;
00038 #endif
00039
00040 extern int errcount;
00041
00042
00043
00044 NODE *
00045 do_ext(NODE *tree)
00046 {
00047 NODE *obj;
00048 NODE *fun;
00049 NODE *(*func) P((NODE *, void *));
00050 void *dl;
00051 int flags = RTLD_LAZY;
00052
00053 #ifdef __GNUC__
00054 AWKNUM junk;
00055
00056 junk = (AWKNUM) dummy;
00057 #endif
00058
00059 if (do_lint)
00060 lintwarn(_("`extension' is a gawk extension"));
00061
00062 if (do_traditional || do_posix) {
00063 errcount++;
00064 error(_("`extension' is a gawk extension"));
00065 }
00066
00067 obj = tree_eval(tree->lnode);
00068 force_string(obj);
00069
00070 #ifdef RTLD_GLOBAL
00071 flags |= RTLD_GLOBAL;
00072 #endif
00073 if ((dl = dlopen(obj->stptr, flags)) == NULL)
00074 fatal(_("extension: cannot open `%s' (%s)\n"), obj->stptr,
00075 dlerror());
00076
00077 fun = tree_eval(tree->rnode->lnode);
00078 force_string(fun);
00079
00080 func = (NODE *(*) P((NODE *, void *))) dlsym(dl, fun->stptr);
00081 if (func == NULL)
00082 fatal(_("extension: library `%s': cannot call function `%s' (%s)\n"),
00083 obj->stptr, fun->stptr, dlerror());
00084 free_temp(obj);
00085 free_temp(fun);
00086
00087 return (*func)(tree, dl);
00088 }
00089
00090
00091
00092 void
00093 make_builtin(char *name, NODE *(*func) P((NODE *)), int count)
00094 {
00095 NODE *p, *b, *f;
00096 char **vnames, *parm_names, *sp;
00097 char buf[200];
00098 int space_needed, i;
00099
00100
00101 space_needed = 0;
00102 for (i = 0; i < count; i++) {
00103 sprintf(buf, "p%d", i);
00104 space_needed += strlen(buf) + 1;
00105 }
00106 emalloc(parm_names, char *, space_needed, "make_builtin");
00107 emalloc(vnames, char **, count * sizeof(char *), "make_builtin");
00108 sp = parm_names;
00109 for (i = 0; i < count; i++) {
00110 sprintf(sp, "p%d",i);
00111 vnames[i] = sp;
00112 sp += strlen(sp) + 1;
00113 }
00114
00115 getnode(p);
00116 p->type = Node_param_list;
00117 p->flags |= FUNC;
00118 p->rnode = NULL;
00119 p->param = name;
00120 p->param_cnt = count;
00121 #if 0
00122
00123 p->source_line = __LINE__;
00124 p->source_file = __FILE__;
00125 #endif
00126
00127 getnode(b);
00128 b->type = Node_builtin;
00129 b->builtin = func;
00130 b->subnode = p;
00131 b->source_line = __LINE__;
00132 b->source_file = __FILE__;
00133
00134 f = node(p, Node_func, b);
00135 f->parmlist = vnames;
00136 install(name, f);
00137 }
00138
00139
00140
00141 NODE *
00142 get_argument(NODE *tree, int i)
00143 {
00144 extern NODE **stack_ptr;
00145
00146 if (i < 0 || i >= tree->param_cnt)
00147 return NULL;
00148
00149 tree = stack_ptr[i];
00150 if (tree->lnode == Nnull_string)
00151 return NULL;
00152
00153 if (tree->type == Node_array_ref) {
00154 tree = tree->orig_array;
00155 return tree;
00156 }
00157
00158 if (tree->type == Node_var_array)
00159 return tree;
00160
00161 return tree->lnode;
00162 }
00163
00164
00165
00166 void
00167 set_value(NODE *tree)
00168 {
00169 extern NODE *ret_node;
00170
00171 if (tree)
00172 ret_node = tree;
00173 else
00174 ret_node = Nnull_string;
00175 }
00176 #else
00177
00178
00179
00180 NODE *
00181 do_ext(NODE *tree)
00182 {
00183 const char *emsg = _("Operation Not Supported");
00184
00185 unref(ERRNO_node->var_value);
00186 ERRNO_node->var_value = make_string((char *) emsg, strlen(emsg));
00187 return tmp_number((AWKNUM) -1);
00188 }
00189 #endif