diff options
Diffstat (limited to 'sdk/other')
39 files changed, 2252 insertions, 0 deletions
diff --git a/sdk/other/Makefile.in b/sdk/other/Makefile.in new file mode 100644 index 0000000..17dd18a --- /dev/null +++ b/sdk/other/Makefile.in @@ -0,0 +1,22 @@ +# +# Template to build our "other" object modules(libother.a) +# $Id: Makefile.in 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ +# Copyright (c) 1997 by Tycho Softworks. +# + +OBJS = memalloc.o memdup.o memfree.o mempool.o memrelease.o \ + memreq.o config.o confdir.o bcd.o env.o atob.o strint.o \ + expand.o picture.o xval.o hex.o strcopy.o strdiff.o \ + strblank.o strpos.o strreq.o strtrim.o ccount.o filename.o \ + isftype.o getargv.o search.o token.o fatal.o fncat.o + +.c.o: + $(CC) $(CFLAGS) $(OPTIMIZE) -I.. -o $@ -c $< + $(AR) r ../lib/libother.a $@ + +all: $(OBJS) + ranlib ../lib/libother.a + +clean: + rm *.o + diff --git a/sdk/other/atob.c b/sdk/other/atob.c new file mode 100644 index 0000000..1535f7a --- /dev/null +++ b/sdk/other/atob.c @@ -0,0 +1,47 @@ +/* + * Convert ASCII text into binary value. + * $Id: atob.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use, see product license. + * + * Functions: + * atob() - convert null terminated ASCII string to boolean value. + */ + +#include <other/strcvt.h> + +/* + * Convert null terminated ASCII string to boolean value. + * + * Abstract: + * The input string can be numeric; such as "0" or "1", or alpha; + * such as "T" for true, "F" for false, or "Y" or "N". Only the + * first character of the string is examined. Upper/lower case is + * ignored. + * + * Parameters: + * str - null terminated ASCII string. + * + * Returns: + * logical value of input string. + * + * Exceptions: + * Any unrecognized string value, or a NULL string, return FALSE. + */ + +bool atob(const char *str) +{ + if(!str) + return FALSE; + + switch(*str) + { + case '0': + case 'f': + case 'F': + case 'n': + case 'N': + return FALSE; + } + return TRUE; +} diff --git a/sdk/other/bcd.c b/sdk/other/bcd.c new file mode 100644 index 0000000..3bd6144 --- /dev/null +++ b/sdk/other/bcd.c @@ -0,0 +1,125 @@ +/* + * Convert ASCII numbers to or from BCD representations. + * $Id: bcd.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For condititions of distribution and use, see product license. + * + * Abstract: + * BCD is a format for storing packed decimal data within a nibble. + * We assume "big endian" BCD, in that the high nibble contains the + * first digit within a byte. Any unused digits are filled with the + * nibble value of $F. This module provides the services needed to + * convert BCD data to and from ASCII strings. + * + * Functions: + * str2bcd() - convert ASCII string to packed bcd. + * bcd2str() - convert packed bcd to ASCII string. + */ + +#include <other/strcvt.h> + +/* + * Convert null terminated ASCII string to packed bcd data. + * + * Abstract: + * An ASCII input string is converted to binary packed decimal + * data. Any unused digits are filled with $f. The size specified + * for digits is filled, either with available digits from the input + * string, or with $f nibbles once no more digits are available. + * + * Paramaters: + * bcd - pointer to start of bcd data to store. + * str - null terminated input string. + * max - maximum number of digits in bcd data. + * + * Returns: + * pointer to first non-BCD digit in input string. + * + * Exceptions: + * If NULL input string, returns NULL. If more digits exist in + * the input string than are available in bcd storage (data + * overflow), the remaining digits are ignored. + */ + +char *str2bcd(uchar *bcd, char *str, int max) +{ + uchar packed = 0xff; + bool low = FALSE; + + if(!str) + return NULL; + + while(isdigit(*str)) + { + packed = packed / 16; + packed |= ((*(str++) - '0') * 16); + if(low) + { + *(bcd++) = packed; + packed = 0xff; + if(!--max) + return str; + + low = FALSE; + } + else + low = TRUE; + } + if(low) + { + *(bcd++) = packed; + --max; + } + while(max--) + *(bcd++) = 0xff; + + return str; +} + +/* + * Convert binary coded data to ASCII text. + * + * Abstract: + * A block of bcd data of up to a specified length is read, each + * digit being converted to an ASCII character code. If a $f is + * found before 'len' digits are examined, then the program + * completes with a shorter number. + * + * Paramaters: + * str - start of output string to receive converted data. + * bcd - bcd data input. + * len - maximum number of bcd digits. + * + * Return: + * pointer to next available bcd number in memory (or past end of + * bcd data block). The output string (str) is also given a null + * terminating byte. + * + * Exceptions: + * A NULL bcd pointer returns a NULL string. + */ + +uchar *bcd2str(char *str, uchar *bcd, int len) +{ + uchar nib1, nib2; + if(!bcd) + return NULL; + + while(len--) + { + nib1 = *bcd / 16; + nib2 = *bcd % 16; + if(nib1 < 16) + *(str++) = nib1 + '0'; + else + break; + if(nib2 < 16) + *(str++) = nib2 + '0'; + else + break; + ++bcd; + } + *str = 0; + return bcd; +} + diff --git a/sdk/other/bind.conf b/sdk/other/bind.conf new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/sdk/other/bind.conf @@ -0,0 +1 @@ + diff --git a/sdk/other/ccount.c b/sdk/other/ccount.c new file mode 100644 index 0000000..ec53a98 --- /dev/null +++ b/sdk/other/ccount.c @@ -0,0 +1,45 @@ +/* + * Count character occurances in string. + * $Id: ccount.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see product license. + * + * Functions: + * ccount() - count characters in string. + */ + +#include <other/string.h> + +/* + * Count character occurances in ASCII string. + * + * Abstract: + * A list of possible characters to look for is passed to ccount, + * along with the null terminated ASCII string to look for those + * characters within. + * + * Parameters: + * str - string to examine and count occurances in. + * list - list (null terminated) of characters to search for. + * + * Exceptions: + * Either a NULL list or string is considered to hold no found + * characters (returns 0). + */ + +int ccount(const char *str, const char *list) +{ + int count = 0; + + if(!str || !list) + return 0; + + while(NULL != (str = strpbrk(str, list))) + { + ++count; + ++str; + } + return count; +} + + diff --git a/sdk/other/confdir.c b/sdk/other/confdir.c new file mode 100644 index 0000000..cabc475 --- /dev/null +++ b/sdk/other/confdir.c @@ -0,0 +1,105 @@ +/* + * Routines to access directory of section names in a config file. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see product license. + * + * Abstract: + * These routines may be used to scan the 'directory' of [] section + * names within a config file, much like the MS-DOS find_first() and + * find_next() directory routines. + * + * Functions: + * this_config() - internal routine to return section name. + * first_config() - goto first named [] section within the config file. + * next_config() - skip to the next named [] section. + */ + +#include <other/config.h> +#include <other/string.h> +#include <other/env.h> + +#ifndef LBUF +#define LBUF 1024 +#endif + +/* + * Internal program to support parsing of found section name. + */ + +static char *this_config(CONFIG *cfg) +{ + char *p; + + if(feof(cfg->cfg_fp)) + return NULL; + + if(cfg->cfg_lbuf[0] != '[') + return NULL; + + cfg->cfg_flag = TRUE; + p = strtok(cfg->cfg_lbuf, "[]\n\r"); + return p; +} + +/* + * Automatically seek the very first [] section within a config file. + * + * Paramaters: + * cfg - config object pointer. + * + * Returns: + * Name string of first [] name in config file. + * + * Exceptions: + * If no [] section in config file, NULL cfg pointer, or file + * error, returns NULL. + */ + +char *first_config(CONFIG *cfg) +{ + if(!cfg) + return NULL; + + fseek(cfg->cfg_fp, 0l, SEEK_SET); + return next_config(cfg); +} + +/* + * Skip to the next named [] section within a config file. + * + * Paramaters: + * cfg - config object pointer. + * + * Returns: + * Name string of next named [] section in config file. + * + * Exceptions: + * Returns NULL if cfg invalid or end of file reached. + * + */ + +char *next_config(CONFIG *cfg) +{ + if(!cfg) + return NULL; + + if(feof(cfg->cfg_fp)) + return NULL; + + for(;;) + { + fgets(cfg->cfg_lbuf, LBUF - 1, cfg->cfg_fp); + if(feof(cfg->cfg_fp)) + return NULL; + + if(cfg->cfg_lbuf[0] == '[') + return this_config(cfg); + } +} + + + + + + diff --git a/sdk/other/config.c b/sdk/other/config.c new file mode 100644 index 0000000..e274b85 --- /dev/null +++ b/sdk/other/config.c @@ -0,0 +1,437 @@ +/* + * Routines to access and parse standard text config files. + * $Id: config.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see product license. + * + * Abstract: + * These routines are used to open and parse human readable '.conf' + * files, such as those which may be stored in the /etc directory. + * The .conf file is parsed as a sectioned text file, with the name + * for each logical section appearing in []'s. Entries within each + * section are typically in the format 'keyword = value', though + * there are exceptions for multi-line fixed size lists, in + * the form 'keyword = { list }', and repeated lines. Comments may + * also appear within .conf files. + * + * Functions: + * sys_config() - find and open a /etc or /etc/prior .conf file. + * open_config() - open any text file as a config file. + * read_config() - read a keyword = value pair from current section. + * seek_config() - seek a named [] section within the config file. + * get_config() - tests current input for a specified keyword. + * usr_config() - user specific resource config file. + */ + +#include <other/config.h> +#include <other/strcvt.h> +#include <other/string.h> +#include <other/env.h> +#include <std/process.h> + +/* + * When searching for 'system' .conf files, which are normally held in + * /etc, also search in /etc/prior. This is used so that a human + * readable .conf file can momentarily be moved into '/etc/prior' and + * still be usable while a GUI system management program is in the middle + * building a new .conf file. + */ + +#ifndef CFGPATH +#define CFGPATH "/etc:/etc/prior" +#endif + +/* + * Maximum working space for single or multi-line input records being + * parsed. + */ + +#ifndef LBUF +#define LBUF 1024 +#endif + +#ifndef SUFFIX +#define SUFFIX ".conf" +#endif + +/* + * Open a system .conf file, as found in the system config directories. + * + * Abstract: + * This function finds a .conf file in either the /etc or /etc/prior + * directory. /etc/prior is searched if the current .conf file is + * not found (in /etc), as may happen if it is in the middle of + * being re-built by a management application. This provides an + * initial function which may be used to open most .conf files. + * + * Paramaters: + * cfg_name - 'base' filename of system .conf file to open. + * + * Returns: + * pointer to active CONFIG object for specified filename. + * + * Exceptions: + * If the file is not found, a NULL pointer is returned. + */ + +CONFIG *sys_config(const char *cfg_name) +{ + char cfgname[PATH_MAX + 1]; + + strcpy(cfgname, cfg_name); + strcat(cfgname, SUFFIX); + return open_config(search(CFGPATH, cfgname)); +} + +/* + * Open any specified filename as a .conf file. + * + * Abstract: + * This function opens the specified file as a 'config' file for use + * in config file parsing routines. Any filename may be specified + * and opened as a config file with this routine. + * + * Paramaters: + * config_name - full pathname of a .conf file to open. + * + * Returns: + * pointer to a newly allocated CONFIG parsing object for the + * specified filename. + * + * Exceptions: + * If the file is not found, a NULL pointer is returned. + */ + + +CONFIG *open_config(const char *config_name) +{ + CONFIG *new; + char *env; + + if(NULL == (new = (CONFIG *)malloc(sizeof(CONFIG) + LBUF))) + return NULL; + + if(NULL == (new->cfg_fp = fopen(config_name, "r"))) + { + free(new); + return NULL; + } + new->cfg_flag = FALSE; + return new; +} + +/* + * Close an open config file and destroy the CONFIG parser object. + */ + +void close_config(CONFIG *cfg) +{ + if(!cfg) + return; + + fclose(cfg->cfg_fp); + free(cfg); +} + +/* Read a line of ASCII text input from an open config file. + * + * Abstract: + * This routine extracts a line of input from an open config file. + * The input line extracted and returned is a "keyword = value" line + * found within the current [] section. If the end of the current + * [] section has been reached, then no further input is returned. + * + * Lines which contain comments are automatically skipped. Comments + * include those lines which begin with a '#' or ';' character. + * Empty lines are also automatically skipped. + * + * Special {} subsections may also be used to specify language + * variant .conf values. When these subsection identifiers are found + * and the current language found in the ENV (LANG=) does not match + * the language for the specified {} section, the entire {} section + * is skipped. + * + * The input line retreived automatically has lead and trailing + * whitespaces removed. + * + * Paramaters: + * cfg - a 'config' parser object. + * + * Returns: + * ASCII text for 'keyword = value' item from config file. + * + * Exceptions: + * A NULL is returned when the current [] section has been completed, + * when at the end of the file, or if any error occurs while reading. + */ + +char *read_config(CONFIG *cfg) +{ + char *p, *q; + int skip = 0; + + if(!cfg) + return NULL; + + if(!cfg->cfg_flag) + return NULL; + + for(;;) + { + fgets(cfg->cfg_lbuf, LBUF - 1, cfg->cfg_fp); + if(feof(cfg->cfg_fp) || cfg->cfg_lbuf[0] == '[' || ferror(cfg->cfg_fp)) + { + cfg->cfg_flag = FALSE; + return NULL; + } + p = strtrim(cfg->cfg_lbuf, __SPACES); + + if(*p == '{') + { + skip = 1; + p = strtok(p, "{}| \t"); + while(p) + { + if(!stricmp(p, "all")) + skip = 0; + if(!stricmp(p, language())) + skip = 0; + p = strtok(NULL, "{}| \t"); + } + continue; + } + + if(!*p || *p == '!' || *p == '#' || *p == ';' || skip) + continue; + + return p; + } +} + +/* + * Seek a named [] section within the .conf file to begin input. + * + * Abstract: + * The named section is found within the .conf file. Once + * found, all read_config() input will be returned from the + * specified [] section. Section names are case insensitive. + * + * Paramaters: + * cfg - config object pointer. + * seek_name - name of config [] section to find. + * + * Returns: + * TRUE if the section name is found in the .conf file , FALSE if + * not. + * + * Exceptions: + * If a NULL cfg or seek_name is passed, the search always fails. + * If a file error is found, the search always fails. The maximum + * size of a [] section name that is tested is 22 characters. + */ + +bool seek_config(CONFIG *cfg, const char *seek_name) +{ + char group[25]; + int len; + + if(!cfg || !seek_name) + return FALSE; + + cfg->cfg_flag = FALSE; /* mark as outside old [] section */ + + len = strlen(seek_name); + if (len > 22) + len = 22; + + memset(group, 0, sizeof(group)); + + if(*seek_name != '[') + strcpy(group, "["); + + strncat(group, seek_name, len); + + if(*seek_name != '[' && strlen(seek_name) < 23) + strcat(group, "]"); + + fseek(cfg->cfg_fp, 0l, SEEK_SET); + len = strlen(group); + for(;;) + { + fgets(cfg->cfg_lbuf, LBUF - 1, cfg->cfg_fp); + if(feof(cfg->cfg_fp) || ferror(cfg->cfg_fp)) + return FALSE; + + if(!strnicmp(group, cfg->cfg_lbuf, len)) + { + cfg->cfg_flag = TRUE; + return TRUE; + } + } +} + +/* + * Parse and test a keyword value pair from current config input. + * + * Abstract: + * This routine is commonly used to search the current input line + * that is returned by read_config() for a specified keyword. The + * current input line is assumed to be in the form 'keyword = value'. + * lead and trailing spaces around the '=' are ignored, as is keyword + * case. White spaces within a keyword are also ignored. + * + * Assuming the keyword requested is found in the current input line, + * the 'value' string is returned. If the keyword being tested is + * a multi-line keyword = { list }, then all lines for the value are + * scanned and loaded into the config line buffer. If the special + * '+' entry is found in the config file, then the keyword is assumed + * to be a continuation of the last one found. + * + * A value is normally stripped of all lead and trailing spaces. If + * these need to be preserved, then the value may be put in single + * or double quotes. + * + * Since get_config() only looks at the current input line buffered + * by read_config(), a test for every possible keyword the application + * may need should be performed after each successful read_config() + * for a given [] section. + * + * Paramaters: + * cfg - config object pointer. + * keyword - keyword to test for. + * + * Returns: + * Value string if keyword is found in current input line, else NULL. + * + * Exceptions: + * If a NULL pointer or keyword is used, a NULL value is returned. + */ + +char *get_config(CONFIG *cfg, const char *keyword) +{ + char *cbuf; + char *out, *p; + int pos = 0; + bool found = FALSE; + + if(!cfg || !keyword) + return NULL; + + cbuf = cfg->cfg_lbuf; + + if(*cbuf == '+') /* alternate multi-line syntax */ + { + if(!stricmp(cfg->cfg_test, keyword)) + return strltrim(++cbuf, __SPACES); + else + return NULL; + } + + while((pos < 33) && *cbuf && (*cbuf != '=')) + { + if((*cbuf != ' ') && (*cbuf != '_') && (*cbuf != '\t')) + cfg->cfg_test[pos++] = *(cbuf++); + else + ++cbuf; + } + cfg->cfg_test[pos] = 0; + out = p = strltrim(++cbuf, __SPACES); + switch(*p) + { + case '{': + cbuf = p; + while(!found) + { + while(*(++p)) + { + if(*p == '}') + { + found = TRUE; + *p = 0; + } + else + *(cbuf++) = *p; + } + + if(!found) + { + p = cbuf; + fgets(p, LBUF - 1 + (int)(cfg->cfg_lbuf - p), cfg->cfg_fp); + if(feof(cfg->cfg_fp) || *p == '[') + { + cfg->cfg_flag = FALSE; + *p = 0; + break; + } + *(cbuf++) = '\n'; + p = strtrim(p, __SPACES); + } + } + *cbuf = 0; + out = strltrim(++out, __SPACES); + break; + case '\'': + case '\"': + while(*(++p)) + { + if(*p == *out) + { + *p = 0; + break; + } + } + out = strltrim(++out, __SPACES); + break; + } + if(!stricmp(cfg->cfg_test, keyword)) + return out; + else + return NULL; +} + +/* + * Find config file in user's home directory. + * + * Abstract: + * In addition to searching for a master config file in /etc, many + * applications may support an optional user specific 'rc' or config + * file in the user's own home directory, which, if found, may + * override global defaults. This ability is easily supported with + * the usr_config() service, which looks for a named .config file + * in the user's home. + * + * Paramaters: + * Filename of '.config' file to look for in a user's home directory, + * without the leading '.'. + * + * Returns: + * Config object pointer if file is found in user's home, otherwise + * a NULL pointer. + * + * Exceptions: + * A NULL filename will result in a NULL object being returned. + */ + +CONFIG *usr_config(const char *name) +{ + char path[NAME_MAX + 1]; + + if(!name) + return NULL; + + strcpy(path, homedir()); + fncat(path, "."); + strcat(path, name); + return open_config(path); +} + + + + + + + + + + + diff --git a/sdk/other/config.h b/sdk/other/config.h new file mode 100644 index 0000000..4d76d1a --- /dev/null +++ b/sdk/other/config.h @@ -0,0 +1,67 @@ +/* + * Portable human readable config text file parsing routines. + * $Id: config.h 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see product license. + * + * Abstract: + * The config routines allow locating, opening, and parsing of + * human readable .conf files. These .conf files are broken into + * seperate named [] sections, each of which may be individually + * located and examined, and config data. Config data is usually + * in the form of a 'keyword = value' statement. + * + * Data types: + * CONFIG - object line parse buffer for an open config file. + */ + +#ifndef __OTHER_CONFIG_H__ +#define __OTHER_CONFIG_H__ + +#ifndef __OTHER_STRING_H__ +#include <other/string.h> +#endif + +#ifndef __OTHER_FILES_H__ +#include <other/files.h> +#endif + +typedef struct +{ + bool cfg_flag; + FILE *cfg_fp; + char cfg_test[33]; + char cfg_lbuf[ EMPTY ]; +} CONFIG; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define open_config __NAMESPACE(open_config) +#define sys_config __NAMESPACE(sys_config) +#define usr_config __NAMESPACE(usr_config) +#define first_config __NAMESPACE(first_config) +#define next_config __NAMESPACE(next_config) +#define seek_config __NAMESPACE(seek_config) +#define read_config __NAMESPACE(read_config) +#define close_config __NAMESPACE(close_config) +#define get_config __NAMESPACE(get_config) +#endif + +CONFIG *open_config(const char *name); +CONFIG *sys_config(const char *name); +CONFIG *usr_config(const char *name); +char *first_config(CONFIG *cfg); +char *next_config(CONFIG *cfg); +bool seek_config(CONFIG *cfg, const char *name); +char *read_config(CONFIG *cfg); +void close_config(CONFIG *cfg); +char *get_config(CONFIG *cfg, const char *option); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/env.c b/sdk/other/env.c new file mode 100644 index 0000000..cf3dfb0 --- /dev/null +++ b/sdk/other/env.c @@ -0,0 +1,36 @@ +/* + * Common values found in process environment space. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * See conditions of distribution and reuse see product license. + */ + +#include <other/env.h> +#include <std/string.h> + +char *homedir(void) +{ + char *env = getenv("HOME"); + + if(!env) + env = "/"; + + return env; +} + +char *language(void) +{ + static char lbuf[32] = "default"; + + char *env = getenv("LANG"); + + if(env) + { + strncpy(lbuf, env, 31); + lbuf[31] = 0; + strtok(lbuf, "._"); + } + return lbuf; +} + + diff --git a/sdk/other/env.h b/sdk/other/env.h new file mode 100644 index 0000000..96b70e3 --- /dev/null +++ b/sdk/other/env.h @@ -0,0 +1,31 @@ +/* + * Portable process environment routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_ENV_H__ +#define __OTHER_ENV_H__ + +#ifndef __STD_PROCESS_H__ +#include <std/process.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define homedir __NAMESPACE(homedir) +#define language __NAMESPACE(language) +#endif + +char *homedir(void); +char *language(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/expand.c b/sdk/other/expand.c new file mode 100644 index 0000000..8005957 --- /dev/null +++ b/sdk/other/expand.c @@ -0,0 +1,36 @@ +/* + * String expansion and normalization of 'plain text' line data. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <std/string.h> + +char *expand(const char *s) +{ + static char buf[320]; + + int pos = 0; + + while(*s) + { + if(*s == '\t') + { + buf[pos++] = ' '; + while(pos % 8) + buf[pos++] = ' '; + } + else if (*s > 31) + buf[pos++] = *s; + else + { + buf[pos++] = '^'; + buf[pos++] = *s + '@'; + } + ++s; + } + buf[pos] = 0; + return buf; +} + diff --git a/sdk/other/fatal.c b/sdk/other/fatal.c new file mode 100644 index 0000000..fd3ef54 --- /dev/null +++ b/sdk/other/fatal.c @@ -0,0 +1,23 @@ +/* + * Print error message to stderr and exit with status code. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/string.h> +#include <std/files.h> +#include <std/process.h> +#include <stdarg.h> + +void fatal(int excode, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + exit(excode); +} + + diff --git a/sdk/other/filename.c b/sdk/other/filename.c new file mode 100644 index 0000000..2a7275e --- /dev/null +++ b/sdk/other/filename.c @@ -0,0 +1,74 @@ +/* + * Portable file and directory name functions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/files.h> +#include <std/string.h> +#include <std/math.h> + +char *dirname(char *path) +{ + char *p = basename(path); + if(p == path) + return "."; + + *(--p) = 0; + return path; +} + +char *basename(const char *path) +{ + char *p = strrchr(path, '/'); +#if defined(_MSDOS) || defined(_OS2) || defined(_WIN32) + char *p1 = strrchr(path, '\\'); + p = max(p, p1); +#endif + + if(p) + return ++p; + else + return (char *)path; +} + +char *extfname(const char *path) +{ + char *e = strrchr(pathfname(path), '.'); + + if(e) + return e; + else + return ""; +} + +bool ispath(const char *p) +{ + if(strchr(p, '/')) + return TRUE; +#if defined(_MSDOS) || defined(_OS2) || defined(_WIN32) + if(strchr(p, '\\')) + return TRUE; +#endif + return FALSE; +} + +bool isroot(const char *p) +{ +#if defined(_MSDOS) || defined(_OS2) || defined(_WIN32) + if(!strncmp(p, "\\\\", 2)) + return TRUE; + + if(p[1] == ':') + return TRUE; +#else + if(*p == '/') + return TRUE; +#endif + return FALSE; +} + + + + diff --git a/sdk/other/files.h b/sdk/other/files.h new file mode 100644 index 0000000..7e9f421 --- /dev/null +++ b/sdk/other/files.h @@ -0,0 +1,52 @@ +/* + * Portable support for file manipulation and access related functions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_FILES_H__ +#define __OTHER_FILES_H__ + +#ifndef __STD_FILES_H__ +#include <std/files.h> +#endif + +#define isdir(fpath) isftype(fpath, S_IFDIR) +#define isfile(fpath) isftype(fpath, S_IFREG) +#define islink(fpath) isftype(fpath, S_IFLNK) +#define isfifo(fpath) isftype(fpath, S_IFIFO) +#define pathfname(fn) basename(fn) +#define rewind(fd) lseek(fd, (off_t)0, SEEK_SET) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define isnewfile __NAMESPACE(isnewfile) +#define isftype __NAMESPACE(isftype) +#define ispath __NAMESPACE(ispath) +#define isroot __NAMESPACE(isroot) +#define fncat __NAMESPACE(fncat) +#define search __NAMESPACE(search) +#define basename __NAMESPACE(basename) +#define dirname __NAMESPACE(dirname) +#define extfname __NAMESPACE(extfname) +#endif + +bool isnewfile(const char *from, const char *to); +bool isftype(const char *fpath, int ftype); +bool ispath(const char *fpath); +bool isroot(const char *fpath); +char *fncat(char *prefix, const char *suffix); +char *search(const char *path, const char *fname); +char *basename(const char *path); +char *dirname(char *path); +char *extfname(const char *path); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/fncat.c b/sdk/other/fncat.c new file mode 100644 index 0000000..1d8e3e7 --- /dev/null +++ b/sdk/other/fncat.c @@ -0,0 +1,30 @@ +/* + * Concatenate filenames. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse review product license. + */ + +#include <std/files.h> +#include <other/string.h> + +char *fncat(char *prefix, const char *suffix) +{ + char *t = tail(prefix); + + if(!*prefix) + { + strcpy(prefix, suffix); + return prefix; + }; + + if(*(--t) != '/') + { + *(++t) = '/'; + *(++t) = 0; + } + + strcat(prefix, suffix); + return prefix; +} + diff --git a/sdk/other/getargv.c b/sdk/other/getargv.c new file mode 100644 index 0000000..bae4d4f --- /dev/null +++ b/sdk/other/getargv.c @@ -0,0 +1,57 @@ +/* + * Portable routines to create argv[] argument lists for exec and spawn. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/string.h> + +int getargv(char *base[], char *cbuf) +{ + int arg = 0; + int qflag = 0; + int sflag = 1; + + while(*cbuf) + { + switch(*cbuf) + { + case ' ': + case '\t': + if(qflag) + break; + if(!sflag) + { + *cbuf = 0; + sflag = 1; + } + break; + case '\"': + if(!qflag) + { + *cbuf = 0; + base[arg++] = cbuf + 1; + sflag = 0; + qflag = 1; + } + else + { + *cbuf = 0; + sflag = 1; + qflag = 0; + } + break; + default: + if(sflag) + { + base[arg++] = cbuf; + sflag = 0; + } + } + ++cbuf; + } + base[arg] = NULL; + return arg; +} + diff --git a/sdk/other/hex.c b/sdk/other/hex.c new file mode 100644 index 0000000..ae5ccec --- /dev/null +++ b/sdk/other/hex.c @@ -0,0 +1,44 @@ +/* + * Hex digit conversion functions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/strcvt.h> + +char hex(int digit) +{ + if(digit < 10) + return '0' + digit; + else + return '7' + digit; +}; + +char *hexbyte(uchar v) +{ + static char h[3]; + + h[0] = hex(v / 16); + h[1] = hex(v % 16); + h[2] = 0; + return h; +}; + +char *hexshort(ushort v) +{ + static char h[5]; + + strcpy(h, hexbyte((uchar)(v / 256))); + strcpy(h + 2, hexbyte((uchar)(v % 256))); + return h; +}; + +char *hexlong(ulong v) +{ + static char h[9]; + + strcpy(h, hexshort((ushort)(v / 65536))); + strcpy(h + 4, hexshort((ushort)(v % 65536))); + return h; +}; diff --git a/sdk/other/isftype.c b/sdk/other/isftype.c new file mode 100644 index 0000000..bee42ca --- /dev/null +++ b/sdk/other/isftype.c @@ -0,0 +1,22 @@ +/* + * File type testing routine. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <std/files.h> + +bool isftype(const char *path, int ftype) +{ + struct stat ino; + + if(stat(path, &ino)) + return FALSE; + + if((ino.st_mode & S_IFMT) == ftype) + return TRUE; + + return FALSE; +} + diff --git a/sdk/other/make.conf b/sdk/other/make.conf new file mode 100644 index 0000000..e8b05bd --- /dev/null +++ b/sdk/other/make.conf @@ -0,0 +1,2 @@ +fn_find_file MEMORY_H_MISSING $inc/memory.h + diff --git a/sdk/other/memalloc.c b/sdk/other/memalloc.c new file mode 100644 index 0000000..6d31108 --- /dev/null +++ b/sdk/other/memalloc.c @@ -0,0 +1,35 @@ +/* + * Advanced memory pool allocation scheme. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse consult product license. + */ + +#include <other/memory.h> +#include <std/math.h> + +void *memalloc(MEMPOOL *mem, int len) +{ + _MEMFREE *free = mem->mem_free; + _MEMCELL *cell = NULL; + + len = align(len, __OBJALIGN); + + while(free) + { + if(free->size == len) + { + cell = free->list; + break; + } + free = free->next; + } + + if(cell) + { + free->list = cell->next; + return cell; + } + + return memreq(mem, len); +} diff --git a/sdk/other/memdup.c b/sdk/other/memdup.c new file mode 100644 index 0000000..af1f3cf --- /dev/null +++ b/sdk/other/memdup.c @@ -0,0 +1,22 @@ +/* + * Duplicate object into a memory pool. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <std/string.h> +#include <other/memory.h> + +void *memdup(void *obj, size_t size) +{ + void *new = (void *)malloc(size); + + if(!new) + return NULL; + + memcpy(new, obj, size); + return new; +} + + diff --git a/sdk/other/memfree.c b/sdk/other/memfree.c new file mode 100644 index 0000000..1939f14 --- /dev/null +++ b/sdk/other/memfree.c @@ -0,0 +1,38 @@ +/* + * Advanced free space deallocation for memory pools. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/memory.h> +#include <std/math.h> + +void memfree(MEMPOOL *mem, void *obj, int len) +{ + _MEMFREE *free = mem->mem_free; + _MEMCELL *cell = (_MEMCELL *)obj; + len = align(len, __OBJALIGN); + + while(free) + { + if(free->size == len) + break; + + free = free->next; + } + + if(!free) + { + free = memreq(mem, sizeof(_MEMFREE)); + free->list = NULL; + free->next = mem->mem_free; + mem->mem_free = free; + } + + if(free) + { + cell->next = free->list; + free->list = cell; + } +} diff --git a/sdk/other/memory.h b/sdk/other/memory.h new file mode 100644 index 0000000..902edd2 --- /dev/null +++ b/sdk/other/memory.h @@ -0,0 +1,103 @@ +/* + * Portable memory manipulation and management routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_MEMORY_H__ +#define __OTHER_MEMORY_H__ + +#ifndef __STD_TYPES_H__ +#include <std/types.h> +#endif + +#ifndef MEMORY_H_MISSING +#include <memory.h> +#endif + +#ifndef __MEMALIGN +#define __MEMALIGN sizeof(ptr_t) +#endif + +#ifndef __OBJALIGN +#define __OBJALIGN __MEMALIGN +#endif + +struct _mempool; +struct _mempage; +struct _memfree; +struct _memcell; + +typedef struct _mempool +{ + int mem_psize; + int mem_pcount; + int mem_pused; + void *(*mem_pfault)(struct _mempool *mem, int reqsize); + struct _memfree *mem_free; + struct _mempage *mem_reuse; + struct _mempage *mem_last; +} MEMPOOL; + +typedef struct _mempage +{ + struct _mempage *page_next; + int page_used; + uchar page[ EMPTY ]; +} MEMPAGE; + +typedef struct _memfree +{ + struct _memfree *next; + struct _memcell *list; + int size; +} _MEMFREE; + +typedef struct _memcell +{ + void *next; +} _MEMCELL; + +#define memfault(mem, fault) mem->mem_pfault = fault; +#define memfirst(mem) ((MEMPAGE *)((char *)(mem) - sizeof(MEMPAGE))) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define mempool __NAMESPACE(mempool) +#define memreuse __NAMESPACE(memreuse) +#define memrelease __NAMESPACE(memrelease) +#define memreq __NAMESPACE(memreq) +#define memlreq __NAMESPACE(memlreq) +#define strreq __NAMESPACE(strreq) +#define strlreq __NAMESPACE(strlreq) +#define memdup __NAMESPACE(memdup) +#define memalloc __NAMESPACE(memalloc) +#define memfree __NAMESPACE(memfree) +#endif + +MEMPOOL *mempool(int psize, int pcount); +void memreuse(MEMPOOL *mem); +void memrelease(MEMPOOL *mem); +void *memreq(MEMPOOL *mem, size_t memsize); +void *memlreq(MEMPOOL *mem, size_t memsize); +char *strreq(MEMPOOL *mem, const char *str); +char *strlreq(MEMPOOL *mem, const char *str); +void *memdup(void *, size_t); + +/* more advanced allocation schemes */ + +void *memalloc(MEMPOOL *mem, int memsize); +void memfree(MEMPOOL *mem, void *obj, int memsize); + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/sdk/other/mempool.c b/sdk/other/mempool.c new file mode 100644 index 0000000..ef27638 --- /dev/null +++ b/sdk/other/mempool.c @@ -0,0 +1,49 @@ +/* + * Memory pool creation. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/memory.h> +#include <std/files.h> +#include <std/math.h> +#include <std/process.h> + +static void *fault(MEMPOOL *mem, int request) +{ + fputs("* mempool: memory pool exhausted\n", stderr); + exit(EX_SOFTWARE); +} + +MEMPOOL *mempool(int psize, int pcount) +{ + char *page; + MEMPAGE *first; + MEMPOOL *pool; + + psize = align(psize, __MEMALIGN); + if(NULL == (page = (char *)malloc(psize))) + return NULL; + + first = (MEMPAGE *)page; + pool = (MEMPOOL *)(page + sizeof(MEMPAGE)); + + first->page_next = NULL; + first->page_used = sizeof(MEMPOOL); + + pool->mem_psize = psize - sizeof(MEMPAGE); + pool->mem_pcount = pcount; + pool->mem_pused = 1; + pool->mem_pfault = fault; + pool->mem_reuse = NULL; + pool->mem_last = first; + pool->mem_free = NULL; + return pool; +} + + + + + + diff --git a/sdk/other/memrelease.c b/sdk/other/memrelease.c new file mode 100644 index 0000000..144bff6 --- /dev/null +++ b/sdk/other/memrelease.c @@ -0,0 +1,43 @@ +/* + * Relallocate and release memory pools. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/memory.h> + +void memrelease(MEMPOOL *mem) +{ + MEMPAGE *page = memfirst(mem); + MEMPAGE *next; + + while(page) + { + next = page->page_next; + free(page); + page = next; + } +} + +void memreuse(MEMPOOL *mem) +{ + MEMPAGE *page = memfirst(mem); + MEMPAGE *next; + + page = page->page_next; + while(page) + { + next = page->page_next; + free(page); + page = next; + } + mem->mem_pused = 1; + mem->mem_free = NULL; + page = mem->mem_last = memfirst(mem); + page->page_used = 0; + page->page_next = NULL; +} + + + diff --git a/sdk/other/memreq.c b/sdk/other/memreq.c new file mode 100644 index 0000000..16f8433 --- /dev/null +++ b/sdk/other/memreq.c @@ -0,0 +1,59 @@ +/* + * Copy strings and objects into a memory pool. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/memory.h> +#include <std/math.h> + +static void *memrequest(MEMPOOL *mem, MEMPAGE *page, size_t len) +{ + int psize = mem->mem_psize; + void *obj; + + /* align objects to ptr field size */ + + len = align(len, __OBJALIGN); + + if(len > mem->mem_psize) + return (*mem->mem_pfault)(mem, len); + + while(page) + { + if(page->page_used + len <= psize) + { + obj = &page->page[page->page_used]; + page->page_used += len; + return obj; + } + page = page->page_next; + } + + if(mem->mem_pused >= mem->mem_pcount) + return (*mem->mem_pfault)(mem, len); + + ++mem->mem_pused; + page = (MEMPAGE *)malloc(psize + sizeof(MEMPAGE)); + if(!page) + return (*mem->mem_pfault)(mem, len); + + mem->mem_last->page_next = page; + mem->mem_last = page; + page->page_used = len; + page->page_next = NULL; + return page->page; +} + +void *memlreq(MEMPOOL *mem, size_t len) +{ + return memrequest(mem, mem->mem_last, len); +} + +void *memreq(MEMPOOL *mem, size_t len) +{ + return memrequest(mem, memfirst(mem), len); +} + + diff --git a/sdk/other/picture.c b/sdk/other/picture.c new file mode 100644 index 0000000..3ff2dba --- /dev/null +++ b/sdk/other/picture.c @@ -0,0 +1,112 @@ +/* + * String formatting of numeric data. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <std/string.h> + +char *picture(char *buf, const char *pict, long value) +{ + char *bp = buf, *tp; + long shift = 0; + int sign = 0; + int zfill = 0; + int digit; + int currency = 0; + int digits = 0; + + if(value < 0) + { + ++sign; + value = -value; + } + + while(*pict) + { + switch(*pict) + { + case '$': + ++currency; + *(bp++) = ' '; + ++pict; + break; + case '+': + if(sign) + *(bp++) = ' '; + else + *(bp++) = '+'; + ++pict; + break; + case '-': + if(sign) + *(bp++) = '-'; + else + *(bp++) = ' '; + ++pict; + break; + case '9': + case '0': + shift *= 10; + if(!shift) + shift = 1; + default: + *(bp++) = *(pict++); + } + } + if(value >= shift * 10) + { + bp = buf; + while(*bp) + { + if(isdigit(*bp)) + *bp = '#'; + ++bp; + } + return buf; + } + bp = tp = buf; + while(*bp) + { + switch(*bp) + { + case ',': + if(*(bp - 1) == '#') + { + *bp = '#'; + break; + } + if(!zfill) + *bp = ' '; + break; + case '#': + if(!digits) + if(shift > value) + break; + case '0': + ++zfill; + case '9': + ++digits; + digit = (int)(value / shift); + if((digit > 0) || (shift == 1)) + ++zfill; + if(!zfill && !digit) + digit = (int)(' ' - '0'); + *bp = (char)('0' + digit); + if(isdigit(*bp) && currency) + { + currency = 0; + *(tp - 1) = '$'; + } + value %= shift; + shift /= 10; + } + if(*bp != '#') + *(tp++) = *bp; + ++bp; + } + *tp = 0; + return buf; +} + diff --git a/sdk/other/search.c b/sdk/other/search.c new file mode 100644 index 0000000..15963bf --- /dev/null +++ b/sdk/other/search.c @@ -0,0 +1,46 @@ +/* + * File path search routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/files.h> +#include <other/string.h> +#include <std/process.h> + +#ifdef QNX +#define PATHMARK "!" +#endif + +#ifndef PATHMARK +#define PATHMARK ":" +#endif + +char *search(const char *path, const char *file) +{ + static char buf[PATH_MAX + 1]; + char pbuf[PATH_MAX + 1]; + char *p; + + if(!path) + return NULL; + + strcpy(pbuf, path); + + p = strtok(pbuf, PATHMARK); + + while(p) + { + if(*p) + fncat(strcpy(buf, p), file); + else + strcpy(buf, file); + if(isfile(buf)) + return buf; + p = strtok(NULL, PATHMARK); + } + return NULL; +} + + diff --git a/sdk/other/strblank.c b/sdk/other/strblank.c new file mode 100644 index 0000000..d3e8d18 --- /dev/null +++ b/sdk/other/strblank.c @@ -0,0 +1,24 @@ +/* + * Test for blank strings. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/string.h> + +char __SPACES[] = " \t\r\n"; + +bool strblank(const char *str) +{ + if(!str) + return TRUE; + + while(*str) + { + if(!strchr(__SPACES, *str)) + return FALSE; + ++str; + } + return TRUE; +} diff --git a/sdk/other/strcopy.c b/sdk/other/strcopy.c new file mode 100644 index 0000000..077f897 --- /dev/null +++ b/sdk/other/strcopy.c @@ -0,0 +1,61 @@ +/* + * String copying defined for supporting over-lapping strings 'insertion'. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/string.h> + +static char *revcopy(char *to, const char *from, size_t count) +{ + while(count--) + *(to--) = *(from--); + + *to = *from; + return to; +}; + +char *strcopy(char *to, const char *from) +{ + char *s1 = to; + int l = from - to; + int l2 = len(from); + + if(!to || !from) + return NULL; + + if(l > 0 && l <= l2) + return revcopy(to + l2, from + l2, l2); + + ++l2; + while(l2--) + *(to++) = *(from++); + + return s1; +}; + +char *strncopy(char *to, const char *from, int l2) +{ + char *s1 = to; + int l = from - to; + if(len(from) < l2) + return strcopy(to, from); + + if(!to || !from) + return NULL; + + if(l > 0 && l <= l2) + { + to[l2] = 0; + --l2; + return revcopy(to + l2, from + l2, l2); + } + + while(l2--) + *(to++) = *(from++); + + *to = 0; + return s1; +}; + diff --git a/sdk/other/strcvt.h b/sdk/other/strcvt.h new file mode 100644 index 0000000..443c820 --- /dev/null +++ b/sdk/other/strcvt.h @@ -0,0 +1,56 @@ +/* + * Portable string handling routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_STRCVT_H__ +#define __OTHER_STRCVT_H__ + +#ifndef __STD_STRING_H__ +#include <std/string.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define __SPACES __NAMESPACE(__SPACES) +#endif + +extern char __SPACES[]; + +#ifdef __NAMESPACE +#define atob __NAMESPACE(atob) +#define strint __NAMESPACE(strint) +#define picture __NAMESPACE(picture) +#define expand __NAMESPACE(expand) +#define xdigit __NAMESPACE(xdigit) +#define xtol __NAMESPACE(xtol) +#define hex __NAMESPACE(hex) +#define hexbyte __NAMESPACE(hexbyte) +#define hexshort __NAMESPACE(hexshort) +#define hexlong __NAMESPACE(hexlong) +#define str2bcd __NAMESPACE(str2bcd) +#define bcd2str __NAMESPACE(bcd2str) +#endif + +bool atob(const char *str); +char *strint(long i, int z); +char *picture(char *buf, const char *pict, long value); +char *expand(const char *str); +int xdigit(char digit); +ulong xtol(const char *digit); +char hex(int value); +char *hexbyte(uchar); +char *hexshort(ushort); +char *hexlong(ulong); +char *str2bcd(uchar *bcd, char *str, int max); +uchar *bcd2str(char *str, uchar *bcd, int len); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/strdiff.c b/sdk/other/strdiff.c new file mode 100644 index 0000000..a0297f6 --- /dev/null +++ b/sdk/other/strdiff.c @@ -0,0 +1,24 @@ +/* + * Often used to evaluate similarity of soundex codes. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/string.h> +#include <std/math.h> + +int strdiff(const char *s1, const char *s2) +{ + int l1 = len(s1); + int l2 = len(s2); + int l = min(l1, l2); + int dif = abs(l1 - l2); + + while(l--) + { + if(*(s1++) != *(s2++)) + ++dif; + } + return dif; +} diff --git a/sdk/other/string.h b/sdk/other/string.h new file mode 100644 index 0000000..5db8cd4 --- /dev/null +++ b/sdk/other/string.h @@ -0,0 +1,65 @@ +/* + * Portable string handling routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_STRINGS_H__ +#define __OTHER_STRINGS_H__ + +#ifndef __STD_STRING_H__ +#include <std/string.h> +#endif + +#ifndef __STD_TYPES_H__ +#include <std/types.h> +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define __SPACES __NAMESPACE(__SPACES) +#endif + +extern char __SPACES[]; + +#ifdef __NAMESPACE +#define strblank __NAMESPACE(strblank) +#define strtrim __NAMESPACE(strtrim) +#define strrtrim __NAMESPACE(strrtrim) +#define strltrim __NAMESPACE(strltrim) +#define right __NAMESPACE(right) +#define left __NAMESPACE(left) +#define ccount __NAMESPACE(ccount) +#define tail __NAMESPACE(tail) +#define field __NAMESPACE(field) +#define token __NAMESPACE(token) +#define strcopy __NAMESPACE(strcopy) +#define strncopy __NAMESPACE(strncopy) +#define strdiff __NAMESPACE(strdiff) +#define getargv __NAMESPACE(getargv) +#endif + +bool strblank(const char *str); +char *strtrim(char *s, const char *trim); +char *strrtrim(char *s, const char *trim); +char *strltrim(char *s, const char *trim); +char *right(char *str, size_t len); +char *left(char *str, size_t len); +int ccount(const char *str, const char *list); +char *tail(const char *str); +char *field(char **ptr, const char *tok); +char *token(char **ptr, const char *tok); +char *strcopy(char *to, const char *from); +char *strncopy(char *to, const char *from, int len); +int strdiff(const char *s1, const char *s2); +int getargv(char *base[], char *str); +void fatal(int exitcode, const char *format, ...); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/strint.c b/sdk/other/strint.c new file mode 100644 index 0000000..f4291a1 --- /dev/null +++ b/sdk/other/strint.c @@ -0,0 +1,51 @@ +/* + * Convert integer to string, with optional leading zeros. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/strcvt.h> + +char *strint(long i, int z) +{ + static char buf[30]; + char b1[30]; + char *p = buf, *q = b1; + unsigned u; + + if(!i) + { + if(z < 1) + z = 1; + while(z--) + *(p++) = '0'; + *p = 0; + return buf; + } + if((i < 0) && !z) + { + i = -i; + buf[0] = '-'; + ++p; + } + u = (unsigned)i; + + while(u > 0) + { + *(q++) = (char)(u % 10) + '0'; + u /= 10; + } + *q = 0; + z -= strlen(b1); + while(z-- > 0) + *(p++) = '0'; + + while(q > b1) + *(p++) = *(--q); + *p = 0; + return buf; +} + + + diff --git a/sdk/other/strpos.c b/sdk/other/strpos.c new file mode 100644 index 0000000..79afbf5 --- /dev/null +++ b/sdk/other/strpos.c @@ -0,0 +1,46 @@ +/* + * String pointer manipulation routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/string.h> + +char *tail(const char *tail) +{ + if(!tail) + return NULL; + + while(*tail) + ++tail; + + return (char *)tail; +} + +char *left(char *str, size_t pos) +{ + if(!str) + return NULL; + + if(pos < strlen(str)) + str[pos] = 0; + + return str; +}; + +char *right(char *s, size_t l) +{ + size_t len; + + if(!s) + return NULL; + + len = strlen(s); + if(len <= l) + return s; + + return s + len - l; +} + + diff --git a/sdk/other/strreq.c b/sdk/other/strreq.c new file mode 100644 index 0000000..fb69b95 --- /dev/null +++ b/sdk/other/strreq.c @@ -0,0 +1,39 @@ +/* + * Memory pool string copy. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/memory.h> + +char *strreq(MEMPOOL *mem, const char *str) +{ + char *newstr; + + if(!str) + return NULL; + + newstr = memreq(mem, strlen(str) + 1); + if(!newstr) + return NULL; + + strcpy(newstr, str); + return newstr; +} + +char *strlreq(MEMPOOL *mem, const char *str) +{ + char *newstr; + + if(!str) + return NULL; + + newstr = memlreq(mem, strlen(str) + 1); + if(!newstr) + return NULL; + + strcpy(newstr, str); + return newstr; +} + diff --git a/sdk/other/strtrim.c b/sdk/other/strtrim.c new file mode 100644 index 0000000..9afcfd5 --- /dev/null +++ b/sdk/other/strtrim.c @@ -0,0 +1,45 @@ +/* + * Portable string trimming routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/string.h> + +char *strtrim(char *str, const char *trim) +{ + return strltrim(strrtrim(str, trim), trim); +} + +char *strrtrim(char *str, const char *trim) +{ + char *end; + + if(!str) + return NULL; + + end = str + strlen(str); + + while(end-- > str) + { + if(!strchr(trim, *end)) + return str; + *end = 0; + } + return str; +} + +char *strltrim(char *str, const char *trim) +{ + if(!str) + return NULL; + + while(*str) + { + if(!strchr(trim, *str)) + return str; + ++str; + } + return str; +} diff --git a/sdk/other/token.c b/sdk/other/token.c new file mode 100644 index 0000000..c9846ed --- /dev/null +++ b/sdk/other/token.c @@ -0,0 +1,50 @@ +/* + * Alternate thread-safe string token parsing. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/string.h> + +char *token(char **ptr, const char *tok) +{ + char *p; + char *brk; + + if(strblank(*ptr)) + return NULL; + + p = strltrim(*ptr, tok); + brk = strpbrk(p, tok); + if(brk) + { + *brk = 0; + *ptr = strltrim(++brk, tok); + if(!(**ptr)) + *ptr = NULL; + } + else + *ptr = NULL; + return p; +} + +char *field(char **ptr, const char *tok) +{ + char *p = *ptr; + char *brk; + + if(strblank(p)) + return NULL; + + brk = strpbrk(p, tok); + if(brk) + { + *brk = 0; + *ptr = ++brk; + } + else + *ptr = NULL; + + return p; +} diff --git a/sdk/other/xval.c b/sdk/other/xval.c new file mode 100644 index 0000000..c7d1276 --- /dev/null +++ b/sdk/other/xval.c @@ -0,0 +1,28 @@ +/* + * Hex digit conversions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include <other/strcvt.h> + +int xdigit(char c) +{ + if(c > '9') + return upper(c) - '7'; + + return digit(c); +}; + +ulong xtol(const char *s) +{ + ulong v = 0l; + + while(isxdigit(*s)) + { + v = v << 4 | xdigit(*s); + ++s; + } + return v; +}; |