Saturday, April 26, 2014

fopen() read/write/create/append brokenness

It's amazing how long fopen() has managed to be around while still having confusing behavior.

The big culprit in my mind is the "a+" mode, which really ought to do the thing I want, which is to open the file read/write, creating it if it doesn't exist, and sure, go ahead and put the file pointer at the end, whatever.  But it has a bizarre behavior of always appending, as if it were fseek()ing to the end just before every write.

"w+" mode would still work fine for that purpose, but it insists on wiping out the file right when it's opened.

And even "r+" mode would work fine, except that it won't create the file if it doesn't exist.

So none of the three available read/write modes do what I figure must be the most common thing, which is to open the file read/write, creating it if it doesn't exist, and not wiping out all the contents.

I'm not even mad at the original authors for omitting that case.  I'm just amazed that nobody has added a mode for that, and that many docs don't go out of their way to mention the funky "a+" behavior.

So, here in 2014, we still have to do things like:

FILE *f = fopen("foo", "r+");
if (f == NULL) {
  f = fopen("foo", "w+");
  if (f == NULL) {
    return FAIL;
  }
}

Monday, April 21, 2014

Saving a variable number of matches from a Perl regex

Intuitively it seems like the regex /(.)+/ should return an array of all the characters in a string.  It's a match group with a quantifier allowing it to repeat, after all.  But in fact it only returns the last group.

My best guess is that it's done this way so that the rule always works that says you can always count left parens to figure out which position the matching value will be returned in.

To get around this, remove the quantifier and use /g.  For example, 'asdf' =~ /(.)/g returns ('a', 's', 'd', 'f') as expected.

The downside is that I can't use fancier expressions as I would have hoped.  What I originally wanted was an expression like this: 'a12345' =~ /^([a-z])(\d)+$/ to return ('a', '1', '2', '3', '4', '5').  I don't see an obvious way to have multiple matches like that with /g, since with /g it has to match the entire regex multiple times.

The best I can come up with for that scenario is to split into multiple regexes and handle the input in chunks:

$_ = 'a12345';
s/^([a-z])//;
$letter = $1;
@numbers = /(\d)/g;

Is there a better solution I'm missing?

Wednesday, April 09, 2014

Using xrandr instead of nvidia-settings

On my Linux Ubuntu 12.04 machine, the nvidia-settings app has been crashing, preventing me from changing screen resolution or refresh rate (I like to switch to 24fps for watching movies so that slow pans don't look all jerky).  I'm using a G210 video card, and getting errors like this when I run nvidia-settings from the command line:
The program 'nvidia-settings' received an X Window System error.
This probably reflects a bug in the program.
The error was 'BadValue (integer parameter out of range for operation)'.
xrandr to the rescue!  Turns out it's not just for screen rotation and reflection; it can also do resolution and refresh rate:

$ xrandr --output HDMI-0 --mode 1920x1080 --rate 24.0

(Try running it without arguments to see what resolutions and refresh rates are possible)

Death, the destroyer of worlds

Lots of people know Oppenheimer's quote about being present at the Trinity test, the first man-made nuclear explosion: 

"We knew the world would not be the same. Few people laughed, few people cried, most people were silent. I remembered the line from the Hindu scripture, the Bhagavad-Gita. Vishnu is trying to persuade the Prince that he should do his duty and to impress him takes on his multi-armed form and says, "Now I am become Death, the destroyer of worlds." I suppose we all thought that, one way or another."
I've often wondered if he had originally been thinking of an earlier part of Chapter XI:

If a thousand suns were to rise
and stand in the noon sky, blazing,
such brilliance would be like the fierce 
brilliance of that mighty Self.

Arjuna saw the whole universe
enfolded, with its countless billions
of life-forms, gathered together
in the body of the God of gods.

...

I see you everywhere, with billions
of arms, eyes, bellies, faces,
without end, middle or beginning,
your body the whole universe, Lord.

Crowned, bearing mace and discus,
you dazzle my vision, blazing
in the measureless, massive, sun-flame
splendor of your radiant form.

You are the deathless, the utmost
goal of all knowledge, the world's base,
the guardian of the eternal
law, the primordial Person.

I see you beginningless, endless,
infinite in power, with a billion
arms, the sun and moon
your eyeballs, the flames of your mouth

lighting the whole universe with splendor.
You alone fill all space
...

But the chapter gets much darker almost immediately:

As you touch the sky, many-hued,
gape-mouthed, your huge eyes blazing,
my innards tremble, my breath
stops, my bones turn to jelly.

Seeing your billion-fanged mouths
blaze like the fires of doomsday,
I faint, I stagger, I despair.
Have mercy on me, Lord Vishnu!

All Dhritarashtra's men
and all these multitudes of kings--
Bhishma, Drona, Karna,
with all our warriors behind them--

are rushing headlong into
your hideous, gaping, knife-fanged
jaws; I see them with skulls crushed,
their raw flesh stuck to your teeth.

As the rivers in many torrents
rush toward the ocean, all
these warriors are pouring down 
into your blazing mouths.

As moths rush into a flame 
and are burned in an instant, all
beings plunge down your gullet
and instantly are consumed.

You gulp down all worlds, everywhere
swallowing them in your flames,
and your rays, Lord Vishnu, fill all
the universe with dreadful brilliance.

Who are you, in this terrifying form?
Have mercy, Lord; grant me even
a glimmer of understanding
to prop up my staggering mind.

Vishnu:

I am death, shatterer of worlds,
annihilating all things.
With or without you, these warriors
in their facing armies will die.

(Stephen Mitchell translation)

Hard to imagine a verse more fitting the dawn of the atomic age.

Sunday, April 06, 2014

On Hydrogen Bombs

From "Turing's Cathedral", regarding the H-bomb:
According to Oppenheimer, at a briefing given by Edward Teller and the RAND Corporation, Secretary of the Air Force Thomas K. Finletter "got to his feet and said 'give us this weapon and we will rule the world.' "