My lib

Some thing constructive for the night. Cleaned up a lot of stuff in my utility/portability lib. Including a bool datatype for when stdbool.h is not around. And if it is or its C++ use the local boolean.

Aslo tried to make it slightly more friendly to pre-ansi compilers. Not that I’ve ever used one or seen one.. have heard of a few people meeting up with one though !

Basically I started it out both out of interest and Windows. I’m a tad lazy, I’d rather use an err( int, string ) then fprintf a string to stderr and append errno plus call exit() — A good 2 or 3 lines usually. When I can do it in 1 or 2 depending on the type of message I want displayed on exit(). BSD/GNU extensions have err()/warn() routines.

Windows of course lacks this totally as far as I can find. So since I was interested for a long time in how to create libraries I looked up how and implemented the err()/errx() I used so much in it. As well as most of the routines I’ve created in a few small programs. I don’t expect to use the thing for much more then building my programs on Windows w/o having to do a lot of search and replace. I just love err() 😉

Wow… just like when I’m sleepy I find a comment like this as I read lol

2230:         /*
2231: * If the new process paused because it was
2232: * swapped out, set the stack level to the last call
2233: * to savu(u_ssav). This means that the return
2234: * which is executed immediately after the call to aretu
2235: * actually returns from the last routine which did
2236: * the savu.
2237: *
2238: * You are not expected to understand this.
2239: */
2240: if(rp->p_flag&SSWAP) {
2241: rp->p_flag =& ~SSWAP;
2242: aretu(u.u_ssav);
2243: }

Been toying qith QTRuby and Korundum (QT3/KDE3 bindings for Ruby).

So far I think I rather like it hehe.

Got QTRuby installed fine, Korundums being a bit picky by libtool way. Hope to have a PBI with both in it by next week.

Some likes I need to bookmark in my master-bookmarks-file and want to post on PC-BSD forums.

Terry@Dixie$ rf ~/tmp/notes 5:20
–with-qt-dir=DIR where the root of Qt is installed
–with-qt-includes=DIR where the Qt includes are.
–with-qt-libraries=DIR where the Qt library is installed.
–with-smoke[=qt|kde] Smoke: build Smoke for qt+kde or qt only [default:qt]
–without-gl disable 3D GL modes

configured as:
./configure –prefix=/Programs/QT-KDE-Ruby-Runtime1.0 –with-qt-dir=/usr/X11R6/include –with-qt-includes=/usr/X11R6/include –with-qt-libraries=/usr/X11R6/lib/

http://developer.kde.org/language-bindings/ruby/tutorial/tutorial.html

http://developer.kde.org/language-bindings/ruby/tutorial2/tutorial2.html

http://www.arachnoid.com/ruby/RubyGUIProject/index.html

http://developer.kde.org/language-bindings/ruby/kde3tutorial/index.html

arning: you chose to install this package in /Programs/QT-KDE-Ruby-Runtime1.0,
but KDE was found in /usr/local.
For this to work, you will need to tell KDE about the new prefix, by ensuring
that KDEDIRS contains it, e.g. export KDEDIRS=/Programs/QT-KDE-Ruby-Runtime1.0:/usr/local
Then restart KDE.

http://doc.trolltech.com/3.3/how-to-learn-qt.html

Terry@Dixie$ 5:20

am I to young ?

When I first read this, I figured a call to panic() would likely bring down the system or set it in motion to abort before the frag explodes . Maaaybe I’ve just lived in a world where the Blue Screen Of Death (BSOD, a Microsoft copyright) is prevelent a little to long. The idea that it calls update(“which I have yet to disect”), prints an error message and calls the kernels idle() loop times infinty is neat. Rather then bringing the system to a screeching halt right then and there. At first glance I would’ve expected it to take down the system right bam’n’slam now.

/*
* Panic is called on unresolvable
* fatal errors.
* It syncs, prints "panic: mesg" and
* then loops.
*/
panic(s)
char *s;
{
panicstr = s;
update();
printf("panic: %sn", s);
for(;;)
idle();
}

Of course from the fine book for study. It seems the only way out of a panic() attack is a restart any way, but its not an instant ‘crash, have a nice foo&ing day, rebooting now sucker’ kind of thing. Which interestingly a lot of times my Windows machines have gone down, *cough*. Its kind of been to the BSOD what the expression ‘Do not pass go, do not collect $200’ is to monopoly. It dies, you get an error, but it kills itself before you get to read it. Then tells you it was *probably* a driver issue lol.

Note that the above code snippet is probably under the this license.

It is from UNIX Version 6 as viewed from here. File is /usr/src/sys/kern/prf.c

Of Code and Programs

Hmm, do I regret never having formal education in programming ? Not really no. Although I think it would’ve been cool to of had a teacher.

When it comes to languages and what not, every thing I know I’ve basically learned on my own. With the assistance of the fine World Wide Web of course. For what ever reason, don’t know any more lmao. I started learning C++ one day. Said what the heck, installed an IDE and hit the web.

That was maybe 1.5-2.5 years ago I think..

One thing I do think I’ve missed out on. Is being educated on the things that transcend the languages. For example.. implementing a bubble sort in language foo should be easy enough ! But on the other hand. I’d much rather have a strong understanding of sorting algorithms and how to work out such problems my self. Then be able to implement the same solutions in many tongues. Although there’s arguably no optimal algorithm that can solve any problem hehehe.

I find my self most often thinking in C or Pseudo English when trying to express my thoughts about computer code. I know about linked lists and such. But implementation wise I tend to visualize that sorta stuff in C =/.

I don’t know why but Unix, C, and Vi feel just right. Like an extension of my hands. Now, I’m no solid programmer that’s for sure. But for all of my personal study C is my strongest language. I’m not sure which I’m better at expressing my self in. English or C, its like a First and Second language kinda thing =/.

I don’t really think I’m cut out for systems work but I often think about it. Stuff like implementing languages, compilers, drivers e.t.c. all interest me. Hell I’d write my own device drivers if I knew what the heck I was doing. Only thing is I don’t :@

For me the language is a way of expressing a problem, an idea, or maybe even a solution. Although I reckon its meant to be easier for the computer to understand then humans lol. When reading programs I find the hardest things not figuring out what the code does. But how it interacts with the things around it.

Like, the initiation code in the FreeBSD kernel. The codes right there, plain enough as the nose in front of my face. But its hard to understand it. Because I know jack about it. The intimate relationship between the hardware… hard to grasp that fine. Yet its some thing that interests me so.

alas, tis late and I have a feeling to be close to some code. But I have no problem to solve. Well other then a little idea for the Rct Checklist hehe. I know near diddly squat about PHP and MySQL. But its fun and the syntax is close enough to C/C++/Java/Perl that I can figure it out, looking up a few odds and ends to be sure. As I go along with it. Like functions scope.

I do rather like C in that regard, I feel how it handles scope and linkage to be rather logical. Yet in a simple manor for most of it.

While I’m to tired to understand why this writes past the end of the array

#include <assert.h>
#define bounds(_i, _n) (assert( (unsigned) (_i) < (_n) ), (_i) )
....

/*
* fout is what we are appending to and should be open rw as necessary.
* farray is an array of file pointers, "farsize" is the size of the array.
*/
void
concatenate( FILE *fout, FILE *farray[], const unsigned char *farsize) {

int c;
unsigned int fi = 1;
FILE *fin; /* current segment of farray[] to fout. */

while ( (fi < farsize[0])) {
fin = farray[bounds(fi, *farsize)];
fi++;
while ( (c = fgetc(fin )) != EOF ) {
fputc( c, fout );
}
}
}

I’m GOING TO BED. 0832 Zulu time on my clock…. must sleeep sleep….

what is that again?

Well since Windows lacks fgetln() but as far as I can tell the BSD and GNU C Libraries have it.

/* The origenal, basically the same as one of the functions in FreeBSDs head(1) implementation.

static void
read_top( FILE *fp, int lncnt ) {

char *cp;
size_t error, rlen;
while ( lncnt && (cp = fgetln( fp, &rlen )) != NULL ) {
error = fwrite( cp, sizeof(char), rlen, stdout );
if ( error != rlen )
err( 1, "stdout" );
lncnt--;
}
}

/* A new version of read_top that *should* be a bit more standard compilent and simple to read */

static void
read_top( FILE *fp, int lncnt ) {

int c = 0;
int f = 0;

while ( (c < lncnt) && (f != EOF ) ) {
f = fgetc( fp );
printf( "%c", f );
if ( (f == 'n') ) {
c++;
}
}
}

The biggest problem with rf.c is the use of err()/errx(), a nice pair of Macros that expand to a fairly compatible meaning would be nice for portability. *cough* Windows *cough* and I don’t even want to know how groff works on WIN32 if at all….

10 Thou shalt foreswear, renounce, and abjure the vile heresy which claimeth that “All the world’s a VAX”, and have no commerce with the benighted heathens who cling to this barbarous belief, that the days of thy program may be long even though the days of thy current machine be short.
This particular heresy bids fair to be replaced by “All the world’s a Sun” or “All the world’s a 386” (this latter being a particularly revolting invention of Satan), but the words apply to all such without limitation. Beware, in particular, of the subtle and terrible “All the world’s a 32-bit machine”, which is almost true today but shall cease to be so before thy resume grows too much longer.

Ten Commandments of C Programming

This some times reminds me of how I feel about assumtions. Uusally met with me thinking.

“I’m not running Windows, !@#$ you”

“I’m not running Linux, !@#$ you”

“I’m not using MS-DOS, !@#$ off!”

“I’m not working in Visual BASIC or Visual C++, really un-!@#$ you”

“What if I’m not on a 32-Bit system, oh go !@#$ your self”

lol.

1 Thing I’d love to see. Is a simple yet powerful language like Perl/Python/Ruby thats got a C/C++ style compiler like GCC. Like being able to run the C pre-processor on the files before compilation and being able to link the object files together into an executable.

But also, a simple interpreter that implements the standard library and can run single file ‘scripts’ like a Bourne Shell. Yet with the options of being able to ‘link’ to pre-compiled libraries of code to extend itself in order to run the script. That way, people could use the interpreter for use interactive (like irb / python) yet run scripts and not have to have a development environment (compiler and friends) and any precompiled libraries could be distributed with the script.

Like

import math_module
import sockets_module

Compile the app and link it to a math and socket library. Or i f we’re using the interpreter.

foo -l lib1, lib2

or even in the script

#!/usr/bin/foo -L /usr/lib/foo/

Would be kinda cool.

The power, flexibility, and speed of a compiler yet the simplicity of an interpretor. But with keeping the ability to also use various libraries of code with the scripts. One could probably do some preprocessor work to include the library code in the script before using it too and save disk space.

Wouldn’t it be awesome if one could work on a Project in Python instead of C++ and keep a compiled executable. Yet when ya need a little script for some ‘loose ends’ to just go ahead and write a script to do it in the same language as the project ? Hehehehe.

I think D has the ability of doing a script, like #!/path/compiler -run at the top of the file. No clue if its a dual-purpose compiler/interpretor or if it just compiles an executable in temp space and runs it or what.

rf.c semi-final

Well to make a long story short. I found out that calling setlocale() made my program (rf) crash when ever I used to -b switch. But strangely on OpenBSD it ran perfectly fine.

Sure enough after 2 days of tracking I found a few bugs and the little blighter I’ve just squashed was just the one I expected to find. It was just a matter of how. Just a bad pointer, my guess is after the setlocale() call. It was pointing some where FreeBSD didn’t like and without the call it wasn’t enough to get ballocked at. Who cares how thats possible… as long as its fixed hehe. Well as best as _I_ can tell any way.

The projects grown and I’ve learned quite since the start. Both about working in C, using Makefiles, dealing with GCC, GDB in more depth, and groff e.t.c. For sear size we are at:

#wc [ lines | words | bytes | filename ] 
16 121 778 COPYING
25 68 735 Makefile.optimize
255 1023 6517 rf.c
11 114 3636 rf.o
87 333 1819 rf.1
9 68 404 tags
403 1727 13889 total

I have 3 Makefiles, a generic makefile for building the application on i686. Makefile.debug that does likewise but includes debugging symbols. And Makefile.optimize that has a few extra flags with mostly optimization options in it (hence the name). Each also can do a ‘make install’ for me. All in all gcc gets called from Makefile.optimize with:

-Wall -Wpointer-arith -Wcast-qual -Wcast-align -Wconversion -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Winline -Wnested-externs -std=c99 -march=i686 -fforce-mem -fforce-addr -finline-functions -fstrength-reduce -floop-optimize

I made some other changes too. I rewrote parts of main, its still not pretty but a wrapper on fopen() I think makes it easier to dick with. I finally added a -v option to see the file name. I was trying to figure out how to make a variadic macro and stumbled onto the __FILE__ and __LINE__ additions to C hehehe. I also decided to have it clean up after its malloc’ing. AFAIK a programs memory is free()’d after it exits so I didn’t bother. Now I did for completeness sake. clean_up() is called after handling the output done in read_bottom (which actually uses read_all() to printout the file). So that if for some odd reason theres really low memory or some thing and it takes *awhile* to handle malloc’ing and seeking semi-end-to-end through a linked-list. I figured it’d be a good ‘just in case’ even if its not likely.

I really would like to rewrite read_top() b/c I don’t know of any comparable function to fgetln() on windows and a Macro that inlines a rough equivalent to my beloved err() function too. Which likewise is available from the BSD and GNU C Libraries and both are marked as ‘first appeared in 4.4BSD’ in the man pages. And AFAICT not available from Microsofts implementation.

One thing I need to do is learn more about groff and the man page macros and stuff. So far its mostly been a matter of reading my systems man pages and trial/error to get a fairly decent manpage.

I try to keep things small, my displays usually 80×25 or 80×35 if I’m working on Windows (GVIM) and 1 thing I really hate. Is a huge function thats so freaking big, you don’t even remember the NAME of it by the time you hit the closing bra}e. So lol, I do my best not to write functions that long. At 60 some lines with comments I think read_bottom should be broken up into 2 smaller functions, the extra function call is negiable overhead I’m sure. I just think it would take longer to read. Really if you snip off the variable declarations and list startup (which could be function’ized) it almost fits on 1 screen. be_verbose man as well be a macro or inline function too. Although a compiler could take care of that choice it self I’m sure.

To be honest, I just like functions that are small, do whats asked, and avoid being swiss-army knifes.

/*-
* Copyright (C) 2007
* Terry M. P*****. All rights reserved.
*
* permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/


// vim: set noexpandtab ts=8 sw=4 ai :
// vi: set ai nu ts=8 sw=4 :

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <locale.h>
#include <unistd.h>

struct lnpos {
long nl;
struct lnpos *next;
} lnpos = { .next = 0, .nl = 0 };

static FILE *open_file( char * );
static void read_all( FILE *, int );
static void read_top( FILE *, int );
static void read_bottom( FILE *, int );
static void clean_up( struct lnpos *);
static void be_verbose( void );
static void usage( void );


static const char *this_progname;

/*
* rf - read file to standard out v1.27
*/

int
main( int argc, char *argv[] ) {

char *erptr;
int t_flag = 0, b_flag = 0, v_flag = 0;
int ch, lncnt;
FILE *fp;

(void)setlocale( LC_ALL, "" );

this_progname = argv[0];

while ( (ch = getopt(argc, argv, "b:t:v")) != -1 ) {
switch (ch) {
case 'b':
b_flag++;
lncnt = strtol(optarg, &erptr, 10);
if ( *erptr || lncnt <= 0 )
errx( 1, "Improper line count -- %s", optarg );
break;
case 't':
t_flag++;
lncnt = strtol(optarg, &erptr, 10);
if ( *erptr || lncnt <= 0 )
errx( 1, "Improper line count -- %s", optarg );
break;
case 'v':
v_flag++;
break;
case '?':
default:
usage();
/* NOTREACHED */
}
}

/* This is ugly but cleaner then w/o open_file(). */
if ( argv[1] == NULL ) {
usage();
} else if ( (t_flag < 1) && (b_flag < 1) && (v_flag < 1) ) {
fp = open_file( argv[1] );
read_all( fp, lncnt );
} else if ( (v_flag != 0) && (t_flag < 1) && (b_flag < 1) ) {
fp = open_file( argv[2] );
read_all( fp, lncnt );
} else if ( t_flag > 0 ) {
fp = open_file( argv[3] );
read_top( fp, lncnt );
} else if ( b_flag > 0 ) {
fp = open_file( argv[3] );
read_bottom( fp, lncnt );
} else {
usage();
/* NOTREACHED */
}

if ( v_flag != 0 )
be_verbose();

fclose( fp );
return 0;

}


/* Simple fopen wrapper to keep the if...else if...else blockage from
* getting even uglier. Since doing other wise would defeat the purpose of it.
* open_file() halts the program if fopen failed.
*/
static FILE
*open_file( char *arg ) {

FILE *fto;

fto = fopen( arg, "r" );
if ( fto == NULL )
errx( 1, "File can not be opened or"
" does not exist -- %sn", arg );
return fto;
}


/*
* print out an open file to standard output
*/

static void
read_all( FILE *fp, int lncnt ) {

while ( (lncnt = fgetc( fp )) != EOF ) {
printf( "%c", lncnt );
}
}

/* Read n lines from the top of the file.
* note that it was very inspired by the head(1) implementation of BSD
*/
static void
read_top( FILE *fp, int lncnt ) {

char *cp;
size_t error, rlen;
while ( lncnt && (cp = fgetln( fp, &rlen )) != NULL ) {
error = fwrite( cp, sizeof(char), rlen, stdout );
if ( error != rlen )
err( 1, "stdout" );
lncnt--;
}
}


/* Read n lines from the bottom of the file
*/
static void
read_bottom( FILE *fp, int lncnt ) {

int hmany = lncnt;
long nlnum = 0;
long where;

struct lnpos *root = 0;
struct lnpos *cur = 0;

root = malloc( sizeof(struct lnpos) );
if ( root == NULL )
err( 1, "can't init the list" );
root->next = 0;
cur = root;

cur->next = malloc( sizeof(struct lnpos) );
if ( cur->next == NULL )
err( 1, "can't add first node" );
cur = cur->next;

/* read the file, count every 'n' and store them in a new member of
* our linked list.
*/
while ( (lncnt = fgetc( fp )) != EOF ) {
if ( lncnt == 'n' ) {
nlnum++;
cur->nl = ftell( fp );
cur->next = malloc( sizeof(struct lnpos) );
if ( cur->next == NULL )
err( 1, "can't store line feeds" );
cur = cur->next;

}
}

/* Let's mark the end of the list and move to it */
cur->next = malloc( sizeof(struct lnpos) );
if ( cur->next == NULL )
err( 1, "can't terminate the list" );
cur = cur->next;
cur->next = NULL;

/* rewind our linked-list and seek to b_flag segments. So readall() starts from
* the correct fseek offset to print till EOF. - This keeps down on
* unnecessary code here !
*/
cur = root;
while ( hmany < nlnum ) {
cur = cur->next;
nlnum--;

}

where = fseek( fp, cur->nl, SEEK_SET );
if ( where != 0 )
err( 1, "could not seek through the filen" );

read_all( fp, lncnt );
clean_up( root );
}

/* Simple destructor - walk the list and free() the memory before the
* program exits.
*/
static void
clean_up( struct lnpos *rp ) {

struct lnpos *t = rp;
struct lnpos *atpos = rp;

while ( atpos != NULL ) {
free( t );
atpos = atpos->next;
t = atpos;
}
}

static void
be_verbose( void ) {

printf("==> %s <==n", __FILE__);
}

static void
usage( void ) {

(void)fprintf( stderr, "usage: %s [-t count | -b count] "
"[-v] [file ...]n",
this_progname );

exit( EXIT_FAILURE );
}

I’ve learned so much in the past 2 months, its awesome. Really this is the largest project I’ve ever worked on in my ~/Programming directory. 255 Lines isn’t much but when your a bumbling baboon trying to learn in the wilderness. It kinda helps to learn by reading and writing code I guess.

I also want to start assembling a little personal library of functions and macros that I can draw on to do odds and ends without rewriting them. After all with my little ‘toys’ I might have use of other stuff from time to time hehe.

Time for BEEEEEEEEEEEEEEEEEEEEEEEEEEDDDDDDDDDDDDDDD!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!