Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 998a40a

Browse files
committed
Mods by Donovan Preston (with changes by me to make them "go with the flow")
that will detect an __main__.py or __rawmain__.py in the application bundle. This file is then exectued as the main script. We now have applets in MachO Python!!! The difference between __main__ and __rawmain__ is that the former gets a complete simulated argv (so you can drop files on the applet and the script sees them in sys.argv) while the latter skips the argv simulation and the <option>key dialog. This keeps the AppleEvent that started the app intact, as well as the funny "-psn_xxxx" argv[1] argument, so the script can do with these what it wants.
1 parent 0b60772 commit 998a40a

1 file changed

Lines changed: 90 additions & 14 deletions

File tree

Mac/Python/macmain.c

Lines changed: 90 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ int console_output_state = STATE_UNKNOWN;
8181

8282
PyMac_PrefRecord PyMac_options;
8383

84-
static void Py_Main(int, char **); /* Forward */
84+
static void Py_Main(int, char **, char *); /* Forward */
8585
void PyMac_Exit(int); /* Forward */
8686

8787
static void init_appearance(void)
@@ -488,17 +488,87 @@ PyMac_Initialize(void)
488488
#endif /* USE_MAC_APPLET_SUPPORT */
489489

490490
#if TARGET_API_MAC_OSX
491+
492+
static int
493+
locateResourcePy(char * resourceName, char * resourceURLCStr, int length) {
494+
CFBundleRef mainBundle = NULL;
495+
CFURLRef URL, absoluteURL;
496+
CFStringRef filenameString, filepathString, rsrcString;
497+
CFIndex size, i;
498+
CFArrayRef arrayRef;
499+
Boolean success = 0;
500+
501+
/* Create a CFString with the resource name in it */
502+
rsrcString = CFStringCreateWithCString(0, resourceName, kCFStringEncodingMacRoman);
503+
504+
/* Get a reference to our main bundle */
505+
mainBundle = CFBundleGetMainBundle();
506+
507+
/* Look for py files in the main bundle by type */
508+
arrayRef = CFBundleCopyResourceURLsOfType( mainBundle,
509+
CFSTR("py"),
510+
NULL );
511+
512+
/* See if there are any filename matches */
513+
size = CFArrayGetCount(arrayRef);
514+
for (i = 0; i < size; i++) {
515+
URL = CFArrayGetValueAtIndex(arrayRef, i);
516+
filenameString = CFURLCopyLastPathComponent(URL);
517+
if (CFStringCompare(filenameString, rsrcString, 0) == kCFCompareEqualTo) {
518+
/* We found a match, get the file's full path */
519+
absoluteURL = CFURLCopyAbsoluteURL(URL);
520+
filepathString = CFURLCopyFileSystemPath(absoluteURL, kCFURLPOSIXPathStyle);
521+
CFRelease(absoluteURL);
522+
523+
/* Copy the full path into the caller's character buffer */
524+
success = CFStringGetCString(filepathString, resourceURLCStr, length,
525+
kCFStringEncodingMacRoman);
526+
527+
CFRelease(filepathString);
528+
}
529+
CFRelease(filenameString);
530+
}
531+
CFRelease(rsrcString);
532+
CFRelease(arrayRef);
533+
534+
return success;
535+
}
536+
491537
int
492538
main(int argc, char **argv)
493539
{
494-
int i;
495-
printf("first argc=%d\n", argc);
496-
for(i=0; i<argc; i++) printf("first argv[%d] = \"%s\"\n", i, argv[i]);
497-
init_common(&argc, &argv, 0);
498-
printf("second argc=%d\n", argc);
499-
for(i=0; i<argc; i++) printf("second argv[%d] = \"%s\"\n", i, argv[i]);
500-
Py_Main(argc, argv);
501-
return 0;
540+
int i;
541+
static char scriptpath[1024];
542+
char *script = NULL;
543+
544+
/* First we see whether we have __rawmain__.py and run that if it
545+
** is there
546+
*/
547+
if (locateResourcePy("__rawmain__.py", scriptpath, 1024)) {
548+
/* If we have a raw main we don't do AppleEvent processing.
549+
** Notice that this also means we keep the -psn.... argv[1]
550+
** value intact. Not sure whether that is important to someone,
551+
** but you never know...
552+
*/
553+
script = scriptpath;
554+
} else {
555+
/* Otherwise we look for __main__.py. Whether that is
556+
** found or not we also process AppleEvent arguments.
557+
*/
558+
if (locateResourcePy("__main__.py", scriptpath, 1024))
559+
script = scriptpath;
560+
561+
printf("original argc=%d\n", argc);
562+
for(i=0; i<argc; i++) printf("original argv[%d] = \"%s\"\n", i, argv[i]);
563+
564+
init_common(&argc, &argv, 0);
565+
566+
printf("modified argc=%d\n", argc);
567+
for(i=0; i<argc; i++) printf("modified argv[%d] = \"%s\"\n", i, argv[i]);
568+
}
569+
570+
Py_Main(argc, argv, script);
571+
return 0;
502572
}
503573

504574
#else
@@ -533,21 +603,27 @@ PyMac_InitApplication(void)
533603
exit(0);
534604
}
535605
}
536-
Py_Main(argc, argv);
606+
Py_Main(argc, argv, NULL);
537607
}
538608
#endif /* TARGET_API_MAC_OSX */
539609

540610
/* Main program */
541611

542612
static void
543-
Py_Main(int argc, char **argv)
613+
Py_Main(int argc, char **argv, char *filename)
544614
{
545615
int sts;
546616
char *command = NULL;
547-
char *filename = NULL;
548617
FILE *fp = stdin;
549618

550-
filename = argv[1];
619+
if ( filename ) {
620+
/* Someone else has found our "script" already */
621+
argv[0] = filename;
622+
} else {
623+
filename = argv[1];
624+
argv++;
625+
argc--;
626+
}
551627

552628
if (Py_VerboseFlag ||
553629
(command == NULL && filename == NULL && isatty((int)fileno(fp))))
@@ -573,7 +649,7 @@ Py_Main(int argc, char **argv)
573649

574650
PyMac_InstallNavServicesForSF();
575651

576-
PySys_SetArgv(argc-1, argv+1);
652+
PySys_SetArgv(argc, argv);
577653

578654
if (filename == NULL && isatty((int)fileno(fp))) {
579655
FILE *fp = fopen(STARTUP, "r");

0 commit comments

Comments
 (0)