-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
1 changed file
with
153 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
/*****************************************************************************/ | ||
/* Copyright (C) 2011 NORMAN MEGILL nm at alum.mit.edu */ | ||
/* License terms: GNU General Public License */ | ||
/*****************************************************************************/ | ||
/*34567890123456 (79-character line to adjust editor window) 2345678901234567*/ | ||
|
||
#ifndef METAMATH_MMVSTR2_H_ | ||
#define METAMATH_MMVSTR2_H_ | ||
|
||
#include <stdio.h> | ||
|
||
/**************************************************************************//** | ||
* \file | ||
* VMS-BASIC variable length string library routines header | ||
* | ||
* Variable-length string handler | ||
* ------------------------------ | ||
* | ||
* This collection of string-handling functions emulate most of the | ||
* string functions of [VMS BASIC][1]. The objects manipulated by these | ||
* functions are strings of a special type called \ref vstring which have no | ||
* pre-defined upper length limit but are dynamically allocated and | ||
* deallocated as needed. To use the vstring functions within a program, | ||
* all vstrings must be initially set to the null string when declared or | ||
* before first used, for example: | ||
* | ||
* vstring_def(string1); | ||
* vstring stringArray[] = {"", "", ""}; | ||
* | ||
* vstring bigArray[100][10]; /- Must be initialized before using -/ | ||
* int i, j; | ||
* for (i = 0; i < 100; i++) | ||
* for (j = 0; j < 10; j++) | ||
* bigArray[i][j] = ""; /- Initialize -/ | ||
* | ||
* | ||
* After initialization, vstrings should be assigned with the `let(&` | ||
* function only; for example the statements | ||
* | ||
* let(&string1, "abc"); | ||
* let(&string1, string2); | ||
* let(&string1, left(string2, 3)); | ||
* | ||
* all assign the second argument to `string1`. The \ref let function must | ||
* _not_ be used to initialize a vstring the first time. | ||
* | ||
* Any local vstrings in a function must be deallocated before returning | ||
* from the function, otherwise there will be memory leakage and eventual | ||
* memory overflow. To deallocate, assign the vstring to "" with \ref free_vstring: | ||
* | ||
* void abc(void) { | ||
* vstring_def(xyz); | ||
* ... | ||
* free_vstring(xyz); | ||
* } | ||
* | ||
* The 'cat' function emulates the '+' concatenation operator in BASIC. | ||
* It has a variable number of arguments, and the last argument should always | ||
* be NULL. For example, | ||
* | ||
* let(&string1,cat("abc","def",NULL)); | ||
* | ||
* assigns "abcdef" to `string1`. Warning: 0 will work instead of NULL on the | ||
* VAX but not on the Macintosh, so always use NULL. | ||
* | ||
* All other functions are generally used exactly like their BASIC | ||
* equivalents. For example, the BASIC statement | ||
* | ||
* let string1$=left$("def",len(right$("xxx",2)))+"ghi"+string2$ | ||
* | ||
* is emulated in C as | ||
* | ||
* let(&string1,cat(left("def",len(right("xxx",2))),"ghi",string2,NULL)); | ||
* | ||
* Note that ANSI C does not allow "$" as part of an identifier | ||
* name, so the names in C have had the "$" suffix removed. | ||
* | ||
* The string arguments of the vstring functions may be either standard C | ||
* strings or vstrings (except that the first argument of the `let(&` function | ||
* must be a vstring). The standard C string functions may use vstrings or | ||
* vstring functions as their string arguments, as long as the vstring variable | ||
* itself (which is a char * pointer) is not modified and no attempt is made to | ||
* increase the length of a vstring. Caution must be exercised when | ||
* assigning standard C string pointers to vstrings or the results of | ||
* vstring functions, as the memory space may be deallocated when the | ||
* `let(&` function is next executed. For example, | ||
* | ||
* char *stdstr; /- A standard c string pointer -/ | ||
* ... | ||
* stdstr=left("abc",2); | ||
* | ||
* will assign "ab" to 'stdstr', but this assignment will be lost when the | ||
* next 'let(&' function is executed. To be safe, use 'strcpy': | ||
* | ||
* char stdstr1[80]; /- A fixed length standard c string -/ | ||
* ... | ||
* strcpy(stdstr1,left("abc",2)); | ||
* | ||
* Here, of course, the user must ensure that the string copied to `stdstr1` | ||
* does not exceed 79 characters in length. | ||
* | ||
* The vstring functions allocate temporary memory whenever they are called. | ||
* This temporary memory is deallocated whenever a `let(&` assignment is | ||
* made. The user should be aware of this when using vstring functions | ||
* outside of `let(&` assignments; for example | ||
* | ||
* for (i=0; i<10000; i++) | ||
* print2("%s\n",left(string1,70)); | ||
* | ||
* will allocate another 70 bytes or so of memory each pass through the loop. | ||
* If necessary, \ref freeTempAlloc can be used periodically to clear | ||
* this temporary memory: | ||
* | ||
* for (i=0; i<10000; i++) { | ||
* print2("%s\n",left(string1,70)); | ||
* freeTempAlloc(); | ||
* } | ||
* | ||
* It should be noted that the \ref linput function assigns its target string | ||
* with `let(&` and thus has the same effect as `let(&`. | ||
* | ||
* [1]: http://bitsavers.org/pdf/dec/vax/lang/basic/AA-HY16B-TE_VAX_BASIC_Reference_Manual_Feb90.pdf | ||
* | ||
*****************************************************************************/ | ||
|
||
/*! | ||
* \typedef vstring | ||
* \brief contains NUL terminated, character oriented data | ||
* | ||
* A vstring is like a C string, but it contains a control block allowing | ||
* for memory allocation. New vstrings should always be constructed from the | ||
* `vstring_def` macro. | ||
* | ||
* - A vstring is never NULL; | ||
* - If the text is empty, i.e. the pointer points to the terminating 0x00 | ||
* character, then its contents is not allocated memory and not mutable | ||
* instead; | ||
* - If not empty, i.e. the pointer points to a character different from | ||
* 0x00, then this is never a true left portion of another \a vstring. | ||
* - Although not required under all circumstances, it is highly recommended to | ||
* uniquely point to some allocated memory only. | ||
* | ||
* You can use a vstring to read the associated text, but you must never write | ||
* to memory pointed to by a vstring directly, nor may you change the pointer's | ||
* value. Declaration, definition and write access to a vstring, or the text it | ||
* points to, is exclusively done through dedicated functions. Although the | ||
* encoding of the text (or whatever data it is) requires only the existence of | ||
* exactly one 0x00 at the end, using ASCII, or at least UTF-8, is recommended | ||
* to allow various print instructions. | ||
*/ | ||
typedef char* vstring; | ||
|
||
#endif /* METAMATH_MMVSTR2_H_ */ |