tclAppInit.cc

Go to the documentation of this file.
00001 /* 
00002  * tclAppInit.c --
00003  *
00004  *  Provides a default version of the main program and Tcl_AppInit
00005  *  procedure for Tcl applications (without Tk).
00006  *
00007  * Copyright (C) 2000 USC/ISI
00008  * Copyright (c) 1993 The Regents of the University of California.
00009  * Copyright (c) 1994-1995 Sun Microsystems, Inc.
00010  *
00011  * See the file "license.terms" for information on usage and redistribution
00012  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
00013  *
00014  * SCCS: @(#) tclAppInit.c 1.17 96/03/26 12:45:29
00015  */
00016 
00017 #include "config.h"
00018 
00019 extern void init_misc(void);
00020 extern EmbeddedTcl et_ns_lib;
00021 extern EmbeddedTcl et_ns_ptypes;
00022 
00023 /* MSVC requires this global var declaration to be outside of 'extern "C"' */
00024 #ifdef MEMDEBUG_SIMULATIONS
00025 #include "mem-trace.h"
00026 MemTrace *globalMemTrace;
00027 #endif
00028 
00029 #define NS_BEGIN_EXTERN_C   extern "C" {
00030 #define NS_END_EXTERN_C     }
00031 
00032 NS_BEGIN_EXTERN_C
00033 
00034 #ifdef HAVE_FENV_H
00035 #include <fenv.h>
00036 #endif /* HAVE_FENV_H */
00037 
00038 /*
00039  * The following variable is a special hack that is needed in order for
00040  * Sun shared libraries to be used for Tcl.
00041  */
00042 
00043 #ifdef TCL_TEST
00044 EXTERN int      Tcltest_Init _ANSI_ARGS_((Tcl_Interp *interp));
00045 #endif /* TCL_TEST */
00046 
00047 /*
00048  *----------------------------------------------------------------------
00049  *
00050  * main --
00051  *
00052  *  This is the main program for the application.
00053  *
00054  * Results:
00055  *  None: Tcl_Main never returns here, so this procedure never
00056  *  returns either.
00057  *
00058  * Side effects:
00059  *  Whatever the application does.
00060  *
00061  *----------------------------------------------------------------------
00062  */
00063 
00064 int
00065 main(int argc, char **argv)
00066 {
00067     Tcl_Main(argc, argv, Tcl_AppInit);
00068     return 0;           /* Needed only to prevent compiler warning. */
00069 }
00070 
00071 #if defined(__i386__) && defined(__GNUC__)
00072 
00073 #define HAVE_NS_SETUP_FPU   /* convenience flag to check on later */
00074     
00075 /* This function is supposed to set up a uniform FPU state on all i386
00076  * platforms.  It may (should) be called instead of functions in the
00077  * fe- family.
00078  */
00079 static void ns_setup_fpu() {
00080 
00081 static const int NS_FPU_CW_IC  = 0x1000; /* Infty control(12): support +/- infinity */
00082 static const int NS_FPU_CW_RC  = 0x0000; /* Round control(11,10): to nearest */
00083 static const int NS_FPU_CW_PC  = 0x0200; /* Precision control(9,8): 53 bits */
00084 static const int NS_FPU_CW_IEM = 0x0000; /* Interrupt enable mask(7): enabled */
00085 static const int NS_FPU_CW_B6  = 0x0040; /* undefined, set to one in my FPU */
00086 static const int NS_FPU_CW_PM  = 0x0020; /* Precision mask(5), inexact exception: disabled */
00087 static const int NS_FPU_CW_UM  = 0x0010; /* Underflow mask(4): disabled */
00088 static const int NS_FPU_CW_OM  = 0x0000; /* Overflow mask(3): enabled */
00089 static const int NS_FPU_CW_ZM  = 0x0000; /* Zero divide mask(2): enabled */
00090 static const int NS_FPU_CW_DM  = 0x0002; /* Denormalized operand(1): disabled */
00091 static const int NS_FPU_CW_IM  = 0x0000; /* Invalid operation mask(0): enabled */
00092 
00093 static const int NS_FPU_CW    = NS_FPU_CW_IC
00094                 | NS_FPU_CW_RC
00095                 | NS_FPU_CW_PC  
00096                 | NS_FPU_CW_IEM 
00097                 | NS_FPU_CW_B6  
00098                 | NS_FPU_CW_PM  
00099                 | NS_FPU_CW_UM  
00100                 | NS_FPU_CW_OM  
00101                 | NS_FPU_CW_ZM  
00102                 | NS_FPU_CW_DM  
00103                 | NS_FPU_CW_IM;
00104 
00105     unsigned short _cw = NS_FPU_CW;
00106     asm ("fldcw %0" : : "m" (*&_cw));
00107 }
00108 #endif /* !HAVE_NS_SETUP_FPU && __i386__ && __GNUC__ */
00109 
00110 #if !defined(HAVE_FESETPRECISION) && defined(__i386__) && defined(__GNUC__)
00111 // use our own!
00112 #define HAVE_FESETPRECISION
00113 /*
00114  * From:
00115  |  Floating-point environment <fenvwm.h>                                    |
00116  | Copyright (C) 1996, 1997, 1998, 1999                                      |
00117  |                     W. Metzenthen, 22 Parker St, Ormond, Vic 3163,        |
00118  |                     Australia.                                            |
00119  |                     E-mail   billm@melbpc.org.au                          |
00120  * used here with permission.
00121  */
00122 #define FE_FLTPREC       0x000
00123 #define FE_INVALIDPREC   0x100
00124 #define FE_DBLPREC       0x200
00125 #define FE_LDBLPREC      0x300
00126 /*
00127  * From:
00128  * fenvwm.c
00129  | Copyright (C) 1999                                                        |
00130  |                     W. Metzenthen, 22 Parker St, Ormond, Vic 3163,        |
00131  |                     Australia.  E-mail   billm@melbpc.org.au              |
00132  * used here with permission.
00133  */
00134 /*
00135   Set the precision to prec if it is a valid
00136   floating point precision macro.
00137   Returns 1 if precision set, 0 otherwise.
00138   */
00139 static inline int fesetprecision(int prec)
00140 {
00141   if ( !(prec & ~FE_LDBLPREC) && (prec != FE_INVALIDPREC) )
00142     {
00143       unsigned short cw;
00144       asm ("fnstcw %0":"=m" (*&cw));
00145       asm ("fwait");
00146 
00147       cw = (cw & ~FE_LDBLPREC) | (prec & FE_LDBLPREC);
00148 
00149       asm volatile ("fldcw %0" : /* Don't push these colons together */ : "m" (*&cw));
00150       return 1;
00151     }
00152   else
00153     return 0;
00154 }
00155 #endif /* !HAVE_FESETPRECISION && __i386__ && __GNUC__ */
00156 
00157 
00158 /*
00159  * setup_floating_point_environment
00160  *
00161  * Set up the floating point environment to be as standard as possible.
00162  *
00163  * For example:
00164  * Linux i386 uses 60-bit floats for calculation,
00165  * not 56-bit floats, giving different results.
00166  * Fix that.
00167  *
00168  * See <http://www.linuxsupportline.com/~billm/faq.html>
00169  * for why we do this fix.
00170  *
00171  * This function is derived from wmexcep
00172  *
00173  */
00174 static inline void
00175 setup_floating_point_environment()
00176 {
00177 #ifdef HAVE_NS_SETUP_FPU
00178 
00179     ns_setup_fpu();
00180 
00181 #else /* !HAVE_NS_SETUP_FPU */
00182 
00183     // In general, try to use the C99 standards to set things up.
00184     // If we can't do that, do nothing and hope the default is right.
00185 #ifdef HAVE_FESETPRECISION
00186     fesetprecision(FE_DBLPREC);
00187 #endif
00188 
00189 #ifdef HAVE_FEENABLEEXCEPT
00190     /*
00191      * In general we'd like to catch some serious exceptions (div by zero)
00192      * and ignore the boring ones (overflow/underflow).
00193      * We set up that up here.
00194      * This depends on feenableexcept which is (currently) GNU
00195      * specific.
00196      */
00197     int trap_exceptions = 0;
00198 #ifdef FE_DIVBYZERO
00199     trap_exceptions |= FE_DIVBYZERO;
00200 #endif
00201 #ifdef FE_INVALID
00202     trap_exceptions |= FE_INVALID;
00203 #endif
00204 #ifdef FE_OVERFLOW
00205     trap_exceptions |= FE_OVERFLOW;
00206 #endif
00207 //#ifdef FE_UNDERFLOW
00208 //  trap_exceptions |= FE_UNDERFLOW;
00209 //#endif
00210     
00211     feenableexcept(trap_exceptions);
00212 #endif /* HAVE_FEENABLEEXCEPT */
00213 #endif /* !HAVE_NS_SETUP_FPU */
00214 }
00215 
00216 
00217 /*
00218  *----------------------------------------------------------------------
00219  *
00220  * Tcl_AppInit --
00221  *
00222  *  This procedure performs application-specific initialization.
00223  *  Most applications, especially those that incorporate additional
00224  *  packages, will have their own version of this procedure.
00225  *
00226  * Results:
00227  *  Returns a standard Tcl completion code, and leaves an error
00228  *  message in interp->result if an error occurs.
00229  *
00230  * Side effects:
00231  *  Depends on the startup script.
00232  *
00233  *----------------------------------------------------------------------
00234  */
00235 
00236 int
00237 Tcl_AppInit(Tcl_Interp *interp)
00238 {
00239 #ifdef MEMDEBUG_SIMULATIONS
00240         extern MemTrace *globalMemTrace;
00241         globalMemTrace = new MemTrace;
00242 #endif
00243 
00244     setup_floating_point_environment();
00245        
00246     if (Tcl_Init(interp) == TCL_ERROR ||
00247         Otcl_Init(interp) == TCL_ERROR)
00248         return TCL_ERROR;
00249 
00250 #ifdef HAVE_LIBTCLDBG
00251     extern int Tcldbg_Init(Tcl_Interp *);   // hackorama
00252     if (Tcldbg_Init(interp) == TCL_ERROR) {
00253         return TCL_ERROR;
00254     }
00255 #endif
00256 
00257     Tcl_SetVar(interp, "tcl_rcFileName", "~/.ns.tcl", TCL_GLOBAL_ONLY);
00258     Tcl::init(interp, "ns");
00259     init_misc();
00260         et_ns_ptypes.load();
00261     et_ns_lib.load();
00262 
00263 
00264 #ifdef TCL_TEST
00265     if (Tcltest_Init(interp) == TCL_ERROR) {
00266         return TCL_ERROR;
00267     }
00268     Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init,
00269               (Tcl_PackageInitProc *) NULL);
00270 #endif /* TCL_TEST */
00271 
00272     return TCL_OK;
00273 }
00274 
00275 #ifndef WIN32
00276 void
00277 abort()
00278 {
00279     Tcl& tcl = Tcl::instance();
00280     tcl.evalc("[Simulator instance] flush-trace");
00281 #ifdef abort
00282 #undef abort
00283     abort();
00284 #else
00285     exit(1);
00286 #endif /*abort*/
00287     /*NOTREACHED*/
00288 }
00289 #endif
00290 
00291 NS_END_EXTERN_C
00292 
00293 

Generated on Tue Mar 6 16:47:51 2007 for ns2 Network Simulator 2.29 by  doxygen 1.4.6