/* $Id: ctalklib,v 1.2 2008/11/28 20:27:59 kiesling Exp $ -*-c-*-*/

/*
  This file is part of ctalk.
  Copyright  2005-2008  Robert Kiesling, ctalk@ctalklang.org.
  Permission is granted to copy this software provided that this copyright
  notice is included in all source code modules.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library 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
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*/

#ifndef _STDLIB_H
#include <stdlib.h>
#endif
#ifndef _STRING_H
#include <string.h>
#endif
#ifndef _SYS_TYPES_H
#include <sys/types.h>
#endif
#ifndef _SYS_STAT_H
#include <sys/stat.h>
#endif
#ifndef _UNISTD_H
#include <unistd.h>
#endif

#ifndef _ERRNO_H
#include <errno.h>
#endif

#ifndef _STDIO_H
#include <stdio.h>
#endif

#ifndef MAXLABEL
#define MAXLABEL 255
#endif

#ifndef MAXMSG
#define MAXMSG MAXLABEL
#endif

#ifndef MAXUSERDIRS
#define MAXUSERDIRS 15
#endif

#ifndef SUCCESS
#define SUCCESS 0
#endif

#ifndef ERROR
#define ERROR -1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#ifndef TRUE
#define TRUE !(FALSE)
#endif

#ifndef MAXARGS
#define MAXARGS 512
#endif

#ifndef CTALK_DIRECTORY_MODE
#define CTALK_DIRECTORY_MODE 0755
#endif

#ifndef FILENAME_MAX
# if defined (__sparc__) && defined (__svr4__)
#  define FILENAME_MAX 1024
# else
#  ifdef __CYGWIN__
/* Avoid a symbol redefinition warning. */
#   define __FILENAME_MAX__ (260 - 1 /* NUL */)
#   define FILENAME_MAX __FILENAME_MAX__
#  else
#   define FILENAME_MAX 4096
#  endif
# endif /* defined (__sparc__) && defined (__svr4__) */
#endif /* ifndef FILENAME_MAX */

#ifndef NULL
#define NULL ((void *)0)
#endif

#ifndef NULLSTR
#define NULLSTR "(null)"
#endif

#ifndef N_MESSAGES
#define N_MESSAGES (MAXARGS * 120)
#endif

/*
 *  Scopes of objects.  Also defined in object.h and ctldjgpp.
 */
#ifndef GLOBAL_VAR 
#define GLOBAL_VAR (1 << 0)
#endif
#ifndef LOCAL_VAR
#define LOCAL_VAR (1 << 1)
#endif
#ifndef ARG_VAR
#define ARG_VAR (1 << 2)
#endif
#ifndef RECEIVER_VAR
#define RECEIVER_VAR (1 << 3)
#endif
#ifndef PROTOTYPE_VAR
#define PROTOTYPE_VAR (1 << 4)
#endif
#ifndef BLOCK_VAR
#define BLOCK_VAR (1 << 5)
#endif
#ifndef CREATED_PARAM
#define CREATED_PARAM (1 << 6)
#endif

#ifndef METHOD_RETURN
#define METHOD_RETURN "OBJECT * "
#endif

/*
 *  When changing this, also change in object.h, message.h, and ctldjgpp. 
 */
#define GNUC_PACKED_STRUCT (defined(__linux__) && defined(__i386__) && \
			    defined(__GNUC__) && (__GNUC__ >= 3))
/*
 *   Maximum unsigned arithmetic values.  Use unsigned 
 *   maximums 
 */
#ifndef MAX_UCHAR 
#define MAX_UCHAR 255
#endif
#ifndef MAX_UINT
#define MAX_UINT 4294967295U
#endif
#ifndef MAX_ULONGLONG
#define MAX_ULONGLONG 18446744073709551615
#endif

/*
 * Value type, determined during parsing.  The values must correspond to
 * the values in typeof.h.
 */
#ifndef __ctalk_INTEGER_T
#define __ctalk_INTEGER_T         1
#endif
#ifndef __ctalk_LONG_T
#define __ctalk_LONG_T            2
#endif
#ifndef __ctalk_LONGLONG_T
#define __ctalk_LONGLONG_T        3
#endif
#ifndef __ctalk_DOUBLE_T
#define __ctalk_DOUBLE_T          4
#endif
#ifndef __ctalk_LONGDOUBLE_T
#define __ctalk_LONGDOUBLE_T      6
#endif
#ifndef __ctalk_LITERAL_T
#define __ctalk_LITERAL_T         7
#endif
#ifndef __ctalk_LITERAL_CHAR_T
#define __ctalk_LITERAL_CHAR_T    8
#endif
#ifndef __ctalk_PTR_T
#define __ctalk_PTR_T             10
#endif

/* Define typedefs first so the compiler knows about them.*/

#ifndef LIB_BUILD
#ifndef METHOD
typedef struct _method METHOD;
#define __need_method 
#endif
#ifndef OBJECT
typedef struct _object OBJECT;
#define __need_object
#endif
#ifndef VAL
typedef struct _val VAL;
#define __need_val

#ifndef PARAM
typedef struct _param PARAM;
#define __need_param
#endif

#ifndef CVAR
typedef struct _cvar CVAR;
#define __need_cvar
#endif

#define __need_boolean

#ifndef MESSAGE
typedef struct _message MESSAGE;
#define __need_message
#endif

#ifndef I_EXCEPTION
typedef struct _i_exception I_EXCEPTION;
#define __need_i_exception
#endif

#ifndef RT_INFO
typedef struct _rtinfo RT_INFO;
#define __need_rt_info
#endif

#ifndef SYMBOL
typedef struct _symbol SYMBOL;
#define __need_symbol
#endif

#ifndef VARENTRY
typedef struct _varentry VARENTRY;
#define __need_varentry
#endif


#endif /* #ifndef LIB_BUILD */


#ifdef __need_boolean
/*
 *  Compatible with X11/Intrinsic.h.  Make sure this matches the 
 *  typedef in object.h.
 */
#ifdef CRAY
typedef long Boolean;
#else
typedef char Boolean;
#endif
#define True 1
#define False 0
#undef __need_boolean
#endif

#ifdef __need_param
struct _param {
  char sig[5];
  char class[MAXLABEL];
  char name[MAXLABEL];
  int attrs;
  int is_ptr,
    is_ptrptr,
    n_derefs;
};
#undef __need_param
#endif

#ifdef __need_varentry
struct _varentry {
  PARAM *var_decl;
  OBJECT *var_object;
  struct _varentry *next, *prev;
};
#endif

#ifdef __need_val
struct _val{
  int type;
  union {
    void *ptr;
    int i;
    Boolean b;
    double d;        /* Double and float. */
    long double ld;
    long l;
    long long ll;
  } value;
};
#undef __need_val
#endif

#ifdef __need_method
struct _method {
  char sig[6];
  char name[MAXLABEL];
  char selector[MAXLABEL];
  char returnclass[MAXLABEL];
  OBJECT *rcvr_class_obj;
  OBJECT *(*cfunc)();
  char *src;
  PARAM *params[MAXARGS];
  int n_params;
  int varargs;
  int no_init;
  int n_args;
  int error_line;
  int error_column;
  int arg_frame_top;
  int rcvr_frame_top;
  Boolean imported;
  Boolean queued;
  OBJECT *args[MAXARGS];
  OBJECT *local_objs;
  CVAR *local_cvars;
  struct _method *next;
  struct _method *prev;
};
#undef __need_method
#endif

#ifdef __need_object
struct _object {
  char sig[16];
  char __o_name[MAXLABEL];
  char __o_classname[MAXLABEL];
  OBJECT *__o_class;
  char __o_superclassname[MAXLABEL];
  OBJECT *__o_superclass;
  OBJECT *__o_p_obj;
  VARENTRY *__o_varentry;
  char *__o_value;
  METHOD *instance_methods,
    *class_methods;
  int scope;
  int nrefs;
  struct _object *classvars;
  struct _object *instancevars;    
  struct _object *next;
  struct _object *prev;
#if GNUC_PACKED_STRUCT
} __attribute__ ((packed));
#else
};
#endif

#ifndef _OBJECT_H
#define OBJREF(__o) (&(__o))
typedef OBJECT** OBJREF_T;
#endif

#undef __need_object
#endif /* __need_object */

#ifdef __need_cvar
struct _cvar {
  char sig[4];
  char decl[MAXLABEL];
  char type[MAXLABEL];
  char qualifier[MAXLABEL];
  char qualifier2[MAXLABEL];
  char qualifier3[MAXLABEL];
  char qualifier4[MAXLABEL];
  char storage_class[MAXLABEL];
  char name[MAXLABEL];
  int n_derefs;
  int attrs;
  Boolean is_unsigned;
  int scope;
  VAL val;                /* Used at run time to evaluate expressions
			     and for enum values.                     */
  struct _cvar *members;
  struct _cvar *params;
  struct _cvar *next;
  struct _cvar *prev;
};
#undef __need_cvar
#endif

#ifdef __need_message
struct _message {
  char sig[7];
  char *name;
  char *value;
  OBJECT *value_obj;
  OBJECT *obj;
  int tokentype; 
  int evaled;
  int output;
  int error_line;
  int error_column;
  OBJECT *receiver_obj;
  struct _message *receiver_msg;
};
#undef __need_message
#endif

#ifdef __need_rt_info
struct _rtinfo {
  char source_file[FILENAME_MAX];
  OBJECT *rcvr_obj;
  OBJECT *rcvr_class_obj;
  OBJECT *(*method_fn)(void);
  Boolean classlib_read;
};
#undef __need_rt_info
#endif

#ifndef EXPR_PARSER
typedef struct {
  int lvl;
  int rcvr_frame_top;
  int msg_frame_top;
  METHOD *e_method;
} EXPR_PARSER;
#endif

/*
 *  This declaration must match the declaration in except.h.
 */
typedef enum {
  no_x,
  cplusplus_header_x,     /* Preprocessor exceptions. */
  mismatched_paren_x,
  false_assertion_x,
  file_is_directory_x,
  file_already_open_x,
  undefined_param_class_x,
  parse_error_x,
  invalid_operand_x,
  ptr_conversion_x,
  undefined_class_x,
  undefined_method_x,
  self_without_receiver_x,
  elif_w_o_if_x,
  undefined_label_x,
  undefined_type_x,
  undefined_receiver_x,
  unknown_file_mode_x,
  eperm_x,                /* These are looked up in errno_exceptions[] */
  enoent_x,               /* in except.c.                              */
  esrch_x,
  eintr_x,
  eio_x,
  enxio_x,
  e2big_x,
  enoexec_x,
  ebadf_x,
  echild_x,
  eagain_x,
  enomem_x,
  eaccess_x,
  efault_x,
  enotblk_x,
  ebusy_x,
  eexist_x,
  exdev_x,
  enodev_x,
  enotdir_x,
  eisdir_x,
  einval_x,
  enfile_x,
  emfile_x,
  enotty_x,
  etxtbsy_x,
  efbig_x,
  enospc_x,
  espipe_x,
  erofs_x,
  emlink_x,
  epipe_x,
  edom_x,
  erange_x,
  edeadlk_x,
  enametoolong_x,
  enolck_x,
  enosys_x,
  enotempty_x,
  eloop_x,
  ewouldblock_x,
  enomsg_x,
  eidrm_x,
  echrng_x,
  el2nsync_x,
  el3hlt_x,
  el3rst_x,
  elnrng_x,
  eunatch_x,
  enocsi_x,
  el2hlt_x,
  ebade_x,
  ebadr_x,
  exfull_x,
  enoano_x,
  ebadrqc_x,
  ebadslt_x,
  edeadlock_x,
  ebfont_x,
  enostr_x,
  enodata_x,
  etime_x,
  enosr_x,
  enonet_x,
  enopkg_x,
  eremote_x,
  enolink_x,
  eadv_x,
  esrmnt_x,
  ecomm_x,
  eproto_x,
  emultihop_x,
  edotdot_x,
  ebadmsg_x,
  eoverflow_x,
  enotuniq_x,
  ebadfd_x,
  eremchg_x,
  elibacc_x,
  elibbad_x,
  elibscn_x,
  elibmax_x,
  elibexex_x,
  eilseq_x,
  erestart_x,
  estrpipe_x,
  eusers_x,
  enotsock_x,
  edestaddrreq_x,
  emsgsize_x,
  eprototype_x,
  enoprotopt_x,
  eprotonotsuppport_x,
  esocktnosupport_x,
  eopnotsupp_x,
  epfnosupport_x,
  eafnosupport_x,
  eaddrinuse_x,
  eaddrnotavail_x,
  enetdown_x,
  enetunreach_x,
  enetreset_x,
  econnaborted_x,
  econnreset_x,
  enobufs_x,
  eisconn_x,
  enotconn_x,
  eshutdown_x,
  etoomanyrefs_x,
  etimeout_x,
  econnrefused_x,
  ehostdown_x,
  ehostunreach_x,
  ealready_x,
  einprogress_x,
  estale_x,
  euclean_x,
  enotnam_x,
  enavail_x,
  eisnam_x,
  eremoteio_x,
  edquot_x,
  enomedium_x,
  emediumtype_x
} EXCEPTION;

typedef enum {
  null_context,
  lvalue_context,
  receiver_context,
  argument_context,     /* Argument to a method. */
  c_argument_context,   /* Argument to a C operator. */
  c_context
} OBJECT_CONTEXT;

#ifdef __need_symbol
struct _symbol {
  char name[MAXLABEL];
  struct _symbol *next, *prev;
};
#undef __need_symbol
#endif

#ifdef __need_i_exception
struct _i_exception {
  int parser_lvl, 
    error_line,
    error_col;
  RT_INFO rtinfo;
  EXCEPTION exception;
  SYMBOL *unresolved_classes,
    *unresolved_symbols;
  char text[MAXMSG];
  struct _i_exception *next,
    *prev;
};
#undef __need_i_exception
#endif

#endif /* LIB_BUILD */

/*  Dictionaries for class objects and object instances. */
OBJECT *__ctalk_receivers[MAXARGS+1];
int __ctalk_receiver_ptr;

OBJECT *__ctalk_classes;
OBJECT *__ctalk_last_class;

VARENTRY *__ctalk_dictionary;
VARENTRY *__ctalk_last_object;

extern OBJECT *__ctalk_argstack[N_MESSAGES+1];
extern int __ctalk_arg_ptr;

extern OBJECT *instanceVariableObject;

extern char **environ;

#ifndef _CTALK_LIB

/* 
 *   Prototypes of ctalk library functions. 
 */
extern char   *substrcat (char *, char *, int, int);
extern char   *substrcpy (char *, char *, int, int);
extern void   _error (char *, ...);
extern void   _warning (char *, ...);
extern void   __argvName (char *);
extern char   *__argvFileName (void);
extern OBJECT *__ctalkAddClassVariable (OBJECT *, char *, OBJECT *);
extern OBJECT *__ctalkAddInstanceVariable (OBJECT *, char *, OBJECT *);
extern OBJECT *__ctalkCCharPtrToObj (char *);
extern OBJECT *__ctalkCDoubleToObj (double);
extern char   *__ctalkCharRadixToChar (char *);
extern OBJECT *__ctalkCIntToObj (int);
extern OBJECT *__ctalkCLongLongToObj (long long int);
extern char   *__ctalkCPrintFmtToCtalkFmt (char *, char *);
extern int     __ctalkCreateArg (char *, char *, void *);
extern OBJECT *__ctalkCreateObject (char *, char *, char *, int);
extern OBJECT *__ctalkCreateObjectInit (char *,char *, char *, int, char *);
extern void    __ctalkClassMethodInitReturnClass (char *, char *, char *);
extern OBJECT *__ctalkClassObject (OBJECT *);
extern CVAR   *__ctalkCopyCVariable (CVAR *);
extern OBJECT *__ctalkCopyObject (OBJREF_T, OBJREF_T);
extern int     __ctalkCriticalExceptionInternal (MESSAGE *, EXCEPTION, char *);
extern int     __ctalkCriticalSysErrExceptionInternal (MESSAGE *, int, char *);
extern void    __ctalkDecimalIntegerToASCII (int, char *);
extern void    __ctalkDecimalLongLongToASCII (long long int, char *);
extern int     __ctalkDefineClassMethod (char *, char *, OBJECT *(*)(), int);
extern OBJECT *__ctalkDefineClassVariable (char *, char *, char *, char *);
extern int     __ctalkDefineInstanceMethod (char *, char *, OBJECT *(*)(), int);
extern OBJECT *__ctalkDefineInstanceVariable (char *, char *, char *, char *);
extern int     __ctalkDeleteObjectList (OBJECT *);
extern void    __ctalkDoubleToASCII (double, char *);
extern OBJECT *__ctalkEvalExpr (char *);
extern int     __ctalkExceptionInternal (MESSAGE *, EXCEPTION, char *);
extern OBJECT *__ctalkExceptionNotifyInternal (I_EXCEPTION *);
extern METHOD *__ctalkFindClassMethodByFn (OBJECT **, OBJECT *(*)(void), int);
extern METHOD *__ctalkFindClassMethodByName (OBJECT **, const char *, int);
extern METHOD *__ctalkFindInstanceMethodByFn (OBJECT **, OBJECT *(*)(void), int);
extern METHOD *__ctalkFindInstanceMethodByName (OBJECT **, const char *, int);
extern OBJECT *__ctalkGetClass (const char *);
extern METHOD *__ctalkGetClassMethodByFn (OBJECT *, OBJECT *(*)(void), int);
extern METHOD *__ctalkGetClassMethodByName (OBJECT *, const char *, int);
extern OBJECT *__ctalkFindClassVariable (char *, int);
extern OBJECT *__ctalkGetClassVariable (OBJECT *, char *, int);
extern CVAR   *__ctalkGetCArg (OBJECT *);
extern EXPR_PARSER *__ctalkGetExprParserAt (int);
extern int     __ctalkGetExprParserPtr (void);
extern METHOD *__ctalkGetInstanceMethodByFn (OBJECT *, OBJECT *(*)(void), int);
extern METHOD *__ctalkGetInstanceMethodByName (OBJECT *, const char *, int);
extern OBJECT *__ctalkGetInstanceVariable (OBJECT *, char *, int);
extern OBJECT *__ctalkGetInstanceVariableByName (char *, char *, int);
extern int     __ctalkGetReceiverPtr (void);
extern CVAR *__ctalkGetTypedef (char *);
extern METHOD *__ctalkFindMethodByFn (OBJECT **, OBJECT *(*)(void), int);
extern METHOD *__ctalkFindMethodByName (OBJECT **, const char *, int);
extern char *__ctalkGetRunTimeException (void);
extern OBJECT *__ctalkGetTemplateCallerCVAR (char *);
extern int    __ctalkHandleInterpreterExceptionInternal (MESSAGE *);
extern int    __ctalkHandleRunTimeException (void);
extern int    __ctalkHandleRunTimeExceptionInternal (void);
extern OBJECT *__ctalkInlineMethod (OBJECT *, METHOD *);
extern void   __ctalkInstanceMethodInitReturnClass (char *, char *, char *);
extern void   __ctalkInstanceMethodParam (char *, char *, char *, char *, int);
extern int    __ctalkInstanceVarsFromClassObject (OBJECT *);
extern char   *__ctalkIntRadixToDecimal (char *);
extern int    __ctalkIsDir (char *);
extern int    __ctalkIsClassVariableOf (OBJECT *, const char *);
extern int    __ctalkIsInstanceVariableOf (OBJECT *, const char *);
extern int     __ctalkIsObject (void *);
extern int     __ctalkIsSubClassOf (char *, char *);
extern OBJECT *__ctalkLibcFnWithMethodVarArgs (int (*)(), METHOD *,char *);
extern char   *__ctalkLongLongRadixToDecimal (char *);
extern void    __ctalkMethodReturnClass (char *);
extern int     __ctalkNewSignalEventInternal (int, int, char *);
extern int __ctalkPendingException (void);
extern int __ctalkPrintObject (char *);
extern int __ctalkRegisterCTypedef (char *, char *, char *, char *, char *, char *, char *, int, int, int, int);
extern OBJECT *__ctalkReplaceVarEntry (VARENTRY *, OBJECT *);
extern void   *__ctalkRtGetMethodFn (void);
extern void    __ctalkRtMethodClass (OBJECT *);
extern OBJECT *__ctalkRtMethodClassObject (void);
/* This function can be inserted before this file, so use the implicit 
 declaration. */
extern int   __ctalkRtSaveSourceFileName (char *);
extern void    __ctalkRtReceiver (OBJECT *);
extern OBJECT *__ctalkRtReceiverObject (void);
extern int __ctalkSelfPrintOn (void);
extern int __ctalkSetObjectValue (OBJECT *, char *);
extern int __ctalkSetObjectValueBuf (OBJECT *, char *);
extern int __ctalkSetObjectValueVar (OBJECT *, char *);
extern int __ctalkSetObjectName (OBJECT *, char *);
extern void __ctalkSleep (int);
extern int __ctalkSysErrExceptionInternal (MESSAGE *, int, char *);
extern void __ctalkTemplateCallerCVARCleanup (void);
extern void *__ctalkToCArrayElement (OBJECT *);
extern char *__ctalkToCCharPtr (OBJECT *, int);
extern int __ctalkToCIntArrayElement (OBJECT *);
extern int __ctalkToCInteger (OBJECT *o, int);
extern I_EXCEPTION *__ctalkTrapException (void);
extern I_EXCEPTION *__ctalkTrapExceptionInternal (MESSAGE *);
extern void __ctalkWarning (char *, ...);
extern int     __ctalk_arg (char *, char *, void *);
extern int     __ctalk_arg_cleanup (void);
extern int     __ctalk_check_args (METHOD *);
extern void    __ctalk_class_initialize (void);
extern OBJECT *__ctalk_define_class (OBJECT **);
extern void    __ctalk_dictionary_add (OBJECT *);
/* This function can be inserted before this file, so use the implicit 
 declaration. */
extern int    __ctalk_exitFn (int);
extern OBJECT *__ctalk_get_object (const char *, const char *);
/* This function can be inserted before this file, so use the implicit 
 declaration. */
extern int    __ctalk_initFn (char *);
extern void    __ctalk_initRtFns (void);
extern void    __ctalk_initLocalObjects (void);
extern OBJECT *__ctalk_method (char *, OBJECT *(*)());
extern OBJECT *__ctalk_new_object (OBJECT **);
extern int     __ctalk_receiver_push (OBJECT *);
extern OBJECT *__ctalk_receiver_pop (void);
extern int     __ctalk_register_c_method_arg (char *, char *, char *, char *, 
				      char *, char *, int, int, int, void *);
extern OBJECT *__ctalk_arg_internal (int);
extern char   __ctalk_to_c_char (OBJECT *);
extern double __ctalk_to_c_double (OBJECT *);
extern int    __ctalk_to_c_int (OBJECT *);
extern char   *__ctalk_to_c_char_ptr (OBJECT *);
extern void   *__ctalk_to_c_ptr (OBJECT *);
extern long long int __ctalk_to_c_longlong (OBJECT *);
extern void   __ctalkDeleteObject (OBJECT *);
extern METHOD *__ctalk_getMethodByFn (OBJECT *, OBJECT *(*)(void));
extern METHOD *__ctalk_getMethodByName (OBJECT *, char *);
extern void __ctalk_primitive_method (char *, char *, int);
extern OBJECT *__ctalk_self_internal (void);
extern void __ctalk_set_global (char *, char *);
extern void __ctalk_set_local (OBJECT *);
extern void __ctalk_init (char *);
extern void __objRefCntSet (OBJREF_T, int);
extern void __refObj (OBJREF_T, OBJREF_T);
extern void __objRefCntInc (OBJREF_T);
extern void __objRefCntDec (OBJREF_T);
extern void *__xalloc (int);
extern void __xfree(void *);

#define ARG(n) (__ctalk_arg_internal(n))

#ifndef TRIM_LITERAL
#define TRIM_LITERAL(s) (substrcpy (s, s, 1, strlen (s) - 2))
#endif
#ifndef TRIM_CHAR
#define TRIM_CHAR(c)    (substrcpy (c, c, 1, strlen (c) - 2))
#endif
#ifndef TRIM_CHAR_BUF
#define TRIM_CHAR_BUF(s) \
  { \
    while ((s[0] == '\'')&&(s[1] != '\0')) \
       substrcpy (s, s, 1, strlen (s) - 2); \
  } \

#endif

#if defined(__GNUC__) && defined(__sparc__) && defined(__svr4__)
#define index strchr
#define rindex strrchr
#define __source_file __set_source_file
/* SunOS headers define these as "__EXTENSION__'s". We should be
   able to use the prototypes from the headers by defining 
   __EXTENSIONS__ and/or _LARGEFILE_SOURCE.  However, we need to 
   declare the prototypes from SunOS math.h here, because the 
   functions can appear in the class libraries and templates
   (which are not preprocessed); i.e., before math.h would be 
   #included in the input.
*/
extern double acosh (double);
extern double asinh (double);
extern double atanh (double);
extern double cbrt (double);
extern double erf (double);
extern double erfc (double);
extern double expm1 (double);
extern long long int atoll(const char *);

/* Solaris 8 needs these. */
extern int strcasecmp(const char *, const char *);
extern int strncasecmp(const char *, const char *, size_t);
#endif /* defined(__GNUC__) && defined(__sparc__) && defined(__svr4__) */

#ifdef __CYGWIN__
/*
 *  Cygwin does not move the include files, so we need
 *  to predeclare some functions here.  Do this by including
 *  the header files.  Otherwise, the compiler will generate
 *  implicit function declaration warnings if you use the -Wall
 *  switch.
 */
int	__attribute__((__cdecl__)) sprintf  (char *, const char *, ...)
                __attribute__ ((__format__ (__printf__, 2, 3)))            ;
int	__attribute__((__cdecl__)) sscanf  (const char *, const char *, ...)
     __attribute__ ((__format__ (__scanf__, 2, 3)))            ;
#endif

#ifndef LIB_BUILD
require Object;
require Symbol;
require Integer;
require String; 
require ArgumentList;

#define methodReturnInteger(i) { char __b[MAXMSG]; \
                                 __ctalkDecimalIntegerToASCII((i),__b); \
                                 return __ctalkCreateObjectInit ("result", \
                                "Integer", "Magnitude", LOCAL_VAR, __b);}
#define methodReturnNULL      { return NULL; }
#define methodReturnObject(__o) { char *__s; __s=__ctalkEvalExpr(#__o)->__o_name; \
                                  return __ctalk_get_object(__s, NULL); }
#define methodReturnObjectName(__o) { return __ctalk_get_object(#__o, NULL); }
#define methodReturnSelf      { return __ctalk_self_internal (); }
#define methodReturnString(s) { return __ctalkCreateObjectInit ("result", \
                                "String", "Character", LOCAL_VAR, (s)); }
#define methodReturnFalse     { return __ctalkCreateObjectInit ("result", \
                                "Boolean", "Integer", LOCAL_VAR, "0"); }
#define methodReturnTrue      { return __ctalkCreateObjectInit ("result", \
                                "Boolean", "Integer", LOCAL_VAR, "1"); }

#endif  /* #ifndef LIB_BUILD */

#define _CTALK_LIB

#endif  /* _CTALK_LIB */


