strings
Warren Tucker
wht at tridom.uucp
Wed May 17 04:00:50 AEST 1989
This might be a little long, but maybe it'll help reduce
some further dialog (or provoke more :-|). I have needed
nice formal string-descriptor based strings _RARELY_ and
this is a sort of tool box I pick stuff out of. Hope it
helps.
#!/bin/sh
# shar: Shell Archiver (v1.22)
#
# Run the following text with /bin/sh to create:
# esd2.h
# esd2util.c
#
sed 's/^X//' << 'SHAR_EOF' > esd2.h &&
X/* CHK=0x1793 */
X/*+-----------------------------------------------------------------------
X esd2.h -- support header for users of esd2util.c
X ...!gatech!emory!tridom!wht
X------------------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:10-31-1988-16:37-wht-esd2 adapted from esd.h/esdutil.c */
X
Xtypedef struct esd
X{
X char *pb; /* full pointer to esd strings */
X short cb; /* count of bytes */
X short maxcb; /* maximum bytes allowed */
X short index; /* next character of significance */
X short old_index; /* last token (backup or error reporting) */
X} ESD;
X
Xtypedef struct keyword_table_type /* table terminated with null key_word */
X{
X char *key_word; /* key word */
X int key_token; /* token returned on match */
X} KEYTAB;
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
chmod 0644 esd2.h || echo "restore of esd2.h fails"
sed 's/^X//' << 'SHAR_EOF' > esd2util.c &&
X/* CHK=0x2302 */
X/*+----------------------------------------------------------------
X esd2util.c
X ...!gatech!emory!tridom!wht
X
X Defined functions:
X append_zstr_to_esd(tesd,zstr)
X esdstrindex(esd1,esd2,index1_flag,index2_flag)
X fgetesd(tesd,fileptr)
X fputesd(tesd,fileptr,index_flag,nl_flag)
X free_esd(tesd)
X get_alpha_zstr(param,strbuf,strbuf_maxcb)
X get_alphanum_zstr(param,strbuf,strbuf_maxcb)
X get_numeric_value(param,value)
X get_numeric_zstr(param,strbuf,strbuf_maxcb)
X get_word_zstr(param,strbuf,strbuf_maxcb)
X init_esd(tesd,cptr,maxcb)
X keyword_lookup(ktable,param)
X make_esd(maxcb)
X null_terminate_esd(tesd)
X skip_cmd_break(tesd)
X skip_cmd_char(param,skipchar)
X skip_comma(param)
X skip_ld_break(zstr)
X skip_paren(param,fLeft)
X strindex(str1,str2)
X strip_trailing_spaces_esd(ztext)
X
X-----------------------------------------------------------------*/
X/*+:EDITS:*/
X/*:10-31-1988-16:37-wht-esd2 adapted from esd.h/esdutil.c */
X/*:04-18-1988-18:19-wht-more routines */
X/*:01-28-1987-12:30-wht-add get_word_zstr */
X/*:01-28-1987-12:00-wht-include MSC 4.0 / MSDOS compatibility */
X/*:01-16-1986-01:00-WHT-Creation of edits (version beta 1.01) */
X
X#include <stdio.h>
X#include <ctype.h>
X#include "esd2.h"
X
X#if XENIX | MSDOS
X#include <string.h>
X#else
Xextern char *index();
X#endif
X
X/*+-------------------------------------------------------------------------
X void null_terminate_esd(&esd)
X puts null at 'cb' position of string (standard esd always
X has one more byte in buffer than maxcb says)
X--------------------------------------------------------------------------*/
Xvoid
Xnull_terminate_esd(tesd)
Xregister ESD *tesd;
X{
X tesd->pb[tesd->cb] = 0;
X} /* end of null_terminate_esd */
X
X/*+-----------------------------------------------------------------------
X void init_esd(tesd,cptr,maxcb) init an esd
X------------------------------------------------------------------------*/
Xvoid init_esd(tesd,cptr,maxcb)
Xregister ESD *tesd;
Xchar *cptr;
Xregister int maxcb;
X{
X tesd->pb = cptr; /* pointer to string */
X tesd->maxcb = maxcb; /* max characters in buffer */
X tesd->cb = 0; /* current count == 0 */
X tesd->index = 0; /* parse index to first position */
X tesd->old_index = 0; /* parse index to first position */
X *tesd->pb = 0; /* start with null terminated string */
X
X} /* end of init_esd */
X
X/*+-----------------------------------------------------------------------
X esdptr = make_esd(maxcb) allocate an esd and buffer
X------------------------------------------------------------------------*/
XESD *
Xmake_esd(maxcb)
Xregister int maxcb; /* desired maxcb */
X{
X register ESD *tesd;
X register int actual_cb;
X
X /* we get an extra character to ensure room for null past maxcb */
X actual_cb = maxcb + sizeof(ESD) + 1;
X if(actual_cb & 1) /* even allocation */
X ++actual_cb;
X if((tesd = (ESD *)malloc( (unsigned)actual_cb )) == NULL)
X return((ESD *)0); /* return NULL if failure */
X
X init_esd(tesd,(char *)(tesd + 1),maxcb);
X return(tesd);
X
X} /* end of make_esd */
X
X/*+-----------------------------------------------------------------------
X free_esd(esdptr)
X------------------------------------------------------------------------*/
Xvoid free_esd(tesd)
Xregister ESD *tesd;
X{
X tesd->maxcb = 0;
X tesd->cb = 0;
X free((char *)tesd);
X}
X
X/*+----------------------------------------------------------------
X strindex: string index function
X
X Returns position of 'str2' in 'str1' if found
X If 'str2' is null, then 0 is returned (null matches anything)
X Returns -1 if not found
X-----------------------------------------------------------------*/
Xint
Xstrindex(str1,str2)
Xchar *str1; /* the (target) string to search */
Xchar *str2; /* the (comparand) string to search for */
X{
X register int istr1 = 0;
X register int lstr2 = strlen(str2);
X register char *mstr = str1; /* the (target) string to search */
X
X if(*str2 == 0) /* null string matches anything */
X return(0);
X
X while(*mstr)
X {
X if(*mstr == *str2)
X { /* we have a first char match... does rest of string match? */
X if(!strncmp(mstr,str2,lstr2))
X return(istr1); /* if so, return match position */
X }
X mstr++;
X istr1++;
X }
X
X return(-1); /* if we exhaust target string, flunk */
X
X} /* end of strindex */
X
X/*+-------------------------------------------------------------------------
X esdstrindex(esd1,esd2,index1_flag,index2_flag)
X
X Call strindex with esd1->pb and esd2->pb.
X If index1_flag != 0, esd1->pb + esd1->index passed
X If index2_flag != 0, esd2->pb + esd2->index passed
X--------------------------------------------------------------------------*/
Xesdstrindex(esd1,esd2,index1_flag,index2_flag)
Xregister ESD *esd1;
Xregister ESD *esd2;
Xregister int index1_flag;
Xregister int index2_flag;
X{
X return(strindex((index1_flag) ? esd1->pb : esd1->pb + esd1->index,
X (index2_flag) ? esd2->pb : esd2->pb + esd2->index));
X
X} /* end of esdstrindex */
X
X/*+----------------------------------------------------------------
X keyword_lookup(ktable,param)
X
X Lookup string in keyword_table struct array
X Returns table->key_token if 'param' found in
X 'table', else -1
X
X Beware substrings. "type","typedef" will both match "type"
X Ordering of table can help this.
X-----------------------------------------------------------------*/
Xkeyword_lookup(ktable,param)
Xregister KEYTAB *ktable;
Xregister char *param;
X{
X register int plen = strlen(param);
X
X while(ktable->key_word)
X {
X if(!strncmp(ktable->key_word,param,plen))
X return(ktable->key_token);
X ++ktable;
X } /* end of while */
X
X return(-1); /* search failed */
X
X} /* end of keyword_lookup */
X
X/*+----------------------------------------------------------------
X skip_cmd_break(tesd)
X
X Finds next non-break or end of command line text
X 'tesd' is an esd with valid 'index' field
X Returns 0 index field points to non-break character
X -1 end of line found
X-----------------------------------------------------------------*/
Xint
Xskip_cmd_break(tesd)
Xregister ESD *tesd;
X{
X register int cb = tesd->cb;
X register int index = tesd->index;
X register char *pb = tesd->pb + index;
X
X while(index < cb)
X {
X if(*pb++ != 0x20)
X break;
X index++;
X }
X tesd->old_index = tesd->index = index;
X if(index >= cb)
X return(-1);
X else
X return(0);
X
X} /* end of skip_cmd_break */
X
X/*+-------------------------------------------------------------------------
X erc = skip_cmd_char(param,skipchar)
X--------------------------------------------------------------------------*/
Xint
Xskip_cmd_char(param,skipchar)
Xregister ESD *param;
Xregister char skipchar;
X{
X register int erc;
X
X if(erc = skip_cmd_break(param))
X return(erc);
X
X if(param->pb[param->index] == skipchar)
X {
X ++param->index;
X return(0);
X }
X
X return(-1);
X
X} /* end of skip_cmd_char */
X
X/*+-------------------------------------------------------------------------
X erc = skip_comma(param)
X--------------------------------------------------------------------------*/
Xint
Xskip_comma(param)
Xregister ESD *param;
X{
X register int erc;
X
X if(erc = skip_cmd_break(param))
X return(erc);
X
X if(param->pb[param->index] == ',')
X {
X ++param->index;
X return(0);
X }
X
X return(-1);
X
X} /* end of skip_comma */
X
X/*+-------------------------------------------------------------------------
X erc = skip_paren(fparam,LEFT or RIGHT)
X--------------------------------------------------------------------------*/
Xint
Xskip_paren(param,fLeft)
Xregister ESD *param;
Xint fLeft; /* if =LEFT , skip left paren, else skip right */
X{
X register int erc;
X
X if(erc = skip_cmd_break(param))
X return(erc);
X
X if(fLeft)
X {
X if(param->pb[param->index++] == 0x28) /* 0x28 == open parenthesis */
X return(0);
X else
X {
X --param->index;
X return(-1);
X }
X }
X else
X {
X if(param->pb[param->index++] == 0x29) /* 0x29 == close parenthesis */
X return(0);
X else
X {
X --param->index;
X return(-1);
X }
X }
X
X} /* end of skip_paren */
X
X/*+----------------------------------------------------------------
X get_alpha_zstr(&esd,&strbuf,strbuf_maxcb)
X converts next alphabetic string token to upper case and places it
X into the null-terminated 'strbuf' string. returns 0 or -1
X or skip_cmd_break error codes
X-----------------------------------------------------------------*/
Xint
Xget_alpha_zstr(param,strbuf,strbuf_maxcb)
Xregister ESD *param;
Xregister char *strbuf;
Xregister int strbuf_maxcb;
X{
X register int izstr;
X register int schar;
X register char *param_ptr = param->pb;
X
X if(izstr = skip_cmd_break(param))
X return(izstr);
X izstr = 0;
X while( (izstr < strbuf_maxcb-1) && (param->index < param->cb) )
X {
X schar = param_ptr[param->index];
X if( !isalpha(schar) )
X break;
X param->index++;
X strbuf[izstr++] = to_upper(schar);
X }
X
X strbuf[izstr] = 0; /* terminate the string for "C" anal retentives */
X if(izstr)
X return(0);
X else /* decide whether to return badparam or noparam err */
X return(-1);
X
X} /* end of get_alpha_zstr */
X
X/*+----------------------------------------------------------------
X get_alphanum_zstr(&esd,&strbuf,strbuf_maxcb)
X converts next alphabetic string token to upper case and places it
X into the null-terminated 'strbuf' string. returns 0 or -1
X or skip_cmd_break error codes
X-----------------------------------------------------------------*/
Xint
Xget_alphanum_zstr(param,strbuf,strbuf_maxcb)
Xregister ESD *param;
Xregister char *strbuf;
Xregister int strbuf_maxcb;
X{
X register int izstr = 0;
X register int schar;
X
X if(izstr = skip_cmd_break(param))
X return(izstr);
X
X while( (izstr < strbuf_maxcb-1) && (param->index < param->cb) )
X {
X schar = param->pb[param->index++];
X if( isalnum(schar) )
X strbuf[izstr++]=to_upper(schar);
X else
X {
X --param->index;
X break;
X }
X }
X
X strbuf[izstr]=0; /* terminate the string for "C" anal retentives */
X if(strlen(strbuf))
X return(0);
X else /* decide whether to return badparam or noparam err */
X return(-1);
X
X} /* end of get_alphanum_zstr */
X
X/*+----------------------------------------------------------------
X get_numeric_zstr(&esd,&strbuf,strbuf_maxcb)
X gets next numeric string token places it
X into the null-terminated 'strbuf' string. returns 0 or -1
X or skip_cmd_break error codes
X-----------------------------------------------------------------*/
Xint
Xget_numeric_zstr(param,strbuf,strbuf_maxcb)
Xregister ESD *param;
Xregister char *strbuf;
Xregister int strbuf_maxcb;
X{
X register int izstr;
X register int schar;
X
X if(izstr = skip_cmd_break(param))
X return(izstr);
X
X while( (izstr < strbuf_maxcb-1) && (param->index < param->cb) )
X {
X schar = param->pb[param->index++];
X if( isdigit(schar) )
X strbuf[izstr++]=schar;
X else
X {
X --param->index;
X break;
X }
X }
X
X strbuf[izstr]=0; /* terminate the string for "C" anal retentives */
X
X if(strlen(strbuf))
X return(0);
X else /* decide whether to return badparam or noparam err */
X {
X return(skip_cmd_break(param));
X }
X
X} /* end of get_numeric_zstr */
X
X/*+----------------------------------------------------------------
X get_word_zstr(&esd,&strbuf,strbuf_maxcb)
X gets next word (continuous string of characters
X without spacesor tabs )
X returns 0 or -1 or skip_cmd_break error codes
X-----------------------------------------------------------------*/
Xint
Xget_word_zstr(param,strbuf,strbuf_maxcb)
Xregister ESD *param;
Xregister char *strbuf;
Xregister int strbuf_maxcb;
X{
X register int izstr;
X register int schar;
X
X if(izstr = skip_cmd_break(param))
X return(izstr);
X
X while( (izstr < strbuf_maxcb-1) && (param->index < param->cb) )
X {
X schar = param->pb[param->index++];
X if( (schar > 0x20) && (schar <= 0x7e))
X strbuf[izstr++]=schar;
X else
X {
X --param->index;
X break;
X }
X }
X
X strbuf[izstr]=0; /* terminate the string for "C" anal retentives */
X
X if(strlen(strbuf))
X return(0);
X else /* decide whether to return badparam or noparam err */
X {
X return(skip_cmd_break(param));
X }
X
X} /* end of get_word_zstr */
X
X/*+-----------------------------------------------------------------------
X get_numeric_value(param,&long_var)
X------------------------------------------------------------------------*/
Xget_numeric_value(param,value)
Xregister ESD *param;
Xregister long *value;
X{
X register int erc;
X char buf[32];
X
X if(erc = get_numeric_zstr(param,buf,sizeof(buf)))
X return(erc);
X sscanf(buf,"%ld",value);
X return(0);
X
X} /* end of get_numeric_value */
X
X/*+-------------------------------------------------------------------------
X strip_trailing_spaces_esd(tesd)
X--------------------------------------------------------------------------*/
Xvoid
Xstrip_trailing_spaces_esd(ztext)
Xregister ESD *ztext;
X{
X while(ztext->cb && (ztext->pb[ztext->cb-1] == 0x20))
X ztext->cb--;
X} /* end of strip_trailing_spaces_esd */
X
X/*+-------------------------------------------------------------------------
X fgetesd(&esd,fileptr)
X
X stdio read from FILE *fileptr into esd
X returns -1 on stdio error, -2 on line too long, 0 on success
X returns tesd->cb set up not including trailing nl, tesd->index == 0
X--------------------------------------------------------------------------*/
Xint fgetesd(tesd,fileptr)
Xregister ESD *tesd;
Xregister FILE *fileptr;
X{
X register char *cptr;
X
X if(fgets(tesd->pb,tesd->maxcb,fileptr) == NULL)
X return(-1);
X#if XENIX | MSDOS
X if((cptr = strchr(tesd->pb,0x0A)) == NULL)
X return(-2);
X#else
X if((cptr = index(tesd->pb,0x0A)) == NULL)
X return(-2);
X#endif
X tesd->cb = (int)(cptr - tesd->pb);
X null_terminate_esd(tesd);
X tesd->index = 0;
X tesd->old_index = 0;
X return(0);
X
X} /* end of fgetesd */
X
X/*+-------------------------------------------------------------------------
X fputesd(&esd,fileptr,index_flag,nl_flag)
X
X write esd contents to stdio FILE *fileptr
X if index_flag is true, write from tesd->index thru end of esd
X otherwise, from start of esd
X if nl_flag is true, append nl to write, else just esd contents
X returns -1 on stdio error, 0 on success
X--------------------------------------------------------------------------*/
Xint fputesd(tesd,fileptr,index_flag,nl_flag)
Xregister ESD *tesd;
Xregister FILE *fileptr;
Xint index_flag;
Xint nl_flag;
X{
X register char *cptr;
X register int write_length;
X
X if(index_flag)
X {
X cptr = &tesd->pb[tesd->index];
X write_length = tesd->cb - tesd->index;
X }
X else
X {
X cptr = tesd->pb;
X write_length = tesd->cb;
X }
X
X if(write_length)
X if(fwrite(cptr,write_length,1,fileptr) == 0)
X return(-1);
X
X if(nl_flag)
X if(fputc(0x0A,fileptr) == 0)
X return(-1);
X
X return(0);
X} /* end of fputesd */
X
X/*+-------------------------------------------------------------------------
X cptr = skip_ld_break(cptr)
X Skip leading spaces and tabs
X--------------------------------------------------------------------------*/
Xchar *skip_ld_break(zstr)
Xregister char *zstr;
X{
X while((*zstr == 0x20) || (*zstr == 0x09))
X zstr++;
X return(zstr);
X} /* end of skip_ld_break */
X
X/*+-----------------------------------------------------------------
X append_zstr_to_esd
X------------------------------------------------------------------*/
Xappend_zstr_to_esd(tesd,zstr)
XESD *tesd;
Xchar *zstr;
X{
X register int zstrlen = strlen(zstr);
X
X if(zstrlen > (tesd->maxcb - tesd->cb))
X zstrlen = tesd->maxcb - tesd->cb;
X
X if(zstrlen)
X {
X strncpy(tesd->pb + tesd->cb,zstr,zstrlen);
X tesd->cb += zstrlen;
X }
X}
X/* end of esd2util.c */
X
X/* vi: set tabstop=4 shiftwidth=4: */
SHAR_EOF
chmod 0644 esd2util.c || echo "restore of esd2util.c fails"
exit 0
--
-------------------------------------------------------------------
Warren Tucker, Tridom Corporation ...!gatech!emory!tridom!wht
Sforzando (It., sfohr-tsahn'-doh). A direction to perform the tone
or chord with special stress, or marked and sudden emphasis.
More information about the Comp.lang.c
mailing list