Logo Search packages:      
Sourcecode: nawm version File versions  Download package

mod.c

/* mod.c: loadable nawm modules */

/* Copyright (C) 1999 by the Massachusetts Institute of Technology.
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies and that both that copyright
 * notice and this permission notice appear in supporting
 * documentation, and that the name of M.I.T. not be used in
 * advertising or publicity pertaining to distribution of the
 * software without specific, written prior permission.
 * M.I.T. makes no representations about the suitability of
 * this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 */

#include "nawm.h"
#include "lang.h"
#include "parser.h"
#include <dlfcn.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#ifdef NEED_UNDERSCORES
#define SYMNAME(x) ("_" x)
#else
#define SYMNAME
#endif

static char **nawm_libpath;
extern long eventmask;
extern event_handler *eventhandlers;

void initmodules(void)
{
  char *libpath, *p;
  int i;

  libpath = getenv("NAWM_LIBRARY_PATH");
  if (!libpath)
    libpath = NAWM_DEFAULT_LIBPATH;

  for (i = 0, p = libpath; *p; p++)
    {
      if (*p == ':')
      i++;
    }

  nawm_libpath = xmalloc((i + 2) * sizeof(char *));

  /* split libpath into components, recognizing an empty component
   * as NAWM_DEFAULT_LIBPATH
   */
  for (i = 0, p = libpath; *libpath; p++)
    {
      if (*p == ':' || *p == '\0')
      {
        if (p == libpath)
          nawm_libpath[i] = NAWM_DEFAULT_LIBPATH;
        else
          {
            int len = p - libpath;

            while (libpath[len] == '/')
            len--;
            nawm_libpath[i] = xmalloc(len + 1);
            memcpy(nawm_libpath[i], libpath, len);
            nawm_libpath[i][len] = '\0';
          }
        libpath = *p ? p + 1 : p;
        i++;
      }
    }
  nawm_libpath[i] = NULL;
}

void load_module(char *name)
{
  int i, len = strlen(name), *modrev, found = 0, opened = 0;
  void *dlconfig = NULL;
  void (*modinit)();

  for (i = 0; nawm_libpath[i]; i++)
    {
      char *path = xmalloc(strlen(nawm_libpath[i]) + len + 5);
      sprintf(path, "%s/%s.so", nawm_libpath[i], name);

      if (!access(path, R_OK))
      {
        found = 1;
        dlconfig = dlopen(path, RTLD_NOW);
        free(path);
        if (!dlconfig)
          continue;
        opened = 1;
        modrev = dlsym(dlconfig, SYMNAME("nawm_modrev"));
        if (!modrev || *modrev != 1)
          continue;
        modinit = dlsym(dlconfig, SYMNAME("modinit"));
        if (!modinit)
          continue;
        modinit();
        return;
      }
    }

  if (opened)
    {
      if (modrev)
      die("No symbol \"modinit\" in module \"%s\".", name);
      else
      die("No symbol \"nawm_modrev\" in module \"%s\".", name);
    }
  else if (found)
    die("Couldn't open module \"%s\":\n%s", name, dlerror());
  else
    die("Couldn't find module \"%s\"", name);
}


      
void module_define_procedure(char *name, dtype rtype, void (*body)(),
                       int numargs, ...)
{
  function *f;
  va_list ap;
  int i, nargs;

  nargs = (numargs < 0) ? -numargs : numargs;

  f = xmalloc(sizeof(function) + (nargs - 3) * sizeof(dtype));
  f->body = body;
  f->type = rtype;
  f->numvars = -1;
  f->numargs = numargs;

  if (numargs < 0)
    numargs = -numargs;

  va_start(ap, numargs);
  for (i = 0; i < numargs; i++)
    f->vartype[i] = va_arg(ap, dtype);
  va_end(ap);

  define(rtype ? FUN : CMD, name, f);
}

void module_define_variable(char *name, dtype type, nawmval data)
{
  variable *v = mkvar(type);

  v->data = data;
  define(VAR, name, v);
}

int module_define_type(char *name)
{
  return newtype(name);
}

int module_lookup_type(char *name)
{
  int kind;
  int type = (nawmval)lookup(name, &kind, 0);

  if (kind != DTYPE || type == 0)
    return -1;
  else
    return type;
}

void module_define_event_handler(void (*handler)(XEvent *), long mask)
{
  event_handler *h;

  eventmask |= mask;
  h = xmalloc(sizeof(event_handler));
  h->handler = handler;
  h->next = eventhandlers;
  eventhandlers = h;
}

Generated by  Doxygen 1.6.0   Back to index