Thursday, June 16, 2005 

For the last three years, I've been involved with The Wild Geese Players of Seattle, an amateur group that does readings of Irish literature, particularly the works of James Joyce and W.B. Yeats. Our big event every year is Bloomsday, June 16th, commemorating Joyce's Ulysses, which takes place on June 16th, 1904. It's a tale of a Jewish everyman, Leopold Bloom, wandering through Dublin one day, and of the young writer (and Joyce's alter ego), Stephen Dedalus. We're working our way through the book, reading a chapter or two each year. In this, our eighth year, we'll be reading Chapter 11, Sirens, at the Brechemin Auditorium in the School of Music at the University of Washington, on Thursday 16th and Saturday 18th. Congressman Jim McDermott will be reading the part of Bloom on the Saturday.

Last year and this year, I have been the assistant dramaturge, helping to turn chapters into a script to be read by 15-20 readers. In previous years, the director made a photocopy of the book, wrote attributions ("Narrator 1", "Bloom", "Stephen", etc) on the paper, then photocopied that text and handed it out to the readers. Since the script was a moving target, everyone ended up with a set of scruffy, tatty, inconsistently hand-annotated sheets. It was a mess.

I knew there had to be a better way. Now, we've adapted the etext of the 1922 Paris Edition, prepared by Project Gutenberg, which saves a lot of typing. The script is marked up in XML and styled with XSLT to produce an HTML page. After a rehearsal or two, when it's apparent that the script isn't quite right, it's an easy matter to make a few changes, render fresh HTML, and print new scripts.

The XSLT required is fairly straightforward. About the only mildly interesting thing is defining one template in terms of another; e.g., I want all the speakers to share the same styling, so I defined a parameterized speaker template:

<xsl:template name="speaker">
    <xsl:param name="name" />
    <div class="speaker">
        <span class="speaker"><xsl:value-of select="$name"/>: </span>
        <xsl:apply-templates />
    </div>
</xsl:template>

which is called thus:

<xsl:template match="bloom">
    <xsl:call-template name="speaker">
        <xsl:with-param name="name">Bloom</xsl:with-param>
    </xsl:call-template>
</xsl:template>

The real challenge in preparing the script is dramaturgical. Ulysses is a notoriously difficult and dense text, woven through with Bloom's stream-of-consciousness interior monologue. Each chapter is written in a different style. Sirens, for example, has musical themes running through it, and we'll be accompanied by a piano player this year.

What would you do with this?

Bloom heard a jing, a little sound. He's off. Light sob of breath Bloom sighed on the silent bluehued flowers. Jingling. He's gone. Jingle. Hear.

Here's what we came up with:

N1: Bloom heard a jing, a little sound.
Bloom: He's off.
N1: Light sob of breath Bloom sighed on the silent bluehued flowers. Jingling.
Bloom: He's gone.
N1: Jingle.
Bloom: Hear.

Or with this paragraph?

--Yes, Mr Bloom said, teasing the curling catgut line. It certainly is. Few lines will do. My present. All that Italian florid music is. Who is this wrote? Know the name you know better. Take out sheet notepaper, envelope: unconcerned. It's so characteristic.

We chose this:

Bloom (Aloud): Yes.
N1: Mr Bloom said, teasing the curling catgut line.
Bloom (Aloud): It certainly is.
Bloom: Few lines will do. My present.
Bloom (Aloud): All that Italian florid music is.
Bloom: Who is this wrote? Know the name you know better. Take out sheet notepaper, envelope: unconcerned.
Bloom (Aloud): It's so characteristic.

We ended up with three narrators in this chapter: N1 deals with Bloom, primarily; N2 is mostly for Miss Douce and Miss Kennedy, the siren barmaids; and N3 handles the other characters.

Lest I scare you off, much of the chapter is quite clear and often very funny, even for people who are unfamiliar with the book.

The James Joyce Portal is a good starting point for matters Joycean.

posted on Thursday, June 16, 2005 7:54:52 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Thursday, June 02, 2005 

Printf Tricks

It may be old-fashioned, but I still find printf (and sprintf and _vsnprintf) incredibly useful, both for printing debug output and for generating formatted strings.

Here are a few lesser-known formats that I use again and again. See MSDN for the full reference.

%04x - 4-digit hex number with leading zeroes

A quick review of some of the basics.

%x prints an int in hexadecimal.

%4x prints a hex int, right-justified to 4 places. If it's less than 4 digits, it's preceded by spaces. If it's more than 4 digits, you get the full number.

%04x prints a hex int, right-justified to 4 places. If it's less than 4 digits, it's preceded by zeroes. If it's more than 4 digits, you get the full number, but no leading zeroes.

Similarly, %d prints a signed int in decimal, and %u prints an unsigned int in decimal.

Not so similarly, %c prints a character and %s prints a string. For wide (Unicode) strings, prefix with l (ell, or w): %lc and %ls.

Note: For the Unicode variants, such as wprintf and friends, %c and %s print wide strings. To force a narrow string, no matter which variant, use the %h size prefix, and to force a wide string, use the %l size prefix; e.g., %hs and %lc.

%p - pointer

The wrong way to print a pointer is to use %x. The right way is to use %p. It's portable to Win64, as well as to all other operating systems.

Everyone should know this one, but many don't.

%I64d, %I64u, %I64x - 64-bit integers

To print 64-bit numbers (__int64), use the I64 size prefix.

%Iu, %Id, %Ix - ULONG_PTR

ULONG_PTR, LONG_PTR, and DWORD_PTR are numeric types that are as wide as a pointer. In other words, they map to ULONG, LONG, and DWORD respectively on Win32, and ULONGLONG, LONGLONG, and ULONGLONG on Win64.

The I size prefix (capital-i, not lowercase-L) is what you need to print *LONG_PTR on Win32 and Win64.

%*d - runtime width specifier

If you want to calculate the width of a field at runtime, you can use %*. This says the next argument is the width, followed by whatever type you want to print.

For example, the following can be used to print a tree:

 void Tree::Print(Node* pNode, int level)
{
if (NULL != pNode)
{
Print(pNode->Left, level+1);
printf("%*d%s\n", 2 * level, pNode->Key);
Print(pNode->Right, level+1);
}
}

%.*s - print a substring

With a variable precision, you can print a substring, or print a non-NUL-terminated string, if you know its length. printf("%.*s\n", sublen, str) prints the first sublen characters of str.

[2005/7/19: fixed a typo in previous sentence (%.s -> %.*s). A little elaboration on the syntax: . in a printf format specification is followed by the precision. For strings, the precision specificies how many characters will be printed. A precision of * indicates that the precision is the next argument on the stack. If the precision is zero, then nothing is printed. If a string has a precision specification, its length is ignored.]

%.0d - print nothing for zero

I've occasionally found it useful to suppress output when a number is zero, and %.0d is the way to do it. (If you attempt to print a non-zero number with this zero-precision specifier, it will be printed.) Similarly, %.0s swallows a string.

%#x - print a leading 0x

If you want printf to automatically generate 0x before hex numbers, use %#x instead of %x.

Other tricks

See the documentation for other useful tricks.

Security

Never use an inputted string as the format argument: printf(str). Instead, use printf("%s", str). The former is a stack smasher waiting to happen.

%n is dangerous and disabled by default in VS2005.

Don't use sprintf. Use the counted version, _snprintf or _vsnprintf instead. Better still, use the StrSafe.h functions, StringCchPrintf and StringCchVPrintf, to guarantee that your strings are NUL-terminated.

[Update: 2008/01/25: See also Printf %n.]

posted on Thursday, June 02, 2005 7:44:26 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]