summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c
diff options
context:
space:
mode:
authormaja <maja@openbsd.org>2000-03-25 18:16:41 +0000
committermaja <maja@openbsd.org>2000-03-25 18:16:41 +0000
commit05e9de5ac11bf4eb5b700d64593e66bf62b6167f (patch)
tree4b0f8191aef831df789ac65b9bfac3d70d0ffbdd /gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c
parentif_gm attaches on pci, not macobio. (diff)
downloadwireguard-openbsd-05e9de5ac11bf4eb5b700d64593e66bf62b6167f.tar.xz
wireguard-openbsd-05e9de5ac11bf4eb5b700d64593e66bf62b6167f.zip
Upgrade to Lynx 2.8.2. -moj
Diffstat (limited to 'gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c')
-rw-r--r--gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c578
1 files changed, 563 insertions, 15 deletions
diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c
index 5f358b9775f..90b6665bb3e 100644
--- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c
+++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTString.c
@@ -5,15 +5,13 @@
** 02-Dec-91 (JFG) Added stralloccopy and stralloccat
** 23 Jan 92 (TBL) Changed strallocc* to 8 char HTSAC* for VM and suchlike
** 6 Oct 92 (TBL) Moved WWW_TraceFlag in here to be in library
+** 15 Nov 98 (TD) Added HTSprintf.
*/
-#include <ctype.h>
-#include "HTUtils.h"
-#include "tcp.h"
-#include "LYLeaks.h"
-#include "LYStrings.h"
+#include <HTUtils.h>
-#define FREE(x) if (x) {free(x); x = NULL;}
+#include <LYLeaks.h>
+#include <LYStrings.h>
PUBLIC int WWW_TraceFlag = 0; /* Global trace flag for ALL W3 code */
@@ -124,18 +122,81 @@ PUBLIC int strncasecomp ARGS3(
}
#endif /* VM */
+#ifdef NOT_ASCII
+
+/* Case-insensitive with ASCII collating sequence
+** ----------------
+*/
+PUBLIC int AS_casecomp ARGS2(
+ CONST char*, p,
+ CONST char*, q)
+{
+ int diff;
+
+ for ( ; ; p++, q++) {
+ if (!(*p && *q))
+ return ((unsigned char) *p - (unsigned char) *q);
+ diff = TOASCII(TOLOWER(*p))
+ - TOASCII(TOLOWER(*q));
+ if (diff)
+ return diff;
+ }
+ /*NOTREACHED*/
+}
+
+
+/* With count limit and ASCII collating sequence
+** ----------------
+** AS_cmp uses n == -1 to compare indefinite length.
+*/
+PUBLIC int AS_ncmp ARGS3(
+ CONST char *, p,
+ CONST char *, q,
+ unsigned int, n)
+{
+ CONST char *a = p;
+ int diff;
+
+ for ( ; (p-a) < n; p++, q++) {
+ if (!(*p && *q))
+ return ((unsigned char) *p - (unsigned char) *q);
+ diff = TOASCII(*p)
+ - TOASCII(*q);
+ if (diff)
+ return diff;
+ }
+ return 0; /* Match up to n characters */
+}
+
+
+/* With ASCII collating sequence
+** ----------------
+*/
+PUBLIC int AS_cmp ARGS2(
+ CONST char *, p,
+ CONST char *, q)
+{
+ return( AS_ncmp( p, q, -1 ) );
+}
+#endif /* NOT_ASCII */
+
+
/* Allocate a new copy of a string, and returns it
*/
PUBLIC char * HTSACopy ARGS2(
char **, dest,
CONST char *, src)
{
- FREE(*dest);
- if (src) {
- *dest = (char *) malloc (strlen(src) + 1);
- if (*dest == NULL)
- outofmem(__FILE__, "HTSACopy");
- strcpy (*dest, src);
+ if (src != 0) {
+ if (src != *dest) {
+ FREE(*dest);
+ *dest = (char *) malloc (strlen(src) + 1);
+ if (*dest == NULL)
+ outofmem(__FILE__, "HTSACopy");
+ strcpy (*dest, src);
+ }
+ } else {
+ FREE(*dest);
}
return *dest;
}
@@ -146,7 +207,7 @@ PUBLIC char * HTSACat ARGS2(
char **, dest,
CONST char *, src)
{
- if (src && *src) {
+ if (src && *src && (src != *dest)) {
if (*dest) {
int length = strlen(*dest);
*dest = (char *)realloc(*dest, length + strlen(src) + 1);
@@ -235,8 +296,8 @@ PUBLIC char * HTNextField ARGS1(
*/
PUBLIC char * HTNextTok ARGS4(
char **, pstr,
- const char *, delims,
- const char *, bracks,
+ CONST char *, delims,
+ CONST char *, bracks,
char *, found)
{
char * p = *pstr;
@@ -342,3 +403,490 @@ PUBLIC char * HTNextTok ARGS4(
*pstr = p;
return start;
}
+
+PRIVATE char *HTAlloc ARGS2(char *, ptr, size_t, length)
+{
+ if (ptr != 0)
+ ptr = (char *)realloc(ptr, length);
+ else
+ ptr = (char *)malloc(length);
+ if (ptr == 0)
+ outofmem(__FILE__, "HTAlloc");
+ return ptr;
+}
+
+/*
+ * Replacement for sprintf, allocates buffer on the fly according to what's needed
+ * for its arguments. Unlike sprintf, this always concatenates to the destination
+ * buffer, so we do not have to provide both flavors.
+ */
+typedef enum { Flags, Width, Prec, Type, Format } PRINTF;
+
+#define VA_INTGR(type) ival = va_arg((*ap), type)
+#define VA_FLOAT(type) fval = va_arg((*ap), type)
+#define VA_POINT(type) pval = (void *)va_arg((*ap), type)
+
+#define NUM_WIDTH 10 /* allow for width substituted for "*" in "%*s" */
+ /* also number of chars assumed to be needed in addition
+ to a given precision in floating point formats */
+
+#define GROW_EXPR(n) (((n) * 3) / 2)
+#define GROW_SIZE 256
+
+PRIVATE char * StrAllocVsprintf ARGS4(
+ char **, pstr,
+ size_t, dst_len,
+ CONST char *, fmt,
+ va_list *, ap)
+{
+ size_t tmp_len = GROW_SIZE;
+ size_t have, need;
+ char *tmp_ptr = 0;
+ char *fmt_ptr;
+ char *dst_ptr = *pstr;
+ CONST char *format = fmt;
+
+ if (fmt == 0 || *fmt == '\0')
+ return 0;
+
+ need = strlen(fmt) + 1;
+ if ((fmt_ptr = malloc(need*NUM_WIDTH)) == 0
+ || (tmp_ptr = malloc(tmp_len)) == 0) {
+ outofmem(__FILE__, "StrAllocVsprintf");
+ }
+
+ if (dst_ptr == 0) {
+ dst_ptr = HTAlloc(dst_ptr, have = GROW_SIZE + need);
+ } else {
+ have = strlen(dst_ptr) + 1;
+ need += dst_len;
+ if (have < need)
+ dst_ptr = HTAlloc(dst_ptr, have = GROW_SIZE + need);
+ }
+
+ while (*fmt != '\0') {
+ if (*fmt == '%') {
+ static char dummy[] = "";
+ PRINTF state = Flags;
+ char *pval = dummy; /* avoid const-cast */
+ double fval = 0.0;
+ int done = FALSE;
+ int ival = 0;
+ int prec = -1;
+ int type = 0;
+ int used = 0;
+ int width = -1;
+ size_t f = 0;
+
+ fmt_ptr[f++] = *fmt;
+ while (*++fmt != '\0' && !done) {
+ fmt_ptr[f++] = *fmt;
+
+ if (isdigit(*fmt)) {
+ int num = *fmt - '0';
+ if (state == Flags && num != 0)
+ state = Width;
+ if (state == Width) {
+ if (width < 0)
+ width = 0;
+ width = (width * 10) + num;
+ } else if (state == Prec) {
+ if (prec < 0)
+ prec = 0;
+ prec = (prec * 10) + num;
+ }
+ } else if (*fmt == '*') {
+ VA_INTGR(int);
+ if (state == Flags)
+ state = Width;
+ if (state == Width) {
+ width = ival;
+ } else if (state == Prec) {
+ prec = ival;
+ }
+ sprintf(&fmt_ptr[--f], "%d", ival);
+ f = strlen(fmt_ptr);
+ } else if (isalpha(*fmt)) {
+ done = TRUE;
+ switch (*fmt) {
+ case 'Z': /* FALLTHRU */
+ case 'h': /* FALLTHRU */
+ case 'l': /* FALLTHRU */
+ case 'L': /* FALLTHRU */
+ done = FALSE;
+ type = *fmt;
+ break;
+ case 'o': /* FALLTHRU */
+ case 'i': /* FALLTHRU */
+ case 'd': /* FALLTHRU */
+ case 'u': /* FALLTHRU */
+ case 'x': /* FALLTHRU */
+ case 'X': /* FALLTHRU */
+ if (type == 'l')
+ VA_INTGR(long);
+ else if (type == 'Z')
+ VA_INTGR(size_t);
+ else
+ VA_INTGR(int);
+ used = 'i';
+ break;
+ case 'f': /* FALLTHRU */
+ case 'e': /* FALLTHRU */
+ case 'E': /* FALLTHRU */
+ case 'g': /* FALLTHRU */
+ case 'G': /* FALLTHRU */
+#if 0 /* we don't need this, it doesn't work on SunOS 4.x */
+ if (type == 'L')
+ VA_FLOAT(long double);
+ else
+#endif
+ VA_FLOAT(double);
+ used = 'f';
+ break;
+ case 'c':
+ VA_INTGR(int);
+ used = 'c';
+ break;
+ case 's':
+ VA_POINT(char *);
+ if (prec < 0)
+ prec = strlen(pval);
+ used = 's';
+ break;
+ case 'p':
+ VA_POINT(void *);
+ used = 'p';
+ break;
+ case 'n':
+ VA_POINT(int *);
+ used = 0;
+ break;
+ default:
+ CTRACE(tfp, "unknown format character '%c' in %s\n",
+ *fmt, format);
+ break;
+ }
+ } else if (*fmt == '.') {
+ state = Prec;
+ } else if (*fmt == '%') {
+ done = TRUE;
+ used = '%';
+ }
+ }
+ fmt_ptr[f] = '\0';
+
+ if (prec > 0) {
+ switch (used) {
+ case 'f':
+ if (width < prec + NUM_WIDTH)
+ width = prec + NUM_WIDTH;
+ case 'i':
+ case 'p':
+ if (width < prec + 2)
+ width = prec + 2; /* leading sign/space/zero, "0x" */
+ case 'c':
+ case '%':
+ break;
+ default:
+ if (width < prec)
+ width = prec;
+ }
+ }
+ if (width >= (int)tmp_len) {
+ tmp_len = GROW_EXPR(tmp_len + width);
+ tmp_ptr = HTAlloc(tmp_ptr, tmp_len);
+ }
+
+ switch (used) {
+ case 'i':
+ case 'c':
+ sprintf(tmp_ptr, fmt_ptr, ival);
+ break;
+ case 'f':
+ sprintf(tmp_ptr, fmt_ptr, fval);
+ break;
+ default:
+ sprintf(tmp_ptr, fmt_ptr, pval);
+ break;
+ }
+ need = dst_len + strlen(tmp_ptr) + 1;
+ if (need >= have) {
+ dst_ptr = HTAlloc(dst_ptr, have = GROW_EXPR(need));
+ }
+ strcpy(dst_ptr + dst_len, tmp_ptr);
+ dst_len += strlen(tmp_ptr);
+ } else {
+ if ((dst_len + 2) >= have) {
+ dst_ptr = HTAlloc(dst_ptr, (have += GROW_SIZE));
+ }
+ dst_ptr[dst_len++] = *fmt++;
+ }
+ }
+
+ FREE(tmp_ptr);
+ FREE(fmt_ptr);
+ dst_ptr[dst_len] = '\0';
+ if (pstr)
+ *pstr = dst_ptr;
+ return (dst_ptr);
+}
+
+/*
+ * Replacement for sprintf, allocates buffer on the fly according to what's needed
+ * for its arguments. Unlike sprintf, this always concatenates to the destination
+ * buffer.
+ */
+#if ANSI_VARARGS
+PUBLIC char * HTSprintf (char ** pstr, CONST char * fmt, ...)
+#else
+PUBLIC char * HTSprintf (va_alist)
+ va_dcl
+#endif
+{
+ char *result = 0;
+ size_t inuse = 0;
+ va_list ap;
+
+ LYva_start(ap,fmt);
+ {
+#if !ANSI_VARARGS
+ char ** pstr = va_arg(ap, char **);
+ CONST char * fmt = va_arg(ap, CONST char *);
+#endif
+ if (pstr != 0 && *pstr != 0)
+ inuse = strlen(*pstr);
+ result = StrAllocVsprintf(pstr, inuse, fmt, &ap);
+ }
+ va_end(ap);
+
+ return (result);
+}
+
+/*
+ * Replacement for sprintf, allocates buffer on the fly according to what's
+ * needed for its arguments. Like sprintf, this always resets the destination
+ * buffer.
+ */
+#if ANSI_VARARGS
+PUBLIC char * HTSprintf0 (char ** pstr, CONST char * fmt, ...)
+#else
+PUBLIC char * HTSprintf0 (va_alist)
+ va_dcl
+#endif
+{
+ char *result = 0;
+ va_list ap;
+
+ LYva_start(ap,fmt);
+ {
+#if !ANSI_VARARGS
+ char ** pstr = va_arg(ap, char **);
+ CONST char * fmt = va_arg(ap, CONST char *);
+#endif
+ result = StrAllocVsprintf(pstr, 0, fmt, &ap);
+ }
+ va_end(ap);
+
+ return (result);
+}
+
+/*
+ * Returns a quoted or escaped form of the given parameter, suitable for use in
+ * a command string.
+ */
+#if USE_QUOTED_PARAMETER
+#define S_QUOTE '\''
+#define D_QUOTE '"'
+PUBLIC char *HTQuoteParameter ARGS1(
+ CONST char *, parameter)
+{
+ size_t i;
+ size_t last = strlen(parameter);
+ size_t n = 0;
+ size_t quoted = 0;
+ char * result;
+
+ for (i=0; i < last; ++i)
+ if (strchr("\\&#$^*?(){}<>\"';`|", parameter[i]) != 0
+ || isspace(parameter[i]))
+ ++quoted;
+
+ result = (char *)malloc(last + 5*quoted + 3);
+ if (result == NULL)
+ outofmem(__FILE__, "HTQuoteParameter");
+
+ n = 0;
+ if (quoted)
+ result[n++] = S_QUOTE;
+ for (i = 0; i < last; i++) {
+ if (parameter[i] == S_QUOTE) {
+ result[n++] = S_QUOTE;
+ result[n++] = D_QUOTE;
+ result[n++] = parameter[i];
+ result[n++] = D_QUOTE;
+ result[n++] = S_QUOTE;
+ } else if (parameter[i] == '\\') {
+ result[n++] = parameter[i];
+ result[n++] = parameter[i];
+ } else {
+ result[n++] = parameter[i];
+ }
+ }
+ if (quoted)
+ result[n++] = S_QUOTE;
+ result[n] = '\0';
+ return result;
+}
+#endif
+
+#define HTIsParam(string) ((string[0] == '%' && string[1] == 's'))
+
+/*
+ * Returns the number of "%s" tokens in a system command-template.
+ */
+PUBLIC int HTCountCommandArgs ARGS1(
+ CONST char *, command)
+{
+ int number = 0;
+ while (command[0] != 0) {
+ if (HTIsParam(command))
+ number++;
+ command++;
+ }
+ return number;
+}
+
+/*
+ * Returns a pointer into the given string after the given parameter number
+ */
+PRIVATE CONST char *HTAfterCommandArg ARGS2(
+ CONST char *, command,
+ int, number)
+{
+ while (number > 0) {
+ if (command[0] != 0) {
+ if (HTIsParam(command)) {
+ number--;
+ command++;
+ }
+ command++;
+ } else {
+ break;
+ }
+ }
+ return command;
+}
+
+/*
+ * Like HTAddParam, but the parameter may be an environment variable, which we
+ * will expand and append. Do this only for things like the command-verb,
+ * where we obtain the parameter from the user's configuration. Any quoting
+ * required for the environment variable has to be done within its value, e.g.,
+ *
+ * setenv EDITOR 'xvile -name "No such class"'
+ *
+ * This is useful only when we quote parameters, of course.
+ */
+#if USE_QUOTED_PARAMETER
+PUBLIC void HTAddXpand ARGS4(
+ char **, result,
+ CONST char *, command,
+ int, number,
+ CONST char *, parameter)
+{
+ if (number > 0) {
+ CONST char *last = HTAfterCommandArg(command, number - 1);
+ CONST char *next = last;
+
+ if (number <= 1) {
+ FREE(*result);
+ }
+
+ while (next[0] != 0) {
+ if (HTIsParam(next)) {
+ if (next != last) {
+ size_t len = (next - last)
+ + ((*result != 0) ? strlen(*result) : 0);
+ HTSACat(result, last);
+ (*result)[len] = 0;
+ }
+ HTSACat(result, parameter);
+ CTRACE(tfp, "PARAM-EXP:%s\n", *result);
+ return;
+ }
+ next++;
+ }
+ }
+}
+#endif /* USE_QUOTED_PARAMETER */
+
+/*
+ * Append string-parameter to a system command that we are constructing. The
+ * string is a complete parameter (which is a necessary assumption so we can
+ * quote it properly). We're given the index of the newest parameter we're
+ * processing. Zero indicates none, so a value of '1' indicates that we copy
+ * from the beginning of the command string up to the first parameter,
+ * substitute the quoted parameter and return the result.
+ *
+ * Parameters are substituted at "%s" tokens, like printf. Other printf-style
+ * tokens are not substituted; they are passed through without change.
+ */
+PUBLIC void HTAddParam ARGS4(
+ char **, result,
+ CONST char *, command,
+ int, number,
+ CONST char *, parameter)
+{
+ if (number > 0) {
+ CONST char *last = HTAfterCommandArg(command, number - 1);
+ CONST char *next = last;
+ char *quoted;
+
+ if (number <= 1) {
+ FREE(*result);
+ }
+ if (parameter == 0)
+ parameter = "";
+ while (next[0] != 0) {
+ if (HTIsParam(next)) {
+ if (next != last) {
+ size_t len = (next - last)
+ + ((*result != 0) ? strlen(*result) : 0);
+ HTSACat(result, last);
+ (*result)[len] = 0;
+ }
+#if USE_QUOTED_PARAMETER
+ quoted = HTQuoteParameter(parameter);
+ HTSACat(result, quoted);
+ FREE(quoted);
+#else
+ HTSACat(result, parameter);
+#endif
+ CTRACE(tfp, "PARAM-ADD:%s\n", *result);
+ return;
+ }
+ next++;
+ }
+ }
+}
+
+/*
+ * Append the remaining command-string to a system command (compare with
+ * HTAddParam). Any remaining "%s" tokens are copied as empty strings.
+ */
+PUBLIC void HTEndParam ARGS3(
+ char **, result,
+ CONST char *, command,
+ int, number)
+{
+ CONST char *last;
+ int count;
+ count = HTCountCommandArgs (command);
+ if (count < number)
+ number = count;
+ last = HTAfterCommandArg(command, number);
+ if (last[0] != 0) {
+ HTSACat(result, last);
+ }
+ CTRACE(tfp, "PARAM-END:%s\n", *result);
+}