Annotation of capa/capa51/GUITools/tcl2c-qz.c, revision 1.1.1.1

1.1       albertel    1: #include <tcl.h>
                      2: #include <stdio.h>
                      3: 
                      4: #ifdef __cplusplus
                      5: extern C {
                      6: #endif
                      7: 
                      8: extern void exit _ANSI_ARGS_((int status));
                      9: extern int isupper _ANSI_ARGS_((int ch));
                     10: extern int tolower _ANSI_ARGS_((int ch));
                     11: 
                     12: #ifdef __cplusplus
                     13: }
                     14: #endif
                     15: 
                     16: #define MAX_STRING_LEN 8192 /* give warning if string length exceeds this value */
                     17: 
                     18: #ifdef NO_STRING_H
                     19: #   include <strings.h>
                     20: #   define strchr index
                     21: #   define strrchr rindex
                     22: #else
                     23: #   include <string.h>
                     24: #endif
                     25: 
                     26: typedef struct tableitem {
                     27:     char *package;/* corresponding packagename */
                     28:     char *option; /* option expected */
                     29:     int flag ;    /* which packages are needed */
                     30: } tableitem;
                     31: 
                     32: static tableitem table[] = {
                     33: {"Tcl"  ,"-tcl"  ,  1},
                     34: {"Tk"   ,"-tk"   ,  3},
                     35: {"Tclx" ,"-tclx" ,  5},
                     36: {"Itcl" ,"-itcl" ,  9},
                     37: {"Otcl" ,"-otcl" , 17},	/* not tested yet */
                     38: {"Pvm"  ,"-pvm"  , 33},
                     39: {"Tkx"  ,"-tkx"  , 71},
                     40: {"Itk"  ,"-itk" ,  139},
                     41: {"Iwidgets" ,"-iwidgets" ,  395},
                     42: {"Img"  ,"-img"  ,515},
                     43: {"Tix"  ,"-tix"  ,1027}, /* not tested yet */
                     44: {"Blt"  ,"-blt"  ,2051}, /* not tested yet */
                     45: {"Vtcl" ,"-vtcl" ,4103}, /* not tested yet */
                     46: {"Quizzer", "-qz",8195},
                     47: {"Grader", "-gd", 16387},
                     48: {"Manager", "-mn", 32771},
                     49: {"Webpage", "-wb", 65537},
                     50: };
                     51: 
                     52: static char *verbose = "\n\
                     53: *************************** tcl2c ********************************\n\
                     54: written by: Jan Nijtmans\n\
                     55:             CMG (Computer Management Group) Arnhem B.V.\n\
                     56: 	    email: nijtmans@worldaccess.nl (private)\n\
                     57: 	           Jan.Nijtmans@cmg.nl (work)\n\
                     58: 	    url:   http://www.worldaccess.nl/~nijtmans/\n\n\
                     59: Modified by: Guy Albertelli \n\n\
                     60: usage:	tcl2c -o file source1 source2 ... ?options?\n\
                     61: 	tcl2c -help\n\
                     62: ";
                     63: 
                     64: static char *help = "\n\
                     65: available options:\n\
                     66:         -a              use character array instead of string for script\n\
                     67:         -n script_name  name of script variable\n\
                     68:         -o filename	output file (default is stdout)\n\
                     69: 	-tcl		use Tcl\n\
                     70: 	-tclx		use Tclx\n\
                     71: 	-otcl		use Otcl (not tested yet)\n\
                     72: 	-pvm		use tkPvm\n\
                     73: 	-tk		use Tk\n\
                     74: 	-tkx		use Tkx (not really useful)\n\
                     75: 	-img		use Img\n\
                     76: 	-tix		use Tix (not tested yet)\n\
                     77: 	-blt		use Blt (not tested yet)\n\
                     78: 	-vtcl		use Vtcl (not tested yet)\n\
                     79:         -qz	    use Quizzer\n\
                     80: 	-gd	    use Grader\n\
                     81: Other command line arguments are assumed to be tcl script-files. It is \n\
                     82: possible to include C-files (with the extension .c), which are already\n\
                     83: converted tcl-scripts. These are included using the \"#include\".\n\n\
                     84: The output file can be compiled with any C or C++ compiler.\n\
                     85: ";
                     86: 
                     87: static char *part1 = "\n\
                     88: /* This file is created by the \"tcl2c-qz\" utility, which is included in\n\
                     89:  * most \"plus\"-patches (e.g. for Tcl7.6 and Tcl8.0). Standalone\n\
                     90:  * executables can be made by providing alternative initialization\n\
                     91:  * functions which don't read files any more. Sometimes, small\n\
                     92:  * adaptations to the original libraries are needed to get the\n\
                     93:  * application truly standalone. The \"plus\"-patches contain these\n\
                     94:  * adaptations for Tcl and Tk. If you just create your own\n\
                     95:  * Xxx_InitStandAlone() function for your package, you can\n\
                     96:  * easyly extend the \"tcl2c\" utility to your own requirements.\n\
                     97:  *\n\
                     98:  *	Jan Nijtmans\n\
                     99:  *	CMG (Computer Management Group) Arnhem B.V.\n\
                    100:  *	email: nijtmans@worldaccess.nl (private)\n\
                    101:  *	       Jan.Nijtmans@cmg.nl (work)\n\
                    102:  *	url:   http://www.worldaccess.nl/~nijtmans/\n\
                    103:  */\n\
                    104: #include \"tcl.h\"\n\
                    105: #ifdef __WIN32__\n\
                    106: #define WIN32_LEAN_AND_MEAN\n\
                    107: #include <windows.h>\n\
                    108: #undef WIN32_LEAN_AND_MEAN\n\
                    109: #include <malloc.h>\n\
                    110: #include <locale.h>\n\
                    111: \n\
                    112: static int setargv _ANSI_ARGS_((char ***argvPtr));\n\
                    113: static void TclshPanic _ANSI_ARGS_(TCL_VARARGS(char *,format));\n\
                    114: extern void TclWinSetTclInstance(HINSTANCE instance);\n\
                    115: \n\
                    116: #endif\n\
                    117: \n\
                    118: /*\n\
                    119:  * Defines to replace the standard Xxx_Init calls to Xxx_InitStandAlone.\n\
                    120:  * If you don't have this function, just delete the corresponding\n\
                    121:  * define such that the normal initialization function is used.\n\
                    122:  * Similar: If SafeInit functions exists, you can use these\n\
                    123:  * by commenting out the corresponding lines below.\n\
                    124:  */\n\
                    125: \n\
                    126: #if defined(TCL_ACTIVE) && !defined(SHARED)\n\
                    127: ";
                    128: 
                    129: static char *part2 = "#endif\n\
                    130: \n\
                    131: #if TCL_MAJOR_VERSION < 8\n\
                    132: ";
                    133: 
                    134: static char *part3 = "\
                    135: #endif\n\
                    136: \n\
                    137: /*\n\
                    138:  * Prototypes of all initialization functions and the free() function.\n\
                    139:  * So, only \"tcl.h\" needs to be included now.\n\
                    140:  */\n\
                    141: \n\
                    142: #ifdef __cplusplus\n\
                    143: extern \"C\" {\n\
                    144: #endif\n\
                    145: \n\
                    146: #ifndef USE_TCLALLOC\n\
                    147: #   define USE_TCLALLOC 0\n\
                    148: #endif\n\
                    149: #if USE_TCLALLOC == 0\n\
                    150: extern void free _ANSI_ARGS_((void *));\n\
                    151: #endif\n\
                    152: extern int  Tcl_Init _ANSI_ARGS_((Tcl_Interp *interp));\n\
                    153: \n\
                    154: ";
                    155: 
                    156: static char *part3a = "\n\
                    157: extern void Tk_MainLoop _ANSI_ARGS_((void));\n\
                    158: #define HAS_TK\n\
                    159: #ifdef __WIN32__\n\
                    160: extern void TkWinXInit _ANSI_ARGS_((HINSTANCE hinstance));\n\
                    161: extern void TkWinXCleanup _ANSI_ARGS_((HINSTANCE hinstance));\n\
                    162: #endif\n\
                    163: \n\
                    164: ";
                    165: 
                    166: static char *part4 = "\n\
                    167: \n\
                    168: #ifdef __cplusplus\n\
                    169: }\n\
                    170: #endif\n\
                    171: \n\
                    172: /*\n\
                    173:  * The array \"%s\" contains the script that is compiled in.\n\
                    174:  * It will be executed in tclAppInit() after the other initializations.\n\
                    175:  */\n\
                    176: \n\
                    177: ";
                    178: 
                    179: static char *part4a = "\
                    180: static char *lineformat = \"%%.0s%%d\";\n\
                    181: static int line = (__LINE__ + 1);\n\
                    182: ";
                    183: 
                    184: static char *part4b = "\
                    185: static char *lineformat = \"%%s_line%%d\";\n\
                    186: static int line = 0;\n\
                    187: ";
                    188: 
                    189: static char *part5 = "\
                    190: /*\n\
                    191:  *----------------------------------------------------------------------\n\
                    192:  *\n\
                    193:  * main --\n\
                    194:  *\n\
                    195:  *	This is the main program for the application.\n\
                    196:  *\n\
                    197:  * Results:\n\
                    198:  *	None.\n\
                    199:  *\n\
                    200:  * Side effects:\n\
                    201:  *	Whatever the application does.\n\
                    202:  *\n\
                    203:  *----------------------------------------------------------------------\n\
                    204:  */\n\
                    205: \n\
                    206: #if defined(__WIN32__) && defined(HAS_TK)\n\
                    207: int APIENTRY\n\
                    208: WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)\n\
                    209:     HINSTANCE hInstance;\n\
                    210:     HINSTANCE hPrevInstance;\n\
                    211:     LPSTR lpszCmdLine;\n\
                    212:     int nCmdShow;\n\
                    213: {\n\
                    214:     char **argv;\n\
                    215:     int argc;\n\
                    216: #else\n\
                    217: ";
                    218: 
                    219: static char *part5a = "\
                    220: int\n\
                    221: #ifdef _USING_PROTOTYPES_\n\
                    222: main (int    argc,		/* Number of command-line arguments. */\n\
                    223:       char **argv)		/* Values of command-line arguments. */\n\
                    224: #else\n\
                    225: main(argc, argv)\n\
                    226:     int argc;			/* Number of command-line arguments. */\n\
                    227:     char **argv;		/* Values of command-line arguments. */\n\
                    228: #endif\n\
                    229: {\n\
                    230: #endif\n\
                    231:     Tcl_Interp *interp;\n\
                    232:     char **p = %s;\n\
                    233:     char *q, buffer[256];\n\
                    234:     Tcl_DString data;\n\
                    235:     Tcl_Channel inChannel, outChannel, errChannel;\n\
                    236: \n\
                    237: #ifdef __WIN32__\n\
                    238: #if defined(TCL_ACTIVE) && !defined(SHARED) && defined(HAS_TK)\n\
                    239:     TclWinSetTclInstance(hInstance);\n\
                    240:     TkWinXInit(hInstance);\n\
                    241:     Tcl_CreateExitHandler((Tcl_ExitProc *) TkWinXCleanup, (ClientData) hInstance);\n\
                    242: #endif\n\
                    243: \n\
                    244:     Tcl_SetPanicProc(TclshPanic);\n\
                    245: \n";
                    246: 
                    247: static char *part5b = "\n\
                    248:     /*\n\
                    249:      * Set up the default locale to be standard \"C\" locale so parsing\n\
                    250:      * is performed correctly.\n\
                    251:      */\n\
                    252: \n\
                    253:     setlocale(LC_ALL, \"C\");\n\
                    254: \n\
                    255:     /*\n\
                    256:      * Increase the application queue size from default value of 8.\n\
                    257:      * At the default value, cross application SendMessage of WM_KILLFOCUS\n\
                    258:      * will fail because the handler will not be able to do a PostMessage!\n\
                    259:      * This is only needed for Windows 3.x, since NT dynamically expands\n\
                    260:      * the queue.\n\
                    261:      */\n\
                    262:     SetMessageQueue(64);\n\
                    263: \n\
                    264:     argc = setargv(&argv);\n\
                    265: \n\
                    266:     /*\n\
                    267:      * Replace argv[0] with full pathname of executable, and forward\n\
                    268:      * slashes substituted for backslashes.\n\
                    269:      */\n\
                    270: \n\
                    271: ";
                    272: 
                    273: static char *part5c = "\
                    274:     GetModuleFileName(NULL, buffer, sizeof(buffer));\n\
                    275:     argv[0] = buffer;\n\
                    276:     for (q = buffer; *q != '\\0'; q++) {\n\
                    277: 	if (*q == '\\\\') {\n\
                    278: 	    *q = '/';\n\
                    279: 	}\n\
                    280:     }\n\
                    281: \n\
                    282: #endif\n\
                    283:     Tcl_FindExecutable(argv[0]);\n\
                    284:     interp = Tcl_CreateInterp();\n\
                    285: \n\
                    286:     q = Tcl_Merge(argc-1, argv+1);\n\
                    287:     Tcl_SetVar(interp, \"argv\", q, TCL_GLOBAL_ONLY);\n\
                    288:     ckfree(q);\n\
                    289:     sprintf(buffer, \"%%d\", argc-1);\n\
                    290:     Tcl_SetVar(interp, \"argc\", buffer, TCL_GLOBAL_ONLY);\n\
                    291:     Tcl_SetVar(interp, \"argv0\", argv[0],TCL_GLOBAL_ONLY);\n\
                    292:     Tcl_SetVar(interp, \"tcl_interactive\",\"0\", TCL_GLOBAL_ONLY);\n\
                    293: \n\
                    294: ";
                    295: 
                    296: static char *part6 = "\n\
                    297:     /*\n\
                    298:      * Execute the script that is compiled in.\n\
                    299:      */\n\
                    300: \n\
                    301:     inChannel = Tcl_GetStdChannel(TCL_STDIN);\n\
                    302:     outChannel = Tcl_GetStdChannel(TCL_STDOUT);\n\
                    303:     Tcl_DStringInit(&data);\n\
                    304:     while(*p) {\n\
                    305: 	Tcl_DStringSetLength(&data,0);\n\
                    306: 	Tcl_DStringAppend(&data,*p++,-1);\n\
                    307: 	if (Tcl_Eval(interp,Tcl_DStringValue(&data)) != TCL_OK) {\n\
                    308: 	    Tcl_DStringFree(&data);\n\
                    309: 	    while (p-- != %s) {\n\
                    310: 		for (q = *p;*q; q++) {\n\
                    311: 		    if (*q=='\\n') line++;\n\
                    312: 		}\n\
                    313: 		line++;\n\
                    314: 	    }\n\
                    315: 	    sprintf(buffer,lineformat,\"%s\",line);\n\
                    316: 	    Tcl_AddErrorInfo(interp,\"\\n	( Error in file: \\\"\");\n\
                    317: 	    Tcl_AddErrorInfo(interp,__FILE__);\n\
                    318: 	    Tcl_AddErrorInfo(interp,\"\\\", line: \");\n\
                    319: 	    Tcl_AddErrorInfo(interp,buffer);\n\
                    320: 	    Tcl_AddErrorInfo(interp,\")\");\n\
                    321: 	    errChannel = Tcl_GetStdChannel(TCL_STDERR);\n\
                    322: 	    if (errChannel) {\n\
                    323: 		Tcl_Write(errChannel,\n\
                    324: 			Tcl_GetVar(interp, \"errorInfo\", TCL_GLOBAL_ONLY), -1);\n\
                    325: 		Tcl_Write(errChannel, \"\\n\", 1);\n\
                    326: 	    }\n\
                    327: #ifdef __WIN32__\n\
                    328: 	    TclshPanic(Tcl_GetVar(interp, \"errorInfo\", TCL_GLOBAL_ONLY));\n\
                    329: #endif\n\
                    330: 	    sprintf(buffer, \"exit %%d\", 1);\n\
                    331: 	    Tcl_Eval(interp, buffer);\n\
                    332: 	}\n\
                    333:     }\n\
                    334:     Tcl_DStringFree(&data);\n\
                    335: ";
                    336: 
                    337: static char *part6a = "\
                    338:     Tk_MainLoop();\n\
                    339: ";
                    340: 
                    341: static char *part6b = "\
                    342:     sprintf(buffer, \"exit %%d\", 0);\n\
                    343:     Tcl_Eval(interp, buffer);\n\
                    344: \n\
                    345: error:\n\
                    346:     errChannel = Tcl_GetStdChannel(TCL_STDERR);\n\
                    347:     if (errChannel) {\n\
                    348: 	Tcl_Write(errChannel,\n\
                    349: 		\"application-specific initialization failed: \", -1);\n\
                    350: 	Tcl_Write(errChannel, interp->result, -1);\n\
                    351: 	Tcl_Write(errChannel, \"\\n\", 1);\n\
                    352:     }\n\
                    353: #ifdef __WIN32__\n\
                    354:     TclshPanic(interp->result);\n\
                    355: #endif\n\
                    356:     sprintf(buffer, \"exit %%d\", 1);\n\
                    357:     Tcl_Eval(interp, buffer);\n\
                    358:     return 0;\n\
                    359: }\n\
                    360: \n\
                    361: #ifdef __WIN32__\n\
                    362: /*\n\
                    363:  *----------------------------------------------------------------------\n\
                    364:  *\n\
                    365:  * TclshPanic --\n\
                    366:  *\n\
                    367:  *	Display a message and exit.\n\
                    368:  *\n\
                    369:  * Results:\n\
                    370:  *	None.\n\
                    371:  *\n\
                    372:  * Side effects:\n\
                    373:  *	Exits the program.\n\
                    374:  *\n\
                    375:  *----------------------------------------------------------------------\n\
                    376:  */\n\
                    377: \n\
                    378: void\n\
                    379: TclshPanic TCL_VARARGS_DEF(char *,arg1)\n\
                    380: {\n\
                    381:     va_list argList;\n\
                    382:     char buf[1024];\n\
                    383:     char *format;\n\
                    384: \n\
                    385:     format = TCL_VARARGS_START(char *,arg1,argList);\n\
                    386:     vsprintf(buf, format, argList);\n\
                    387: \n\
                    388:     MessageBeep(MB_ICONEXCLAMATION);\n\
                    389:     MessageBox(NULL, buf, \"Fatal Error in Tclsh\",\n\
                    390: 	    MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);\n\
                    391: #ifdef _MSC_VER\n\
                    392:     _asm {\n\
                    393:         int 3\n\
                    394:     }\n\
                    395: #endif\n\
                    396:     ExitProcess(1);\n\
                    397: }\n\
                    398: ";
                    399: 
                    400: static char *part6c = "\
                    401: \n\
                    402: /*\n\
                    403:  *-------------------------------------------------------------------------\n\
                    404:  *\n\
                    405:  * setargv --\n\
                    406:  *\n\
                    407:  *	Parse the Windows command line string into argc/argv.  Done here\n\
                    408:  *	because we don't trust the builtin argument parser in crt0.  \n\
                    409:  *	Windows applications are responsible for breaking their command\n\
                    410:  *	line into arguments.\n\
                    411:  *\n\
                    412:  *	2N backslashes + quote -> N backslashes + begin quoted string\n\
                    413:  *	2N + 1 backslashes + quote -> literal\n\
                    414:  *	N backslashes + non-quote -> literal\n\
                    415:  *	quote + quote in a quoted string -> single quote\n\
                    416:  *	quote + quote not in quoted string -> empty string\n\
                    417:  *	quote -> begin quoted string\n\
                    418:  *\n\
                    419:  * Results:\n\
                    420:  *	returns the number of arguments and fill argvPtr with the\n\
                    421:  *	array of arguments.\n\
                    422:  *\n\
                    423:  * Side effects:\n\
                    424:  *	Memory allocated.\n\
                    425:  *\n\
                    426:  *--------------------------------------------------------------------------\n\
                    427:  */\n\
                    428: \n\
                    429: ";
                    430: 
                    431: static char *part6d = "\
                    432: static int\n\
                    433: setargv(argvPtr)\n\
                    434:     char ***argvPtr;		/* Filled with argument strings (malloc'd). */\n\
                    435: {\n\
                    436:     char *cmdLine, *p, *arg, *argSpace;\n\
                    437:     char **argv;\n\
                    438:     int argc, size, inquote, copy, slashes;\n\
                    439: \n\
                    440:     cmdLine = GetCommandLine();\n\
                    441: \n\
                    442:     /*\n\
                    443:      * Precompute an overly pessimistic guess at the number of arguments\n\
                    444:      * in the command line by counting non-space spans.\n\
                    445:      */\n\
                    446: \n\
                    447:     size = 2;\n\
                    448:     for (p = cmdLine; *p != '\\0'; p++) {\n\
                    449: 	if (isspace(*p)) {\n\
                    450: 	    size++;\n\
                    451: 	    while (isspace(*p)) {\n\
                    452: 		p++;\n\
                    453: 	    }\n\
                    454: 	    if (*p == '\\0') {\n\
                    455: 		break;\n\
                    456: 	    }\n\
                    457: 	}\n\
                    458:     }\n\
                    459:     argSpace = (char *) ckalloc((unsigned) (size * sizeof(char *)\n\
                    460: 	    + strlen(cmdLine) + 1));\n\
                    461:     argv = (char **) argSpace;\n\
                    462:     argSpace += size * sizeof(char *);\n\
                    463:     size--;\n\
                    464: \n\
                    465:     p = cmdLine;\n\
                    466:     for (argc = 0; argc < size; argc++) {\n\
                    467: 	argv[argc] = arg = argSpace;\n\
                    468: 	while (isspace(*p)) {\n\
                    469: 	    p++;\n\
                    470: 	}\n\
                    471: 	if (*p == '\\0') {\n\
                    472: 	    break;\n\
                    473: 	}\n\
                    474: \n\
                    475: ";
                    476: 
                    477: static char *part6e = "\
                    478: 	inquote = 0;\n\
                    479: 	slashes = 0;\n\
                    480: 	while (1) {\n\
                    481: 	    copy = 1;\n\
                    482: 	    while (*p == '\\\\') {\n\
                    483: 		slashes++;\n\
                    484: 		p++;\n\
                    485: 	    }\n\
                    486: 	    if (*p == '\"') {\n\
                    487: 		if ((slashes & 1) == 0) {\n\
                    488: 		    copy = 0;\n\
                    489: 		    if ((inquote) && (p[1] == '\"')) {\n\
                    490: 			p++;\n\
                    491: 			copy = 1;\n\
                    492: 		    } else {\n\
                    493: 			inquote = !inquote;\n\
                    494: 		    }\n\
                    495:                 }\n\
                    496:                 slashes >>= 1;\n\
                    497:             }\n\
                    498: \n\
                    499:             while (slashes) {\n\
                    500: 		*arg = '\\\\';\n\
                    501: 		arg++;\n\
                    502: 		slashes--;\n\
                    503: 	    }\n\
                    504: \n\
                    505: 	    if ((*p == '\\0') || (!inquote && isspace(*p))) {\n\
                    506: 		break;\n\
                    507: 	    }\n\
                    508: 	    if (copy != 0) {\n\
                    509: 		*arg = *p;\n\
                    510: 		arg++;\n\
                    511: 	    }\n\
                    512: 	    p++;\n\
                    513:         }\n\
                    514: 	*arg = '\\0';\n\
                    515: 	argSpace = arg + 1;\n\
                    516:     }\n\
                    517:     argv[argc] = NULL;\n\
                    518: \n\
                    519:     *argvPtr = argv;\n\
                    520:     return argc;\n\
                    521: }\n\
                    522: #endif /* __WIN32__ */\n\
                    523: ";
                    524: 
                    525: static char *partwebpage ="\
                    526:  if (argc >1) {\n\
                    527:     if (!strcmp(argv[1],\"-emailcapaid\")) { emailcapaid(argc,argv);return 0;}\n\
                    528:     if (!strcmp(argv[1],\"-getid\")) { getid(argc,argv);return 0;}\n\
                    529:   }\n\
                    530: ";
                    531: 
                    532: static char *defineproto1 = "\
                    533: #define %s_Init %s_InitStandAlone\n\
                    534: ";
                    535: 
                    536: static char *defineproto2 = "\
                    537: #define %s_SafeInit (Tcl_PackageInitProc *) NULL\n\
                    538: ";
                    539: 
                    540: static char *initproto = "\
                    541: extern int  %s_Init _ANSI_ARGS_((Tcl_Interp *interp));\n\
                    542: #ifndef %s_SafeInit\n\
                    543: extern int  %s_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));\n\
                    544: #endif\n\
                    545: ";
                    546: 
                    547: static char *packageproto = "\
                    548:     Tcl_StaticPackage(interp, \"%s\", %s_Init, %s_SafeInit);\n\
                    549: ";
                    550: 
                    551: static char *callinit = "\
                    552:     if (%s_Init(interp) != TCL_OK) {\n\
                    553:         goto error;\n\
                    554:     }\n\
                    555: ";
                    556: 
                    557: static char buffer[32768];
                    558: static unsigned int max_buffer = 0;
                    559: static char max_buffer_content[80];
                    560: 
                    561: static char array_instead_of_string = 0;
                    562: static unsigned int num_lines = 0;
                    563: 
                    564: static char script_name[256];
                    565: 
                    566: int printline _ANSI_ARGS_((FILE *f, char *buf, char *dir, int flags));
                    567: int printfile _ANSI_ARGS_((FILE *fout, char *filename, char *dir, int flags));
                    568: 
                    569: int
                    570: #ifdef _USING_PROTOTYPES_
                    571: printline (
                    572:     FILE *f,
                    573:     char *buf,
                    574:     char *dir,
                    575:     int flags)
                    576: #else
                    577: printline(f,buf,dir,flags)
                    578:     FILE *f;
                    579:     char *buf;
                    580:     char *dir;
                    581:     int flags;
                    582: #endif
                    583: {
                    584:     char *p,*q;
                    585:     char path[128];
                    586:     unsigned int l;
                    587: 
                    588:     p=buf; while (*p=='\t' || *p==' ') p++;
                    589:     if (!strncmp(p,"catch",5)) {
                    590: 	q=p+5; while (*q=='\t' || *q==' ') q++;
                    591: 	if (*q++=='{') {
                    592: 	    while (*q=='\t' || *q==' ') q++;
                    593: 	    if (strncmp(q,"source",6)) q=(char *)NULL;
                    594: 	} else {
                    595: 	    q=(char *)NULL;
                    596: 	}
                    597:     } else {
                    598: 	q=(char *)NULL;
                    599:     }
                    600:     if (!strncmp(p,"source",6) || q) {
                    601: 	if (q!=(char *)NULL) {
                    602: 	    p = q;	    
                    603: 	}
                    604: 	p += 6;
                    605: 	while(*p=='\t' || *p==' ') p++;
                    606: 	if (*p=='/') {
                    607: 	    strcpy(path,p);
                    608: 	} else {
                    609: 	    strcpy(path,dir);
                    610: 	    strcat(path,p);
                    611: 	}
                    612: 	if (q) {
                    613: 	    q=strrchr(p,'}');
                    614: 	    if (q) {
                    615: 		*q=0;
                    616: 	    }
                    617: 	}
                    618: 
                    619: 	if (!printfile(f, path, dir, flags)) {
                    620: 	    return 0;
                    621: 	} else {
                    622: 	    p = strrchr(p,'/');
                    623: 	    if (p) {
                    624: 		strcpy(path,dir);
                    625: 		strcat(path,p+1);
                    626: 		if (!printfile(f ,path ,dir, flags)) {
                    627: 		    return 0;
                    628: 		}
                    629: 	    }
                    630: 	}
                    631: 	if (q) {
                    632: 	    *q='}';
                    633: 	}
                    634:     }
                    635:     p = buf;
                    636:     while ((p = strstr(p, "[list source [file join $dir")) != NULL) {
                    637: 	q = strstr(p,".tcl]]");
                    638: 	if (q != NULL) {
                    639: 	    memcpy(p,"{source -rsrc",13);
                    640: 	    memcpy(p+13,p+28,q-p-28);
                    641: 	    memcpy(q-15,"}",1);
                    642: 	    strcpy(q-14,q+6);
                    643: 	} else {
                    644: 	    p++;
                    645: 	}
                    646:     }
                    647:     if (array_instead_of_string) {
                    648:       fprintf(f, "\nstatic char %s_line%d[] = {\n   ",
                    649:          script_name, ++num_lines);
                    650:       while (*buf) {
                    651:          for (l = 0; *buf && l < 14; l++) {
                    652:             fputc('\'', f);
                    653:             if (*buf == '\n') { fprintf(f,"\\n',"); buf++; continue; }
                    654:             if (*buf == '\'' || *buf == '\\') fputc('\\', f);
                    655:             fprintf(f, "%c',", *buf++);
                    656:          }
                    657:          fprintf(f, "\n   ");
                    658:       }
                    659:       fprintf(f, "'\\0' };\n");
                    660:     } else {
                    661:       fputc('\"',f);
                    662:       l = strlen(buf);
                    663:       if (l>max_buffer) {
                    664: 	max_buffer = l;
                    665: 	p = (strchr(buf,'\n'));
                    666: 	if (p) {
                    667: 	    l = p - buf;
                    668: 	} else {
                    669: 	    l = strlen(buf);
                    670: 	}
                    671: 	if (l>72) {l = 72;}
                    672: 	memcpy(max_buffer_content,buf,l);
                    673: 	max_buffer_content[l] = 0;
                    674:       }
                    675:       while(*buf) {
                    676: 	if (*buf=='\"'||*buf=='\\') fputc('\\',f);
                    677: 	if (*buf=='\n') {fputc('\\',f); fputc('n',f); fputc('\\',f); }
                    678: 	fputc(*buf++,f);
                    679:       }
                    680:       fprintf(f, "\",\n");
                    681:     }
                    682:     return 0;
                    683: }
                    684: 
                    685: int
                    686: #ifdef _USING_PROTOTYPES_
                    687: printfile (
                    688:     FILE *fout,
                    689:     char *filename,
                    690:     char *dir,
                    691:     int flags)
                    692: #else
                    693: printfile(fout,filename,dir, flags)
                    694:     FILE *fout;
                    695:     char *filename;
                    696:     char *dir;
                    697:     int flags;
                    698: #endif
                    699: {
                    700:     FILE *fin;
                    701:     char *p, *q;
                    702:     int c;
                    703: 
                    704:     if (!(fin=fopen(filename,"r"))) {
                    705: 	return 1 /* cannot open file */;
                    706:     }
                    707:     p = q = buffer;
                    708:     while ((c=fgetc(fin))!=EOF) {
                    709: 	*p = 0;
                    710: 	if (c=='\n') {
                    711: 	    if (!strncmp(buffer,"if {[info exists tk_library] && [string compare $tk_library {}]} {",66)) {
                    712: 		int flag = 1;
                    713: 		while (((c=fgetc(fin))!=EOF) && flag) {
                    714: 		    if (c=='{') {
                    715: 			flag++;
                    716: 		    } else if (c=='}') {
                    717: 			flag--;
                    718: 		    }
                    719: 		}
                    720: 		p=q=buffer;
                    721: 	    } else if ((p==buffer)||(*q=='\n')||(*q=='#')) {
                    722: 		if ((*q=='#') && (*(p-1)=='\\')) {
                    723: 		    p=q+1;
                    724: 		} else {
                    725: 		    p=q;
                    726: 		}
                    727: 	    } else {
                    728: 		*p++ = '\n'; *p=0;
                    729: 		if (Tcl_CommandComplete(buffer)) {
                    730: 		    p--; *p = 0; printline(fout,buffer,dir,flags);
                    731: 		    p = q = buffer;
                    732: 		} else {
                    733: 		    q=p;
                    734: 		}
                    735: 	    }
                    736: 	} else {
                    737: 	    *p++ = (char) c;
                    738: 	}
                    739:     }
                    740:     if (p!=buffer) {
                    741: 	*p=0; printline(fout,buffer,dir,flags);
                    742:     }
                    743:     fclose(fin);
                    744:     return 0; /* O.K. */
                    745: }
                    746: 
                    747: int
                    748: #ifdef _USING_PROTOTYPES_
                    749: main (
                    750: 	int argc,
                    751: 	char *argv[])
                    752: #else
                    753: main(argc, argv)
                    754: 	int argc;
                    755: 	char *argv[];
                    756: #endif
                    757: {
                    758:     FILE *fout;
                    759:     char *p,*q, *filename=NULL;
                    760:     char dir[128];
                    761:     tableitem *t;
                    762:     int c,i, flags=0;
                    763: 
                    764:     if (argc==1) {
                    765: 	printf(verbose);
                    766: 	exit(0);
                    767:     }
                    768:     if (argc==2&&!strcmp(argv[1],"-help")) {
                    769: 	printf(verbose);
                    770: 	printf(help);
                    771: 	exit(0);
                    772:     }
                    773:     script_name[0] = 0;
                    774: /* parse all command line arguments */
                    775:     for (i=1; i<argc; i++) {
                    776: 	if (!strcmp(argv[i],"-a")) {
                    777: 	    array_instead_of_string = 1;
                    778: 	} else if (!strcmp(argv[i],"-n")) {
                    779: 	    i++; strcpy(script_name,argv[i]);
                    780: 	} else if (!strcmp(argv[i],"-o")) {
                    781: 	    i++; filename = argv[i];
                    782: 	} else {
                    783: 	    for (t=table;t<table+(sizeof(table)/sizeof(tableitem));t++) {
                    784: 		if (!strcmp(argv[i],t->option)) {
                    785: 		    flags |= t->flag;
                    786: 		}
                    787: 	    }
                    788: 	}
                    789:     }
                    790: /* open output file, if not stdout */
                    791:     if (filename) {
                    792: 	fout = fopen(filename,"w");
                    793: 	if (fout==NULL) {
                    794: 	    fprintf(stderr,"error opening file %s\n",filename);
                    795: 	    exit(1);
                    796: 	}
                    797:     } else {
                    798: 	fout = stdout;
                    799:     }
                    800:     p = script_name;
                    801:     if ((q = strrchr(p,':')) != NULL) {
                    802: 	p = q+1;
                    803:     }
                    804:     if ((q = strrchr(p,'/')) != NULL) {
                    805: 	p = q+1;
                    806:     }
                    807:     if ((q = strrchr(p,'\\')) != NULL) {
                    808: 	p = q+1;
                    809:     }
                    810:     strcpy(script_name,p);
                    811:     q = script_name;
                    812:     while (*q) {
                    813: 	if (*q == '.') {
                    814: 	    *q = '_';
                    815: 	} else if (isupper(*q)) {
                    816: 	    *q = tolower(*q);
                    817: 	}
                    818: 	q++;
                    819:     }
                    820:     while ((q = strchr(script_name,'.')) != NULL) {
                    821: 	*q = '_';
                    822:     }
                    823: /* create prototypes for all initialization functions that are used */
                    824:     if (flags) {
                    825: 	if (script_name[0] == 0) {
                    826: 	    strcpy(script_name,"script");
                    827: 	}
                    828: 	fprintf(fout, part1);
                    829: 	for (i=0,c=1;i<(sizeof(table)/sizeof(tableitem));i++,c<<=1) {
                    830: 	    if (flags & c) {
                    831: 		fprintf(fout,defineproto1,table[i].package,
                    832: 			table[i].package);
                    833: 	    }
                    834: 	}
                    835: 	fprintf(fout, part2);
                    836: 	for (i=1,c=2;i<(sizeof(table)/sizeof(tableitem));i++,c<<=1) {
                    837: 	    if (flags & c) {
                    838: 		fprintf(fout,defineproto2,table[i].package);
                    839: 	    }
                    840: 	}
                    841: 	fprintf(fout, part3);
                    842: 	if (flags & 2) {
                    843: 	    fprintf(fout, part3a);
                    844: 	}
                    845: 	for (i=1,c=2;i<(sizeof(table)/sizeof(tableitem));i++,c<<=1) {
                    846: 	    if (flags & c) {
                    847: 		fprintf(fout,initproto,table[i].package,
                    848: 			table[i].package,table[i].package);
                    849: 	    }
                    850: 	}
                    851: 	fprintf(fout, part4, script_name);
                    852: 	if (array_instead_of_string) {
                    853: 	    fprintf(fout, part4b);
                    854: 	} else {
                    855: 	    fprintf(fout, part4a);
                    856: 	}
                    857:     }
                    858:     if ( !array_instead_of_string && script_name[0]) {
                    859: 	fprintf(fout, "static char *%s[] = {\n", script_name);
                    860:     }
                    861: /* handle all remaining arguments */
                    862:     if (argc) {argc--; argv++;}
                    863:     while(argc) {
                    864: 	if ((*argv)[0]=='-') {
                    865: 	    if ((((*argv)[1]=='o')||((*argv)[1]=='n'))&&((*argv)[2]==0)) {
                    866: 		argc--; argv++;
                    867: 	    }
                    868: 	} else if ((p=strstr(*argv,".c"))&&(p[2]==0)) {
                    869: 	    fprintf(fout,"#include \"%s\"\n",*argv);
                    870: 	} else {
                    871: 	    strcpy(dir,*argv);
                    872: 	    if ((p=strrchr(dir,'/'))!= NULL) { *(p+1)=0; } else {*dir=0;}
                    873: 	    if (printfile(fout,*argv,dir,flags)) {
                    874: 		fprintf(stderr,"Error: cannot open file %s\n",*argv);
                    875: 	    }
                    876: 	}
                    877: 	argc--; argv++;
                    878:     }
                    879:     if ( array_instead_of_string ) {
                    880:       fprintf(fout, "static char *%s[] = {\n", script_name);
                    881:       for (i = 0; (unsigned int)i < num_lines;)
                    882:           fprintf(fout, "%s_line%d,\n", script_name, ++i);
                    883:     }
                    884:     if (script_name[0]) {
                    885:       fprintf(fout, "(char *) NULL\n};\n\n");
                    886:     }
                    887: /* end of scripts, finally the functions main() and tclAppInit()  */
                    888:     if (flags) {
                    889: 	fprintf(fout, part5, script_name);
                    890: 	fprintf(fout, part5a, script_name);
                    891: 	fprintf(fout, part5b);
                    892: 	fprintf(fout, part5c);
                    893:     if (flags==65537) { fprintf(fout, partwebpage); }
                    894: 	fprintf(fout,callinit,table[0].package);
                    895: 	for (i=1,c=2;i<(sizeof(table)/sizeof(tableitem));i++,c<<=1) {
                    896: 	    if (flags & c) {
                    897: 		fprintf(fout,callinit,table[i].package);
                    898: 		fprintf(fout,packageproto,table[i].package,table[i].package,table[i].package);
                    899: 	    }
                    900: 	}
                    901: 	p=filename?filename:"app";
                    902: 	if ((q=strrchr(p,'/')) != NULL) p=q+1;
                    903: 	if ((q=strchr(p,'.')) != NULL) *q=0;
                    904: 	if (!*p) p="app";
                    905: 	fprintf(fout, part6,script_name,script_name,p,p);
                    906: 	if (flags & 2) {
                    907: 	    fprintf(fout, part6a);
                    908: 	}
                    909: 	fprintf(fout, part6b);
                    910: 	fprintf(fout, part6c);
                    911: 	fprintf(fout, part6d);
                    912: 	fprintf(fout, part6e);
                    913:     }
                    914: /* close output-file, if not stdout */
                    915:     if (fout!=stdout) {
                    916: 	fclose(fout);
                    917:     }
                    918:     if (max_buffer>MAX_STRING_LEN) {
                    919: 	fprintf(stderr,"warning: largest sting in output file is %d bytes\n\
                    920:          many compilers can only handle %d characters in a string\n\
                    921: 	 first line: %s\n",max_buffer,MAX_STRING_LEN,max_buffer_content);
                    922:     }
                    923:     exit(0);
                    924:     return 0;
                    925: }
                    926: 
                    927: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>