I’m a big fan of source code control systems. They help you not shoot yourself in the foot when making changes and it is an essential part of any form of development. Heck, it even comes in handy for managing changes to configuration files.
Solaris ships with SCCS, the source code control system for pretty much all forms of unix. It’s a file based source control system, and is used as the binder for other products such as teamware.
On Linux there’s rcs for file based source code control and then there’s CVS or Subversion for the remote repository work.
Subversion really beats the pants off CVS for features that make it more sensible. If you’ve ever tried to move a file in CVS you know what I mean.
debian makes life more realistic
It’s very simple really. Ubuntu uses dash as the default shell for executing init scripts as it is faster (there’s less overhead). dash is, of course the debian almquist shell, which is a bourne shell compatible shell. Not bourne again, but simply bourne, this means that features such as [[ are not present (see a previous blog entry for a complaint about that). We all like the fast boot, but it kinda breaks Makefiles that assume sh == bash (ieeee80211.sf.net, ipw3945.sf.net).
I’m too used to writing makefiles under Solaris to use features that are not present in the original bourne shell.
Makefile default shell
This one is a bit of a gotcha that I encountered in the ieee80211 and ipw3945 source. The make files used some convoluted shell syntax to check the state of the kernel. The problem is that it uses particular non bourne-shell isms, such as the [[ syntax, which simply doesn’t work in bourne, because it’s so bloody simple.
The short solution was to put SHELL=/bin/bash at the start of the Makefile, which causes the shell that is used to be bash instead of sh. This is of course one of the regular issues between the different versions of Linux that float around. Some use bash as sh, which technically speaking is a bit of an evilness. It can hit you time and again in writing rc scripts as well, where the choice of shell is not generally determined by the magical ‘#!’ on the first line, but by the rcX script (X is generally S, 1, 2, 3, …).
Again, the quantity of run levels is determined by the provenance of the Operating System – for example the machine I’m currently working on(Ubuntu) claims a run-level of 2, while the fedora core desktop I’ve just checked claims a run-level of 5. Solaris makes thing really fun by informing you that tour run-level is a legacy state that you should stop considering to be useful, after all it’s about the services that you have enabled, not the run-level.
So I decided to play with c++ builder
Probably one of the handiest features of C++ is the ability to create an object on the stack, and have it destroyed once the class has gone out of scope. This is because of the design of the language.
When you create an object using the syntax ‘ObjectT foo’ the object is instantly initialized, and you refer to each of the items in the object as foo.<whatever>. When the function returns the ObjectT’s destructor is called to clean up the object. This happens for every class.
Borland have seen it fit to make their compiler barf when you use one of the Visual Class Library(VCL) classes to create an object. Personally, I find the fact that you have to then wrap the code in a __try__ __finally__ block to be a waste of my time. After all there is no rational reason for preventing me from using the variable on the stack, as stack memory is just as good as heap memory (I’m old skool me!).
All you’re going to have on the stack is a pointer to a VTBL and the data concerned with the object; nothing more. If you have to cast it to a lesser object, then cast it to a lesser object. If you are using this object in another object (for example adding it to a collection), then use the proper syntax (in this case the ObjectT *foo = new ObjectT()). As a programmer you should know these things.
I would argue that the compiler should not protect us from such annoyances, but the reality is that to make better code we need more assertive nannies. All my C code is compiled with -Wall -Werror, which catches a lot of stupid mistakes, but doesn’t catch a lot of normal problems. Sometimes I think I would be better in a garbage collected, reference managed, array overrun protected world… but where would be the fun in that? I like my assembly language, I’m more careful as I know every instruction counts. That and the fact that a review of assembly code takes significantly longer than the same review of C code makes me pray that the developers are paying more attention.
Would you people please write proper applications
I’m getting annoyed with the number of programs that I have to exclude from DEP. Practically all of the palm simulators fall into this category along with all the securom games I’ve used.
Grrrr.
Just so you know… the palm database file format
Trivial, I know, but some people need to know these things.
From the start we have the header, appinfo (optional), sortinfo (optional) followed by the record entry headers.
The header is:
Field | Size | Value |
---|---|---|
Db Name | 32 | Ascii Database Name |
attributes | 2 | See DataMgr.h for meaning (dmHdrAttrResDB) |
version | 2 | Version number an application would use this to decide if the content was compatible |
creationDate | 4 | Creation date of the database – time from the palm epoch when it was created |
modificationDate | 4 | Last modifiied date of the db. creationDate by default. |
lastBackupDate | 4 | date last backed up ina hotsync |
modificationNumber | 4 | when changed this gets bumped |
appInfoID | 4 | Offset in this DB to the appinfo block (0 if it does not exist). |
sortInfoId | 4 | Offset in the DB to the sortinfo block (0 if it does not exist) |
type | 4 | the 4 character type of the pdb |
creator | 4 | the 4 character creator of the pdb |
uniqueIDSeed | 4 | Stumped – I don’t know what this is for, leave it at 0 |
This is the end of the header structure, the next is the record entry information |
Record list:
Field | Size | Value |
---|---|---|
nextrecordList | 4 | Address of the next record list (only used for really bit pdbs) |
nRecords | 2 | Number of records in the recordlist |
pad | 2 | Number of records in the recordlist |
nRecords items | 4 * nRecords | Addresses of the records in the pdb |
The address of the first record usually lies immediately following the appinfo and sortinfo data. As this data is consumer defined, the only way of determining it’s size is to use relative calculations. For example, the size of the appinfo structure it’s local address up to min(addr(sortinfo, Address of any data records)) – 1. The size of the sortinfo structure is it’s local address up to the min(Address of any data records) – 1. They are application defined, and as such should not be messed with.
This is really a WTF
I discovered this one in a state management routine – save the address of the database corresponding to the module that’s loaded. It works until the program is restarted or the operating system is rebooted. I’m going to have to change it to use the name of the module instead of it’s address. The only problem I can forsee is the presence of multiple copies of the same named module in the application path; That’s just another thing to work out.
It’s not just me but security elevation prompts in vista are a pain in the ass
Firstly, it’s cool that they are there. Rather than having to do something surreal involving runas, explorer and a couple of other things to allow you to run an application at a privileged level you now encounter the ubiquitous shield icon, which tells you that to perform this operation you need to acquire the appropriate privileges. It’s a lot like the linux sudo, except by default you just have to click the ‘continue’ prompt instead of a password.
Pretty cool, even if you’re an administrative user, you don’t start with all the privileges that your group memberships provide.
Here comes the rub – I’ve stopped reading the prompts, I just find the one that tells me how to get to the next step and click on it. I’m not positive, but I think this is probably par for the course for other users as well.
Shame that, nice idea, but hamstrung by having too many things need administrative privileges.
Palm Binary Compatibility
I find the Palm platform convenient for programming. You can build something using the latest and greatest Palm 5 based SDK and then run it on the oldest cruddiest palm you have. As long as you make sure to not use unsupported APIs your program just works. It’s like static linking under Unix/Linux – all you need to make sure is that the underlying system calls are there (or in this case entries in the trap table.
Depends, really
Some people think that make is a terrible piece of software. Honestly, it is just awful for modern projects with large numbers of dependencies. Header file dependencies become a problem. There are options to auto-insert the dependencies on header files into the makefile. Subdirectories are a problem – isolating certain code in directories is tricky. You can use the VPATH feature to provide a certain level of automatic path traversal without over-complicating the makefiles, and for trickier features you have the :sh= [svr] or $(shell …) [gnu] options to pass the work off to the shell or a script. Still the best thing about make is that it completely evaluates the dependency graph for targets; explicitly forbidding loops (or self reference).
Then we come to software releases, and their dependencies. You can’t install X without Y. you can’t remove X without remving Y. Removing X will break Y therefore you can only remove X and Y together. Good idea. Difficult on customers, though. They want an ‘add/remove programs’ option which installs and uninstalls all the needed components. I recently bought Sin Episodes from steam. It auto-installed Sin 1/Sin Multiplayer. I wanted to uninstall Sin 1/Sin Multiplayer. You can’t Sin 1 depends on Sin Multiplayer. Sin Multiplayer depends on Sin 1. Perfect cyclic dependency preventing you from uninstalling. Uninstalling means going in and deleting the .gcf file. Ah well, that’s life, I suppose.