diff options
| author | Javier <dev.git@javispedro.com> | 2026-08-29 17:45:02 +0200 |
|---|---|---|
| committer | Javier <dev.git@javispedro.com> | 2026-08-29 17:45:02 +0200 |
| commit | 003a26a76982f512e2f3a1108e46b88aa29ab306 (patch) | |
| tree | 6c508e3ee1fc995ed9e13ffc5075927ff94ed5fe /kitten.c | |
| parent | d25f344b9980c2d030f8388df84aaf8ff88d2591 (diff) | |
| download | vbados-003a26a76982f512e2f3a1108e46b88aa29ab306.tar.gz vbados-003a26a76982f512e2f3a1108e46b88aa29ab306.zip | |
split bda from int10vga.h , update kitten version to latest from freedos
Diffstat (limited to 'kitten.c')
| -rw-r--r-- | kitten.c | 869 |
1 files changed, 389 insertions, 480 deletions
@@ -19,155 +19,142 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifndef NO_KITTEN - -#include <stdio.h> /* sprintf */ -#ifndef _MICROC_ -#include <stdlib.h> /* getenv */ -#include <string.h> /* strchr */ -#include <dos.h> -#ifndef __PACIFIC__ +#include <stdio.h> /* sprintf */ +#include <stdlib.h> /* getenv */ +#include <string.h> /* strchr */ #include <fcntl.h> -#else -#define O_RDONLY 0 -#define O_TEXT 0 -#endif -#else -#include <intr.h> -#include <file.h> -#define O_RDONLY READONLY -#define O_TEXT 0 +#include <dos.h> +#if !defined(__TURBOC__) +#include <sys/stat.h> +#include <sys/types.h> #endif -/* assert we are running in small model */ -/* else pointer below has to be done correctly */ -/* char verify_small_pointers[sizeof(void*) == 2 ? 1 : -1]; */ #include "kitten.h" -char catcontents[8192]; +#if defined(__TURBOC__) +int dos_open(char *filename, int mode); +#define open(filename,mode) dos_open(filename,mode) -struct catstring -{ +int dos_read(int file, void *ptr, unsigned count); +#define read(file, ptr, count) dos_read(file,ptr,count) + +int dos_write(int file, void *ptr, unsigned count); +#define write(file, ptr, count) dos_write(file,ptr,count) + +void dos_close(int file); +#define close(file) dos_close(file) +#endif + +static char catcontents[6144]; /* *** Maximum size of PROGRAM.%LANG% file *** */ + +struct catstring{ char key1; char key2; char *text; }; -/* Micro-C does not support typedef */ -#define catstring_t struct catstring +typedef struct catstring catstring_t; -catstring_t catpoints[128]; +static catstring_t catpoints[128]; /* max 128 strings can be defined... */ /* Local prototypes */ -int catread (char *catfile); /* Reads a catfile into the hash */ -char *processEscChars (char *line); /* Converts c escape sequences to chars */ +int catread (char *catfile); /* Reads a catfile into the hash */ +char *processEscChars(char *line); /* Converts c escape sequences to chars */ -int get_char (int file); /* not meant for external use */ +int get_char(int); /* not meant for external use */ /* external use would cause consistency problems if */ /* value or related file of the file handle changes */ -int mystrtoul (char *src, int base, int size); +int mystrtoul(char *, int, int); /* Globals */ -nl_catd _kitten_catalog = 0; /* _kitten_catalog descriptor or 0 */ -char catfile[_MAX_PATH]; /* full path to _kitten_catalog */ - -char getlbuf[8192]; /* read buffer for better speed */ -char *getlp; /* current point in buffer */ -int getlrem = -1; /* remaining bytes in buffer */ -char lastcr = 0; /* for 2byte CR LF sequences */ +static nl_catd _kitten_catalog = 0; /* _kitten_catalog descriptor or 0 */ +static char catfile[128]; /* full path to _kitten_catalog */ +static char getlbuf[1024]; /* read buffer (better speed) -- 7/2004: 1k, not 8k */ +static char *getlp; /* current point in buffer */ +static int getlrem = -1; /* remaining bytes in buffer */ -#ifndef _MICROC_ -#ifndef __DJGPP__ +#if defined(__TURBOC__) /* DOS handle based file usage */ -int -dos_open (char *filename) +int dos_open(char *filename, int mode) { - union REGS r; - struct SREGS s; - - r.h.ah = 0x3d; - r.h.al = 0; /* read mode only supoported now !! */ - r.x.dx = FP_OFF (filename); - s.ds = FP_SEG (filename); - intdosx (&r, &r, &s); - return ((r.x.cflag) ? -1 : (int) r.x.ax); + union REGS r; + struct SREGS s; + (void)mode; /* mode ignored - readonly supported */ + r.h.ah = 0x3d; + r.h.al = 0; /* read mode only supoported now !! */ + r.x.dx = FP_OFF(filename); + s.ds = FP_SEG(filename); + intdosx(&r,&r,&s); + return ( (r.x.cflag) ? -1 : r.x.ax ); } -int -dos_read (int file, void *ptr, unsigned count) +int dos_read(int file, void *ptr, unsigned count) { - union REGS r; - struct SREGS s; - r.h.ah = 0x3f; - r.x.bx = file; - r.x.cx = count; - r.x.dx = FP_OFF (ptr); - s.ds = FP_SEG (ptr); - intdosx (&r, &r, &s); - return ((r.x.cflag) ? 0 : r.x.ax); + union REGS r; + struct SREGS s; + r.h.ah = 0x3f; + r.x.bx = file; + r.x.cx = count; + r.x.dx = FP_OFF(ptr); + s.ds = FP_SEG(ptr); + intdosx(&r,&r,&s); + return ( (r.x.cflag) ? 0 : r.x.ax ); } -int -dos_write (int file, void *ptr, unsigned count) +int dos_write(int file, void *ptr, unsigned count) { - union REGS r; - struct SREGS s; - r.h.ah = 0x40; - r.x.bx = file; - r.x.cx = count; - r.x.dx = FP_OFF (ptr); - s.ds = FP_SEG (ptr); - intdosx (&r, &r, &s); - return ((r.x.cflag) ? 0 : r.x.ax); + union REGS r; + struct SREGS s; + r.h.ah = 0x40; + r.x.bx = file; + r.x.cx = count; + r.x.dx = FP_OFF(ptr); + s.ds = FP_SEG(ptr); + intdosx(&r,&r,&s); + return ( (r.x.cflag) ? 0 : r.x.ax ); } -void -dos_close (int file) +void dos_close(int file) { - union REGS r; - r.h.ah = 0x3e; - r.x.bx = file; - intdos (&r, &r); + union REGS r; + r.h.ah = 0x3e; + r.x.bx = file; + intdos(&r,&r); } +#else +#include <unistd.h> +#endif + -#endif /*DJGPP*/ -#endif /*Micro-C */ /* Functions */ + /** * On success, catgets() returns a pointer to an internal * buffer area containing the null-terminated message string. * On failure, catgets() returns the value 'message'. */ -char * -kittengets (int setnum, int msgnum, char *message) + +const char *kittengets(int setnum, int msgnum, const char *message) { -/* In Micro-C, variables must be defined at the start of the - * function and may not be immediately assigned a value - */ -#ifdef _MICROC_ - int i; - i = 0; -#else - int i = 0; -#endif - while ((catpoints[i].key1 != setnum) || (catpoints[i].key2 != msgnum)) - { - if ((catpoints[i].text == NULL) || (i > 127)) /* at EOF */ - return message; - i++; - } + int i = 0; + + while ((catpoints[i].key1 != setnum) || (catpoints[i].key2 != msgnum)) { + if ((catpoints[i].text == NULL) || (i>127)) /* at EOF */ + return message; + i++; + } if (catpoints[i].text == NULL) return message; @@ -175,60 +162,39 @@ kittengets (int setnum, int msgnum, char *message) return (catpoints[i].text); } -/** - * Obtains path to current exec. - */ -static char * get_cmd_path(char *buf) -{ - char cmd_drive[_MAX_DRIVE]; - char cmd_dir[_MAX_DIR]; - - _splitpath(__argv[0], cmd_drive, cmd_dir, NULL, NULL); - _makepath(buf, cmd_drive, cmd_dir, "", NULL); - - return buf; -} - /** * Initialize kitten for program (name). */ -nl_catd -kittenopen (char *name) +nl_catd kittenopen(char *name) { /* catopen() returns a message _kitten_catalog descriptor * * of type nl_catd on success. On failure, it returns -1. */ - char catlang[3]; /* from LANG environment var. */ - char *nlsptr; /* ptr to NLSPATH */ - char *lang; /* ptr to LANG */ + char catlang[3]; /* from LANG environment var. */ + char *nlsptr; /* ptr to NLSPATH */ + char *lang; /* ptr to LANG */ int i; -#ifdef _MICROC_ - char *tok; - int toklen; -#endif - + /* Open the _kitten_catalog file */ /* The value of `_kitten_catalog' will be set based on catread */ - if (_kitten_catalog) - { /* Already one open */ - write (1, "cat already open\r\n", strlen ("cat already open\r\n")); - return (-1); - } + if (_kitten_catalog) { /* Already one open */ + write(1,"cat already open\r\n",strlen("cat already open\r\n")); + return (-1); + } - for (i = 0; i < 128; i++) + for (i=0; i<128; i++) catpoints[i].text = NULL; - if (strchr (name, '\\')) - { - /* unusual case: 'name' is a filename */ - write (1, "found \\\r\n", 9); - _kitten_catalog = catread (name); - if (_kitten_catalog) - return (_kitten_catalog); - } + if (strchr (name, '\\')) { + /* unusual case: 'name' is a filename */ + write(1,"found \\\r\n",9); + _kitten_catalog = catread (name); + if (_kitten_catalog) + return (_kitten_catalog); + } /* If the message _kitten_catalog file name does not contain a directory * * separator, then we need to try to locate the message _kitten_catalog. */ @@ -238,100 +204,79 @@ kittenopen (char *name) lang = getenv ("LANG"); - if (lang == NULL) - { - /* printf("no lang= found\n"); *//* not fatal, though */ + if (lang == NULL) { + /* printf("no lang= found\n"); */ /* not fatal, though */ /* Return failure - we won't be able to locate the cat file */ return (-1); - } + } - if ((strlen (lang) < 2) || ((strlen (lang) > 2) && (lang[2] != '-'))) - { + if ( ( strlen(lang) < 2 ) || + ( (strlen(lang) > 2) && (lang[2] != '-') ) ) { /* Return failure - we won't be able to locate the cat file */ return (-1); - } + } - memcpy (catlang, lang, 2); + memcpy(catlang, lang, 2); /* we copy the full LANG value or the part before "-" if "-" found */ catlang[2] = '\0'; - - /* first try to find catalog file in the same path as exe */ - get_cmd_path(catfile); - - strcat (catfile, name); - strcat (catfile, "."); - strcat (catfile, catlang); - _kitten_catalog = catread (catfile); - if (_kitten_catalog) - return (_kitten_catalog); - - - /* otherwise step through NLSPATH */ + /* step through NLSPATH */ nlsptr = getenv ("NLSPATH"); - if (nlsptr == NULL) - { - /* printf("no NLSPATH= found\n"); *//* not fatal either */ + if (nlsptr == NULL) { + /* printf("no NLSPATH= found\n"); */ /* not fatal either */ /* Return failure - we won't be able to locate the cat file */ return (-1); - } + } catfile[0] = '\0'; - while (nlsptr && nlsptr[0]) - { -#ifdef _MICROC_ - tok = strchr (nlsptr, ';'); -#else - char *tok = strchr (nlsptr, ';'); + while (nlsptr != NULL) { + char *tok = strchr(nlsptr, ';'); int toklen; -#endif if (tok == NULL) - toklen = strlen (nlsptr); /* last segment */ + toklen = strlen(nlsptr); /* last segment */ else - toklen = tok - nlsptr; /* segment terminated by ';' */ - + toklen = (int)(tok - nlsptr); /* segment terminated by ';' */ + /* catfile = malloc(toklen+1+strlen(name)+1+strlen(lang)+1); */ /* Try to find the _kitten_catalog file in each path from NLSPATH */ - if ((toklen + 6 + strlen (name)) > sizeof (catfile)) - { - write (1, "NLSPATH overflow\r\n", strlen ("NLSPATH overflow\r\n")); - return 0; /* overflow in NLSPATH, should never happen */ - } + if ((toklen+6+strlen(name)) > sizeof(catfile)) { + write(1,"NLSPATH overflow\r\n",strlen("NLSPATH overflow\r\n")); + return 0; /* overflow in NLSPATH, should never happen */ + } /* Rule #1: %NLSPATH%\%LANG%\cat */ - memcpy (catfile, nlsptr, toklen); - strcpy (catfile + toklen, "\\"); - strcat (catfile, catlang); - strcat (catfile, "\\"); - strcat (catfile, name); - _kitten_catalog = catread (catfile); - if (_kitten_catalog) - return (_kitten_catalog); + memcpy(catfile, nlsptr, toklen); + strcpy(catfile+toklen,"\\"); + strcat(catfile,catlang); + strcat(catfile,"\\"); + strcat(catfile,name); + _kitten_catalog = catread (catfile); + if (_kitten_catalog) + return (_kitten_catalog); /* Rule #2: %NLSPATH%\cat.%LANG% */ - /* memcpy(catfile, nlsptr, toklen); */ - strcpy (catfile + toklen, "\\"); - strcat (catfile, name); - strcat (catfile, "."); - strcat (catfile, catlang); - _kitten_catalog = catread (catfile); - if (_kitten_catalog) - return (_kitten_catalog); + /* memcpy(catfile, nlsptr, toklen); */ + strcpy(catfile+toklen,"\\"); + strcat(catfile,name); + strcat(catfile,"."); + strcat(catfile,catlang); + _kitten_catalog = catread (catfile); + if (_kitten_catalog) + return (_kitten_catalog); /* Grab next tok for the next while iteration */ - nlsptr = tok; - if (nlsptr) - nlsptr++; - - } /* while tok */ + nlsptr = tok; + if (nlsptr) nlsptr++; + + } /* while tok */ /* We could not find it. Return failure. */ @@ -343,115 +288,92 @@ kittenopen (char *name) * Load a message catalog into memory. */ -int -catread (char *catfile) +int catread (char *catfile) { - int file; /* pointer to the catfile */ - int i; - char *where; - char *tok; -#ifdef _MICROC_ - char *msg; - char *key; - int key1; - int key2; -#endif + int file; /* pointer to the catfile */ + int i; + char *where; + char *tok; /* Get the whole catfile into a buffer and parse it */ + + file = open (catfile, O_RDONLY); + if (file < 0) + /* Cannot open the file. Return failure */ + return 0; - file = open (catfile, O_RDONLY | O_TEXT); - if (file < 0) - /* Cannot open the file. Return failure */ - return 0; - - for (i = 0; i < 128; i++) + for (i=0; i<128; i++) catpoints[i].text = NULL; - for (i = 0; (unsigned int) i < sizeof (catcontents); i++) + for (i=0; i<sizeof(catcontents); i++) catcontents[i] = '\0'; /* Read the file into memory */ - i = read (file, catcontents, sizeof (catcontents) - 1); + i = read (file, catcontents, sizeof(catcontents)-1); - if ((i == sizeof (catcontents) - 1) || (i < 1)) - return 0; /* file was too big or too small */ + if ((i == sizeof(catcontents)-1) || (i < 1)) + return 0; /* file was too big or too small */ where = catcontents; - i = 0; /* catpoints entry */ + i = 0; /* catpoints entry */ - do - { -#ifndef _MICROC_ - char *msg; - char *key; - int key1 = 0; - int key2 = 0; -#else - key1 = 0; - key2 = 0; -#endif + do { + char *msg; + char *key; + int key1 = 0; + int key2 = 0; - tok = strchr (where, '\n'); + tok = strchr(where, '\n'); - if (tok == NULL) - { /* done? */ - close (file); - return 1; /* success */ - } - - tok[0] = '\0'; /* terminate here */ - tok--; /* guess: \r before \n */ - if (tok[0] != '\r') - tok++; /* if not, go back */ - else - { - tok[0] = '\0'; /* terminate here already */ - tok++; - } - tok++; /* this is where the next line starts */ - - if ((where[0] >= '0') && (where[0] <= '9') && - ((msg = strchr (where, ':')) != NULL)) - { - /* Skip everything which starts with # or with no digit */ - /* Entries look like "1.2:This is a message" */ - - msg[0] = '\0'; /* remove : */ - msg++; /* go past the : */ - - if ((key = strchr (where, '.')) != NULL) - { - key[0] = '\0'; /* turn . into terminator */ - key++; /* go past the . */ - key1 = mystrtoul (where, 10, strlen (where)); - key2 = mystrtoul (key, 10, strlen (key)); - - if ((key1 >= 0) && (key2 >= 0)) - { - catpoints[i].key1 = key1; - catpoints[i].key2 = key2; - catpoints[i].text = processEscChars (msg); - if (catpoints[i].text == NULL) /* ESC parse error */ - catpoints[i].text = msg; - i++; /* next entry! */ - } /* valid keys */ - - } /* . found */ - - } /* : and digit found */ - - where = tok; /* go to next line */ + if (tok == NULL) { /* done? */ + close(file); + return 1; /* success */ + } + tok[0] = '\0'; /* terminate here */ + tok--; /* guess: \r before \n */ + if (tok[0] != '\r') + tok++; /* if not, go back */ + else { + tok[0] = '\0'; /* terminate here already */ + tok++; } - while (1); -#ifdef __PACIFIC__ - return 0; -#endif + tok++; /* this is where the next line starts */ + + if ( (where[0] >= '0') && (where[0] <= '9') && + ( (msg = strchr(where,':')) != NULL) ) { + /* Skip everything which starts with # or with no digit */ + /* Entries look like "1.2:This is a message" */ + + msg[0] = '\0'; /* remove : */ + msg++; /* go past the : */ + + if ((key = strchr (where, '.')) != NULL) { + key[0] = '\0'; /* turn . into terminator */ + key++; /* go past the . */ + key1 = mystrtoul(where, 10, strlen(where)); + key2 = mystrtoul(key, 10, strlen(key)); + + if ((key1 >= 0) && (key2 >= 0)) { + catpoints[i].key1 = key1; + catpoints[i].key2 = key2; + catpoints[i].text = processEscChars(msg); + if (catpoints[i].text == NULL) /* ESC parse error */ + catpoints[i].text = msg; + i++; /* next entry! */ + } /* valid keys */ + + } /* . found */ + + } /* : and digit found */ + + where = tok; /* go to next line */ + + } while (1); } -void -kittenclose (void) +void kittenclose (void) { /* close a message _kitten_catalog */ _kitten_catalog = 0; @@ -464,46 +386,33 @@ kittenclose (void) * chars of the string are parsed. */ -int -mystrtoul (char *src, int base, int size) +int mystrtoul(char *src, int base, int size) { -#ifdef _MICROC_ - int ret; - int digit; - int ch; - ret = 0; -#else - int ret = 0; -#endif - - for (; size > 0; size--) - { -#ifdef _MICROC_ - ch = *src; -#else - int digit; - int ch = *src; -#endif - src++; - - if (ch >= '0' && ch <= '9') - digit = ch - '0'; - else if (ch >= 'A' && ch <= 'Z') - digit = ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'z') - digit = ch - 'a' + 10; - else - return -1; - - if (digit >= base) - return -1; - - ret = ret * base + digit; - } /* for */ - - return ret; -} - + int ret = 0; + + for (; size > 0; size--) { + int digit; + int ch = *src; + src++; + + if (ch >= '0' && ch <= '9') + digit = ch - '0'; + else if (ch >= 'A' && ch <= 'Z') + digit = ch - 'A' + 10; + else if (ch >= 'a' && ch <= 'z') + digit = ch - 'a' + 10; + else + return -1; + + if (digit >= base) + return -1; + + ret = ret * base + digit; + } /* for */ + + return ret; +} + /** * Process strings, converting \n, \t, \v, \b, \r, \f, \\, @@ -514,118 +423,95 @@ mystrtoul (char *src, int base, int size) * Returns a pointer to input string. */ -char * -processEscChars (char *line) +char *processEscChars(char *line) { + char *src = line; + char *dst = line; /* possible as dst is shorter than src */ + /* used when converting \xdd and \ddd (hex or octal) characters */ char ch; -#ifdef _MICROC_ - char *src; - char *dst; - int chx; - src = line; - dst = line; -#else - char *src = line; - char *dst = line; /* possible as dst is shorter than src */ -#endif if (line == NULL) return line; /* cycle through copying characters, except when a \ is encountered. */ - while (*src != '\0') - { - ch = *src; + while (*src != '\0') { + ch = *src; + src++; + + if (ch == '\\') { + ch = *src; /* what follows slash? */ src++; - if (ch == '\\') - { - ch = *src; /* what follows slash? */ - src++; - - switch (ch) - { - case '\\': /* a single slash */ - *dst = '\\'; - dst++; - break; - case 'n': /* a newline (linefeed) */ - *dst = '\n'; - dst++; - break; - case 'r': /* a carriage return */ - *dst = '\r'; - dst++; - break; - case 't': /* a horizontal tab */ - *dst = '\t'; - dst++; - break; - case 'v': /* a vertical tab */ - *dst = '\v'; - dst++; - break; - case 'b': /* a backspace */ - *dst = '\b'; - dst++; - break; - case 'a': /* alert */ - *dst = '\a'; - dst++; - break; - case 'f': /* formfeed */ - *dst = '\f'; - dst++; - break; - case 'x': /* extension supporting hex numbers \xdd or \x0dd */ - { -#ifdef _MICROC_ - chx = mystrtoul (src, 16, 2); /* get value */ -#else - int chx = mystrtoul (src, 16, 2); /* get value */ -#endif - if (chx >= 0) - { /* store character */ - *dst = chx; - dst++; - src += 2; - } - else /* error so just store x (loose slash) */ - { - *dst = *src; - dst++; - } - } - break; - default: /* just store letter (loose slash) or handle octal */ - { -#ifdef _MICROC_ - chx = mystrtoul (src, 8, 3); /* get value */ -#else - int chx = mystrtoul (src, 8, 3); /* get value */ -#endif - if (chx >= 0) - { /* store character */ - *dst = chx; - dst++; - src += 3; - } - else - { - *dst = *src; - dst++; - } - } - break; - } /* switch */ - } /* if backslash */ - else - { - *dst = ch; + switch (ch) { + case '\\': /* a single slash */ + *dst = '\\'; + dst++; + break; + case 'n': /* a newline (linefeed) */ + *dst = '\n'; + dst++; + break; + case 'r': /* a carriage return */ + *dst = '\r'; dst++; - } - } /* while */ + break; + case 't': /* a horizontal tab */ + *dst = '\t'; + dst++; + break; + case 'v': /* a vertical tab */ + *dst = '\v'; + dst++; + break; + case 'b': /* a backspace */ + *dst = '\b'; + dst++; + break; + case 'a': /* alert */ + *dst = '\a'; + dst++; + break; + case 'f': /* formfeed */ + *dst = '\f'; + dst++; + break; + case 'x': /* extension supporting hex numbers \xdd or \x0dd */ + { + int chx = mystrtoul(src, 16, 2); /* get value */ + if (chx >= 0) { /* store character */ + *dst = chx; + dst++; + src += 2; + } else /* error so just store x (loose slash) */ + { + *dst = *src; + dst++; + } + } + break; + default: /* just store letter (loose slash) or handle octal */ + { + int chx = mystrtoul(src, 8, 3); /* get value */ + if (chx >= 0) {/* store character */ + *dst = chx; + dst++; + src += 3; + } else + { + *dst = *src; + dst++; + } + } + break; + } /* switch */ + } /* if backslash */ + else + { + *dst = ch; + dst++; + } + } /* while */ /* ensure '\0' terminated */ *dst = '\0'; @@ -634,30 +520,21 @@ processEscChars (char *line) } -int -get_char (int file) -{ -#ifdef _MICROC_ - int rval; - rval = -1; -#else +int get_char(int file) { int rval = -1; -#endif - if (getlrem <= 0) - { /* (re)init buffer */ - getlrem = read (file, getlbuf, sizeof (getlbuf)); - if (getlrem <= 0) - return -1; /* fail: read error / EOF */ - getlp = getlbuf; /* init pointer */ - } + if (getlrem <= 0) { /* (re)init buffer */ + getlrem = read(file, getlbuf, sizeof(getlbuf)); + if (getlrem <= 0) + return -1; /* fail: read error / EOF */ + getlp = getlbuf; /* init pointer */ + } - if (getlrem > 0) - { /* consume byte from buffer */ - rval = getlp[0]; - getlp++; - getlrem--; - } + if (getlrem > 0) { /* consume byte from buffer */ + rval = getlp[0]; + getlp++; + getlrem--; + } return rval; } @@ -670,53 +547,85 @@ get_char (int file) * be used for 2 files at the same time. */ -int -get_line (int file, char *str, int size) +int get_line (int file, char *orig_str, int size) { int ch; -#ifdef _MICROC_ - int success; - success = 0; -#else - int success = 0; -#endif + char *str = orig_str; - if ((size == 0) || (str == NULL)) - { /* re-init get_line buffers */ - getlp = getlbuf; - getlrem = -1; - lastcr = 0; - return 0; - } + if ((size == 0) || (str == NULL)) { /* re-init get_line buffers */ + getlp = getlbuf; + getlrem = -1; + return 0; + } str[0] = '\0'; - while ((size > 0) && (success == 0)) - { - ch = get_char (file); - if (ch < 0) - break; /* (can cause fail if no \n found yet) */ + while (size > 0) { + ch = get_char (file); + if (ch < 0) { + /* encountered EOF / read error, so no more content*/ + str[0] = '\0'; + + /* test if the pointers are equal, there is not content in the buffer */ + if(str == orig_str) + return 0; /* fail, no more content */ + + return 1; /* success */ + } - if (ch == '\r') - ch = get_char (file); /* ignore \r */ + if (ch == '\r') + ch = get_char (file); /* ignore \r */ - str[0] = ch; + str[0] = ch; - if ((ch == '\n') || (ch == '\r')) - { /* done? */ - str[0] = '\0'; - return 1; /* success */ - } + if ( (ch == '\n') || (ch == '\r') || (ch < 0) ) { /* done? */ + str[0] = '\0'; + return 1; /* success */ + } - str++; - size--; + str++; + size--; - } /* while */ + } /* while */ - str[0] = '\0'; /* terminate buffer */ + str[0] = '\0'; /* terminate buffer */ - return success; + return 0; /* fail, because the line is longer than the buffer? */ } -#endif /*NO_KITTEN */ +/* + * input + * s : input string to be parsed + * delimiters : start, intermediate and end + * responses : output buffer (has to be long enough for num chars) + * num : required number of responses + * + * return + * 0 on failure + * 1 on success + */ +int kitten_extract_response(const char *s, const char *delimiters, + char *responses, int num) { + int slen = strlen(s); + const char *p, *q; + int i; + + /* Response parsing requires substring usually of the form '(%c/%c)' */ + p = strchr(s, delimiters[0]); + if (!p) + return 0; + + /* Each response requires letter followed by a delimiter e.g. 'Y/' or 'N)' */ + if (p + 1 - s > slen - 2 * num) + return 0; + + for (i = 0; i < num; i++) { + q = p + 2 + i * 2; + if (*q != delimiters[1] && *q != delimiters[2]) + return 0; + responses[i] = *(p + 1 + i * 2); + } + + return 1; +} |
