/******************************** -*- C -*- ****************************
 *
 *	Dynamic Linking for GNU Smalltalk
 *
 *	$Revision: 1.7.5$
 *	$Date: 2000/05/28 16:56:52$
 *	$Author: pb$
 *
 ***********************************************************************/

/***********************************************************************
 *
 * Copyright 1988-92, 1994-95, 1999, 2000 Free Software Foundation, Inc.
 * Written by Paolo Bonzini.
 *
 * This file is part of GNU Smalltalk.
 *
 * GNU Smalltalk is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2, or (at your option) any later 
 * version.
 * 
 * GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * GNU Smalltalk; see the file COPYING.  If not, write to the Free Software
 * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
 *
 ***********************************************************************/


#include "gst.h"
#include "dld_gst.h"
#include "alloc.h"
#include <stdio.h>

#if STDC_HEADERS
#  include <string.h>
#endif /* STDC_HEADERS */

voidPtr
gst_dld_openext (filename)
     char *filename;
{
  voidPtr handle;
  char	*completed, *ext, **i;
  int	len;

  if (handle = gst_dld_open(filename)) {
    /* the file name as given worked */
    return (handle);
  }

  if (!filename || !filename[0]) {
    /* no hope to succeed */
    return (handle);
  }

  len = strlen(filename);
  completed = xmalloc(len + 20);
  strcpy(completed, filename);
  for (i = gst_dld_exts; *i; i++) {
    int n;
    char *src;
    for (src = *i, n = 0, ext = completed + len; *src && (n < 20); n++) {
      *ext++ = *src++;
    }
    *ext = '\0';

    if (handle = gst_dld_open(completed)) {
      break;
    }
  }
  xfree(completed);
  return (handle);
}

voidPtr
gst_dld_getsym (handle, symbol)
     voidPtr handle;
     char *symbol;
{
#ifdef NEED_DLSYM_UNDERSCORE
  char *underscoreSymbol = alloca(strlen(symbol) + 2);
  sprintf(underscoreSymbol, "_%s", symbol);
  return gst_dld_sym(handle, underscoreSymbol);
#else
  return gst_dld_sym(handle, symbol);
#endif
}

void
initDldLib ()
{
  defineCFunc("defineCFunc", defineCFunc);
  defineCFunc("dldLink", gst_dld_openext);
  defineCFunc("dldGetFunc", gst_dld_getsym);
  defineCFunc("dldError", gst_dld_error);
}
