Vincent Gable’s Blog

December 8, 2008

C Comment Trivia

Filed under: Bug Bite,C++,Objective-C,Programming | , ,
― Vincent Gable on December 8, 2008

//I'll bet \
you \
didn't \
know \
you \
could \
comment \
like \
this \
in \
C/C++/Objective-C

Well, you can. Finding out was a lot of fun, believe me.

At some point, I’m not sure when, I unknowingly put a ‘\’ at the end of a block of // comments. That commented out the method-call the block was referring to. As you might guess from the fact that it had a big comment talking about why it was there, this was an important method call. I spent more time then I want to admit debugging and staring at my code trying to see the problem. Finally I noticed “hey, the color of that code is like a comment, even though it’s not in a comment”.

The More You Know!

November 24, 2008

How To Put a % in an NSString/NSLog/printf

Filed under: Cocoa,MacOSX,Objective-C,Programming | , , , , , ,
― Vincent Gable on November 24, 2008

%% is turned into a single % in a call to NSLog, or -[NSString stringWithFormat:], or the printf-family of functions.

Note that %%format will become %format, even if %format usually prints an argument. For example, the code

NSLog(@"%%a will print a float in a machine-readable format, so that *scanf can read it back in from a string with no loss of precision.", 1.0f);

prints:

%a will print a float in a machine-readable format, so that *scanf can read
it back in from a string with no loss of precision.

not:

%0x1p+0 will print a float in a machine-readable format, so that *scanf can read it back in from a string with no loss of precision.

September 27, 2008

CFShow is NSLog for Core Foundation Types

Filed under: MacOSX,Programming,Tips | , , , ,
― Vincent Gable on September 27, 2008

CFShow(coreFoundationThingy) will print out a description of coreFoundationThingy to the console. Output looks something like:

{value = w:1186.000000 h:687.000000 type = kAXValueCGSizeType}

If NSLog() is printing something out as an NSCFType, try CFShow().

June 6, 2008

My First Octal Value

Filed under: Bug Bite,C++,Cocoa,Objective-C,Programming | , , ,
― Vincent Gable on June 6, 2008

Octal is useless today. It is easy to convert between octal and binary, so octal was used in some early computers. But hexadecimal has totally replaced it in modern use. There’s no advantage that octal has over hexadecimal, which is why hexadecimal has replaced it.

The C programming language has support for values in octal. This wouldn’t be a problem, except for the horrible syntax used to define octal values.

In C, any integral value that starts with 0 is interpreted as octal! So 010 is eight, not ten. I’ve been bitten by this before. I don’t know why this syntax was chosen over an 0o prefix (which google calculator uses), that would match the 0x prefix for defining hexadecimal values. In retrospect it was almost certainly a mistake to go with the current syntax.

Anyway, the reason I’m writing this is because for the first time ever, I used an octal value in a C program. I had to create a directory structure that could be be accessed by different accounts on the same system. So I had to explicitly set it’s permissions when I created it with createDirectoryAtPath:attributes: . I wanted the NSFilePosixPermissions value that determines the folders permissions to have the same format that the chmod command takes. And it takes an octal value. So 0777 is the first, and only, octal constant that I’ve written in any program. Even when I’ve written in assembly I’ve used hexadecimal. There’s a good chance I will never write another octal value — I hope that’s the case.

March 5, 2008

Calling the Command Line from Cocoa

Filed under: Cocoa,MacOSX,Objective-C,Programming,Tips,UNIX | , , , ,
― Vincent Gable on March 5, 2008

The best way to call a shell-command from Coca is by using an NSTask. Here are the three resources on using an NSTask that I found the most helpful:
CocoDev’s write up
A few quick exaples
NSTask Class Refrence

And here is some sample code to do it for you. You are free to use this code however you please, but attribution is always appreciated. The two principle functions are:

+ (NSString*) executeShellCommandSynchronously:(NSString*)command executes the command “command” with sh, wait until it finishes, and return whatever it printed to stdout and stderr as an NSString.
CAUTION: may deadlock under some circumstances if the output gets so big it fills the pipe. See http://dev.notoptimal.net/search/label/NSTask for an overview of the problem, and a solution. I have not experienced the problem myself, so I can’t comment.

executeShellCommandAsynchronously: will have sh execute command in the background, without blocking anything.

For quick hacks, the POSIX int system(const char* command) function, might be a good one-line solution. It synchronously evaluates command with sh.

Enjoy!

EDITED 2009-11-29: this code probably won’t have the same $PATH you would get if you used Terminal. See this question on stackoverflow for more details. A solution that seems to work is to do,

    [task setLaunchPath:@"/bin/bash"];
    NSArray	*args = [NSArray arrayWithObjects:@"-l",
    				 @"-c",
    				 commandlineHere,
    				 nil];
    [task setArguments: args];

This launches bash (not in sh compatibility mode), and -l (lowercase L) tells it to “act as if it had been invoked as a login shell”. I haven’t tested this on systems where bash isn’t the default shell. There are lots of ways $PATH could be set, and I haven’t tested them all. But you are almost certainly going to be OK if everything you refer to is in /usr/bin:/bin:/usr/sbin:/sbin.

« Newer Posts

Powered by WordPress