Commits

dtrg committed 64d6e6e

Add some missing libc functions: setenv, unsetenv, strdup.

  • Participants
  • Parent commits a19eb60
  • Branches dtrg-videocore

Comments (0)

Files changed (7)

File lang/cem/libcc.ansi/build.mk

 $(call ackfile, lang/cem/libcc.ansi/stdlib/atexit.c)
 $(call ackfile, lang/cem/libcc.ansi/stdlib/exit.c)
 $(call ackfile, lang/cem/libcc.ansi/stdlib/getenv.c)
+$(call ackfile, lang/cem/libcc.ansi/stdlib/setenv.c)
 $(call ackfile, lang/cem/libcc.ansi/stdlib/labs.c)
 $(call ackfile, lang/cem/libcc.ansi/stdlib/ldiv.c)
 $(call ackfile, lang/cem/libcc.ansi/stdlib/mblen.c)
 $(call ackfile, lang/cem/libcc.ansi/string/strspn.c)
 $(call ackfile, lang/cem/libcc.ansi/string/strncmp.c)
 $(call ackfile, lang/cem/libcc.ansi/string/strxfrm.c)
+$(call ackfile, lang/cem/libcc.ansi/string/strdup.c)
 
 # Time
 

File lang/cem/libcc.ansi/headers/stdlib.h

 extern void exit(int _status);
 extern void _Exit(int _status);
 extern char* getenv(const char *_name);
+extern int setenv(const char *_name, const char *_value, int _overwrite);
+extern int unsetenv(const char *_name);
+extern int putenv(char *_string);
 extern int system(const char *_string);
 extern void* bsearch(const void *_key, const void *_base,
 			size_t _nmemb, size_t _size,

File lang/cem/libcc.ansi/headers/string.h

 extern void	*memset(void *_s, int _c, size_t _n);
 extern char	*strerror(int _errnum);
 extern size_t	strlen(const char *_s);
+extern char *strdup(const char *_s);
+
+#define bcopy(s, d, z) memmove(d, s, z)
 
 #endif

File lang/cem/libcc.ansi/misc/putenv.c

 #define	ENTRY_INC	10
 #define	rounded(x)	(((x / ENTRY_INC) + 1) * ENTRY_INC)
 
-extern const char **_penvp;
-extern const char **environ;	/* environ is a shadow name for _penvp */
+extern char **environ;
 
 int
 putenv(char *name)
 {
-	register const char **v = _penvp;
+	register char **v = environ;
 	register char *r;
 	static int size = 0;
 	/* When size != 0, it contains the number of entries in the
 	 * table (including the final NULL pointer). This means that the
-	 * last non-null entry  is _penvp[size - 2].
+	 * last non-null entry  is environ[size - 2].
 	 */
 
 	if (!name) return 0;
 			}
 		}
 		*r = '=';
-		v = _penvp;
+		v = environ;
 	}
 
 	if (!size) {
-		register const char **p;
+		register char **p;
 		register int i = 0;
 
 		if (v)
 		if (!(v = malloc(rounded(i) * sizeof(char **))))
 			return 1;
 		size = i;
-		p = _penvp;
-		_penvp = v;
+		p = environ;
+		environ = v;
 		while (*v++ = *p++);		/* copy the environment */
-		v = _penvp;
+		v = environ;
 	} else if (!(size % ENTRY_INC)) {
-		if (!(v = realloc(_penvp, rounded(size) * sizeof(char **))))
+		if (!(v = realloc(environ, rounded(size) * sizeof(char **))))
 			return 1;
-		_penvp = v;
+		environ = v;
 	}
 	v[size - 1] = name;
 	v[size] = NULL;
 	size++;
-	environ = _penvp;
 	return 0;
 }

File lang/cem/libcc.ansi/stdlib/getenv.c

 /* $Id$ */
 
 #include <stdlib.h>
-#include <unistd.h>
+#include <string.h>
 
-char *
-getenv(const char *name)
+extern char* _findenv(const char* name, int* offset);
+
+/*
+ * getenv(name) --
+ *	Returns ptr to value associated with name, if any, else NULL.
+ */
+char* getenv(const char* name)
 {
-	register char **v = environ;
-	register const char *p, *q;
+    int offset;
 
-	if (v == NULL || name == NULL)
-		return (char *)NULL;
-	while ((p = *v++) != NULL) {
-		q = name;
-		while (*q && (*q == *p++))
-			q++;
-		if (*q || (*p != '='))
-			continue;
-		return (char *)p + 1;
-	}
-	return (char *)NULL;
+    return(_findenv(name,&offset));
 }
+
+/*
+ * _findenv(name,offset) --
+ *	Returns pointer to value associated with name, if any, else NULL.
+ *	Sets offset to be the offset of the name/value combination in the
+ *	environmental array, for use by setenv(3) and unsetenv(3).
+ *	Explicitly removes '=' in argument name.
+ *
+ *	This routine *should* be a static; don't use it.
+ */
+char* _findenv(register const char* name, int* offset)
+{
+    extern char **environ;
+    register int    len;
+    register char **P;
+    register const char *C;
+
+	if (!environ)
+		return NULL;
+
+    for (C = name,len = 0;*C && *C != '=';++C,++len);
+    for (P = environ;*P;++P)
+        if (!strncmp(*P,name,len))
+            if (*(C = *P + len) == '=') {
+                *offset = P - environ;
+                return (char*)(++C);
+            }
+    return(NULL);
+}
+

File lang/cem/libcc.ansi/stdlib/setenv.c

+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+/* $Id$ */
+
+#include <stdlib.h>
+#include <string.h>
+
+extern char* _findenv(const char* name, int* offset);
+extern char **environ;
+
+/*
+ * setenv(name,value,rewrite)
+ *	Set the value of the environmental variable "name" to be
+ *	"value".  If rewrite is set, replace any current value.
+ */
+int setenv(register const char* name, register const char* value, int rewrite)
+{
+    static int  alloced = 0;        /* if allocated space before */
+    register char   *C;
+    int l_value,
+        offset;
+
+    if (*value == '=')          /* no `=' in value */
+        ++value;
+    l_value = strlen(value);
+    if ((C = _findenv(name,&offset))) { /* find if already exists */
+        if (!rewrite)
+            return(0);
+        if (strlen(C) >= l_value) { /* old larger; copy over */
+            while (*C++ = *value++);
+            return(0);
+        }
+    }
+    else {                  /* create new slot */
+        register int    cnt = 0;
+        register char   **P;
+
+		if (environ)
+			for (P = environ;*P;++P,++cnt);
+        if (alloced) {          /* just increase size */
+            environ = (char **)realloc((char *)environ,
+                (unsigned)(sizeof(char *) * (cnt + 2)));
+            if (!environ)
+                return(-1);
+        }
+        else {              /* get new space */
+            alloced = 1;        /* copy old entries into it */
+            P = (char **)malloc((unsigned)(sizeof(char *) *
+                (cnt + 2)));
+            if (!P)
+                return(-1);
+            if (environ)
+				bcopy(environ,P,cnt * sizeof(char *));
+            environ = P;
+        }
+        environ[cnt + 1] = NULL;
+        offset = cnt;
+    }
+    for (C = name;*C && *C != '=';++C); /* no `=' in name */
+    if (!(environ[offset] =         /* name + `=' + value */
+        malloc((unsigned)((int)(C - name) + l_value + 2))))
+        return(-1);
+    for (C = environ[offset];(*C = *name++) && *C != '=';++C);
+    for (*C++ = '=';*C++ = *value++;);
+    return(0);
+}
+
+/*
+ * unsetenv(name) --
+ *	Delete environmental variable "name".
+ */
+int
+unsetenv(const char* name)
+{
+    register char   **P;
+    int offset;
+
+    while (_findenv(name,&offset))      /* if set multiple times */
+        for (P = &environ[offset];;++P)
+            if (!(*P = *(P + 1)))
+                break;
+
+    return 0;
+}
+

File lang/cem/libcc.ansi/string/strdup.c

+/*
+ * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
+ * See the copyright notice in the ACK home directory, in the file "Copyright".
+ */
+/* $Id$ */
+
+#include	<string.h>
+
+char*
+strdup(const char *s)
+{
+	int len = strlen(s);
+	char *p = malloc(len+1);
+	if (p)
+		memcpy(p, s, len+1);
+	return p;
+}