Leonard J. Harding
Copyright © 1999 OG Software, Inc. All rights reserved.
Abridged Edition (19 pages)
This monograph, including the software contained in it, is provided AS IS with no warranties of any kind, either express or implied. The liability of OG Software, Inc., is limited to the replacement of defective distribution media returned to OG Software, Inc., within ninety (90) days of purchase together with a receipt evidencing such purchase. The purchaser of this monograph is authorized to distribute executables of his/her POO applications that contain object code of the POO software. All other rights are reserved to OG Software, Inc.
Internal Links: [ TOC | Intro | Using... | Writing... | Examples | Source ]
I wrote this monograph for people who program, people whose real business is not programming but who are not spectators. There was a time when our numbers were legion, but complex circumstances have thinned our ranks. There are lots of programmers, of course, but this monograph is for people who program. The advances that moved computers onto every desktop, e.g., windowing technology, served to disenfranchise many people who program because the advances require that they invest more knowledge and effort in their programming than they can afford. Consequently, many people who program were cast up on the shore amongst a flotsam of xterms and DOS windows.
This monograph contains the minimal, basic software that I regard as essential. Using the POO software, you can write applications that use multiple, windowed, text I/O streams based on an interface consistent with the basic I/O capabilities of the ANSI C and Fortran languages. In short, you can open and close windowed text streams, can append text to an output stream, and can obtain text from an input stream. As the user of a POO application, you can manage the attributes of its windows, the strings assigned to the function keys, the relationships between the output and input streams associated with its windows and the underlying file system, and the execution of the application itself. To manage the windows created by the application, you can interact with the windowing system directly or through the POO software. You can open windows to view files or directories in the file system. Scrolling, input editing, typeahead input, and line re-entry are supported.
There are, of course, some limitations. First, this monograph contains versions of the POO software only for the X Window System commonly supported in Unix, Microsoft's Windows, and IBM's OS/2 Presentation Manager. Thus your POO applications will be portable only among these systems. Second, you will need a C compiler that supports the development of windowed applications; if you write Fortran applications, you will need to learn how to build mixed-language applications. The versions of the POO software contained in this monograph are written in C, and you must compile the appropriate version. Third, you will need to learn how to tell your C compiler that your applications are both windowed and multithreaded. The POO software can be run single threaded in any of the supported environments but may not be satisfactory; the X version is predicated on the POSIX threads standard. Finally, you may need to install the X development system, e.g., include files, which many people omit to install in their Unix system.
This monograph consists of five files: a text file, a C source file containing the example applications, and a C source file for each of the supported windowing systems. The pure text in this monograph is relatively short; most of the text is contained in the source files. Much of the source code is the same in all versions and has been successfully compiled by nine or more C compilers and run successfully in three windowing systems.
Having spent many years writing anonymous documents in the third person and now being retired and free to exercise my First Amendment rights, I have chosen to write this monograph in the first person, perhaps with some backsliding. I have tried to limit the text to the necessary and sufficient information you need to start using the software and have relegated much of the documentation to the comments in the source code, which you should consult for detailed information. If you're reading this monograph, you're probably more interested in exploiting the software than reading my prose anyway.
Leonard J. HardingInternal Links: [ Preface | Intro | Using... | Writing... | Examples | Source ]
INTRODUCTION
IntroductionUSING A POO APPLICATION
IntroductionWRITING A POO APPLICATION
IntroductionREFERENCES
EXAMPLE APPLICATIONS C/C++ SOURCE
Introduction
X WINDOW SYSTEM C/C++ SOURCE
MICROSOFT WINDOWS C/C++ SOURCE
OS/2 PRESENTATION MANAGER C/C++ SOURCE
Internal Links: [ Preface | TOC | Using... | Writing... | Examples | Source ]
This monograph is intended for people who program in conjunction with their professional or leisure activities and would like to write portable windowed applications in C/C++ or Fortran for the X Window System commonly available in Unix, Microsoft's Windows, or IBM's OS/2 Presentation Manager. I assume that you would find delving into windowing technology for a period of several weeks or months to expand your computing skills an interesting but unwelcome diversion from your principal interests. I further assume that portability is an important consideration for your colleagues, if not for yourself. If you have experience programming in nonwindowed environments, such as xterms and DOS windows, and using windowed environments but have no background in constructing windowed applications, the software contained in this monograph may enable you to write windowed applications that are portable among the supported windowing environments. The POO software has been designed to build on your familiarity with the I/O functionality of C and Fortran so that you can write windowed applications with little more effort than you now invest in writing your nonwindowed applications.
The software contained in this monograph is an outgrowth of an effort to provide the full capabilities of today's windowed environments to people who program, which includes myself, but is limited to supporting text windows. Windowing systems involve some unusual elements, at least in comparison to those common in numerical applications, and the knowledge necessary to construct even simple windowed applications is neither easily acquired nor retained. People who program, people whose principal interests lie elsewhere, are unlikely to have either the time to acquire the requisite knowledge of one or more windowing systems or to require it often enough to retain it. The POO software is designed to allow you to construct windowed applications but does not require that you know much about windowing systems let alone be able to write windowing software.
The three versions of the POO software are very similar. The POO Application Programming Interface (API) does not depend on the windowing system so that a properly written POO application can be ported among these systems without change; the examples in this monograph are portable among these systems. The POO User Interface (UI) is almost independent of the windowing system so that users of POO applications are quite portable. Indeed, many aspects of the user interface were designed to encourage user portability.
The ability of an application to provide textual output to its user and to obtain textual input from its user are fundamental, and you may view the I/O capabilities provided by your C/C++ or Fortran compiler as sufficient. Even if your applications require only one I/O stream however, running your applications in an xterm or DOS window or some window created by the compiler for handling standard I/O likely falls far short of providing convenient access to the actual capabilities of your computer system. The real issue is not whether the I/O streams are windowed but rather the environment that is provided to the user while running an application.
The components of an appropriate solution are clear: a portable interface for the application itself, a simple and familiar programming interface, a familiar user interface, a command interface with the appropriate capabilities, and an interface to the underlying file system. The first objective is achieved by embedding the actual main program in the POO software so that a portable interface that is consistent with the C and Fortran standards could be provided for POO applications. The second led to an API that is consistent and, in most cases, compatible with the C and Fortran standards, namely the ANSI C stream I/O functions fopen, fclose, fputs, and fgets and the Fortran OPEN, CLOSE, WRITE, and READ statements when used to transmit textual data. The user interface supports an admixture of the usual keyboard and mouse controls: some may be very familiar because all of the supported windowing systems have many in common, but some may be unusual when viewed in the context of just one of the supported windowing systems. The command interface provides the user many of the capabilities of command windows as well as the ability to manage window attributes and the function keys. The virtual memory file facility embedded in the POO software is adept at dealing with both Unix and PC text files, binary files, and directories and can be exploited by the user to obtain windowed access to the underlying file system. Finally, for the user's convenience, the memory file facility automatically retains window attributes, function key string assignments, and other data between invocations of a POO application.
The POO API is small and easy to use. It is data oriented and contains no suggestion that the corresponding I/O streams are windowed. It employs only standard C data types that can also be represented in Fortran and contains only five functions, none of which take more than three arguments. The API functions provide only for the transmission of data; it is assumed that you will use the standard I/O formatting capabilities of the language to produce output text and to convert input text. You probably write your applications using the integrated I/O capabilities of C or Fortran that combine the formatting and transmission in a single function or statement. I would have preferred to support these integrated capabilities, but doing so would have sundered portability.
The POO UI is driven by the keyboard and mouse just as for any windowed application. Keyboard input will likely elicit the responses you expect, but many keyboard functions are duplicated to foster portability of the user among the supported environments. Mouse input may or may not elicit the responses that you expect because there is minimal standardization. Scrolling, typeahead, line re-entry, and many input editing features are supported. The UI includes a command interface so that you can change window attributes, manage the strings assigned to the function keys, manage the disposition of a window's output stream to a file, establish a file or portion thereof as a window's input stream, open pollsters to update logs and open onlookers to view files and directories, create virtual memory files, create or change files in the file system, and suspend or terminate the application.
Although you may view the focus of the POO software as supporting multiple, windowed I/O streams, the real issue is the user environment it provides when running an application. The POO software acts as an intermediary among the various active and passive participants: the application, the user, the windowing system, the file system, and the operating system. An application's responsibilities and prerogatives are quite limited and necessarily independent of the windowing system; an application should be concerned only with its I/O streams, which is reflected in the API. The user is expected to take an active role in the management of the execution of the application by managing the windows and their associated I/O streams. The remaining participants are passive or dictatorial.
Although all POO windows are alike as far as the windowing system is concerned, the POO software classifies them as either pollsters, onlookers, or others.
The size of the VM file associated with a pollster or onlooker is expanded as necessary. The size of the VM file created for an other and the management strategy, expansion or truncation, are determined by the application when the other is opened.
The Windowing SystemThe windowing systems in Windows and OS/2 are thoroughly integrated into the underlying operating systems, but the X Window System is simply a product that runs on top of an operating system, typically Unix. The X Window System is based on a client-server model; the X application need not be running on the same computer on which it opens its windows.
Both Windows and OS/2 contain the thread support required by the POO software, but you can choose to run your application single threaded. The system in which you run X may or may not support the POSIX threads standard on which the POO software is based; it is a relatively new standard so that many installed Unix systems do not support so-called Pthreads.
The Virtual Memory File FacilityA mechanism for managing the data displayed in the windows created by the application and user as well as an appropriate interface to the underlying file system are essential. The virtual memory file facility embedded in the POO software contains the requisite data management capabilities and handles all interactions with the underlying file system.
The VM file facility includes a couple features designed to enhance user portability. First, it accepts either a slash (/) or backslash (\) as the path name separation character. Second, it processes environmental variables that are specified in the form commonly supported by either Windows and OS/2 or Unix, specifically, %...% or ${...}. The VM file facility treats path names as case sensitive but can be changed to ignore case in file names, i.e., convert to uppercase.
The lines in a Unix text file are terminated by a new line character (\n), while Windows and OS/2 use the two-character sequence \r\n. The POO software adapts to whatever line termination is encountered. By default, new files are created to be consistent with the underlying file system.
The Memory File FacilityOver the years, I have come to appreciate software that can at least remember if not learn from experience. The memory file facility embedded in the POO software provides the required bidirectional capability: dynamic data that is retained between invocations. It retains function key string assignments and window attributes between invocations of a POO application and provides a record of all file references during execution. The memory file is implemented as a plain text file for the user's convenience and uses an abbreviated version of the syntax employed in the X resource manager.
Portability ConsiderationsSoftware is portable if it can be moved between systems with little or no change, which generally requires that it contain no significant system dependencies and be predicated on pertinent standards. A POO application that is itself portable can be ported among the supported environments: the X Window System, Microsoft's Windows, and IBM's OS/2 Presentation Manager. Portability in the broadest sense played a pervasive role in the design and development of this software.
Other Design ConsiderationsIssues arising from the desire to support both C and Fortran also had some impact on the overall design. For example, when a POO I/O stream is opened, the application can elect to treat it as either C stream I/O or Fortran record I/O. The POO software contains very few prohibitions and is not very paternalistic. This software is not designed to protect either itself or its data; there are no terminal errors. The POO software is a tool for people in search of reliable and effective tools. From the application's perspective, it is a very simply tool; from the user's, a perhaps overly permissive and flexible one.
You may find that windowed applications are somewhat more delicate than nonwindowed ones: errors in a windowed application may have bizarre consequences. Some windowed environments are delicate, while others are of sturdier stock.
Internal Links: [ Preface | TOC | Intro | Writing... | Examples | Source ]
You, the user of a POO application, can interact directly with the windowing system or can use the POO User Interface (UI) to interact with the windowing system, file system, or system. You can set and display the colors, font, and geometry of a window, which are your prerogative, indeed, they are your responsibility. You can set, display, and unset the strings assigned to the function keys. You can set and display each window's current directory, issue I/O direction commands to save output in a file or to establish input from a file, establish input from a subfile of an existing file, open additional windows to view directories or files in the file system, or create files in the file system. You can suspend or terminate the application. You can use the keyboard and mouse for scrolling and data entry and editing; both typeahead and line re-entry are supported.
All windows created by the application, whether at your request or the application's, are standard, top-level windows as provided by the window manager. As top-level windows, your desktop is the parent of each window, and all windows are independent of each other. As standard windows, each likely has a system menu box, title bar, a maximize, minimize, and/or restore box, and a sizing border.
The application opens one or more windows and appends text to the output streams that are associated with them. As text is added, the windows are updated to show the most recent output, normally with the last line of the output stream at the bottom of the window. You can scroll the text displayed in a window by using the usual scrolling keys, by dragging the text around the window with the mouse, by using the implicit vertical scroll bar, or by issuing COLUMN or POSITION commands.
For some windows, the application may solicit input. All input through a window is done in the input rectangle in reverse video, but the input rectangle is not drawn unless you are being solicited for input or entering unsolicited input. Input is terminated when you press Enter. Enter and Shift+Enter terminate your input normally, while Ctrl+Enter and Shift+Ctrl+Enter cause your input to be interpreted as a command. Line re-entry is provided by the right mouse button. The cut/copy/paste capability for input is implemented by both the usual Windows and OS/2 keys.
Keyboard InputThe keys are quadrupled based on the states of the Shift and Ctrl keys. The extended keys generally follow common usage, e.g., Insert toggles between insert and overstrike modes, and Delete and Backspace do so. Some of the scrolling keys are context dependent: they either scroll the window or move the input caret. To provide complete functionality while entering input, the scrolling keys in combination with Shift always provide the usual scrolling function.
| Ctrl+ | Function |
|---|---|
| A | deletes the input after the caret OR the file after the bottom line. |
| B | deletes the input before the caret OR the file before the top line. |
| C | copies the input to the cut/copy/paste input buffer. |
| D | terminates the application. |
| H | the same as Backspace. |
| I | ignored (Tab character). |
| M | the same as Enter. |
| O | toggles between text and hex dump format. |
| Q | resumes application execution. |
| S | suspends application execution. |
| U | deletes all input OR restores the whole file. |
| V | pastes the cut/copy/paste input buffer into the input. |
| X | cuts the input to the cut/copy/paste input buffer. |
| Z | generates an EOF. |
The function keys are quadrupled based on the states of the Shift and Ctrl keys so that Shift+F5 is F17, Ctrl+F5 is F29, and Shift+Ctrl+F5 is F41. The commands F1,...,F48 can be used to set, display, or delete a string assignment to the function keys. The function keys F5, F6, and F7 and their progeny are assigned built-in functions; built-in functions have lower precedence than strings you assign.
| Key | Built-In Function |
|---|---|
| F5 | pastes into the input stream or to the end of the file. |
| F6 | toggles the window update mode (others only). |
| F7 | copies the VM file associated with the window. |
Because key processing is table driven, the functions delineated in the tables above can be modified by changing table entries in the POO source.
Mouse InputMouse input is processed when you press a button or, in one case, when you drag with the button pressed; your release of a button is ignored. The mouse buttons are quadrupled based on the Shift and Ctrl keys. You can drag the text around the window. In effect, when you press the left mouse button, the software attaches the pointer to the character under it, and the text is moved to maintain this attachment.
| Button | Function |
|---|---|
| Left | drags text around the window. |
| Shift+Left | scroll bar regardless of pointer location. |
| Right | enter line as input or same as pressing Enter. |
Because button processing is table driven, the functions noted here can be modified by changing table entries in the POO source.
Command OverviewYou enter commands to manage the window attributes, function keys, current directory, I/O direction, and the updating of the memory file; there are also commands for setting the window position and displaying the status of the application or a file. The usual set and display commands are not provided; rather, each value that you can manage is represented as a command. If you provide no operand, the current value is displayed; otherwise, the value is changed. Commands can be abbreviated by truncation on the right provided the abbreviation is unique.
| Command Word(s) | Operand(s) |
|---|---|
| BACKGROUND aka BG | color name |
| FOREGROUND aka FG | color name |
| FONT aka FN | font face name [[ width ]x[ height ]] |
| GEOMETRY | [=](width)x(height){+|-}(x-org){+|-}(y-org) |
| MODE | [+|-](flag-word){+|-}... |
| F1...F48 | text[ \n | ^M ] | - |
| COLUMN | integer |
| POSITION | integer | fraction |
The BACKGROUND, FOREGROUND, FONT, GEOMETRY, and MODE commands provide control over the obvious attributes of the window; the usual X abbreviations BG, FG, and FN are accepted. If successfully executed, these commands update the memory file.
Scrolling CommandsThe COLUMN and POSITION commands provide no new functionality but do provide more precise mechanisms and the ability to display the current values.
Function Key CommandsThe commands F1,...,F48 set, display, or delete string assignments to the 48 function keys. If you assign a string that ends with the the two-character sequence "\n" ("^M"), it has the same effect as if you pressed Enter (Ctrl+Enter) after pressing the function key.
| Command Word(s) | Operand |
|---|---|
| CD | pathname |
| < aka LOAD | filename | - |
| << aka CONTINUE | filename | - |
| > aka STORE | filename | - |
| >> aka APPEND | filename | - |
Canceling output direction can be done with impunity, but canceling input direction should be done carefully. CD and I/O direction commands are not saved in the memory file; but, if qualified by the window name, they are processed when creating others. Unqualified CD commands in the memory file set the application's current directory.
Window Creation Commands
| Command Word(s) | Operand(s) |
|---|---|
| POLLSTER | poll file name |
| ONLOOKER | file or directory name |
| VMF | (size)[ K | B | P ] [ pc | unix | binary ] |
| MEMORY | none opens an onlooker for the memory file. |
| YO | [ filename | none ] |
Both the EXIT and STOP commands terminate the application: the former updates the memory file based on the memory status, while the latter does not update the memory file. In general, MEMORY is on so that attribute commands are recorded automatically and the memory file is updated.
| Command Word(s) | Operand(s) |
|---|---|
| MEMORY | [ off | on ] |
| EXIT aka XIT aka QUIT | none |
| STOP | none |
| CLOSE | none |
| ? | none, displays application and window status. |
| NB | none, inserts N.B.'s in others. |
| CF | integer |
| FIND | [?]string[?] [b] |
The NB command may seem a bit cryptic, but N.B. is the standard abbreviation of "nota bene" and the NB command inserts an N.B. with a date and time stamp and your input in an other. For pollsters, the NB command is implicit. For onlookers, your input is appended to the VM file but not the disk file associated with the onlooker.
The FIND CommandThe FIND command moves the window so that the line containing the next occurrence of the string is at the top of the window. In processing the first operand, an initial or terminal question mark is discarded but not ignored. If present, an initial question mark indicates that you are indifferent to the character preceding the first character of the string; otherwise, the character preceding the first character of the string must be unlike the first character of the string. A terminal question mark has an analogous effect. In this context, 'unlike' means that the two characters in question cannot both be alphanumeric, punctuation characters, or white space characters.
The CF CommandThe CF command compares two files starting with the second line in each window. When a mismatch is found, a message indicating the outcome of the comparison is appended to the command, and each window is moved to show the line containing the mismatch at the top of the window. Before resuming the comparison, you may position the windows to resync the files or to skip sections as desired.
Internal Links: [ Preface | TOC | Intro | Using... | Examples | Source ]
You, as the writer of a POO application, must be familiar with the POO Application Programming Interface (API) and aware of the rules that must be followed when writing and compiling a POO application. The POO API is very primitive: your application can open and close windowed I/O streams, append data to an output stream, and obtain data from an input stream. Your application starts with a function named 'appl' that accepts no arguments and returns an integer. Your application is responsible for providing its name and the names of its I/O streams, all of which should be unique for the user's sake.
| int cappl (char *application_name) |
| void *copen (char *name_title, int size, int extra_size) |
| int cclose (void *id) |
| int cputs (void *id, char *text, int length) |
| int cgets (void *id, char *buffer, int length) |
This API function, cappl or nappl, has two roles: to initialize your application by loading the memory file and to terminate it gracefully. The single argument to this function is a character string. If the argument begins with an alphanumeric character, it is the name of the application and its memory file is loaded; otherwise, the application is terminated. If you do not initialize your application, it runs without a memory file and will be quite forgetful.
The Open FunctionThe open function, copen or nopen, takes three arguments:
The close function, cclose or nclose, closes the window identified by its only argument, a POO I/O identifier, and returns 0 (zero) if successful and -2 otherwise, e.g., the I/O identifier is invalid.
The Put FunctionThe put function, cputs or nputs, takes three arguments:
In general, the descriptions of these control characters in the ANSI standard (5.2.2) are legacies from the era of teletypes and are processed by the POO software in this spirit. The phrases enclosed in quotes are from the ANSI C standard.
| \a | "produces an audible...alert." |
| \r | "moves the active position to the initial position of the current line" or deletes the previous line. |
| \b | "moves the active position to the previous position on the current line" or deletes the previous character. |
| \f | updates the window to show the text being appended at the top of the window. |
| \v | skips the automatic window update. |
| \0 | empties the VM file used to retain the output stream. |
The implementations of \b and \r are not compatible with the ANSI standard and may not be faithful in that the output stream viewable in the window may not be consistent with the file created by output direction. A mischievous application can elicit mischief. If used judiciously, the output stream and file should be consistent. Clearly, the processing of \f and \v, which are described as a form feed and a vertical tab, respectively, do not embody much of the ANSI spirit.
The Get FunctionThe get function, cgets or ngets, takes three arguments:
The noncommittal I/O model is based on macros such as those illustrated in the table. These definitions assume that the various arguments are global variables that have been defined appropriately, e.g., char buf[256]. When using C stream I/O, id has the type FILE * and is set by calling fopen; when using the POO software, it has type void * and is set by calling copen. These macros are used by simply enclosing the format and I/O list appropriately, e.g., "BFO "%i\n", n EFO".
| Macro | POO Definition | Standard C Definition |
|---|---|---|
| #define BFO | cputs(id,buf,sprintf(buf, | fprintf(id, |
| #define EFO | )); | ); |
| #define BFI | cgets(id,buf,buflen); sscanf(buf, | fgets(buf,buflen,id); sscanf(buf, |
| #define EFO | ); | ); |
The principal advantage of this model is that it vests in code only the format and I/O list and leaves the transmission issues to be resolved by the above macros, which can be easily changed. In this respect, this model could also be described as portable but is more aptly termed noncommittal.
A Fortran I/O ModelA convenient model for writing POO applications in Fortran is somewhat more elusive and must overcome a number of minor issues, e.g., formatted output does not generate new line characters because it is record oriented and knows nothing about null terminated strings. About the only feature of Fortran that can be exploited is the inherent structure of the Fortran WRITE and READ statements. Specifically, the structural similarities of WRITEs and READs with a unit and with a buffer allow the same code to be used for standard Fortran I/O and with the POO software, or any other transmission service. For example, I would normally write
Internal Links: [ Preface | TOC | Intro | Using... | Writing... | Source ]
Building an Example Application in Windows or OS/2
To build an example application, you will need this file and the appropriate POO source file. In some Windows environments, a .DEF file is required, but a .RC file is not needed. For some C compilers, you must specify the 'windowed' and the 'multithreaded' options, which vary from obvious to obscure depending on your C compiler. The Windows and OS/2 versions of the software run multithreaded unless you change the source code.
Building an Example Application in Unix/X
You will need this file and the POO source file for the X Window System. You will need an ANSI C compiler; a Kernighan and Ritchie C compiler will NOT compile the POO software. Unix/C compilers generally support the POSIX I/O library, and hopefully you installed the X development system, e.g., the include files required for compiling X applications. When you compile, you must specify the "-lX11" option because the X library is required. The X version of the POO software runs single threaded because the variable POO_MULTITHREADED is undef'd but includes multithreading support based on the POSIX standard, Pthreads. If you elect to try multithreading, you must specify the "-lpthreads" option.
PollsterPollster was designed to keep a reliable log consisting of entries provided by the user. Its progenitor automated an accurate log of my computer activity. Each entry starts with a header containing the date and time and a unique integer. The header is followed by the user's input, indented two spaces for visual separation.
The unique integer in the header is the displacement of the first character of the entry within the file and can be used to position the file in the window or to make internal references. Further, they provide a basis for assessing the integrity of the file since manual editing of the file invalidates them unless it is done very carefully.
OnlookerOnlooker was designed to provide a safe and convenient mechanism for rummaging or browsing through a file system which is the first thing I want to do whenever I fire up a new system. It's aptly named because it's not allowed to change files unless you give the secret password even though onlookers are not restricted in other POO applications.
Pseudorandom Number GeneratorsAt the beginning of the POO source code, there is a #define or #undef for POO_MULTITHREADED, which determines whether the POO software is compiled to run single or multithreaded. You want to use the multithreaded version, and the purpose of Random is to illustrate why in a safe setting.
Simply generating random integers and printing the frequencies is not much of a task for a self-respecting computer, particularly when run using a full-cycle pseudorandom number generator, but it is precisely what this example does. Since Random runs for the full cycle and time is doubling between each output line, Random starts quickly but becomes processor intensive and, depending on your processor, may take up to an hour. You can terminate (Ctrl+D or Esc) or suspend (Ctrl+S or Pause) if you can get its attention, which is what makes threads pertinent.
Windowing Systems and Threads
When running windowed applications, you may have noticed that the pointer often changes from the familiar arrow to an hourglass or clock and that, when this happens, some or all of the windows on your display may be unresponsive until the arrow is restored. The lack of response stems from the fact that one or more applications is ignoring its event queue, a feature common to windowing systems. Threads is an answer, i.e., an application can start a thread, in effect another task, to handle its event queue automatically. There are other ways of handling the event queue, but multiple threads is by far the easiest.
The POO software can be compiled to run either multithreaded or single threaded but should be run multithreaded unless your system does not support threads. When multithreaded, your application runs as one thread, and the POO software creates another thread to service the event queue so that the application remains responsive even though it may be processor intensive. Further, if you are so inclined, your application can be multithreaded if the POO software is running multithreaded, i.e., you can create additional threads. When single threaded, you are responsible for ensuring that your application calls a POO API function frequently enough to remain responsive. When single threaded, each POO API function processes all queued events, then performs its function, and then checks for events again before returning. If you run single threaded and fail to call an API function frequently enough, the underlying system may complain, perhaps bitterly, or even freeze to death.
The X version of the POO software is implemented in terms of the POSIX threads standard, so-called Pthreads. The Windows and OS/2 versions of the POO software use the thread function provided by the compiler, which are based on the thread support embedded in these systems. Thread functions are compiler dependent and very unforgiving.
#define N 4
#define BSO cputs(w,
#define ESO ,0);
#define BFO cputs(w,buf,sprintf(buf,
#define EFO ));
int appl (void)
BEGIN
void *w; int n, i; char buf[120+10*N];
long seed, chk; double bucket[N], cnt, t, pcnt;
seed = 1; for (n = 0; n < N; ++n) bucket[n] = 0.0; cnt = 0.0;
w = copen("io:Random Integers;",1,0); pcnt = 1024.0; chk = 0L;
BSO "The time between output lines is doubling and will\n" ESO
BSO "get lengthy. Hope you're patient; 2B to go!\n\n" ESO
while (1) BEGIN
++bucket[itw(&n,&seed)]; ++cnt;
if (cnt == pcnt || seed == 1)
{ t = (1000000.0/(double)CLOCKS_PER_SEC)/cnt;
BFO "\v%11.0lf %8.3lf",cnt,t*clock() EFO
for (t = 0.0, i = 0; i < N; ++i) { t += bucket[i];
BFO "\v%10.6lf",bucket[i]/cnt EFO }
BSO "\n" ESO
if (t != cnt) {
BFO "Oops, buckets only have %.0lf != %.0lf!\n",t,cnt EFO
break; }
if (seed == 1) break; pcnt += pcnt; }
else if (++chk == CHK_LIMIT) { chk = 0L; cputs(NULL,NULL,0); }
END
BSO "I quit!\n" ESO return 0;
END
Floating-Point Mapping
This example, fpMap, tests the floating-point conversion mappings provided by the C library. This is an old issue that was settled theoretically in the late sixties, and implementations of the correct mappings were in general use in the early seventies.
Polish Notation CalculatorThis example application is a Polish notation calculator and is moderately useful if you're familiar with this notation, e.g., have experience using Hewlett-Packard calculators. It supports only rudimentary calculations but can be easily enhanced.
Convergence Map for Newton's IterationThis application reads/generates a complex polynomial, reads the parameters describing a rectangular region of the complex plane, and then draws a map of this rectangle based on the convergence of Newton's iteration for the zeros of the polynomial when the points in the rectangular region are used to start the iteration. The map is drawn in a window as a printer plot, which is an ancient but honorable technique for drawing pictures with a computer.
Nonsymmetric EigenproblemThe previous example applied a numerical method of dubious virtue to a problem of your choice to illustrate the idiosyncrasies of the method. This example illustrates the converse: an impeccable method applied to nonsymmetric eigenproblems that you specify in terms of their eigenvalues and condition numbers. By varying the condition numbers, you can control the accuracy of the computed eigenvalues because the inevitable rounding errors provide the perturbations necessary to bring the condition numbers into play.
Internal Links: [ Preface | TOC | Intro | Using... | Writing... | Examples ]
.
.
.
The POO software is in one, large file for your convenience. Thus,
to use the software, you only need to copy this file and to add
one dependency to your application. A single file avoids pollution
of your application's name space because all function and variable
references are within this file. Further, if perusing the source,
all references to variables, functions, etc., can be found with a
single search. For this reason, contractions for names are used in
comments so that scans will find only code references, e.g., the
initial O_ is dropped from the names of functions.
Lines of the form "=...=" demarcate the major sections in this
file; each starts with an overview. Within these major sections,
lines of the form "-...-" demarcate the individual functions,
which start with an introduction and contain embedded commentary.
.
.
.
/*
Memory Management Macros
All memory allocations are done using the VM_... macros and are
made in pages, i.e., multiples of 4096 bytes. The ACQUIRE and
POINTER returns are treated as distinct but may be identical,
e.g., in Unix. These macros were designed to be portable among
the supported systems, and any resemblance to an actual design
is purely coincidental. They are placed here because .._HNDL is
required to define the structs in the next section.
*/
typedef size_t VM_SIZE;
typedef void * VM_HNDL;
#define VM_ACQUIRE(h,s) h = malloc(s)
#define VM_POINTER(h) (h)
#define VM_RELEASE(h) free(h)
.
.
.
/*
For all other application names, MemoryLoad is called to load the
memory file, and all windows must be opened explicitly.
*/
else
{ if (! O_MemoryLoad(oNONE)) return -1; State |= sbOTHER; }
return (int)SSN;
.
.
.
/*
The ? command is display-only: the names of the application and
window plus status information. If multithreaded, the state flags
may be wrong in rare instances; the DONE state flag is set if appl
returns, but the application may have started other threads. The
application's date/time stamp is appended.
*/
case oWHOAMI:
O_InputMgr(lw,ApplicationName,0);
if (WindABH == ApplABH) O_InputMgr(lw,"ST",-1);
if (State & sbSTOP) O_InputMgr(lw,"suspended",-1);
if (State & sbDONE) O_InputMgr(lw,"done",-1);
if (State & sbAPI) O_InputMgr(lw,"API",-1);
O_InputMgr(lw,"::",-1); O_InputMgr(lw,lw->wndname,-1);
sprintf(lw->tmp,"#%li",lw->SSN); O_InputMgr(lw,lw->tmp,-1);
if (lw->apiarg) O_InputMgr(lw,"awaiting input",-1);
if (lw->flags & bSTATIC) O_InputMgr(lw,"static",-1);
s = lw->tmp; *(s+1) = *s = ':'; *(s+2) = ' ';
O_Time(s+3,&(Work->mtime));
break;
.
.
.
/*
A NEW file, a file that doesn't exist in the file system or as a
VM file, is not acceptable when calling LoadVMF. If esize is
positive, a directory is not acceptable; likewise a binary file,
but that cannot be detected without loading the file.
*/
if (lf->flags & bNEW)
{ O_DestroyVMF(lf); *e = "doesn't exist."; return NULL; }
if (lf->flags & bDIR && esize > 0)
{ O_DestroyVMF(lf); *e = " Directory!"; return NULL; }
.
.
.
Internal Links: [ Preface | TOC | Intro | Using... | Writing... | Examples | Source ]