![]()
|
Programming with Rudiments using the Utility Classes
Most programs take command line options in the option/value pair format: program -option value -option value ... The commandline class makes it easy to deal with command line options of this format. Below is some code illustrating the use of the commandline class. #include <rudiments/commandline.h> #include <iostream.h> #include <unistd.h> #include <stdlib.h> int main(int argv, char **argc) { commandline cmdline(argv,argc); if (cmdline.found("-help")) { cout << "usage: divide -divisor number -dividend number" << endl; exit(0); } if (cmdline.found("-divisor") && cmdline.found("-dividend")) { int divisor=atoi(cmdline.value("-divisor")); int dividend=atoi(cmdline.value("-dividend")); cout << divisor/dividend << endl; } else { cout << "You must supply a divisor and a dividend." << endl; } }Using the Date/Time Class One of the most difficult things to do in a Unix environment is deal with dates and times. The "standard" functions and structures associated with dates and times are complex and vary widely from platform to platform. The datetime class attempts to rectify this situation. Below is some code illustrating the use of the datetime class. #include <rudiments/datetime.h> #include <iostream.h> main() { // get the current date datetime dt; // Write out the different parts of the date. cout << "Hour :" << dt.getHour() << endl; cout << "Minutes :" << dt.getMinutes() << endl; cout << "Seconds :" << dt.getSeconds() << endl; cout << "Month :" << dt.getMonth() << endl; cout << "DayOfMonth :" << dt.getDayOfMonth() << endl; cout << "DayOfWeek :" << dt.getDayOfWeek() << endl; cout << "DayOfYear :" << dt.getDayOfYear() << endl; cout << "Year :" << dt.getYear() << endl; cout << "Daylight Savings Time :" << dt.isDaylightSavingsTime(); cout << endl; cout << "Time Zone :" << dt.getTimeZone() << endl; cout << "Offset from GMT :" << dt.getTimeZoneOffset() << endl; cout << "Date String :" << dt.getString() << endl; cout << "Seconds since 1970 :" << dt.getEpoch() << endl; }Using the Random Number Class Functions for generating random numbers vary from platform to platform. The randomnumber class attempts to rectify this situation. Below is some code illustrating the use of the randomnumber class. #include <rudiments/datetime.h> #include <rudiments/randomnumber.h> #include <iostream.h> main() { // it's common to seed a random number generator with the number of // seconds since 1970 (the epoch), so we'll get the current date. datetime dt; cout << "A random number between 0 and 2^32: "; cout << randomnumber::generateNumber(dt.getEpoch()); cout << endl; cout << "A random number between 100 and 1000: "; cout << randomnumber::generateScaledNumber(dt.getEpoch(),100,1000); cout << endl; cout << "Another random number between 100 and 1000: "; int basenumber=randomnumber::generateNumber(dt.getEpoch()); int scalednumber=randomnumber::scaleNumber(basenumber,100,1000); cout << scalednumber << endl; }Using the Text Class The text class contains some commonly needed text manipulation and evaluation functions. Below is some code illustrating the use of the text class. #include <rudiments/text.h> #include <iostream.h> #include <string.h> main() { // initialize a text buffer and print it out char buffer[100]; strcpy(buffer," hello "); cout << "!" << buffer << "!" << endl; // trim the spaces off of the right hand side text::rightTrim(buffer); cout << "!" << buffer << "!" << endl; // trim the spaces off of the left hand side text::leftTrim(buffer); cout << "!" << buffer << "!" << endl; // convert buffer to uppercase text::upper(buffer); cout << "!" << buffer << "!" << endl; // convert buffer to lowercase text::lower(buffer); cout << "!" << buffer << "!" << endl; // http escape the buffer char *escbuffer=text::httpEscape("!@#$%^&*()hello-+"); cout << "!@#$%^&*()hello-+ http escaped is " << escbuffer << endl; delete escbuffer; // evaluate a string to see if it's a number if (text::isNumber("-100.5")) { cout << "-100.5 is a number" << endl; } if (!text::isNumber("-100.5.10")) { cout << "-100.5.10 is not a number" << endl; } // evaluate a string to see if it's an integer if (text::isInteger("-100")) { cout << "-100 is an integer" << endl; } if (!text::isInteger("-100.5")) { cout << "-100.5.10 is not an integer" << endl; } }Using the Regular Expression Class Regular expressions allow a programmer to perform complex string matching but methods for using regular expressions vary from platform to platform. The regularexpression class attempts to rectify this situation. Below is some code illustrating the use of the regularexpression class. #include <rudiments/regularexpression.h> #include <iostream.h> main() { // A quick match... if (regularexpression::match("Hello Dave!",".*Dave.*")) { cout << "The string contains .*Dave.*" << endl; } // If you need to match over and over... regularexpression re(".*Dave.*"); if (re.match("Hello Dave!")) { cout << "The string contains .*Dave.*" << endl; } if (re.match("Goodbye Dave!")) { cout << "The string contains .*Dave.*" << endl; } if (re.match("Dave is a jerk!")) { cout << "The string contains .*Dave.*" << endl; } if (re.match("Dave writes cool software!")) { cout << "The string contains .*Dave.*" << endl; } if (re.match("See ya later Dave!")) { cout << "The string contains .*Dave.*" << endl; } }Using the Signal Classes Signals allow processes to interrupt the execution of other processes. Signal handlers allow processes to intercept and react to the signals sent to them. Rudiments provides 3 classes for working with signals: signalset, signalmanager and signalhandler. A signalset is just a collection of signals. The signalset class allows a programmer to build up a collection of signals. The signalmanager class provides methods for sending signals, ignoring signals, waiting for signals and examining blocked signals. The signalhandler class provides methods for catching and handling signals. Below is some code illustrating the use of all three classes. #include <rudiments/signalclasses.h> #include <iostream.h> #include <unistd.h> void handleSigusr1() { cout << "Got a SIGUSR1!" << endl; } main() { // this program will ignore all signals except SIGUSR1 signalset ignoreset; ignoreset.addAllSignals(); ignoreset.removeSignal(SIGUSR1); signalmanager::ignoreSignals(ignoreset.getSignalSet()); // when it gets a SIGUSR1, it will run the handleSigusr1() function signalhandler shandler(SIGUSR1,(void *)&handleSigusr1); shandler.handleSignal(); // Loop forever, each time waiting for a signal not in the ignoreset // to be sent. Since SIGUSR1 is the only signal not in the ignoreset, // waitForSignals will fall through only when SIGUSR1 is received. while(1) { signalmanager::waitForSignals(ignoreset.getSignalSet()); } } Note that you'll have to kill that program with a -9. Using the Permissions ClassThe permissions class provides simple methods for generating permissions. The output of these methods can be used whenever a function takes an argument of type mode_t. Below is some code illustrating the use of the permissions class. #include <rudiments/permissions.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> main() { // Create a file with rw-r--r-- permissions int fd=open("/tmp/tempfile",O_RDWR|O_CREAT, permissions::evalPermString("rw-r--r--")); // change the permissions to rw-rw-r-- permissions::setFilePermissions(fd, permissions::evalPermString("rw-rw-r--")); // close and delete the file close(fd); unlink("/tmp/tempfile"); // do the same as above using different methods fd=open("/tmp/tempfile",O_RDWR|O_CREAT, permissions::ownerReadWrite()| permissions::groupRead()| permissions::othersRead()); permissions::setFilePermissions(fd, permissions::ownerReadWrite()| permissions::groupReadWrite()| permissions::othersRead()); close(fd); unlink("/tmp/tempfile"); }Using the Shared Memory Class Shared memory allows seperate processes to access a common block of memory. The standard functions and structures for managing shared memory segments are complex. The sharedmemory class attempts to rectify this situation. Below is some code illustrating the use of the sharedmemory class. This program puts some data into shared memory then goes to sleep, giving another program time to access the segment. #include <sys/types.h> #include <sys/ipc.h> #include <rudiments/sharedmemory.h> #include <rudiments/permissions.h> #include <unistd.h> #include <string.h> main() { sharedmemory shm; shm.create(ftok("/tmp/shm",0),128, permissions::evalPermString("rw-------")); char *shmptr=(char *)shm.getPointer(); strcpy(shmptr,"This string is in shared memory."); sleep(1000); } This program reads the data from shared memory. #include <sys/types.h> #include <sys/ipc.h> #include <rudiments/sharedmemory.h> #include <rudiments/permissions.h> #include <iostream.h> main() { sharedmemory shm; shm.attach(ftok("/tmp/shm",0)); char *shmptr=(char *)shm.getPointer(); cout << shmptr << endl; } There are other methods in the sharedmemory class that allow you to get and set user/group ownership and permissions of a segment but they are straightforward and rarely used. Using the Semaphore Set ClassSemaphores allow seperate processes or threads to synchronize activities. The standard functions and structures for managing semaphores are complex. The sempahoreset class attempts to rectify this situation. Below is some code illustrating the use of the semaphoreset class. The first program prints out 1 and 3, the second program prints out 2 and 4. They use a set of 2 semaphores to synchronize these activities. No matter what order the programs are started in, they will always print out 1 These programs must both be run to the background. #include <sys/types.h> #include <sys/ipc.h> #include <rudiments/semaphoreset.h> #include <rudiments/permissions.h> #include <iostream.h> main() { int vals[2]={0,1,}; semaphoreset *sem=new semaphoreset(); sem->create(ftok("/tmp/sem",0),2,vals, permissions::evalPermString("rw-------")); for (int i=0; i<10; i++) { sem->wait(0); cout << "2" << endl; sem->signal(1); sem->wait(0); cout << "4" << endl; sem->signal(1); } delete sem; } #include <sys/types.h> #include <sys/ipc.h> #include <rudiments/semaphoreset.h> #include <rudiments/permissions.h> #include <iostream.h> main() { semaphoreset *sem=new semaphoreset(); sem->attach(ftok("/tmp/sem",0),2); for (int i=0; i<10; i++) { sem->wait(1); cout << "0" << endl; sem->signal(0); sem->wait(1); cout << "1" << endl; sem->signal(0); } delete sem; } |