summaryrefslogtreecommitdiffstats
path: root/nsprpub/lib/libc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /nsprpub/lib/libc
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'nsprpub/lib/libc')
-rw-r--r--nsprpub/lib/libc/Makefile.in24
-rw-r--r--nsprpub/lib/libc/README20
-rw-r--r--nsprpub/lib/libc/include/Makefile.in24
-rw-r--r--nsprpub/lib/libc/include/README7
-rw-r--r--nsprpub/lib/libc/include/plbase64.h76
-rw-r--r--nsprpub/lib/libc/include/plerror.h34
-rw-r--r--nsprpub/lib/libc/include/plgetopt.h125
-rw-r--r--nsprpub/lib/libc/include/plstr.h437
-rw-r--r--nsprpub/lib/libc/src/Makefile.in148
-rw-r--r--nsprpub/lib/libc/src/README20
-rw-r--r--nsprpub/lib/libc/src/base64.c416
-rw-r--r--nsprpub/lib/libc/src/plc.def72
-rw-r--r--nsprpub/lib/libc/src/plc.rc70
-rw-r--r--nsprpub/lib/libc/src/plerror.c44
-rw-r--r--nsprpub/lib/libc/src/plgetopt.c251
-rw-r--r--nsprpub/lib/libc/src/plvrsion.c100
-rw-r--r--nsprpub/lib/libc/src/strcase.c206
-rw-r--r--nsprpub/lib/libc/src/strcat.c54
-rw-r--r--nsprpub/lib/libc/src/strchr.c70
-rw-r--r--nsprpub/lib/libc/src/strcmp.c33
-rw-r--r--nsprpub/lib/libc/src/strcpy.c65
-rw-r--r--nsprpub/lib/libc/src/strdup.c59
-rw-r--r--nsprpub/lib/libc/src/strlen.c47
-rw-r--r--nsprpub/lib/libc/src/strpbrk.c79
-rw-r--r--nsprpub/lib/libc/src/strstr.c110
-rw-r--r--nsprpub/lib/libc/src/strtok.c59
26 files changed, 2650 insertions, 0 deletions
diff --git a/nsprpub/lib/libc/Makefile.in b/nsprpub/lib/libc/Makefile.in
new file mode 100644
index 0000000000..28027f9dd1
--- /dev/null
+++ b/nsprpub/lib/libc/Makefile.in
@@ -0,0 +1,24 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#! gmake
+
+MOD_DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+export NSPR20=1
+
+include $(topsrcdir)/config/config.mk
+
+DIRS = include src
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(TARGETS)
+
diff --git a/nsprpub/lib/libc/README b/nsprpub/lib/libc/README
new file mode 100644
index 0000000000..74f246907f
--- /dev/null
+++ b/nsprpub/lib/libc/README
@@ -0,0 +1,20 @@
+NSPR 2.0 libc functions
+-----------------------
+
+Last edited: AOF 04 March 1997
+
+This directory contains various libc-types of functions. All functions in
+this directory are platform independent, thread friendly (both safe and
+efficient). They are contributed from various sources, though the contri-
+butions are monitored by the NSPR group (mailto:freier).
+
+All API items exported by these functions will contain the same three
+character prefix, "PL_" (Portable Library). Internal function names
+that are not exported (static) are of little concern, though some caution
+must be used on those elements that are 'extern' but not really intended
+to be part of the API. Those should all have a prefix of "_PL_" (is that
+legal?).
+
+The responsibility for contributions in this area are distributed among
+all interested parties.
+
diff --git a/nsprpub/lib/libc/include/Makefile.in b/nsprpub/lib/libc/include/Makefile.in
new file mode 100644
index 0000000000..642e0a1842
--- /dev/null
+++ b/nsprpub/lib/libc/include/Makefile.in
@@ -0,0 +1,24 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#! gmake
+
+MOD_DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+include $(topsrcdir)/config/config.mk
+
+HEADERS = $(wildcard $(srcdir)/*.h)
+
+RELEASE_HEADERS = $(HEADERS)
+RELEASE_HEADERS_DEST = $(RELEASE_INCLUDE_DIR)
+
+include $(topsrcdir)/config/rules.mk
+
+export:: $(HEADERS)
+ $(INSTALL) -m 444 $(HEADERS) $(dist_includedir)
diff --git a/nsprpub/lib/libc/include/README b/nsprpub/lib/libc/include/README
new file mode 100644
index 0000000000..2b85218910
--- /dev/null
+++ b/nsprpub/lib/libc/include/README
@@ -0,0 +1,7 @@
+NSPR 2.0 libc functions
+-----------------------
+
+Last edited: AOF 04 March 1997
+
+This directory contains the API for various libc-types of functions.
+
diff --git a/nsprpub/lib/libc/include/plbase64.h b/nsprpub/lib/libc/include/plbase64.h
new file mode 100644
index 0000000000..8f2117cc29
--- /dev/null
+++ b/nsprpub/lib/libc/include/plbase64.h
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _plbase64_h
+#define _plbase64_h
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+/*
+ * PL_Base64Encode
+ *
+ * This routine encodes the data pointed to by the "src" parameter using the
+ * base64 algorithm, and returns a pointer to the result. If the "srclen"
+ * parameter is not zero, it specifies the length of the source data. If it
+ * is zero, the source data is assumed to be null-terminated, and PL_strlen
+ * is used to determine the source length. If the "dest" parameter is not
+ * null, it is assumed to point to a buffer of sufficient size (which may be
+ * calculated: ((srclen + 2)/3)*4) into which the encoded data is placed
+ * (without any termination). If the "dest" parameter is null, a buffer is
+ * allocated from the heap to hold the encoded data, and the result *will*
+ * be terminated with an extra null character. It is the caller's
+ * responsibility to free the result when it is allocated. A null is returned
+ * if the allocation fails.
+ *
+ * NOTE: when calculating ((srclen + 2)/3)*4), first ensure that
+ * srclen <= (PR_UINT32_MAX/4) * 3
+ * to avoid PRUint32 overflow.
+ */
+
+PR_EXTERN(char *)
+PL_Base64Encode
+(
+ const char *src,
+ PRUint32 srclen,
+ char *dest
+);
+
+/*
+ * PL_Base64Decode
+ *
+ * This routine decodes the data pointed to by the "src" parameter using
+ * the base64 algorithm, and returns a pointer to the result. The source
+ * may either include or exclude any trailing '=' characters. If the
+ * "srclen" parameter is not zero, it specifies the length of the source
+ * data. If it is zero, PL_strlen will be used to determine the source
+ * length. If the "dest" parameter is not null, it is assumed to point to
+ * a buffer of sufficient size (which may be calculated: (srclen * 3)/4
+ * when srclen includes the '=' characters) into which the decoded data
+ * is placed (without any termination). If the "dest" parameter is null,
+ * a buffer is allocated from the heap to hold the decoded data, and the
+ * result *will* be terminated with an extra null character. It is the
+ * caller's responsibility to free the result when it is allocated. A null
+ * is retuned if the allocation fails, or if the source is not well-coded.
+ *
+ * NOTE: when calculating (srclen * 3)/4, first ensure that
+ * srclen <= PR_UINT32_MAX/3
+ * to avoid PRUint32 overflow. Alternatively, calculate
+ * (srclen/4) * 3 + ((srclen%4) * 3)/4
+ * which is equivalent but doesn't overflow for any value of srclen.
+ */
+
+PR_EXTERN(char *)
+PL_Base64Decode
+(
+ const char *src,
+ PRUint32 srclen,
+ char *dest
+);
+
+PR_END_EXTERN_C
+
+#endif /* _plbase64_h */
diff --git a/nsprpub/lib/libc/include/plerror.h b/nsprpub/lib/libc/include/plerror.h
new file mode 100644
index 0000000000..cd85dd3f8a
--- /dev/null
+++ b/nsprpub/lib/libc/include/plerror.h
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** File: plerror.h
+** Description: Simple routine to print translate the calling thread's
+** error numbers and print them.
+*/
+
+#if defined(PLERROR_H)
+#else
+#define PLERROR_H
+
+#include "prio.h"
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+/*
+** Print the messages to "syserr" prepending 'msg' if not NULL.
+*/
+PR_EXTERN(void) PL_PrintError(const char *msg);
+
+/*
+** Print the messages to specified output file prepending 'msg' if not NULL.
+*/
+PR_EXTERN(void) PL_FPrintError(PRFileDesc *output, const char *msg);
+
+PR_END_EXTERN_C
+
+#endif /* defined(PLERROR_H) */
+
+/* plerror.h */
diff --git a/nsprpub/lib/libc/include/plgetopt.h b/nsprpub/lib/libc/include/plgetopt.h
new file mode 100644
index 0000000000..bd5181b1db
--- /dev/null
+++ b/nsprpub/lib/libc/include/plgetopt.h
@@ -0,0 +1,125 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** File: plgetopt.h
+** Description: utilities to parse argc/argv
+*/
+
+#if defined(PLGETOPT_H_)
+#else
+#define PLGETOPT_H_
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+
+typedef struct PLOptionInternal PLOptionInternal;
+
+typedef enum
+{
+ PL_OPT_OK, /* all's well with the option */
+ PL_OPT_EOL, /* end of options list */
+ PL_OPT_BAD /* invalid option (and value) */
+} PLOptStatus;
+
+typedef struct PLLongOpt
+{
+ const char * longOptName; /* long option name string */
+ PRIntn longOption; /* value put in PLOptState for this option. */
+ PRBool valueRequired; /* If option name not followed by '=', */
+ /* value is the next argument from argv. */
+} PLLongOpt;
+
+typedef struct PLOptState
+{
+ char option; /* the name of the option */
+ const char *value; /* the value of that option | NULL */
+
+ PLOptionInternal *internal; /* private processing state */
+
+ PRIntn longOption; /* value from PLLongOpt put here */
+ PRIntn longOptIndex; /* index into caller's array of PLLongOpts */
+} PLOptState;
+
+/*
+ * PL_CreateOptState
+ *
+ * The argument "options" points to a string of single-character option
+ * names. Option names that may have an option argument value must be
+ * followed immediately by a ':' character.
+ */
+PR_EXTERN(PLOptState*) PL_CreateOptState(
+ PRIntn argc, char **argv, const char *options);
+
+/*
+ * PL_CreateLongOptState
+ *
+ * Alternative to PL_CreateOptState.
+ * Allows caller to specify BOTH a string of single-character option names,
+ * AND an array of structures describing "long" (keyword) option names.
+ * The array is terminated by a structure in which longOptName is NULL.
+ * Long option values (arguments) may always be given as "--name=value".
+ * If PLLongOpt.valueRequired is not PR_FALSE, and the option name was not
+ * followed by '=' then the next argument from argv is taken as the value.
+ */
+PR_EXTERN(PLOptState*) PL_CreateLongOptState(
+ PRIntn argc, char **argv, const char *options,
+ const PLLongOpt *longOpts);
+/*
+ * PL_DestroyOptState
+ *
+ * Call this to destroy the PLOptState returned from PL_CreateOptState or
+ * PL_CreateLongOptState.
+ */
+PR_EXTERN(void) PL_DestroyOptState(PLOptState *opt);
+
+/*
+ * PL_GetNextOpt
+ *
+ * When this function returns PL_OPT_OK,
+ * - opt->option will hold the single-character option name that was parsed,
+ * or zero.
+ * When opt->option is zero, the token parsed was either a "long" (keyword)
+ * option or a positional parameter.
+ * For a positional parameter,
+ * - opt->longOptIndex will contain -1, and
+ * - opt->value will point to the positional parameter string.
+ * For a long option name,
+ * - opt->longOptIndex will contain the non-negative index of the
+ * PLLongOpt structure in the caller's array of PLLongOpt structures
+ * corresponding to the long option name, and
+ * For a single-character or long option,
+ * - opt->longOption will contain the value of the single-character option
+ * name, or the value of the longOption from the PLLongOpt structure
+ * for that long option. See notes below.
+ * - opt->value will point to the argument option string, or will
+ * be NULL if option does not require argument. If option requires
+ * argument but it is not provided, PL_OPT_BAD is returned.
+ * When opt->option is non-zero,
+ * - opt->longOptIndex will be -1
+ * When this function returns PL_OPT_EOL, or PL_OPT_BAD, the contents of
+ * opt are undefined.
+ *
+ * Notes: It is possible to ignore opt->option, and always look at
+ * opt->longOption instead. opt->longOption will contain the same value
+ * as opt->option for single-character option names, and will contain the
+ * value of longOption from the PLLongOpt structure for long option names.
+ * This means that it is possible to equivalence long option names to
+ * single character names by giving the longOption in the PLLongOpt struct
+ * the same value as the single-character option name.
+ * For long options that are NOT intended to be equivalent to any single-
+ * character option, the longOption value should be chosen to not match
+ * any possible single character name. It might be advisable to choose
+ * longOption values greater than 0xff for such long options.
+ */
+PR_EXTERN(PLOptStatus) PL_GetNextOpt(PLOptState *opt);
+
+PR_END_EXTERN_C
+
+#endif /* defined(PLGETOPT_H_) */
+
+/* plgetopt.h */
+
diff --git a/nsprpub/lib/libc/include/plstr.h b/nsprpub/lib/libc/include/plstr.h
new file mode 100644
index 0000000000..ea59832a35
--- /dev/null
+++ b/nsprpub/lib/libc/include/plstr.h
@@ -0,0 +1,437 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _plstr_h
+#define _plstr_h
+
+/*
+ * plstr.h
+ *
+ * This header file exports the API to the NSPR portable library or string-
+ * handling functions.
+ *
+ * This API was not designed as an "optimal" or "ideal" string library; it
+ * was based on the good ol' unix string.3 functions, and was written to
+ *
+ * 1) replace the libc functions, for cross-platform consistency,
+ * 2) complete the API on platforms lacking common functions (e.g.,
+ * strcase*), and
+ * 3) to implement some obvious "closure" functions that I've seen
+ * people hacking around in our code.
+ *
+ * Point number three largely means that most functions have an "strn"
+ * limited-length version, and all comparison routines have a non-case-
+ * sensitive version available.
+ */
+
+#include "prtypes.h"
+
+PR_BEGIN_EXTERN_C
+/*
+ * PL_strlen
+ *
+ * Returns the length of the provided string, not including the trailing '\0'.
+ */
+
+PR_EXTERN(PRUint32)
+PL_strlen(const char *str);
+
+/*
+ * PL_strnlen
+ *
+ * Returns the length of the provided string, not including the trailing '\0',
+ * up to the indicated maximum. The string will not be examined beyond the
+ * maximum; if no terminating '\0' is found, the maximum will be returned.
+ */
+
+PR_EXTERN(PRUint32)
+PL_strnlen(const char *str, PRUint32 max);
+
+/*
+ * PL_strcpy
+ *
+ * Copies the source string, up to and including the trailing '\0', into the
+ * destination buffer. It does not (can not) verify that the destination
+ * buffer is large enough. It returns the "dest" argument.
+ */
+
+PR_EXTERN(char *)
+PL_strcpy(char *dest, const char *src);
+
+/*
+ * PL_strncpy
+ *
+ * Copies the source string into the destination buffer, up to and including
+ * the trailing '\0' or up to and including the max'th character, whichever
+ * comes first. It does not (can not) verify that the destination buffer is
+ * large enough. If the source string is longer than the maximum length,
+ * the result will *not* be null-terminated (JLRU).
+ */
+
+PR_EXTERN(char *)
+PL_strncpy(char *dest, const char *src, PRUint32 max);
+
+/*
+ * PL_strncpyz
+ *
+ * Copies the source string into the destination buffer, up to and including
+ * the trailing '\0' or up but not including the max'th character, whichever
+ * comes first. It does not (can not) verify that the destination buffer is
+ * large enough. The destination string is always terminated with a '\0',
+ * unlike the traditional libc implementation. It returns the "dest" argument.
+ *
+ * NOTE: If you call this with a source "abcdefg" and a max of 5, the
+ * destination will end up with "abcd\0" (i.e., its strlen length will be 4)!
+ *
+ * This means you can do this:
+ *
+ * char buffer[ SOME_SIZE ];
+ * PL_strncpyz(buffer, src, sizeof(buffer));
+ *
+ * and the result will be properly terminated.
+ */
+
+PR_EXTERN(char *)
+PL_strncpyz(char *dest, const char *src, PRUint32 max);
+
+/*
+ * PL_strdup
+ *
+ * Returns a pointer to a malloc'd extent of memory containing a duplicate
+ * of the argument string. The size of the allocated extent is one greater
+ * than the length of the argument string, because of the terminator. A
+ * null argument, like a zero-length argument, will result in a pointer to
+ * a one-byte extent containing the null value. This routine returns null
+ * upon malloc failure.
+ */
+
+PR_EXTERN(char *)
+PL_strdup(const char *s);
+
+/*
+ * PL_strfree
+ *
+ * Free memory allocated by PL_strdup
+ */
+
+PR_EXTERN(void)
+PL_strfree(char *s);
+
+/*
+ * PL_strndup
+ *
+ * Returns a pointer to a malloc'd extent of memory containing a duplicate
+ * of the argument string, up to the maximum specified. If the argument
+ * string has a length greater than the value of the specified maximum, the
+ * return value will be a pointer to an extent of memory of length one
+ * greater than the maximum specified. A null string, a zero-length string,
+ * or a zero maximum will all result in a pointer to a one-byte extent
+ * containing the null value. This routine returns null upon malloc failure.
+ */
+
+PR_EXTERN(char *)
+PL_strndup(const char *s, PRUint32 max);
+
+/*
+ * PL_strcat
+ *
+ * Appends a copy of the string pointed to by the second argument to the
+ * end of the string pointed to by the first. The destination buffer is
+ * not (can not be) checked for sufficient size. A null destination
+ * argument returns null; otherwise, the first argument is returned.
+ */
+
+PR_EXTERN(char *)
+PL_strcat(char *dst, const char *src);
+
+/*
+ * PL_strncat
+ *
+ * Appends a copy of the string pointed to by the second argument, up to
+ * the maximum size specified, to the end of the string pointed to by the
+ * first. The destination buffer is not (can not be) checked for sufficient
+ * size. A null destination argument returns null; otherwise, the first
+ * argument is returned. If the maximum size limits the copy, then the
+ * result will *not* be null-terminated (JLRU). A null destination
+ * returns null; otherwise, the destination argument is returned.
+ */
+
+PR_EXTERN(char *)
+PL_strncat(char *dst, const char *src, PRUint32 max);
+
+/*
+ * PL_strcatn
+ *
+ * Appends a copy of the string pointed to by the third argument, to the
+ * end of the string pointed to by the first. The second argument specifies
+ * the maximum size of the destination buffer, including the null termination.
+ * If the existing string in dst is longer than the max, no action is taken.
+ * The resulting string will be null-terminated. A null destination returns
+ * null; otherwise, the destination argument is returned.
+ */
+
+PR_EXTERN(char *)
+PL_strcatn(char *dst, PRUint32 max, const char *src);
+
+/*
+ * PL_strcmp
+ *
+ * Returns an integer, the sign of which -- positive, zero, or negative --
+ * reflects the lexical sorting order of the two strings indicated. The
+ * result is positive if the first string comes after the second. The
+ * NSPR implementation is not i18n.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strcmp(const char *a, const char *b);
+
+/*
+ * PL_strncmp
+ *
+ * Returns an integer, the sign of which -- positive, zero, or negative --
+ * reflects the lexical sorting order of the two strings indicated, up to
+ * the maximum specified. The result is positive if the first string comes
+ * after the second. The NSPR implementation is not i18n. If the maximum
+ * is zero, only the existance or non-existance (pointer is null) of the
+ * strings is compared.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strncmp(const char *a, const char *b, PRUint32 max);
+
+/*
+ * PL_strcasecmp
+ *
+ * Returns an integer, the sign of which -- positive, zero or negative --
+ * reflects the case-insensitive lexical sorting order of the two strings
+ * indicated. The result is positive if the first string comes after the
+ * second. The NSPR implementation is not i18n.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strcasecmp(const char *a, const char *b);
+
+/*
+ * PL_strncasecmp
+ *
+ * Returns an integer, the sign of which -- positive, zero or negative --
+ * reflects the case-insensitive lexical sorting order of the first n characters
+ * of the two strings indicated. The result is positive if the first string comes
+ * after the second. The NSPR implementation is not i18n.
+ */
+
+PR_EXTERN(PRIntn)
+PL_strncasecmp(const char *a, const char *b, PRUint32 max);
+
+/*
+ * PL_strchr
+ *
+ * Returns a pointer to the first instance of the specified character in the
+ * provided string. It returns null if the character is not found, or if the
+ * provided string is null. The character may be the null character.
+ */
+
+PR_EXTERN(char *)
+PL_strchr(const char *s, char c);
+
+/*
+ * PL_strrchr
+ *
+ * Returns a pointer to the last instance of the specified character in the
+ * provided string. It returns null if the character is not found, or if the
+ * provided string is null. The character may be the null character.
+ */
+
+PR_EXTERN(char *)
+PL_strrchr(const char *s, char c);
+
+/*
+ * PL_strnchr
+ *
+ * Returns a pointer to the first instance of the specified character within the
+ * first n characters of the provided string. It returns null if the character
+ * is not found, or if the provided string is null. The character may be the
+ * null character.
+ */
+
+PR_EXTERN(char *)
+PL_strnchr(const char *s, char c, PRUint32 n);
+
+/*
+ * PL_strnrchr
+ *
+ * Returns a pointer to the last instance of the specified character within the
+ * first n characters of the provided string. It returns null if the character is
+ * not found, or if the provided string is null. The character may be the null
+ * character.
+ */
+
+PR_EXTERN(char *)
+PL_strnrchr(const char *s, char c, PRUint32 n);
+
+/*
+ * NOTE: Looking for strcasechr, strcaserchr, strncasechr, or strncaserchr?
+ * Use strpbrk, strprbrk, strnpbrk or strnprbrk.
+ */
+
+/*
+ * PL_strpbrk
+ *
+ * Returns a pointer to the first instance in the first string of any character
+ * (not including the terminating null character) of the second string. It returns
+ * null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strpbrk(const char *s, const char *list);
+
+/*
+ * PL_strprbrk
+ *
+ * Returns a pointer to the last instance in the first string of any character
+ * (not including the terminating null character) of the second string. It returns
+ * null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strprbrk(const char *s, const char *list);
+
+/*
+ * PL_strnpbrk
+ *
+ * Returns a pointer to the first instance (within the first n characters) of any
+ * character (not including the terminating null character) of the second string.
+ * It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strnpbrk(const char *s, const char *list, PRUint32 n);
+
+/*
+ * PL_strnprbrk
+ *
+ * Returns a pointer to the last instance (within the first n characters) of any
+ * character (not including the terminating null character) of the second string.
+ * It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strnprbrk(const char *s, const char *list, PRUint32 n);
+
+/*
+ * PL_strstr
+ *
+ * Returns a pointer to the first instance of the little string within the
+ * big one. It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strstr(const char *big, const char *little);
+
+/*
+ * PL_strrstr
+ *
+ * Returns a pointer to the last instance of the little string within the big one.
+ * It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strrstr(const char *big, const char *little);
+
+/*
+ * PL_strnstr
+ *
+ * Returns a pointer to the first instance of the little string within the first
+ * n characters of the big one. It returns null if either string is null. It
+ * returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strnstr(const char *big, const char *little, PRUint32 n);
+
+/*
+ * PL_strnrstr
+ *
+ * Returns a pointer to the last instance of the little string within the first
+ * n characters of the big one. It returns null if either string is null. It
+ * returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strnrstr(const char *big, const char *little, PRUint32 max);
+
+/*
+ * PL_strcasestr
+ *
+ * Returns a pointer to the first instance of the little string within the big one,
+ * ignoring case. It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strcasestr(const char *big, const char *little);
+
+/*
+ * PL_strcaserstr
+ *
+ * Returns a pointer to the last instance of the little string within the big one,
+ * ignoring case. It returns null if either string is null.
+ */
+
+PR_EXTERN(char *)
+PL_strcaserstr(const char *big, const char *little);
+
+/*
+ * PL_strncasestr
+ *
+ * Returns a pointer to the first instance of the little string within the first
+ * n characters of the big one, ignoring case. It returns null if either string is
+ * null. It returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strncasestr(const char *big, const char *little, PRUint32 max);
+
+/*
+ * PL_strncaserstr
+ *
+ * Returns a pointer to the last instance of the little string within the first
+ * n characters of the big one, ignoring case. It returns null if either string is
+ * null. It returns null if the length of the little string is greater than n.
+ */
+
+PR_EXTERN(char *)
+PL_strncaserstr(const char *big, const char *little, PRUint32 max);
+
+/*
+ * PL_strtok_r
+ *
+ * Splits the string s1 into tokens, separated by one or more characters
+ * from the separator string s2. The argument lasts points to a
+ * user-supplied char * pointer in which PL_strtok_r stores information
+ * for it to continue scanning the same string.
+ *
+ * In the first call to PL_strtok_r, s1 points to a string and the value
+ * of *lasts is ignored. PL_strtok_r returns a pointer to the first
+ * token, writes '\0' into the character following the first token, and
+ * updates *lasts.
+ *
+ * In subsequent calls, s1 is null and lasts must stay unchanged from the
+ * previous call. The separator string s2 may be different from call to
+ * call. PL_strtok_r returns a pointer to the next token in s1. When no
+ * token remains in s1, PL_strtok_r returns null.
+ */
+
+PR_EXTERN(char *)
+PL_strtok_r(char *s1, const char *s2, char **lasts);
+
+/*
+ * Things not (yet?) included: strspn/strcspn, strsep.
+ * memchr, memcmp, memcpy, memccpy, index, rindex, bcmp, bcopy, bzero.
+ * Any and all i18n/l10n stuff.
+ */
+
+PR_END_EXTERN_C
+
+#endif /* _plstr_h */
diff --git a/nsprpub/lib/libc/src/Makefile.in b/nsprpub/lib/libc/src/Makefile.in
new file mode 100644
index 0000000000..be488e956f
--- /dev/null
+++ b/nsprpub/lib/libc/src/Makefile.in
@@ -0,0 +1,148 @@
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#! gmake
+
+MOD_DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(MOD_DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/config.mk
+
+INCLUDES = -I$(dist_includedir)
+
+CSRCS =\
+ plvrsion.c \
+ strlen.c \
+ strcpy.c \
+ strdup.c \
+ strcase.c \
+ strcat.c \
+ strcmp.c \
+ strchr.c \
+ strpbrk.c \
+ strstr.c \
+ strtok.c \
+ base64.c \
+ plerror.c \
+ plgetopt.c \
+ $(NULL)
+
+LIBRARY_NAME = plc
+LIBRARY_VERSION = $(MOD_MAJOR_VERSION)
+
+RELEASE_LIBS = $(TARGETS)
+
+ifeq ($(OS_ARCH),WINNT)
+RES=$(OBJDIR)/plc.res
+RESNAME=plc.rc
+endif # WINNT
+
+ifeq ($(OS_ARCH), AIX)
+ifeq ($(CLASSIC_NSPR),1)
+OS_LIBS = -lc
+else
+OS_LIBS = -lc_r
+endif
+endif
+
+ifeq ($(OS_ARCH),SunOS)
+OS_LIBS = -lc
+MAPFILE = $(OBJDIR)/plcmap.sun
+GARBAGE += $(MAPFILE)
+ifdef NS_USE_GCC
+ifdef GCC_USE_GNU_LD
+MKSHLIB += -Wl,--version-script,$(MAPFILE)
+else
+MKSHLIB += -Wl,-M,$(MAPFILE)
+endif
+else
+MKSHLIB += -M $(MAPFILE)
+endif
+# The -R '$ORIGIN' linker option instructs this library to search for its
+# dependencies in the same directory where it resides.
+MKSHLIB += -R '$$ORIGIN'
+endif
+
+ifeq ($(OS_ARCH),OS2)
+MAPFILE = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).def
+GARBAGE += $(MAPFILE)
+MKSHLIB += $(MAPFILE)
+endif
+
+EXTRA_LIBS = $(LIBNSPR)
+
+# On SCOOS, we can't link with extra libraries when
+# we build a shared library. If we do so, the linker doesn't
+# complain, but we would run into weird problems at run-time.
+# Therefore on these platforms, we link just the .o files.
+ifeq ($(OS_ARCH),SCOOS)
+EXTRA_LIBS =
+endif
+
+ifdef RESOLVE_LINK_SYMBOLS
+EXTRA_LIBS += $(OS_LIBS)
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+#
+# Version information generation (begin)
+#
+ECHO = echo
+TINC = $(OBJDIR)/_pl_bld.h
+PROD = $(notdir $(SHARED_LIBRARY))
+NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
+SH_DATE = $(shell date "+%Y-%m-%d %T")
+SH_NOW = $(shell $(NOW))
+
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+ SUF = i64
+else
+ SUF = LL
+endif
+
+GARBAGE += $(TINC)
+
+$(TINC):
+ @$(MAKE_OBJDIR)
+ @$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
+ @if test ! -z "$(SH_NOW)"; then \
+ $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
+ else \
+ true; \
+ fi
+ @$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
+
+
+$(OBJDIR)/plvrsion.$(OBJ_SUFFIX): plvrsion.c $(TINC)
+ifeq ($(NS_USE_GCC)_$(OS_ARCH),_WINNT)
+ $(CC) -Fo$@ -c $(CFLAGS) -I$(OBJDIR) $<
+else
+ $(CC) -o $@ -c $(CFLAGS) -I$(OBJDIR) $<
+endif
+#
+# Version information generation (end)
+#
+
+#
+# The Client build wants the shared libraries in $(dist_bindir),
+# so we also install them there.
+#
+
+export:: $(TARGETS)
+ $(INSTALL) -m 444 $(TARGETS) $(dist_libdir)
+ifdef SHARED_LIBRARY
+ifeq ($(OS_ARCH),HP-UX)
+ $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_libdir)
+ $(INSTALL) -m 755 $(SHARED_LIBRARY) $(dist_bindir)
+else
+ $(INSTALL) -m 444 $(SHARED_LIBRARY) $(dist_bindir)
+endif
+endif
diff --git a/nsprpub/lib/libc/src/README b/nsprpub/lib/libc/src/README
new file mode 100644
index 0000000000..74f246907f
--- /dev/null
+++ b/nsprpub/lib/libc/src/README
@@ -0,0 +1,20 @@
+NSPR 2.0 libc functions
+-----------------------
+
+Last edited: AOF 04 March 1997
+
+This directory contains various libc-types of functions. All functions in
+this directory are platform independent, thread friendly (both safe and
+efficient). They are contributed from various sources, though the contri-
+butions are monitored by the NSPR group (mailto:freier).
+
+All API items exported by these functions will contain the same three
+character prefix, "PL_" (Portable Library). Internal function names
+that are not exported (static) are of little concern, though some caution
+must be used on those elements that are 'extern' but not really intended
+to be part of the API. Those should all have a prefix of "_PL_" (is that
+legal?).
+
+The responsibility for contributions in this area are distributed among
+all interested parties.
+
diff --git a/nsprpub/lib/libc/src/base64.c b/nsprpub/lib/libc/src/base64.c
new file mode 100644
index 0000000000..fc1cc51eb8
--- /dev/null
+++ b/nsprpub/lib/libc/src/base64.c
@@ -0,0 +1,416 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plbase64.h"
+#include "prlog.h" /* For PR_NOT_REACHED */
+#include "prmem.h" /* for malloc / PR_MALLOC */
+
+#include <string.h> /* for strlen */
+
+static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static void
+encode3to4
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ PRUint32 b32 = (PRUint32)0;
+ PRIntn i, j = 18;
+
+ for( i = 0; i < 3; i++ )
+ {
+ b32 <<= 8;
+ b32 |= (PRUint32)src[i];
+ }
+
+ for( i = 0; i < 4; i++ )
+ {
+ dest[i] = base[ (PRUint32)((b32>>j) & 0x3F) ];
+ j -= 6;
+ }
+
+ return;
+}
+
+static void
+encode2to4
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ];
+ dest[1] = base[ (PRUint32)(((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)) ];
+ dest[2] = base[ (PRUint32)((src[1] & 0x0F) << 2) ];
+ dest[3] = (unsigned char)'=';
+ return;
+}
+
+static void
+encode1to4
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ];
+ dest[1] = base[ (PRUint32)((src[0] & 0x03) << 4) ];
+ dest[2] = (unsigned char)'=';
+ dest[3] = (unsigned char)'=';
+ return;
+}
+
+static void
+encode
+(
+ const unsigned char *src,
+ PRUint32 srclen,
+ unsigned char *dest
+)
+{
+ while( srclen >= 3 )
+ {
+ encode3to4(src, dest);
+ src += 3;
+ dest += 4;
+ srclen -= 3;
+ }
+
+ switch( srclen )
+ {
+ case 2:
+ encode2to4(src, dest);
+ break;
+ case 1:
+ encode1to4(src, dest);
+ break;
+ case 0:
+ break;
+ default:
+ PR_NOT_REACHED("coding error");
+ }
+
+ return;
+}
+
+/*
+ * PL_Base64Encode
+ *
+ * If the destination argument is NULL, a return buffer is
+ * allocated, and the data therein will be null-terminated.
+ * If the destination argument is not NULL, it is assumed to
+ * be of sufficient size, and the contents will not be null-
+ * terminated by this routine.
+ *
+ * Returns null if the allocation fails.
+ */
+
+PR_IMPLEMENT(char *)
+PL_Base64Encode
+(
+ const char *src,
+ PRUint32 srclen,
+ char *dest
+)
+{
+ if( 0 == srclen )
+ {
+ size_t len = strlen(src);
+ srclen = len;
+ /* Detect truncation. */
+ if( srclen != len )
+ {
+ return (char *)0;
+ }
+ }
+
+ if( (char *)0 == dest )
+ {
+ PRUint32 destlen;
+ /* Ensure all PRUint32 values stay within range. */
+ if( srclen > (PR_UINT32_MAX/4) * 3 )
+ {
+ return (char *)0;
+ }
+ destlen = ((srclen + 2)/3) * 4;
+ dest = (char *)PR_MALLOC(destlen + 1);
+ if( (char *)0 == dest )
+ {
+ return (char *)0;
+ }
+ dest[ destlen ] = (char)0; /* null terminate */
+ }
+
+ encode((const unsigned char *)src, srclen, (unsigned char *)dest);
+ return dest;
+}
+
+static PRInt32
+codetovalue
+(
+ unsigned char c
+)
+{
+ if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') )
+ {
+ return (PRInt32)(c - (unsigned char)'A');
+ }
+ else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') )
+ {
+ return ((PRInt32)(c - (unsigned char)'a') +26);
+ }
+ else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') )
+ {
+ return ((PRInt32)(c - (unsigned char)'0') +52);
+ }
+ else if( (unsigned char)'+' == c )
+ {
+ return (PRInt32)62;
+ }
+ else if( (unsigned char)'/' == c )
+ {
+ return (PRInt32)63;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+static PRStatus
+decode4to3
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ PRUint32 b32 = (PRUint32)0;
+ PRInt32 bits;
+ PRIntn i;
+
+ for( i = 0; i < 4; i++ )
+ {
+ bits = codetovalue(src[i]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ b32 <<= 6;
+ b32 |= bits;
+ }
+
+ dest[0] = (unsigned char)((b32 >> 16) & 0xFF);
+ dest[1] = (unsigned char)((b32 >> 8) & 0xFF);
+ dest[2] = (unsigned char)((b32 ) & 0xFF);
+
+ return PR_SUCCESS;
+}
+
+static PRStatus
+decode3to2
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ PRUint32 b32 = (PRUint32)0;
+ PRInt32 bits;
+ PRUint32 ubits;
+
+ bits = codetovalue(src[0]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ b32 = (PRUint32)bits;
+ b32 <<= 6;
+
+ bits = codetovalue(src[1]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ b32 |= (PRUint32)bits;
+ b32 <<= 4;
+
+ bits = codetovalue(src[2]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ ubits = (PRUint32)bits;
+ b32 |= (ubits >> 2);
+
+ dest[0] = (unsigned char)((b32 >> 8) & 0xFF);
+ dest[1] = (unsigned char)((b32 ) & 0xFF);
+
+ return PR_SUCCESS;
+}
+
+static PRStatus
+decode2to1
+(
+ const unsigned char *src,
+ unsigned char *dest
+)
+{
+ PRUint32 b32;
+ PRUint32 ubits;
+ PRInt32 bits;
+
+ bits = codetovalue(src[0]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ ubits = (PRUint32)bits;
+ b32 = (ubits << 2);
+
+ bits = codetovalue(src[1]);
+ if( bits < 0 )
+ {
+ return PR_FAILURE;
+ }
+
+ ubits = (PRUint32)bits;
+ b32 |= (ubits >> 4);
+
+ dest[0] = (unsigned char)b32;
+
+ return PR_SUCCESS;
+}
+
+static PRStatus
+decode
+(
+ const unsigned char *src,
+ PRUint32 srclen,
+ unsigned char *dest
+)
+{
+ PRStatus rv;
+
+ while( srclen >= 4 )
+ {
+ rv = decode4to3(src, dest);
+ if( PR_SUCCESS != rv )
+ {
+ return PR_FAILURE;
+ }
+
+ src += 4;
+ dest += 3;
+ srclen -= 4;
+ }
+
+ switch( srclen )
+ {
+ case 3:
+ rv = decode3to2(src, dest);
+ break;
+ case 2:
+ rv = decode2to1(src, dest);
+ break;
+ case 1:
+ rv = PR_FAILURE;
+ break;
+ case 0:
+ rv = PR_SUCCESS;
+ break;
+ default:
+ PR_NOT_REACHED("coding error");
+ }
+
+ return rv;
+}
+
+/*
+ * PL_Base64Decode
+ *
+ * If the destination argument is NULL, a return buffer is
+ * allocated and the data therein will be null-terminated.
+ * If the destination argument is not null, it is assumed
+ * to be of sufficient size, and the data will not be null-
+ * terminated by this routine.
+ *
+ * Returns null if the allocation fails, or if the source string is
+ * not well-formed.
+ */
+
+PR_IMPLEMENT(char *)
+PL_Base64Decode
+(
+ const char *src,
+ PRUint32 srclen,
+ char *dest
+)
+{
+ PRStatus status;
+ PRBool allocated = PR_FALSE;
+
+ if( (char *)0 == src )
+ {
+ return (char *)0;
+ }
+
+ if( 0 == srclen )
+ {
+ size_t len = strlen(src);
+ srclen = len;
+ /* Detect truncation. */
+ if( srclen != len )
+ {
+ return (char *)0;
+ }
+ }
+
+ if( srclen && (0 == (srclen & 3)) )
+ {
+ if( (char)'=' == src[ srclen-1 ] )
+ {
+ if( (char)'=' == src[ srclen-2 ] )
+ {
+ srclen -= 2;
+ }
+ else
+ {
+ srclen -= 1;
+ }
+ }
+ }
+
+ if( (char *)0 == dest )
+ {
+ /* The following computes ((srclen * 3) / 4) without overflow. */
+ PRUint32 destlen = (srclen / 4) * 3 + ((srclen % 4) * 3) / 4;
+ dest = (char *)PR_MALLOC(destlen + 1);
+ if( (char *)0 == dest )
+ {
+ return (char *)0;
+ }
+ dest[ destlen ] = (char)0; /* null terminate */
+ allocated = PR_TRUE;
+ }
+
+ status = decode((const unsigned char *)src, srclen, (unsigned char *)dest);
+ if( PR_SUCCESS != status )
+ {
+ if( PR_TRUE == allocated )
+ {
+ PR_DELETE(dest);
+ }
+
+ return (char *)0;
+ }
+
+ return dest;
+}
diff --git a/nsprpub/lib/libc/src/plc.def b/nsprpub/lib/libc/src/plc.def
new file mode 100644
index 0000000000..ac8aa7bf6d
--- /dev/null
+++ b/nsprpub/lib/libc/src/plc.def
@@ -0,0 +1,72 @@
+;+#
+;+# This Source Code Form is subject to the terms of the Mozilla Public
+;+# License, v. 2.0. If a copy of the MPL was not distributed with this
+;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX, OS/2 and WINDOWS
+;+# 1. For all unix platforms, the string ";-" means "remove this line"
+;+# 2. For all unix platforms, the string " DATA " will be removed from any
+;+# line on which it occurs.
+;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+# On AIX, lines containing ";+" will be removed.
+;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+# 5. For all unix platforms, after the above processing has taken place,
+;+# all characters after the first ";" on the line will be removed.
+;+# And for AIX, the first ";" will also be removed.
+;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+# directives are hidden behind ";", ";+", and ";-"
+;+NSPR_4.0 {
+;+ global:
+LIBRARY plc4 ;-
+EXPORTS ;-
+PL_Base64Decode;
+PL_Base64Encode;
+PL_CreateOptState;
+PL_DestroyOptState;
+PL_FPrintError;
+PL_GetNextOpt;
+PL_PrintError;
+PL_strcasecmp;
+PL_strcaserstr;
+PL_strcasestr;
+PL_strcat;
+PL_strcatn;
+PL_strchr;
+PL_strcmp;
+PL_strcpy;
+PL_strdup;
+PL_strfree;
+PL_strlen;
+PL_strncasecmp;
+PL_strncaserstr;
+PL_strncasestr;
+PL_strncat;
+PL_strnchr;
+PL_strncmp;
+PL_strncpy;
+PL_strncpyz;
+PL_strndup;
+PL_strnlen;
+PL_strnpbrk;
+PL_strnprbrk;
+PL_strnrchr;
+PL_strnrstr;
+PL_strnstr;
+PL_strpbrk;
+PL_strprbrk;
+PL_strrchr;
+PL_strrstr;
+PL_strstr;
+libVersionPoint;
+;+ local: *;
+;+};
+;+
+;+NSPR_4.2 {
+;+ global:
+PL_strtok_r;
+;+} NSPR_4.0;
+;+
+;+NSPR_4.7 {
+;+ global:
+PL_CreateLongOptState;
+;+} NSPR_4.2;
diff --git a/nsprpub/lib/libc/src/plc.rc b/nsprpub/lib/libc/src/plc.rc
new file mode 100644
index 0000000000..144d273751
--- /dev/null
+++ b/nsprpub/lib/libc/src/plc.rc
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+
+#include "prinit.h"
+#include <winver.h>
+
+#define MY_LIBNAME "plc"
+#define MY_FILEDESCRIPTION "PLC Library"
+
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
+#ifdef _DEBUG
+#define MY_DEBUG_STR " (debug)"
+#define MY_FILEFLAGS_1 VS_FF_DEBUG
+#else
+#define MY_DEBUG_STR ""
+#define MY_FILEFLAGS_1 0x0L
+#endif
+#if PR_BETA
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE
+#else
+#define MY_FILEFLAGS_2 MY_FILEFLAGS_1
+#endif
+
+#ifdef WINNT
+#define MY_FILEOS VOS_NT_WINDOWS32
+#define MY_INTERNAL_NAME "lib" MY_LIBNAME PR_VMAJOR_STR
+#else
+#define MY_FILEOS VOS__WINDOWS32
+#define MY_INTERNAL_NAME MY_LIBNAME PR_VMAJOR_STR
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version-information resource
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ PRODUCTVERSION PR_VMAJOR,PR_VMINOR,PR_VPATCH,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+ FILEFLAGS MY_FILEFLAGS_2
+ FILEOS MY_FILEOS
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0x0L // not used
+
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904B0" // Lang=US English, CharSet=Unicode
+ BEGIN
+ VALUE "CompanyName", "Mozilla Foundation\0"
+ VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
+ VALUE "FileVersion", PR_VERSION "\0"
+ VALUE "InternalName", MY_INTERNAL_NAME "\0"
+ VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
+ VALUE "ProductName", "Netscape Portable Runtime\0"
+ VALUE "ProductVersion", PR_VERSION "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/nsprpub/lib/libc/src/plerror.c b/nsprpub/lib/libc/src/plerror.c
new file mode 100644
index 0000000000..2a3510f89f
--- /dev/null
+++ b/nsprpub/lib/libc/src/plerror.c
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** File:plerror.c
+** Description: Simple routine to print translate the calling thread's
+** error numbers and print them to "syserr".
+*/
+
+#include "plerror.h"
+
+#include "prprf.h"
+#include "prerror.h"
+
+PR_IMPLEMENT(void) PL_FPrintError(PRFileDesc *fd, const char *msg)
+{
+ PRErrorCode error = PR_GetError();
+ PRInt32 oserror = PR_GetOSError();
+ const char *name = PR_ErrorToName(error);
+
+ if (NULL != msg) {
+ PR_fprintf(fd, "%s: ", msg);
+ }
+ if (NULL == name)
+ PR_fprintf(
+ fd, " (%d)OUT OF RANGE, oserror = %d\n", error, oserror);
+ else
+ PR_fprintf(
+ fd, "%s(%d), oserror = %d\n",
+ name, error, oserror);
+} /* PL_FPrintError */
+
+PR_IMPLEMENT(void) PL_PrintError(const char *msg)
+{
+ static PRFileDesc *fd = NULL;
+ if (NULL == fd) {
+ fd = PR_GetSpecialFD(PR_StandardError);
+ }
+ PL_FPrintError(fd, msg);
+} /* PL_PrintError */
+
+/* plerror.c */
diff --git a/nsprpub/lib/libc/src/plgetopt.c b/nsprpub/lib/libc/src/plgetopt.c
new file mode 100644
index 0000000000..4e37e65f51
--- /dev/null
+++ b/nsprpub/lib/libc/src/plgetopt.c
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+** File: plgetopt.c
+** Description: utilities to parse argc/argv
+*/
+
+#include "prmem.h"
+#include "prlog.h"
+#include "prerror.h"
+#include "plstr.h"
+#include "plgetopt.h"
+
+#include <string.h>
+
+static char static_Nul = 0;
+
+struct PLOptionInternal
+{
+ const char *options; /* client options list specification */
+ PRIntn argc; /* original number of arguments */
+ char **argv; /* vector of pointers to arguments */
+ PRIntn xargc; /* which one we're processing now */
+ const char *xargv; /* where within *argv[xargc] */
+ PRIntn minus; /* do we already have the '-'? */
+ const PLLongOpt *longOpts; /* Caller's array */
+ PRBool endOfOpts; /* have reached a "--" argument */
+ PRIntn optionsLen; /* is strlen(options) */
+};
+
+/*
+** Create the state in which to parse the tokens.
+**
+** argc the sum of the number of options and their values
+** argv the options and their values
+** options vector of single character options w/ | w/o ':
+*/
+PR_IMPLEMENT(PLOptState*) PL_CreateOptState(
+ PRIntn argc, char **argv, const char *options)
+{
+ return PL_CreateLongOptState( argc, argv, options, NULL);
+} /* PL_CreateOptState */
+
+PR_IMPLEMENT(PLOptState*) PL_CreateLongOptState(
+ PRIntn argc, char **argv, const char *options,
+ const PLLongOpt *longOpts)
+{
+ PLOptState *opt = NULL;
+ PLOptionInternal *internal;
+
+ if (NULL == options)
+ {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return opt;
+ }
+
+ opt = PR_NEWZAP(PLOptState);
+ if (NULL == opt)
+ {
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ return opt;
+ }
+
+ internal = PR_NEW(PLOptionInternal);
+ if (NULL == internal)
+ {
+ PR_DELETE(opt);
+ PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+ return NULL;
+ }
+
+ opt->option = 0;
+ opt->value = NULL;
+ opt->internal = internal;
+ opt->longOption = 0;
+ opt->longOptIndex = -1;
+
+ internal->argc = argc;
+ internal->argv = argv;
+ internal->xargc = 0;
+ internal->xargv = &static_Nul;
+ internal->minus = 0;
+ internal->options = options;
+ internal->longOpts = longOpts;
+ internal->endOfOpts = PR_FALSE;
+ internal->optionsLen = PL_strlen(options);
+
+ return opt;
+} /* PL_CreateLongOptState */
+
+/*
+** Destroy object created by CreateOptState()
+*/
+PR_IMPLEMENT(void) PL_DestroyOptState(PLOptState *opt)
+{
+ PR_DELETE(opt->internal);
+ PR_DELETE(opt);
+} /* PL_DestroyOptState */
+
+PR_IMPLEMENT(PLOptStatus) PL_GetNextOpt(PLOptState *opt)
+{
+ PLOptionInternal *internal = opt->internal;
+
+ opt->longOption = 0;
+ opt->longOptIndex = -1;
+ /*
+ ** If the current xarg points to nul, advance to the next
+ ** element of the argv vector. If the vector index is equal
+ ** to argc, we're out of arguments, so return an EOL.
+ ** Note whether the first character of the new argument is
+ ** a '-' and skip by it if it is.
+ */
+ while (0 == *internal->xargv)
+ {
+ internal->xargc += 1;
+ if (internal->xargc >= internal->argc)
+ {
+ opt->option = 0;
+ opt->value = NULL;
+ return PL_OPT_EOL;
+ }
+ internal->xargv = internal->argv[internal->xargc];
+ internal->minus = 0;
+ if (!internal->endOfOpts && ('-' == *internal->xargv))
+ {
+ internal->minus++;
+ internal->xargv++; /* and consume */
+ if ('-' == *internal->xargv && internal->longOpts)
+ {
+ internal->minus++;
+ internal->xargv++;
+ if (0 == *internal->xargv)
+ {
+ internal->endOfOpts = PR_TRUE;
+ }
+ }
+ }
+ }
+
+ /*
+ ** If we already have a '-' or '--' in hand, xargv points to the next
+ ** option. See if we can find a match in the list of possible
+ ** options supplied.
+ */
+ if (internal->minus == 2)
+ {
+ char * foundEqual = strchr(internal->xargv,'=');
+ PRIntn optNameLen = foundEqual ? (foundEqual - internal->xargv) :
+ strlen(internal->xargv);
+ const PLLongOpt *longOpt = internal->longOpts;
+ PLOptStatus result = PL_OPT_BAD;
+
+ opt->option = 0;
+ opt->value = NULL;
+
+ for (; longOpt->longOptName; ++longOpt)
+ {
+ if (strncmp(longOpt->longOptName, internal->xargv, optNameLen)) {
+ continue; /* not a possible match */
+ }
+ if (strlen(longOpt->longOptName) != optNameLen) {
+ continue; /* not a match */
+ }
+ /* option name match */
+ opt->longOptIndex = longOpt - internal->longOpts;
+ opt->longOption = longOpt->longOption;
+ /* value is part of the current argv[] element if = was found */
+ /* note: this sets value even for long options that do not
+ * require option if specified as --long=value */
+ if (foundEqual)
+ {
+ opt->value = foundEqual + 1;
+ }
+ else if (longOpt->valueRequired)
+ {
+ /* value is the next argv[] element, if any */
+ if (internal->xargc + 1 < internal->argc)
+ {
+ opt->value = internal->argv[++(internal->xargc)];
+ }
+ /* missing value */
+ else
+ {
+ break; /* return PL_OPT_BAD */
+ }
+ }
+ result = PL_OPT_OK;
+ break;
+ }
+ internal->xargv = &static_Nul; /* consume this */
+ return result;
+ }
+ if (internal->minus)
+ {
+ PRIntn cop;
+ PRIntn eoo = internal->optionsLen;
+ for (cop = 0; cop < eoo; ++cop)
+ {
+ if (internal->options[cop] == *internal->xargv)
+ {
+ opt->option = *internal->xargv++;
+ opt->longOption = opt->option & 0xff;
+ /*
+ ** if options indicates that there's an associated
+ ** value, it must be provided, either as part of this
+ ** argv[] element or as the next one
+ */
+ if (':' == internal->options[cop + 1])
+ {
+ /* value is part of the current argv[] element */
+ if (0 != *internal->xargv)
+ {
+ opt->value = internal->xargv;
+ }
+ /* value is the next argv[] element, if any */
+ else if (internal->xargc + 1 < internal->argc)
+ {
+ opt->value = internal->argv[++(internal->xargc)];
+ }
+ /* missing value */
+ else
+ {
+ return PL_OPT_BAD;
+ }
+
+ internal->xargv = &static_Nul;
+ internal->minus = 0;
+ }
+ else {
+ opt->value = NULL;
+ }
+ return PL_OPT_OK;
+ }
+ }
+ internal->xargv += 1; /* consume that option */
+ return PL_OPT_BAD;
+ }
+
+ /*
+ ** No '-', so it must be a standalone value. The option is nul.
+ */
+ opt->value = internal->argv[internal->xargc];
+ internal->xargv = &static_Nul;
+ opt->option = 0;
+ return PL_OPT_OK;
+} /* PL_GetNextOpt */
+
+/* plgetopt.c */
diff --git a/nsprpub/lib/libc/src/plvrsion.c b/nsprpub/lib/libc/src/plvrsion.c
new file mode 100644
index 0000000000..ffa2e95d2d
--- /dev/null
+++ b/nsprpub/lib/libc/src/plvrsion.c
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "prinit.h"
+#include "prvrsion.h"
+
+/************************************************************************/
+/**************************IDENTITY AND VERSIONING***********************/
+/************************************************************************/
+#include "_pl_bld.h"
+#if !defined(_BUILD_TIME)
+#ifdef HAVE_LONG_LONG
+#define _BUILD_TIME 0
+#else
+#define _BUILD_TIME {0, 0}
+#endif
+#endif
+#if !defined(_BUILD_STRING)
+#define _BUILD_STRING ""
+#endif
+#if !defined(_PRODUCTION)
+#define _PRODUCTION ""
+#endif
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplc, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
+{
+ /* version */ 2, /* this is the only one supported */
+ /* buildTime */ _BUILD_TIME, /* usecs since midnight 1/1/1970 GMT */
+ /* buildTimeString */ _BUILD_STRING, /* ditto, but human readable */
+ /* vMajor */ PR_VMAJOR, /* NSPR's version number */
+ /* vMinor */ PR_VMINOR, /* and minor version */
+ /* vPatch */ PR_VPATCH, /* and patch */
+ /* beta */ PR_BETA, /* beta build boolean */
+#if defined(DEBUG)
+ /* debug */ PR_TRUE, /* a debug build */
+#else
+ /* debug */ PR_FALSE, /* an optomized build */
+#endif
+ /* special */ PR_FALSE, /* they're all special, but ... */
+ /* filename */ _PRODUCTION, /* the produced library name */
+ /* description */ "Portable runtime", /* what we are */
+ /* security */ "N/A", /* not applicable here */
+ /* copywrite */ "This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.",
+ /* comment */ "http://www.mozilla.org/MPL/",
+ /* specialString */ ""
+};
+
+#ifdef XP_UNIX
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+static char rcsid[] = "$Header: NSPR " PR_VERSION _DEBUG_STRING
+ " " _BUILD_STRING " $";
+static char sccsid[] = "@(#)NSPR " PR_VERSION _DEBUG_STRING
+ " " _BUILD_STRING;
+
+#endif /* XP_UNIX */
+
+#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint()
+{
+#ifdef XP_UNIX
+ /*
+ * Add dummy references to rcsid and sccsid to prevent them
+ * from being optimized away as unused variables.
+ */
+ const char *dummy;
+
+ dummy = rcsid;
+ dummy = sccsid;
+#endif
+ return &VERSION_DESC_NAME;
+} /* versionEntryPointType */
+#ifdef _PR_HAS_PRAGMA_DIAGNOSTIC
+#pragma GCC diagnostic pop
+#endif
+
+/* plvrsion.c */
+
diff --git a/nsprpub/lib/libc/src/strcase.c b/nsprpub/lib/libc/src/strcase.c
new file mode 100644
index 0000000000..f1ab038cd9
--- /dev/null
+++ b/nsprpub/lib/libc/src/strcase.c
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+#include <string.h>
+
+static const unsigned char uc[] =
+{
+ '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
+ '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
+ '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
+ '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
+ ' ', '!', '"', '#', '$', '%', '&', '\'',
+ '(', ')', '*', '+', ',', '-', '.', '/',
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', ':', ';', '<', '=', '>', '?',
+ '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
+ '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+ 'X', 'Y', 'Z', '{', '|', '}', '~', '\177',
+ 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
+ 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
+ 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
+ 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
+ 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
+ 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
+ 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
+ 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
+ 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
+ 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
+ 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
+ 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
+ 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
+ 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
+ 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
+ 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377
+};
+
+PR_IMPLEMENT(PRIntn)
+PL_strcasecmp(const char *a, const char *b)
+{
+ const unsigned char *ua = (const unsigned char *)a;
+ const unsigned char *ub = (const unsigned char *)b;
+
+ if( (const char *)0 == a ) {
+ return ((const char *)0 == b) ? 0 : -1;
+ }
+ if( (const char *)0 == b ) {
+ return 1;
+ }
+
+ while( (uc[*ua] == uc[*ub]) && ('\0' != *a) )
+ {
+ a++;
+ ua++;
+ ub++;
+ }
+
+ return (PRIntn)(uc[*ua] - uc[*ub]);
+}
+
+PR_IMPLEMENT(PRIntn)
+PL_strncasecmp(const char *a, const char *b, PRUint32 max)
+{
+ const unsigned char *ua = (const unsigned char *)a;
+ const unsigned char *ub = (const unsigned char *)b;
+
+ if( (const char *)0 == a ) {
+ return ((const char *)0 == b) ? 0 : -1;
+ }
+ if( (const char *)0 == b ) {
+ return 1;
+ }
+
+ while( max && (uc[*ua] == uc[*ub]) && ('\0' != *a) )
+ {
+ a++;
+ ua++;
+ ub++;
+ max--;
+ }
+
+ if( 0 == max ) {
+ return (PRIntn)0;
+ }
+
+ return (PRIntn)(uc[*ua] - uc[*ub]);
+}
+
+PR_IMPLEMENT(char *)
+PL_strcasestr(const char *big, const char *little)
+{
+ PRUint32 ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) {
+ return (char *)0;
+ }
+ if( ((char)0 == *big) || ((char)0 == *little) ) {
+ return (char *)0;
+ }
+
+ ll = strlen(little);
+
+ for( ; *big; big++ )
+ /* obvious improvement available here */
+ if( 0 == PL_strncasecmp(big, little, ll) ) {
+ return (char *)big;
+ }
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strcaserstr(const char *big, const char *little)
+{
+ const char *p;
+ PRUint32 bl, ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) {
+ return (char *)0;
+ }
+ if( ((char)0 == *big) || ((char)0 == *little) ) {
+ return (char *)0;
+ }
+
+ bl = strlen(big);
+ ll = strlen(little);
+ if( bl < ll ) {
+ return (char *)0;
+ }
+ p = &big[ bl - ll ];
+
+ for( ; p >= big; p-- )
+ /* obvious improvement available here */
+ if( 0 == PL_strncasecmp(p, little, ll) ) {
+ return (char *)p;
+ }
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strncasestr(const char *big, const char *little, PRUint32 max)
+{
+ PRUint32 ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) {
+ return (char *)0;
+ }
+ if( ((char)0 == *big) || ((char)0 == *little) ) {
+ return (char *)0;
+ }
+
+ ll = strlen(little);
+ if( ll > max ) {
+ return (char *)0;
+ }
+ max -= ll;
+ max++;
+
+ for( ; max && *big; big++, max-- )
+ /* obvious improvement available here */
+ if( 0 == PL_strncasecmp(big, little, ll) ) {
+ return (char *)big;
+ }
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strncaserstr(const char *big, const char *little, PRUint32 max)
+{
+ const char *p;
+ PRUint32 ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) {
+ return (char *)0;
+ }
+ if( ((char)0 == *big) || ((char)0 == *little) ) {
+ return (char *)0;
+ }
+
+ ll = strlen(little);
+
+ for( p = big; max && *p; p++, max-- )
+ ;
+
+ p -= ll;
+ if( p < big ) {
+ return (char *)0;
+ }
+
+ for( ; p >= big; p-- )
+ /* obvious improvement available here */
+ if( 0 == PL_strncasecmp(p, little, ll) ) {
+ return (char *)p;
+ }
+
+ return (char *)0;
+}
diff --git a/nsprpub/lib/libc/src/strcat.c b/nsprpub/lib/libc/src/strcat.c
new file mode 100644
index 0000000000..df847d36aa
--- /dev/null
+++ b/nsprpub/lib/libc/src/strcat.c
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strcat(char *dest, const char *src)
+{
+ if( ((char *)0 == dest) || ((const char *)0 == src) ) {
+ return dest;
+ }
+
+ return strcat(dest, src);
+}
+
+PR_IMPLEMENT(char *)
+PL_strncat(char *dest, const char *src, PRUint32 max)
+{
+ char *rv;
+
+ if( ((char *)0 == dest) || ((const char *)0 == src) || (0 == max) ) {
+ return dest;
+ }
+
+ for( rv = dest; *dest; dest++ )
+ ;
+
+ (void)PL_strncpy(dest, src, max);
+ return rv;
+}
+
+PR_IMPLEMENT(char *)
+PL_strcatn(char *dest, PRUint32 max, const char *src)
+{
+ char *rv;
+ PRUint32 dl;
+
+ if( ((char *)0 == dest) || ((const char *)0 == src) ) {
+ return dest;
+ }
+
+ for( rv = dest, dl = 0; *dest; dest++, dl++ )
+ ;
+
+ if( max <= dl ) {
+ return rv;
+ }
+ (void)PL_strncpyz(dest, src, max-dl);
+
+ return rv;
+}
diff --git a/nsprpub/lib/libc/src/strchr.c b/nsprpub/lib/libc/src/strchr.c
new file mode 100644
index 0000000000..7de1887dc3
--- /dev/null
+++ b/nsprpub/lib/libc/src/strchr.c
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strchr(const char *s, char c)
+{
+ if( (const char *)0 == s ) {
+ return (char *)0;
+ }
+
+ return strchr(s, c);
+}
+
+PR_IMPLEMENT(char *)
+PL_strrchr(const char *s, char c)
+{
+ if( (const char *)0 == s ) {
+ return (char *)0;
+ }
+
+ return strrchr(s, c);
+}
+
+PR_IMPLEMENT(char *)
+PL_strnchr(const char *s, char c, PRUint32 n)
+{
+ if( (const char *)0 == s ) {
+ return (char *)0;
+ }
+
+ for( ; n && *s; s++, n-- )
+ if( *s == c ) {
+ return (char *)s;
+ }
+
+ if( ((char)0 == c) && (n > 0) && ((char)0 == *s) ) {
+ return (char *)s;
+ }
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnrchr(const char *s, char c, PRUint32 n)
+{
+ const char *p;
+
+ if( (const char *)0 == s ) {
+ return (char *)0;
+ }
+
+ for( p = s; n && *p; p++, n-- )
+ ;
+
+ if( ((char)0 == c) && (n > 0) && ((char)0 == *p) ) {
+ return (char *)p;
+ }
+
+ for( p--; p >= s; p-- )
+ if( *p == c ) {
+ return (char *)p;
+ }
+
+ return (char *)0;
+}
diff --git a/nsprpub/lib/libc/src/strcmp.c b/nsprpub/lib/libc/src/strcmp.c
new file mode 100644
index 0000000000..9b00bbc521
--- /dev/null
+++ b/nsprpub/lib/libc/src/strcmp.c
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(PRIntn)
+PL_strcmp(const char *a, const char *b)
+{
+ if( (const char *)0 == a ) {
+ return ((const char *)0 == b) ? 0 : -1;
+ }
+ if( (const char *)0 == b ) {
+ return 1;
+ }
+
+ return (PRIntn)strcmp(a, b);
+}
+
+PR_IMPLEMENT(PRIntn)
+PL_strncmp(const char *a, const char *b, PRUint32 max)
+{
+ if( (const char *)0 == a ) {
+ return ((const char *)0 == b) ? 0 : -1;
+ }
+ if( (const char *)0 == b ) {
+ return 1;
+ }
+
+ return (PRIntn)strncmp(a, b, (size_t)max);
+}
diff --git a/nsprpub/lib/libc/src/strcpy.c b/nsprpub/lib/libc/src/strcpy.c
new file mode 100644
index 0000000000..f49b3e75e6
--- /dev/null
+++ b/nsprpub/lib/libc/src/strcpy.c
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strcpy(char *dest, const char *src)
+{
+ if( ((char *)0 == dest) || ((const char *)0 == src) ) {
+ return (char *)0;
+ }
+
+ return strcpy(dest, src);
+}
+
+PR_IMPLEMENT(char *)
+PL_strncpy(char *dest, const char *src, PRUint32 max)
+{
+ char *rv;
+
+ if( (char *)0 == dest ) {
+ return (char *)0;
+ }
+ if( (const char *)0 == src ) {
+ return (char *)0;
+ }
+
+ for( rv = dest; max && ((*dest = *src) != 0); dest++, src++, max-- )
+ ;
+
+#ifdef JLRU
+ /* XXX I (wtc) think the -- and ++ operators should be postfix. */
+ while( --max ) {
+ *++dest = '\0';
+ }
+#endif /* JLRU */
+
+ return rv;
+}
+
+PR_IMPLEMENT(char *)
+PL_strncpyz(char *dest, const char *src, PRUint32 max)
+{
+ char *rv;
+
+ if( (char *)0 == dest ) {
+ return (char *)0;
+ }
+ if( (const char *)0 == src ) {
+ return (char *)0;
+ }
+ if( 0 == max ) {
+ return (char *)0;
+ }
+
+ for( rv = dest, max--; max && ((*dest = *src) != 0); dest++, src++, max-- )
+ ;
+
+ *dest = '\0';
+
+ return rv;
+}
diff --git a/nsprpub/lib/libc/src/strdup.c b/nsprpub/lib/libc/src/strdup.c
new file mode 100644
index 0000000000..d2deae43c4
--- /dev/null
+++ b/nsprpub/lib/libc/src/strdup.c
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+#include "prmem.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strdup(const char *s)
+{
+ char *rv;
+ size_t n;
+
+ if( (const char *)0 == s ) {
+ s = "";
+ }
+
+ n = strlen(s) + 1;
+
+ rv = (char *)malloc(n);
+ if( (char *)0 == rv ) {
+ return rv;
+ }
+
+ (void)memcpy(rv, s, n);
+
+ return rv;
+}
+
+PR_IMPLEMENT(void)
+PL_strfree(char *s)
+{
+ free(s);
+}
+
+PR_IMPLEMENT(char *)
+PL_strndup(const char *s, PRUint32 max)
+{
+ char *rv;
+ size_t l;
+
+ if( (const char *)0 == s ) {
+ s = "";
+ }
+
+ l = PL_strnlen(s, max);
+
+ rv = (char *)malloc(l+1);
+ if( (char *)0 == rv ) {
+ return rv;
+ }
+
+ (void)memcpy(rv, s, l);
+ rv[l] = '\0';
+
+ return rv;
+}
diff --git a/nsprpub/lib/libc/src/strlen.c b/nsprpub/lib/libc/src/strlen.c
new file mode 100644
index 0000000000..2888175dfc
--- /dev/null
+++ b/nsprpub/lib/libc/src/strlen.c
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+#include "prtypes.h"
+#include "prlog.h"
+#include <string.h>
+
+PR_IMPLEMENT(PRUint32)
+PL_strlen(const char *str)
+{
+ size_t l;
+
+ if( (const char *)0 == str ) {
+ return 0;
+ }
+
+ l = strlen(str);
+
+ /* error checking in case we have a 64-bit platform -- make sure
+ * we don't have ultra long strings that overflow an int32
+ */
+ if( sizeof(PRUint32) < sizeof(size_t) )
+ {
+ if( l > PR_INT32_MAX ) {
+ PR_Assert("l <= PR_INT32_MAX", __FILE__, __LINE__);
+ }
+ }
+
+ return (PRUint32)l;
+}
+
+PR_IMPLEMENT(PRUint32)
+PL_strnlen(const char *str, PRUint32 max)
+{
+ register const char *s;
+
+ if( (const char *)0 == str ) {
+ return 0;
+ }
+ for( s = str; max && *s; s++, max-- )
+ ;
+
+ return (PRUint32)(s - str);
+}
diff --git a/nsprpub/lib/libc/src/strpbrk.c b/nsprpub/lib/libc/src/strpbrk.c
new file mode 100644
index 0000000000..89ccbe698e
--- /dev/null
+++ b/nsprpub/lib/libc/src/strpbrk.c
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strpbrk(const char *s, const char *list)
+{
+ if( ((const char *)0 == s) || ((const char *)0 == list) ) {
+ return (char *)0;
+ }
+
+ return strpbrk(s, list);
+}
+
+PR_IMPLEMENT(char *)
+PL_strprbrk(const char *s, const char *list)
+{
+ const char *p;
+ const char *r;
+
+ if( ((const char *)0 == s) || ((const char *)0 == list) ) {
+ return (char *)0;
+ }
+
+ for( r = s; *r; r++ )
+ ;
+
+ for( r--; r >= s; r-- )
+ for( p = list; *p; p++ )
+ if( *r == *p ) {
+ return (char *)r;
+ }
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnpbrk(const char *s, const char *list, PRUint32 max)
+{
+ const char *p;
+
+ if( ((const char *)0 == s) || ((const char *)0 == list) ) {
+ return (char *)0;
+ }
+
+ for( ; max && *s; s++, max-- )
+ for( p = list; *p; p++ )
+ if( *s == *p ) {
+ return (char *)s;
+ }
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnprbrk(const char *s, const char *list, PRUint32 max)
+{
+ const char *p;
+ const char *r;
+
+ if( ((const char *)0 == s) || ((const char *)0 == list) ) {
+ return (char *)0;
+ }
+
+ for( r = s; max && *r; r++, max-- )
+ ;
+
+ for( r--; r >= s; r-- )
+ for( p = list; *p; p++ )
+ if( *r == *p ) {
+ return (char *)r;
+ }
+
+ return (char *)0;
+}
diff --git a/nsprpub/lib/libc/src/strstr.c b/nsprpub/lib/libc/src/strstr.c
new file mode 100644
index 0000000000..dd27a23ee7
--- /dev/null
+++ b/nsprpub/lib/libc/src/strstr.c
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+#include <string.h>
+
+PR_IMPLEMENT(char *)
+PL_strstr(const char *big, const char *little)
+{
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) {
+ return (char *)0;
+ }
+ if( ((char)0 == *big) || ((char)0 == *little) ) {
+ return (char *)0;
+ }
+
+ return strstr(big, little);
+}
+
+PR_IMPLEMENT(char *)
+PL_strrstr(const char *big, const char *little)
+{
+ const char *p;
+ size_t ll;
+ size_t bl;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) {
+ return (char *)0;
+ }
+ if( ((char)0 == *big) || ((char)0 == *little) ) {
+ return (char *)0;
+ }
+
+ ll = strlen(little);
+ bl = strlen(big);
+ if( bl < ll ) {
+ return (char *)0;
+ }
+ p = &big[ bl - ll ];
+
+ for( ; p >= big; p-- )
+ if( *little == *p )
+ if( 0 == strncmp(p, little, ll) ) {
+ return (char *)p;
+ }
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnstr(const char *big, const char *little, PRUint32 max)
+{
+ size_t ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) {
+ return (char *)0;
+ }
+ if( ((char)0 == *big) || ((char)0 == *little) ) {
+ return (char *)0;
+ }
+
+ ll = strlen(little);
+ if( ll > (size_t)max ) {
+ return (char *)0;
+ }
+ max -= (PRUint32)ll;
+ max++;
+
+ for( ; max && *big; big++, max-- )
+ if( *little == *big )
+ if( 0 == strncmp(big, little, ll) ) {
+ return (char *)big;
+ }
+
+ return (char *)0;
+}
+
+PR_IMPLEMENT(char *)
+PL_strnrstr(const char *big, const char *little, PRUint32 max)
+{
+ const char *p;
+ size_t ll;
+
+ if( ((const char *)0 == big) || ((const char *)0 == little) ) {
+ return (char *)0;
+ }
+ if( ((char)0 == *big) || ((char)0 == *little) ) {
+ return (char *)0;
+ }
+
+ ll = strlen(little);
+
+ for( p = big; max && *p; p++, max-- )
+ ;
+
+ p -= ll;
+ if( p < big ) {
+ return (char *)0;
+ }
+
+ for( ; p >= big; p-- )
+ if( *little == *p )
+ if( 0 == strncmp(p, little, ll) ) {
+ return (char *)p;
+ }
+
+ return (char *)0;
+}
diff --git a/nsprpub/lib/libc/src/strtok.c b/nsprpub/lib/libc/src/strtok.c
new file mode 100644
index 0000000000..df404494fb
--- /dev/null
+++ b/nsprpub/lib/libc/src/strtok.c
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "plstr.h"
+
+PR_IMPLEMENT(char *)
+PL_strtok_r(char *s1, const char *s2, char **lasts)
+{
+ const char *sepp;
+ int c, sc;
+ char *tok;
+
+ if( s1 == NULL )
+ {
+ if( *lasts == NULL ) {
+ return NULL;
+ }
+
+ s1 = *lasts;
+ }
+
+ for( ; (c = *s1) != 0; s1++ )
+ {
+ for( sepp = s2 ; (sc = *sepp) != 0 ; sepp++ )
+ {
+ if( c == sc ) {
+ break;
+ }
+ }
+ if( sc == 0 ) {
+ break;
+ }
+ }
+
+ if( c == 0 )
+ {
+ *lasts = NULL;
+ return NULL;
+ }
+
+ tok = s1++;
+
+ for( ; (c = *s1) != 0; s1++ )
+ {
+ for( sepp = s2; (sc = *sepp) != 0; sepp++ )
+ {
+ if( c == sc )
+ {
+ *s1++ = '\0';
+ *lasts = s1;
+ return tok;
+ }
+ }
+ }
+ *lasts = NULL;
+ return tok;
+}