os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/mac/tclMacBOAMain.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* 
sl@0
     2
 * tclMacBGMain.c --
sl@0
     3
 *
sl@0
     4
 *	Main program for Macintosh Background Only Application shells.
sl@0
     5
 *
sl@0
     6
 * Copyright (c) 1997 Sun Microsystems, Inc.
sl@0
     7
 *
sl@0
     8
 * See the file "license.terms" for information on usage and redistribution
sl@0
     9
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
sl@0
    10
 *
sl@0
    11
 * RCS: @(#) $Id: tclMacBOAMain.c,v 1.4 2001/12/28 23:36:31 dgp Exp $
sl@0
    12
 */
sl@0
    13
sl@0
    14
#include "tcl.h"
sl@0
    15
#include "tclInt.h"
sl@0
    16
#include "tclMacInt.h"
sl@0
    17
#include <Resources.h>
sl@0
    18
#include <Notification.h>
sl@0
    19
#include <Strings.h>
sl@0
    20
sl@0
    21
/*
sl@0
    22
 * This variable is used to get out of the modal loop of the
sl@0
    23
 * notification manager.
sl@0
    24
 */
sl@0
    25
sl@0
    26
int NotificationIsDone = 0;
sl@0
    27
sl@0
    28
/*
sl@0
    29
 * The following code ensures that tclLink.c is linked whenever
sl@0
    30
 * Tcl is linked.  Without this code there's no reference to the
sl@0
    31
 * code in that file from anywhere in Tcl, so it may not be
sl@0
    32
 * linked into the application.
sl@0
    33
 */
sl@0
    34
sl@0
    35
EXTERN int Tcl_LinkVar();
sl@0
    36
int (*tclDummyLinkVarPtr)() = Tcl_LinkVar;
sl@0
    37
sl@0
    38
/*
sl@0
    39
 * Declarations for various library procedures and variables (don't want
sl@0
    40
 * to include tclPort.h here, because people might copy this file out of
sl@0
    41
 * the Tcl source directory to make their own modified versions).
sl@0
    42
 * Note:  "exit" should really be declared here, but there's no way to
sl@0
    43
 * declare it without causing conflicts with other definitions elsewher
sl@0
    44
 * on some systems, so it's better just to leave it out.
sl@0
    45
 */
sl@0
    46
sl@0
    47
extern int		isatty _ANSI_ARGS_((int fd));
sl@0
    48
extern char *		strcpy _ANSI_ARGS_((char *dst, CONST char *src));
sl@0
    49
sl@0
    50
static Tcl_Interp *interp;	/* Interpreter for application. */
sl@0
    51
sl@0
    52
/*
sl@0
    53
 * Forward references for procedures defined later in this file:
sl@0
    54
 */
sl@0
    55
sl@0
    56
void TclMacDoNotification(char *mssg);
sl@0
    57
void TclMacNotificationResponse(NMRecPtr nmRec); 
sl@0
    58
int Tcl_MacBGNotifyObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv);
sl@0
    59
sl@0
    60

sl@0
    61
/*
sl@0
    62
 *----------------------------------------------------------------------
sl@0
    63
 *
sl@0
    64
 * Tcl_Main --
sl@0
    65
 *
sl@0
    66
 *	Main program for tclsh and most other Tcl-based applications.
sl@0
    67
 *
sl@0
    68
 * Results:
sl@0
    69
 *	None. This procedure never returns (it exits the process when
sl@0
    70
 *	it's done.
sl@0
    71
 *
sl@0
    72
 * Side effects:
sl@0
    73
 *	This procedure initializes the Tk world and then starts
sl@0
    74
 *	interpreting commands;  almost anything could happen, depending
sl@0
    75
 *	on the script being interpreted.
sl@0
    76
 *
sl@0
    77
 *----------------------------------------------------------------------
sl@0
    78
 */
sl@0
    79
sl@0
    80
void
sl@0
    81
Tcl_Main(argc, argv, appInitProc)
sl@0
    82
    int argc;			/* Number of arguments. */
sl@0
    83
    char **argv;		/* Array of argument strings. */
sl@0
    84
    Tcl_AppInitProc *appInitProc;
sl@0
    85
				/* Application-specific initialization
sl@0
    86
				 * procedure to call after most
sl@0
    87
				 * initialization but before starting to
sl@0
    88
				 * execute commands. */
sl@0
    89
{
sl@0
    90
    Tcl_Obj *prompt1NamePtr = NULL;
sl@0
    91
    Tcl_Obj *prompt2NamePtr = NULL;
sl@0
    92
    Tcl_Obj *commandPtr = NULL;
sl@0
    93
    char buffer[1000], *args, *fileName;
sl@0
    94
    int code, tty;
sl@0
    95
    int exitCode = 0;
sl@0
    96
sl@0
    97
    Tcl_FindExecutable(argv[0]);
sl@0
    98
    interp = Tcl_CreateInterp();
sl@0
    99
    Tcl_InitMemory(interp);
sl@0
   100
sl@0
   101
    /*
sl@0
   102
     * Make command-line arguments available in the Tcl variables "argc"
sl@0
   103
     * and "argv".  If the first argument doesn't start with a "-" then
sl@0
   104
     * strip it off and use it as the name of a script file to process.
sl@0
   105
     */
sl@0
   106
sl@0
   107
    fileName = NULL;
sl@0
   108
    if ((argc > 1) && (argv[1][0] != '-')) {
sl@0
   109
	fileName = argv[1];
sl@0
   110
	argc--;
sl@0
   111
	argv++;
sl@0
   112
    }
sl@0
   113
    args = Tcl_Merge(argc-1, argv+1);
sl@0
   114
    Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);
sl@0
   115
    ckfree(args);
sl@0
   116
    TclFormatInt(buffer, argc-1);
sl@0
   117
    Tcl_SetVar(interp, "argc", buffer, TCL_GLOBAL_ONLY);
sl@0
   118
    Tcl_SetVar(interp, "argv0", (fileName != NULL) ? fileName : argv[0],
sl@0
   119
	    TCL_GLOBAL_ONLY);
sl@0
   120
sl@0
   121
    /*
sl@0
   122
     * Set the "tcl_interactive" variable.
sl@0
   123
     */
sl@0
   124
sl@0
   125
    tty = isatty(0);
sl@0
   126
    Tcl_SetVar(interp, "tcl_interactive",
sl@0
   127
	    ((fileName == NULL) && tty) ? "1" : "0", TCL_GLOBAL_ONLY);
sl@0
   128
    
sl@0
   129
    /*
sl@0
   130
     * Invoke application-specific initialization.
sl@0
   131
     */
sl@0
   132
sl@0
   133
    if ((*appInitProc)(interp) != TCL_OK) {
sl@0
   134
	Tcl_DString errStr;
sl@0
   135
sl@0
   136
	Tcl_DStringInit(&errStr);
sl@0
   137
	Tcl_DStringAppend(&errStr,
sl@0
   138
		"application-specific initialization failed: \n", -1);
sl@0
   139
	Tcl_DStringAppend(&errStr, Tcl_GetStringResult(interp), -1);
sl@0
   140
	Tcl_DStringAppend(&errStr, "\n", 1);
sl@0
   141
	TclMacDoNotification(Tcl_DStringValue(&errStr));
sl@0
   142
	Tcl_DStringFree(&errStr);
sl@0
   143
	goto done;
sl@0
   144
    }
sl@0
   145
sl@0
   146
    /*
sl@0
   147
     * Install the BGNotify command:
sl@0
   148
     */
sl@0
   149
    
sl@0
   150
    if ( Tcl_CreateObjCommand(interp, "bgnotify", Tcl_MacBGNotifyObjCmd, NULL,
sl@0
   151
             (Tcl_CmdDeleteProc *) NULL) == NULL) {
sl@0
   152
        goto done;
sl@0
   153
    }
sl@0
   154
    
sl@0
   155
    /*
sl@0
   156
     * If a script file was specified then just source that file
sl@0
   157
     * and quit.  In this Mac BG Application version, we will try the
sl@0
   158
     * resource fork first, then the file system second...
sl@0
   159
     */
sl@0
   160
sl@0
   161
    if (fileName != NULL) {
sl@0
   162
        Str255 resName;
sl@0
   163
        Handle resource;
sl@0
   164
        
sl@0
   165
        strcpy((char *) resName + 1, fileName);
sl@0
   166
        resName[0] = strlen(fileName);
sl@0
   167
        resource = GetNamedResource('TEXT',resName);
sl@0
   168
        if (resource != NULL) {
sl@0
   169
            code = Tcl_MacEvalResource(interp, fileName, -1, NULL);
sl@0
   170
        } else {
sl@0
   171
            code = Tcl_EvalFile(interp, fileName);
sl@0
   172
        }
sl@0
   173
        
sl@0
   174
	if (code != TCL_OK) {
sl@0
   175
            Tcl_DString errStr;
sl@0
   176
            
sl@0
   177
            Tcl_DStringInit(&errStr);
sl@0
   178
            Tcl_DStringAppend(&errStr, " Error sourcing resource or file: ", -1);
sl@0
   179
            Tcl_DStringAppend(&errStr, fileName, -1);
sl@0
   180
            Tcl_DStringAppend(&errStr, "\n\nError was: ", -1);
sl@0
   181
            Tcl_DStringAppend(&errStr, Tcl_GetStringResult(interp), -1);
sl@0
   182
            TclMacDoNotification(Tcl_DStringValue(&errStr));
sl@0
   183
	    Tcl_DStringFree(&errStr);
sl@0
   184
        }
sl@0
   185
	goto done;
sl@0
   186
    }
sl@0
   187
sl@0
   188
sl@0
   189
    /*
sl@0
   190
     * Rather than calling exit, invoke the "exit" command so that
sl@0
   191
     * users can replace "exit" with some other command to do additional
sl@0
   192
     * cleanup on exit.  The Tcl_Eval call should never return.
sl@0
   193
     */
sl@0
   194
sl@0
   195
    done:
sl@0
   196
    if (commandPtr != NULL) {
sl@0
   197
	Tcl_DecrRefCount(commandPtr);
sl@0
   198
    }
sl@0
   199
    if (prompt1NamePtr != NULL) {
sl@0
   200
	Tcl_DecrRefCount(prompt1NamePtr);
sl@0
   201
    }
sl@0
   202
    if (prompt2NamePtr != NULL) {
sl@0
   203
	Tcl_DecrRefCount(prompt2NamePtr);
sl@0
   204
    }
sl@0
   205
    sprintf(buffer, "exit %d", exitCode);
sl@0
   206
    Tcl_Eval(interp, buffer);
sl@0
   207
}
sl@0
   208

sl@0
   209
/*----------------------------------------------------------------------
sl@0
   210
 *
sl@0
   211
 * TclMacDoNotification --
sl@0
   212
 *
sl@0
   213
 *	This posts an error message using the Notification manager.
sl@0
   214
 *
sl@0
   215
 * Results:
sl@0
   216
 *	Post a Notification Manager dialog.
sl@0
   217
 *
sl@0
   218
 * Side effects:
sl@0
   219
 *	None.
sl@0
   220
 *
sl@0
   221
 *----------------------------------------------------------------------
sl@0
   222
 */
sl@0
   223
void 
sl@0
   224
TclMacDoNotification(mssg)
sl@0
   225
    char *mssg;
sl@0
   226
{
sl@0
   227
    NMRec errorNot;
sl@0
   228
    EventRecord *theEvent = NULL;
sl@0
   229
    OSErr err;
sl@0
   230
    char *ptr;
sl@0
   231
    
sl@0
   232
    errorNot.qType = nmType;
sl@0
   233
    errorNot.nmMark = 0;
sl@0
   234
    errorNot.nmIcon = 0;
sl@0
   235
    errorNot.nmSound = (Handle) -1;
sl@0
   236
sl@0
   237
    for ( ptr = mssg; *ptr != '\0'; ptr++) {
sl@0
   238
        if (*ptr == '\n') {
sl@0
   239
            *ptr = '\r';
sl@0
   240
        }
sl@0
   241
    }
sl@0
   242
        
sl@0
   243
    c2pstr(mssg);
sl@0
   244
    errorNot.nmStr = (StringPtr) mssg;
sl@0
   245
sl@0
   246
    errorNot.nmResp = NewNMProc(TclMacNotificationResponse);
sl@0
   247
    errorNot.nmRefCon = SetCurrentA5();
sl@0
   248
    
sl@0
   249
    NotificationIsDone = 0;
sl@0
   250
    
sl@0
   251
    /*
sl@0
   252
     * Cycle while waiting for the user to click on the
sl@0
   253
     * notification box.  Don't take any events off the event queue,
sl@0
   254
     * since we want Tcl to do this but we want to block till the notification
sl@0
   255
     * has been handled...
sl@0
   256
     */
sl@0
   257
    
sl@0
   258
    err = NMInstall(&errorNot);
sl@0
   259
    if (err == noErr) { 
sl@0
   260
        while (!NotificationIsDone) {
sl@0
   261
            WaitNextEvent(0, theEvent, 20, NULL);
sl@0
   262
        }
sl@0
   263
        NMRemove(&errorNot);
sl@0
   264
    }
sl@0
   265
    	
sl@0
   266
    p2cstr((unsigned char *) mssg);
sl@0
   267
}
sl@0
   268
sl@0
   269
void 
sl@0
   270
TclMacNotificationResponse(nmRec) 
sl@0
   271
    NMRecPtr nmRec;
sl@0
   272
{
sl@0
   273
    int curA5;
sl@0
   274
    
sl@0
   275
    curA5 = SetCurrentA5();
sl@0
   276
    SetA5(nmRec->nmRefCon);
sl@0
   277
    
sl@0
   278
    NotificationIsDone = 1;
sl@0
   279
    
sl@0
   280
    SetA5(curA5);
sl@0
   281
    
sl@0
   282
}
sl@0
   283
sl@0
   284
int 
sl@0
   285
Tcl_MacBGNotifyObjCmd(clientData, interp, objc, objv)
sl@0
   286
    ClientData clientData;
sl@0
   287
    Tcl_Interp *interp;
sl@0
   288
    int objc;
sl@0
   289
    Tcl_Obj **objv;	
sl@0
   290
{
sl@0
   291
    Tcl_Obj *resultPtr;
sl@0
   292
    
sl@0
   293
    resultPtr = Tcl_GetObjResult(interp);
sl@0
   294
    
sl@0
   295
    if ( objc != 2 ) {
sl@0
   296
        Tcl_WrongNumArgs(interp, 1, objv, "message");
sl@0
   297
        return TCL_ERROR;
sl@0
   298
    }
sl@0
   299
    
sl@0
   300
    TclMacDoNotification(Tcl_GetString(objv[1]));
sl@0
   301
    return TCL_OK;
sl@0
   302
           
sl@0
   303
}
sl@0
   304