diff --git a/direct/src/plugin/p3dMultifileReader.cxx b/direct/src/plugin/p3dMultifileReader.cxx index e96ce50f00..2d665a9e15 100644 --- a/direct/src/plugin/p3dMultifileReader.cxx +++ b/direct/src/plugin/p3dMultifileReader.cxx @@ -158,12 +158,42 @@ read_header(const string &pathname) { return false; } - for (size_t i = 0; i < _header_size; ++i) { - int ch = _in.get(); - if (ch != _header[i]) { - nout << "Failed header check: " << pathname << "\n"; - return false; + char this_header[_header_size]; + _in.seekg(0); + _in.read(this_header, _header_size); + if (_in.fail() || _in.gcount() != (unsigned)_header_size) { + nout + << "Unable to read Multifile header " << pathname << ".\n"; + return false; + } + + // Here's a special case: if the multifile begins with a hash + // character, then we skip at least 6 characters, and continue + // reading and discarding lines of ASCII text, until we come across + // a nonempty line that does not begin with a hash character. This + // allows a P3D application (which is a multifile) to be run + // directly on the command line on Unix-based systems. + if (this_header[0] == '#') { + int ch = '#'; + while (ch != EOF && ch == '#') { + // Skip to the end of the line. + while (ch != EOF && ch != '\n') { + ch = _in.get(); + } + // Skip to the first non-whitespace character of the line. + while (ch != EOF && (isspace(ch) || ch == '\r')) { + ch = _in.get(); + } } + + // Now fill up the header. + this_header[0] = ch; + _in.read(this_header + 1, _header_size - 1); + } + + if (memcmp(this_header, _header, _header_size) != 0) { + nout << "Failed header check: " << pathname << "\n"; + return false; } unsigned int major = read_uint16(); diff --git a/direct/src/showutil/Packager.py b/direct/src/showutil/Packager.py index 82890d2c91..d840a646fb 100644 --- a/direct/src/showutil/Packager.py +++ b/direct/src/showutil/Packager.py @@ -174,10 +174,14 @@ class Packager: if self.dryRun: self.multifile = None else: + self.multifile = Multifile() + + if self.p3dApplication: + self.multifile.setHeaderPrefix('#! /usr/bin/env panda3d\n') + # Write the multifile to a temporary filename until we # know enough to determine the output filename. multifileFilename = Filename.temporary('', self.packageName) - self.multifile = Multifile() self.multifile.openReadWrite(multifileFilename) self.extracts = [] @@ -252,7 +256,7 @@ class Packager: xmodule.SetAttribute('forbid', '1') if mdef.exclude and mdef.allowChildren: xmodule.SetAttribute('allowChildren', '1') - self.components.append((newName.lower(), xmodule)) + self.components.append(('m', newName.lower(), xmodule)) # Now look for implicit shared-library dependencies. if PandaSystem.getPlatform().startswith('win'): @@ -356,10 +360,14 @@ class Packager: multifileFilename.renameTo(self.packageFullpath) - if not self.p3dApplication: + if self.p3dApplication: + # Make the application file executable. + os.chmod(self.packageFullpath.toOsSpecific(), 0755) + else: self.compressMultifile() self.writeDescFile() self.writeImportDescFile() + # Now that all the files have been packed, we can delete # the temporary files. @@ -757,7 +765,7 @@ class Packager: xpackage.InsertEndChild(xrequires) self.components.sort() - for name, xcomponent in self.components: + for type, name, xcomponent in self.components: xpackage.InsertEndChild(xcomponent) doc.InsertEndChild(xpackage) @@ -935,7 +943,7 @@ class Packager: xcomponent = TiXmlElement('component') xcomponent.SetAttribute('filename', newName) - self.components.append((newName.lower(), xcomponent)) + self.components.append(('c', newName.lower(), xcomponent)) def addFoundTexture(self, filename): """ Adds the newly-discovered texture to the output, if it has @@ -979,7 +987,7 @@ class Packager: xcomponent = TiXmlElement('component') xcomponent.SetAttribute('filename', file.newName) - self.components.append((file.newName.lower(), xcomponent)) + self.components.append(('c', file.newName.lower(), xcomponent)) def requirePackage(self, package): """ Indicates a dependency on the given package. This diff --git a/direct/src/showutil/packp3d.py b/direct/src/showutil/packp3d.py index 045aa930c7..d896c60669 100755 --- a/direct/src/showutil/packp3d.py +++ b/direct/src/showutil/packp3d.py @@ -7,12 +7,12 @@ tree of .py files and models, into a p3d file for convenient distribution. The resulting p3d file can be run by the Panda3D runtime executable, or by the Panda3D web browser plugin. -Also see ppackage.py, which can be used to build p3d files more +Also see ppackage, which can be used to build p3d files more generally, using a pdef description file. Usage: - packp3d.py [opts] app.p3d + %s [opts] app.p3d Options: @@ -82,7 +82,7 @@ def makePackedApp(args): elif option == '-x': versionIndependent = True elif option == '-h': - print __doc__ + print __doc__ % (os.path.split(sys.argv[0])[1]) sys.exit(1) if not args: diff --git a/direct/src/showutil/ppackage.py b/direct/src/showutil/ppackage.py index a42be43610..fa67d2947a 100755 --- a/direct/src/showutil/ppackage.py +++ b/direct/src/showutil/ppackage.py @@ -22,7 +22,7 @@ This script is actually a wrapper around Panda's Packager.py. Usage: - ppackage.py [opts] package.pdef + %s [opts] package.pdef Required: @@ -75,7 +75,7 @@ from direct.showutil import make_contents from pandac.PandaModules import * def usage(code, msg = ''): - print >> sys.stderr, __doc__ + print >> sys.stderr, __doc__ % (os.path.split(sys.argv[0])[1]) print >> sys.stderr, msg sys.exit(code)