aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--argz.h1
-rw-r--r--envz.h1
-rw-r--r--errno.h8
-rw-r--r--string/Makefile8
-rw-r--r--string/argz-append.c50
-rw-r--r--string/argz-count.c38
-rw-r--r--string/argz-create.c53
-rw-r--r--string/argz-delete.c41
-rw-r--r--string/argz-extract.c36
-rw-r--r--string/argz-insert.c64
-rw-r--r--string/argz-stringify.c38
-rw-r--r--string/argz.h100
-rw-r--r--string/envz.c171
-rw-r--r--string/envz.h55
-rw-r--r--sysdeps/mach/hurd/errnos.awk3
16 files changed, 677 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 9d7458c488..dd58a9711c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Mon Apr 29 00:11:59 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
+
+ * errno.h [!__error_t_defined] (error_t): New type.
+ * sysdeps/mach/hurd/errnos.awk: #define __error_t_defined after the
+ typedef in errnos.h.
+
+ * string/envz.c, string/envz.h: New files.
+ * string/argz.h, string/argz-append.c, string/argz-count.c,
+ string/argz-create.c, string/argz-delete.c, string/argz-extract.c,
+ string/argz-insert.c, string/argz-stringify.c: New files.
+ * string/Makefile (routines): Add envz, argz-*.
+ (headers): Add argz.h, envz.h.
+
Sun Apr 28 14:14:35 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu>
* sysdeps/unix/sysv/linux/i386/Makefile: New file.
diff --git a/argz.h b/argz.h
new file mode 100644
index 0000000000..179e693106
--- /dev/null
+++ b/argz.h
@@ -0,0 +1 @@
+#include <string/argz.h>
diff --git a/envz.h b/envz.h
new file mode 100644
index 0000000000..0a476ed62a
--- /dev/null
+++ b/envz.h
@@ -0,0 +1 @@
+#include <string/envz.h>
diff --git a/errno.h b/errno.h
index 2b6fd17e72..f1fbd5e082 100644
--- a/errno.h
+++ b/errno.h
@@ -47,6 +47,14 @@ extern int errno;
#endif
#ifdef __USE_GNU
+
+/* The Hurd <errnos.h> defines `error_t' as an enumerated type
+ so that printing `error_t' values in the debugger shows the names. */
+#ifndef __error_t_defined
+typedef int error_t;
+#define __error_t_defined 1
+#endif
+
/* The full and simple forms of the name with which the program was
invoked. These variables are set up automatically at startup based on
the value of ARGV[0] (this works only if you use GNU ld). */
diff --git a/string/Makefile b/string/Makefile
index 5901c36594..d90bf6f857 100644
--- a/string/Makefile
+++ b/string/Makefile
@@ -21,7 +21,8 @@
#
subdir := string
-headers := string.h strings.h memory.h endian.h bytesex.h
+headers := string.h strings.h memory.h endian.h bytesex.h \
+ argz.h envz.h
routines := strcat strchr strcmp strcoll strcpy strcspn strdup \
strerror _strerror strlen strnlen \
@@ -31,7 +32,10 @@ routines := strcat strchr strcmp strcoll strcpy strcspn strdup \
bcopy bzero ffs stpcpy stpncpy \
strcasecmp strncase \
memccpy memcpy wordcopy strsep \
- swab strfry memfrob memmem
+ swab strfry memfrob memmem \
+ $(addprefix argz-,append count create \
+ delete extract insert stringify) \
+ envz
tests := tester testcopy test-ffs
distribute := memcopy.h pagecopy.h
diff --git a/string/argz-append.c b/string/argz-append.c
new file mode 100644
index 0000000000..e61e3acf58
--- /dev/null
+++ b/string/argz-append.c
@@ -0,0 +1,50 @@
+/* Routines for dealing with '\0' separated arg vectors.
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <argz.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Add BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */
+error_t
+__argz_append (char **argz, size_t *argz_len, const char *buf, size_t buf_len)
+{
+ size_t new_argz_len = *argz_len + buf_len;
+ char *new_argz = realloc (*argz, new_argz_len);
+ if (new_argz)
+ {
+ memcpy (new_argz + *argz_len, buf, buf_len);
+ *argz = new_argz;
+ *argz_len = new_argz_len;
+ return 0;
+ }
+ else
+ return ENOMEM;
+}
+weak_alias (__argz_append, argz_append)
+
+/* Add STR to the argz vector in ARGZ & ARGZ_LEN. This should be moved into
+ argz.c in libshouldbelibc. */
+error_t
+__argz_add (char **argz, size_t *argz_len, const char *str)
+{
+ return __argz_append (argz, argz_len, str, strlen (str) + 1);
+}
+weak_alias (__argz_add, argz_add)
diff --git a/string/argz-count.c b/string/argz-count.c
new file mode 100644
index 0000000000..a10119b722
--- /dev/null
+++ b/string/argz-count.c
@@ -0,0 +1,38 @@
+/* Routines for dealing with '\0' separated arg vectors.
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <argz.h>
+#include <string.h>
+
+/* Returns the number of strings in ARGZ. */
+size_t
+__argz_count (const char *argz, size_t len)
+{
+ size_t count = 0;
+ while (len > 0)
+ {
+ size_t part_len = strlen(argz);
+ argz += part_len + 1;
+ len -= part_len + 1;
+ count++;
+ }
+ return count;
+}
+weak_alias (__argz_count, argz_count)
diff --git a/string/argz-create.c b/string/argz-create.c
new file mode 100644
index 0000000000..fab3222cb3
--- /dev/null
+++ b/string/argz-create.c
@@ -0,0 +1,53 @@
+/* Routines for dealing with '\0' separated arg vectors.
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <argz.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Make a '\0' separated arg vector from a unix argv vector, returning it in
+ ARGZ, and the total length in LEN. If a memory allocation error occurs,
+ ENOMEM is returned, otherwise 0. */
+error_t
+__argz_create (char **argv, char **argz, size_t *len)
+{
+ int argc;
+ size_t tlen = 0;
+ char *p, **ap;
+
+ for (argc = 0; argv[argc] != NULL; ++argc)
+ tlen += strlen (argv[argc]);
+
+ if (tlen == 0)
+ *argz = NULL;
+ else
+ {
+ *argz = malloc(tlen);
+ if (*argz == NULL)
+ return ENOMEM;
+
+ for (p = *argz, ap = argv; *ap; ++ap, ++p)
+ p = __stpcpy (p, *ap);
+ }
+ *len = tlen;
+
+ return 0;
+}
+weak_alias (__argz_create, argz_create)
diff --git a/string/argz-delete.c b/string/argz-delete.c
new file mode 100644
index 0000000000..729b1b8371
--- /dev/null
+++ b/string/argz-delete.c
@@ -0,0 +1,41 @@
+/* Routines for dealing with '\0' separated arg vectors.
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <argz.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Delete ENTRY from ARGZ & ARGZ_LEN, if any. */
+void
+argz_delete (char **argz, size_t *argz_len, char *entry)
+{
+ if (entry)
+ /* Get rid of the old value for NAME. */
+ {
+ size_t entry_len = strlen (entry) + 1;
+ *argz_len -= entry_len;
+ memcpy (entry, entry + entry_len, *argz_len - (entry - *argz));
+ if (*argz_len == 0)
+ {
+ free (*argz);
+ *argz = 0;
+ }
+ }
+}
diff --git a/string/argz-extract.c b/string/argz-extract.c
new file mode 100644
index 0000000000..5eb0e84b01
--- /dev/null
+++ b/string/argz-extract.c
@@ -0,0 +1,36 @@
+/* Routines for dealing with '\0' separated arg vectors.
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <argz.h>
+
+/* Puts pointers to each string in ARGZ into ARGV, which must be large enough
+ to hold them all. */
+void
+__argz_extract (const char *argz, size_t len, char **argv)
+{
+ while (len > 0)
+ {
+ size_t part_len = strlen(argz);
+ *argv++ = argz;
+ argz += part_len + 1;
+ len -= part_len + 1;
+ }
+}
+weak_alias (__argz_extract, argz_extract)
diff --git a/string/argz-insert.c b/string/argz-insert.c
new file mode 100644
index 0000000000..a110060e9d
--- /dev/null
+++ b/string/argz-insert.c
@@ -0,0 +1,64 @@
+/* Routines for dealing with '\0' separated arg vectors.
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <argz.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
+ existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
+ Since ARGZ's first entry is the same as ARGZ, argz_insert (ARGZ, ARGZ_LEN,
+ ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ. If BEFORE is not
+ in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
+ ARGZ, ENOMEM is returned, else 0. */
+error_t
+__argz_insert (char **argz, size_t *argz_len, char *before, const char *entry)
+{
+ if (! before)
+ return __argz_add (argz, argz_len, entry);
+
+ if (before < *argz || before >= *argz + *argz_len)
+ return EINVAL;
+
+ if (before > *argz)
+ /* Make sure before is actually the beginning of an entry. */
+ while (before[-1])
+ before--;
+
+ {
+ size_t after_before = *argz_len - (before - *argz);
+ size_t entry_len = strlen (entry) + 1;
+ size_t new_argz_len = *argz_len + entry_len;
+ char *new_argz = realloc (*argz, new_argz_len);
+
+ if (new_argz)
+ {
+ before = new_argz + (before - *argz);
+ memcpy (before + entry_len, before, after_before);
+ memcpy (before, entry, entry_len);
+ *argz = new_argz;
+ *argz_len = new_argz_len;
+ return 0;
+ }
+ else
+ return ENOMEM;
+ }
+}
+weak_alias (__argz_insert, argz_insert)
diff --git a/string/argz-stringify.c b/string/argz-stringify.c
new file mode 100644
index 0000000000..c7a109c0fb
--- /dev/null
+++ b/string/argz-stringify.c
@@ -0,0 +1,38 @@
+/* Routines for dealing with '\0' separated arg vectors.
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <argz.h>
+#include <string.h>
+
+/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
+ except the last into the character SEP. */
+void
+__argz_stringify(char *argz, size_t len, int sep)
+{
+ while (len > 0)
+ {
+ size_t part_len = strlen(argz);
+ argz += part_len;
+ len -= part_len + 1;
+ if (len > 0)
+ *argz++ = sep;
+ }
+}
+weak_alias (__argz_stringify, argz_stringify)
diff --git a/string/argz.h b/string/argz.h
new file mode 100644
index 0000000000..9c03815915
--- /dev/null
+++ b/string/argz.h
@@ -0,0 +1,100 @@
+/* Routines for dealing with '\0' separated arg vectors.
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef __ARGZ_H__
+#define __ARGZ_H__ 1
+#include <errno.h> /* Define error_t. */
+#include <string.h> /* Need size_t, and strchr is called below. */
+
+/* Make a '\0' separated arg vector from a unix argv vector, returning it in
+ ARGZ, and the total length in LEN. If a memory allocation error occurs,
+ ENOMEM is returned, otherwise 0. The result can be destroyed using free. */
+error_t __argz_create (char **argv, char **argz, size_t *len);
+error_t argz_create (char **argv, char **argz, size_t *len);
+
+/* Returns the number of strings in ARGZ. */
+size_t __argz_count (const char *argz, size_t len);
+size_t argz_count (const char *argz, size_t len);
+
+/* Puts pointers to each string in ARGZ into ARGV, which must be large enough
+ to hold them all. */
+void __argz_extract (const char *argz, size_t len, char **argv);
+void argz_extract (const char *argz, size_t len, char **argv);
+
+/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
+ except the last into the character SEP. */
+void __argz_stringify (char *argz, size_t len, int sep);
+void argz_stringify (char *argz, size_t len, int sep);
+
+/* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */
+error_t __argz_append (char **argz, size_t *argz_len,
+ const char *buf, size_t buf_len);
+error_t argz_append (char **argz, size_t *argz_len,
+ const char *buf, size_t buf_len);
+
+/* Append STR to the argz vector in ARGZ & ARGZ_LEN. */
+error_t __argz_add (char **argz, size_t *argz_len, const char *str);
+error_t argz_add (char **argz, size_t *argz_len, const char *str);
+
+/* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there. */
+void __argz_delete (char **argz, size_t *argz_len, char *entry);
+void argz_delete (char **argz, size_t *argz_len, char *entry);
+
+/* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
+ existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
+ Since ARGZ's first entry is the same as ARGZ, argz_insert (ARGZ, ARGZ_LEN,
+ ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ. If BEFORE is not
+ in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
+ ARGZ, ENOMEM is returned, else 0. */
+error_t __argz_insert (char **argz, size_t *argz_len,
+ char *before, const char *entry);
+error_t argz_insert (char **argz, size_t *argz_len,
+ char *before, const char *entry);
+
+/* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there
+ are no more. If entry is NULL, then the first entry is returned. This
+ behavior allows two convenient iteration styles:
+
+ char *entry = 0;
+ while (entry = argz_next (argz, argz_len, entry))
+ ...;
+
+ or
+
+ char *entry;
+ for (entry = argz; entry; entry = argz_next (argz, argz_len, entry))
+ ...;
+*/
+extern inline char *
+argz_next (char *argz, size_t argz_len, const char *entry)
+{
+ if (entry)
+ if (entry >= argz + argz_len)
+ return 0;
+ else
+ return strchr (entry, '\0') + 1;
+ else
+ if (argz_len > 0)
+ return argz;
+ else
+ return 0;
+}
+
+#endif /* __ARGZ_H__ */
diff --git a/string/envz.c b/string/envz.c
new file mode 100644
index 0000000000..4d0816e4e1
--- /dev/null
+++ b/string/envz.c
@@ -0,0 +1,171 @@
+/* Routines for dealing with '\0' separated environment vectors
+
+ Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+ Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <malloc.h>
+#include <string.h>
+
+#include "envz.h"
+
+/* The character separating names from values in an envz. */
+#define SEP '='
+
+/* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none.
+ If NAME contains the separator character, only the portion before it is
+ used in the comparison. */
+char *
+envz_entry (char *envz, unsigned envz_len, char *name)
+{
+ while (envz_len)
+ {
+ char *p = name;
+ char *entry = envz; /* Start of this entry. */
+
+ /* See how far NAME and ENTRY match. */
+ while (envz_len && *p == *envz && *p && *p != SEP)
+ p++, envz++, envz_len--;
+
+ if ((*envz == '\0' || *envz == SEP) && (*p == '\0' || *p =