Pages

Sunday, August 22, 2010

Big-O Notation

Big-O Notation is a kind of a strange foreign language. Interviewers use it in order to show that they are smarter than you, the development managers mention it to demonstrate own IQ to the programmers. :)
In case you have to know what is this Big-O notation read these articles in the following order:
1. A Beginners’ Guide to Big O Notation.
2. An Intro to Big Oh Notation with Java.
3. Complexity and Big-O Notation
4. An informal introduction to O(N) notation
5. Algorithmic Efficiency -- Analyzing Algorithms
6. Algorithmic Efficiency -- Various Orders and Examples
From my point of view it's a bureaucracy that comes to the real programming. Yes, it says something about the algorithm performance. But it can be a real mistake to write a fundamental algorithms yourself in complex commercial projects. It's important to see in the source code the bottle necks, but if I see a nested loop, I do know that it is better to "open" it and the fact that now I know that is O(N^2) does not help me at all.

Sunday, August 15, 2010

Mac OS X. Terminal curl

Today morning I found this blog post:
See Share Quotes In Terminal / Geek Tool

I'm from the Windows world and didn't know about curl in Terminal, so I tested:
Looks interesting? For me too. So I found how to work with the ftp via curl:
http://www.hyperorg.com/blogger/2008/01/01/beginner-to-beginner-ftp-via-curl/
One more nice example: how to detect my IP address with curl:
curl ifconfig.me

XML parsing on Mac. Fast and Dirty.

If you know C better than Objective-C, this is a fast and dirty way to parse an XML-file on Mac OS X:
#import <Foundation/Foundation.h>

void PrintTree(CFXMLTreeRef tree)
{
int kids = CFTreeGetChildCount(tree);
if (kids > 0)
{
int cnt = 0;
while (cnt < kids)
{
CFXMLTreeRef treeChild = CFTreeGetChildAtIndex(tree, cnt);

PrintTree(treeChild);

CFXMLNodeRef treeNode = CFXMLTreeGetNode(treeChild);
//CFXMLNodeTypeCode subNodeType = CFXMLNodeGetTypeCode(treeNode);
CFStringRef text = CFXMLNodeGetString(treeNode);
NSLog(@"text: %@", text);
++cnt;
}
}
}

int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

CFXMLTreeRef tree;
NSString *str;
NSData* data;

str = [[NSMutableString alloc] initWithContentsOfFile: @"data.xml"];
data = [str dataUsingEncoding:NSUTF8StringEncoding];

tree = CFXMLTreeCreateFromData(kCFAllocatorDefault,
(CFDataRef)data, NULL,
kCFXMLParserSkipWhitespace,
kCFXMLNodeCurrentVersion);

PrintTree(tree);

CFRelease(tree);
[str release];
[pool drain];
return 0;
}
As you see, this a Foundation Tool project. It works with data.xml located in the debug folder:
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <person>
    <name>Pavel Gnatyuk</name>
    <age>40</age>
  </person>
</root>
Of course, it could be written in the pure C. But it's enough to give a direction.
BTW, the standard way to work with the XML on iPhone is shown in this nice tutorial:
Parsing XML Files

Saturday, August 14, 2010

Mac OS X. Keep Safari Alive.

launchctl is a tool allowing to load and unload the daemons on Mac OS X. For example, here I will show how Safari can be re-launched automatically in a case of a crash.
In TextEdit make the following file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" 
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.KeepSafariAlive</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Safari.app/Contents/MacOS/Safari</string>
</array>
<key>OnDemand</key>
<false/>
</dict>
</plist>

Save it com.apple.KeepSafariAlive.plist in ~/Library/LaunchAgents folder.
Now in Terminal type:
$ launchctl load Library/LaunchAgents/com.apple.KeepSafariAlive.plist
You see Safari running. Try to kill it, for example:
$ killall -9 Safari
To unload the agent use this command:
$ launchctl unload Library/LaunchAgents/com.apple.KeepSafariAlive.plist

This example was taken from this book:

Friday, August 13, 2010

Snow Leopard. Terminal. Compile Objective-C program

Google always helps. :)
Today it helped me to compile a standard (or GNUStep ?) Objective-C program with gcc.
Here is the code:
#include <objc/Object.h>
#include <stdio.h>
#include <stdio.h>

@interface Test : Object
{
}

- (void) sayHello;

@end;

@implementation Test


- (void) sayHello
{
printf("Hello\n");
}

@end

int main(void)
{
id t;
t = [Test new];
[t sayHello];
[t free];
return 0;
}
The command to compile is the following:
gcc -arch i386 test.m -o test -lobjc
It means that the output file ./test supports the Mach-O architecture. You can verify it as:
file ./test
The output:
./test: Mach-O executable i386

GNUStep on Windows.

Today I installed GNUStep on Windows XP computer and compiled a foundation tool program. Actually. I didn't expect such results.
The installation instruction is here: http://www.gnustep.org/experience/Windows.html
Download GNUstep MSYS System and GNUstep Core. Install them in the same order.
If you didn't change anything within the installation you will find GNUStep folder on your C drive. In this folder you find msys.bat. Launch it or launch Shell in Start->All Programs->GNUStep->Shell.
It's a more or less standard shell. Use vi to type a program. If you prepare a Windows editor, for example Notepad++, you can use it and save the program in /GNUStep/hom/ folder.
I began from the simple C-program and compile it ion the shell as:
gcc test.c

Then, I tried a simple Objective-C program:
#include <objc/object.h>
#include <stdio.h>

@interface Test : Object
{
}
- (void)sayHello;
@end

@implementation Test

- (void) sayHello
{
printf("Hello from Objective-C class\n");
}

@end

int main(void)
{
id t;
t = [Test new];
[t sayHello];
[t free];
return 0;
}
Then I compiled it:
gcc test.m -lobjc
I got a.exe file and launched it:
Next step - test a Foiundation Tool!
#import <Foundation/Foundation.h>

int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

NSLog (@"Hello. It's Foundation Tool");
[pool drain];
return 0;
}
The gcc line looks weird:
$ gcc `gnustep-config --objc-flags` -L /GNUstep/System/Library/Libraries test1.m -o test1.exe -lgnustep-base -lobjc
But then I got the executable that I can launch in the shell:
Helpfull links about the subject:
1. Compile Objective-C Programs Using gcc.
2. Installing and using GNUstep and Objective-C on Windows

Snow Leopard. Terminal. The simplest dissamler

otool is a nice tool showing the dependencies and disassembly listing:
For example, otool -L /bin/pwd:

otool with -h shows the file header:

and otool -tv /bin/ls > ~/Desktop/ls.txt will make a text file on the desktop with the code of the ls.


/bin/ls:
(__TEXT,__text) section
0000000100001478 pushq $0x00
000000010000147a movq %rsp,%rbp
000000010000147d andq $0xf0,%rsp
0000000100001481 movq 0x08(%rbp),%rdi
0000000100001485 leaq    0x10(%rbp),%rsi
0000000100001489 movl %edi,%edx
000000010000148b addl   $0x01,%edx
000000010000148e shll     $0x03,%edx

And dtrace that requires the sudo password allows to trace. But this is a much more complicated story.