Archive for the 'Toolchain' Category

Report-an-Apple-Bug Friday! 3 (repost)

Saturday, February 4th, 2006

fie on Blogger. this post isn’t visible from the front page or the Dashboard, even though it exists. so I’m reposting it.

UPDATE 2006-02-25: it has been closed as a duplicate.


C99 escapes in Obj-C string contain UTF-8 interpreted as an 8-bit encoding. as last time, edited only for HTMLification.

Summary:

since C99, C has a \u escape for Unicode characters. for example, a snowman is \u2603.

when used in an Obj-C string literal (@"foo"), however, these escapes are broken.

Steps to Reproduce:

  1. write a program that displays a string, created from an Obj-C string literal containing a Unicode escape.
  2. compile it.
  3. run it.
  4. observe the display of the string.

Expected Results:

the Unicode character is displayed as such.

Actual Results:

the Unicode character’s UTF-8 representation is displayed in some 8-bit encoding (possibly ISO 8859-1).

Regression:

none known.

Notes:

the bug only occurs in Obj-C string literals, not plain C string literals.

it appears that the compiler uses UTF-8 for internal storage, which works. NSConstantString, however, seems to expect ISO 8859-1, and interpret its input as such.

the enclosed tarball contains test programs (command-line) in plain C (using printf) and Obj-C (using NSLog). the plain C version works; the Obj-C does not.

I found the bug when displaying an Obj-C constant string (which had been passed through NSLocalizedString, but there is no matching localisation for it yet) as an NSMenuItem‘s title. so the problem is not specific to terminals or Terminal’s display, nor dependent on the value of any locale environment variables.


I also attached two test cases.

How to distribute your software

Monday, January 16th, 2006

Recently, I went to Apple’s games site and downloaded a bunch of puzzle/arcade games. I was dismayed to find that many of these games were distributed in formats other than UDIF (the .dmg format). So clearly this matter bears some explanation.

This is the second part of a two-part post. Part 1 came previously; it discussed the difference between compression, archive, and disk-image formats and described the different specific formats in each category. Part 2 covers why you should use a plain dmg (no StuffIt or *zip sprinkles) to distribute your software. This was originally one long post, but I Kill Billed it.


Part 2: How to distribute your software

The sad current state of affairs is that much software is not distributed in a plain dmg. Here’s a brief hall of shame, in increasing order of silliness:

I’m not singling any of these products out (especially for .dmg.gz, .zip, and .sit, as these are absurdly common), nor am I critiquing the quality of the software; these are just examples of how not to distribute your application.


Regarding the last one: StuffIt format? WHY?!?!?! Mac OS X doesn’t even come with StuffIt Expander anymore!

And it’s not even StuffIt X (that would be .sitx); .sit is the older StuffIt 5 format, that doesn’t properly support application packages! Worse: because StuffIt 5 format does not support storage of UNIX permissions, StuffIt Expander relies on a preference setting to know whether to set a file as executable or not. So if you UnStuff an application from a StuffIt 5 archive, it might not even run. Doesn’t that make a great first user impression? And who’s going to suspect that their unarchiver is the cause of the problem?

In fact, it isn’t the cause of the problem at all. If you are still distributing your software in StuffIt format, you are to blame.


Panther added support in the Finder for zipping and unzipping files. Tiger added support in the Finder for gunzipping, bunzip2ing, and untarring files. All of these features are the wrong way to distribute an application.

First off, tarring a dmg is pointless. tar files exist to put multiple files into one file. A dmg is already a single file. There is no need to tar it.

Second, if you created your dmg correctly, it is already compressed (probably with zlib). ‘Correctly’ means making a read-only compressed image, either from a folder or from another (read/write) image. There is no need to compress it further. Be very surprised if the additional savings exceed 20 K. (the .dmg.tar.gz listed above is particularly egregious — hello, Mr. Redundancy Man!)

Third, if somebody on Jaguar (or earlier) downloads your zip file, and you created it using Finder, it will not unpack correctly in StuffIt Expander. Specifically, it will create ugly ‘__MACOSX’ folders. Your application might work (unless you actually did intend to use the resource fork for something, in which case it’s gone then), but littering a user’s system is not a way to build goodwill.

Fourth, the purpose of Finder’s zip support is to allow you to send files to Windows users. Distributing Mac software does not count.

There is only one valid use for zip: getting around stupid web servers that either don’t allow dmgs (*shakes fist at GeoCities*) or that don’t have a proper media type (application/octet-stream) set for it. If you have access to add that media type, do so, and distribute a plain dmg; otherwise, politely badger your admin. And until such time as they fix it, you should include a note on your downloads page acknowledging that having to zip your dmgs is lame.


Lest this article sound completely negative, let me explain the upsides of using UDIF.

The major advantage is that it sandboxes your application. An application shouldn’t install anything outside of its bundle (are you listening, Adobe?). If your application is written correctly, it is self-contained (everything it needs is in the .app bundle — this is what bundles are for) and does not require write access to the volume it is on. If your application can be run without problems from the dmg, then you are doing all right.

The second advantage is that a dmg does not require proprietary software (i.e. StuffIt). This seems to be a bigger advantage than it should be — StuffIt does not come with the OS anymore, and requiring people to download other software in order to use your software at all is not a good way to make them fans of it. Disk Copy/Disk Utility has always come with Mac OS X.

(Before you bring up Growl: Growl isn’t required by most of the applications that use it; it’s just value-added. Those applications that do require Growl are aimed specifically at existing Growl users.)

Third: with a dmg, you can easily embed a license agreement. There is no need for an installer to display it; Disk Copy/Disk Utility will do it for you.


That gives me an idea. Here are a couple of points about installers.

Unless you are installing a framework (that really needs to be installed into a Library directory) or a kernel extension, do not create an installer or an Installer package. There is no point.

The user should be able to try your application without installing it (remember what I said about it being usable from the dmg?). An installer is a barrier to this. You should make it as easy as possible for people to try your app.

Testing Image Units

Sunday, January 8th, 2006

Some of you may know that I’ve been studying Apple’s Core Image API — specifically, how to write an Image Unit. I just found this, buried in Apple’s website: Software Licensing & Trademark Agreements: Image Units.

What’s special about that? Read the page closely:

3. Download the Image Units Validation Tool (DMG). Use of this application is subject to the terms of the Validation Tool License (RTF) presented upon launch.

It’s actually a command-line tool, and the agreement is displayed when the image is mounted rather than when the tool is run, but nonetheless — it’s a tool that examines your Image Unit and attempts to compile its .cikernel file, and tells you if it finds anything wrong. Highly useful.

Coolest program name ever: pstops.

Monday, January 2nd, 2006

Even better, it accepts line noise as input. From the manpage:

To put two pages on one sheet (of A4 paper), the pagespec to use is:

2:0L@.7(21cm,0)+1L@.7(21cm,14.85cm)

To select all of the odd pages in reverse order, use:

2:-0

To re-arrange pages for printing 2-up booklets, use

4:-3L@.7(21cm,0)+0L@.7(21cm,14.85cm)

for the front sides, and

4:1L@.7(21cm,0)+-2L@.7(21cm,14.85cm)

for the reverse sides.

pstops is part of psutils.