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.

Snow Leopard. Terminal. Currently loaded drivers

kextstat command shows all loaded drivers:

If the loaded address is zero, it's a part of the kernel and not a driver. Such things cannot be unloaded. If you look for a specific driver use:
keystat | grep "file"

You wil see only "file related" drivers in the list.
There are three more command from the same seria: kextfind, kextload and kextunload. Last two require the super user password and should be called as
sudo kextload /System/Library/Extensions/msdosfs.kext

kextfind help to find a driver, for example, so:
kextfind -bundle-id -substring 'file'

Wednesday, August 11, 2010

iPhone Explorer


It's happened! iPhone Explorer. I just installed it on my Mac from here:
http://www.macroplant.com/iphoneexplorer/

Sunday, August 1, 2010

Win32: Create window menu programmatically

Standard Windows application contains a menu. Usualy we create the menu in the application resource file. Then load it and pass the menu handle whithin the window class regisration procvedure.
How to create the standard windows menu programmatically?
CreateMenu function in the following Win32 program does it:
#define WIN32_LEAN_AND_MEAN

#include <windows.h>

LPCWSTR s_szWndName = L"A window with a menu";

ATOM RegisterWndClass(HINSTANCE, LPCWSTR);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

void CreateAMenu(HWND hWnd);

int WINAPI wWinMain(HINSTANCE hInstance,
HINSTANCE, LPWSTR, int nShowCmd)
{
RegisterWndClass(hInstance, s_szWndName);

HWND hWnd = CreateWindow(s_szWndName, s_szWndName,
WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0,
NULL, NULL, hInstance, NULL);

if (hWnd != NULL)
{
ShowWindow(hWnd, nShowCmd);
UpdateWindow(hWnd);

MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

return 0;
}

ATOM RegisterWndClass(HINSTANCE hInstance,
LPCWSTR lpszWndClassName)
{
WNDCLASSEX wcex = { 0 };
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = lpszWndClassName;
return RegisterClassEx(&wcex);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
CreateAMenu(hWnd);
break;

case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;

case WM_LBUTTONDOWN:
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

    default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}

#define ID_NEW_RECORD_ITEM 1001
#define ID_SAVE_RECORD_ITEM 1002
#define ID_QUIT_ITEM 1003
#define ID_SHOW_ALL_ITEM 1004
#define ID_SELECT_REPORT_ITEM 1005


void CreateAMenu(HWND hWnd)
{
HMENU hMenu = CreateMenu();
HMENU hSubMenu = CreatePopupMenu();

AppendMenu(hSubMenu, MF_STRING, ID_NEW_RECORD_ITEM, L"&New Record");
AppendMenu(hSubMenu, MF_STRING, ID_SAVE_RECORD_ITEM, L"&Save Record");
AppendMenu(hSubMenu, MF_STRING, ID_QUIT_ITEM, L"&Quit");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, L"&File");

hSubMenu = CreatePopupMenu();
AppendMenu(hSubMenu, MF_STRING, ID_SHOW_ALL_ITEM, L"Show &All Data");
AppendMenu(hSubMenu, MF_STRING, ID_SELECT_REPORT_ITEM, L"S&eelect report");
AppendMenu(hMenu, MF_STRING | MF_POPUP, (UINT)hSubMenu, L"&Reports");

SetMenu(hWnd, hMenu);
}