IJAH400@INDYVAX.BITNET (06/22/88)
<Lost the name of the original sender...> A while back someone posted a note, looking for another C compiler for the VAX, because "strings and string descriptors" were "so hard to deal with in VAX C". We have had to do most of our systems programming work in VAX C here at IUPUI (can't afford Bliss-32 for three people), and use varying- length strings a lot with the library and utility routines. A few handy macros makes life a lot easier, even though the result is not real elegant. Be aware that there are still a few bugs involving varying length strings lurking around in some of the library and utility routines (for example, the dst-str argument to LIB$SYS_FAO and most of the string arguments to the Librarian routines (these are being SPRed as I find them) are not handled correctly when passed a pointer to a varying-length string descriptor). Here is a sample VAXC program that demonstrates the use of a nifty little macro, VSTRING, that is handy for allocating varying-length strings in C. "name" is used as the name of the actual structure allocated, which includes both the string data and a descriptor for it. "name_vs" is the type name used for the structure definition. The descriptor is initialized with the maximum length and address of the string part, and the proper type and class for a varying-length string. The current length field and the string itself is initialized with the C string constant you provide. After you allocate it (note that it can be either static or automatic), you can play with the string all you want, and if automatic the descriptor and string are deallocated when the routine returns (the advantage over using dynamic strings). <<<<<------------------- VSTRING_DEMO.C, cut here ------------------------>>>>> #module DEMO /* ** This little program demonstrates the use of the VSTRING macro. */ #include descrip /* For string descriptor definitions */ #define IDENT(arg) arg /* Handy macro expands to it's argument */ #define VSTRING(name,maxlen,init) \ struct IDENT(name)_vs { \ struct dsc$descriptor_s dx; \ unsigned short int curlen; \ char body[maxlen]; \ } name = { { maxlen, DSC$K_DTYPE_VT, DSC$K_CLASS_VS, &name.curlen }, \ sizeof(init)-1, init } /* Example of use of VSTRING macro: */ #define SUCCESS(arg) ((arg) & 1) #define FAILURE(arg) (~(arg) & 1) #include jpidef main () { int status; $DESCRIPTOR(isnt_dx,"Your username probably isn't \""); $DESCRIPTOR(is_dx,"Your username is \""); $DESCRIPTOR(quote_dx,"\""); VSTRING(user,12,"Fred Berfel"); VSTRING(line,256,""); STR$CONCAT(&line.dx,&isnt_dx,&user.dx,"e_dx); LIB$PUT_OUTPUT(&line.dx); if FAILURE(status = LIB$GETJPI(&JPI$_USERNAME,0,0,0,&user.dx,0)) return status; STR$TRIM(&user.dx,&user.dx,0); STR$CONCAT(&line.dx,&is_dx,&user.dx,"e_dx); LIB$PUT_OUTPUT(&line.dx); } <<<<<------------------- VSTRING_DEMO.C, cut here ------------------------>>>>> Note that this stuff is very VAXC dependent and is really only of interest to people doing a lot of library and utility calls in VAXC. In general I have found that in a particular program it is either best to stick entirely with the standard C runtimes and macros for I/O and string functions, or entirely with the VMS system calls/library/utility stuff. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- James A. Harvey, DEC Systems Group, IUPUI Computing Services BITNET: IJAH400@INDYVAX Internet: IJAH400%IVAX.DECNET@GOLD.BACS.INDIANA.EDU USnail: E&T 1023, 799 W. Michigan St., Indianapolis, IN 46202 AT&T: (317) 274-0747 Disclaimer: "These views are certainly not those of my employer; we have never agreed about anything!" Suggestion: "Everyone thinks oo-ee-pooh-ee is some kind of a service bureau. How about 'Michigan Street University?'" +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-