custom basename(3) and dirname(3)


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@114 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1compiler/Makefile.am b/libasn1compiler/Makefile.am
index 6b2babd..301bbaa 100644
--- a/libasn1compiler/Makefile.am
+++ b/libasn1compiler/Makefile.am
@@ -13,6 +13,7 @@
 	asn1c_lang.c asn1c_lang.h		\
 	asn1c_save.c asn1c_save.h		\
 	asn1c_C.c asn1c_C.h			\
+	asn1c_compat.c asn1c_compat.h		\
 	asn1c_internal.h
 
 libasn1compiler_la_LIBADD =				\
diff --git a/libasn1compiler/Makefile.in b/libasn1compiler/Makefile.in
index 74f9893..64c0037 100644
--- a/libasn1compiler/Makefile.in
+++ b/libasn1compiler/Makefile.in
@@ -54,7 +54,8 @@
 	${top_builddir}/libasn1parser/libasn1parser.la \
 	${top_builddir}/libasn1fix/libasn1fix.la
 am_libasn1compiler_la_OBJECTS = asn1compiler.lo asn1c_misc.lo \
-	asn1c_out.lo asn1c_lang.lo asn1c_save.lo asn1c_C.lo
+	asn1c_out.lo asn1c_lang.lo asn1c_save.lo asn1c_C.lo \
+	asn1c_compat.lo
 libasn1compiler_la_OBJECTS = $(am_libasn1compiler_la_OBJECTS)
 check_compiler_SOURCES = check_compiler.c
 check_compiler_OBJECTS = check_compiler.$(OBJEXT)
@@ -68,6 +69,7 @@
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
 @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/asn1c_C.Plo \
+@AMDEP_TRUE@	./$(DEPDIR)/asn1c_compat.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/asn1c_lang.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/asn1c_misc.Plo \
 @AMDEP_TRUE@	./$(DEPDIR)/asn1c_out.Plo \
@@ -210,6 +212,7 @@
 	asn1c_lang.c asn1c_lang.h		\
 	asn1c_save.c asn1c_save.h		\
 	asn1c_C.c asn1c_C.h			\
+	asn1c_compat.c asn1c_compat.h		\
 	asn1c_internal.h
 
 libasn1compiler_la_LIBADD = \
@@ -281,6 +284,7 @@
 	-rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1c_C.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1c_compat.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1c_lang.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1c_misc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1c_out.Plo@am__quote@
diff --git a/libasn1compiler/asn1c_compat.c b/libasn1compiler/asn1c_compat.c
new file mode 100644
index 0000000..3d8280a
--- /dev/null
+++ b/libasn1compiler/asn1c_compat.c
@@ -0,0 +1,94 @@
+#include <asn1c_compat.h>
+
+#include <string.h>
+#include <errno.h>
+
+#ifdef	HAVE_SYS_PARAM_H
+#include <sys/param.h>	/* For MAXPATHLEN */
+#endif
+
+#ifndef	MAXPATHLEN
+#define	MAXPATHLEN	1024
+#endif
+
+char *
+a1c_basename(const char *path) {
+	static char strbuf[MAXPATHLEN];
+	const char *pend;
+	const char *name;
+
+	pend = path + strlen(path);
+	if(pend == path) {
+		strcpy(strbuf, ".");
+		return strbuf;
+	}
+
+	/* Skip tailing slashes */
+	for(pend--; pend > path && *pend == '/'; pend--);
+
+	if(pend == path && *path == '/') {
+		strcpy(strbuf, "/");
+		return strbuf;
+	}
+
+	for(name = pend; name > path && name[-1] != '/'; name--);
+
+	if((pend - name) >= sizeof(strbuf) - 1) {
+		errno = ENAMETOOLONG;
+		return 0;
+	}
+
+	memcpy(strbuf, name, pend - name + 1);
+	strbuf[pend - name + 1] = '\0';
+
+	return strbuf;
+}
+
+
+char *
+a1c_dirname(const char *path) {
+	static char strbuf[MAXPATHLEN];
+	const char *pend;
+	const char *last = 0;
+	int in_slash = 0;
+
+	/* One-pass determination of the last char of the pathname */
+	for(pend = path; ; pend++) {
+		printf("-%c", *pend);
+		switch(*pend) {
+		case '\0': break;
+		case '/':
+			if(!in_slash) {
+				last = pend;
+				in_slash = 1;
+			}
+			continue;
+		default:
+			if(in_slash) in_slash = 0;
+			continue;
+		}
+		break;
+	}
+	printf("\n");
+
+	if(last <= path) {
+		strcpy(strbuf, *path == '/' ? "/" : ".");
+		return strbuf;
+	}
+
+	if(!last) {
+		strcpy(strbuf, "/");
+		return strbuf;
+	}
+
+	if((last - path) >= sizeof(strbuf)) {
+		errno = ENAMETOOLONG;
+		return 0;
+	}
+
+	memcpy(strbuf, path, last - path);
+	strbuf[last - path] = '\0';
+
+	return strbuf;
+}
+
diff --git a/libasn1compiler/asn1c_compat.h b/libasn1compiler/asn1c_compat.h
new file mode 100644
index 0000000..9461b78
--- /dev/null
+++ b/libasn1compiler/asn1c_compat.h
@@ -0,0 +1,11 @@
+#ifndef	ASN1C_COMPAT_H
+#define	ASN1C_COMPAT_H
+
+#ifdef	HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+char *a1c_basename(const char *path);
+char *a1c_dirname(const char *path);
+
+#endif	/* ASN1C_COMPAT_H */
diff --git a/libasn1compiler/asn1c_internal.h b/libasn1compiler/asn1c_internal.h
index 6192650..08a490f 100644
--- a/libasn1compiler/asn1c_internal.h
+++ b/libasn1compiler/asn1c_internal.h
@@ -1,13 +1,16 @@
 #ifndef	_ASN1_COMPILER_INTERNAL_H_
 #define	_ASN1_COMPILER_INTERNAL_H_
 
+#ifdef	HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/stat.h>		/* for fstat(2) */
 #include <unistd.h>		/* for unlink(2) */
 #include <fcntl.h>		/* for open(2) */
 #include <glob.h>		/* for glob(3) */
-#include <libgen.h>		/* for basename(3) */
 #include <string.h>
 #include <ctype.h>		/* for isalnum(3) */
 #include <stdarg.h>
diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c
index fd1356b..15d1b67 100644
--- a/libasn1compiler/asn1c_save.c
+++ b/libasn1compiler/asn1c_save.c
@@ -1,4 +1,5 @@
 #include "asn1c_internal.h"
+#include "asn1c_compat.h"
 
 static int asn1c_dump_streams(arg_t *arg);
 static int asn1c_print_streams(arg_t *arg);
@@ -73,7 +74,7 @@
 				return -1;
 			} else {
 				fprintf(mkf, "\t\\\n\t%s",
-					basename(pg.gl_pathv[i]));
+					a1c_basename(pg.gl_pathv[i]));
 			}
 		}
 
@@ -213,11 +214,12 @@
 
 static int
 asn1c_copy_over(arg_t *arg, char *path) {
-	char *fname = basename(path);
+	char *fname;
 
 	(void)arg;	/* Unused argument */
 
-	if(symlink(path, fname)) {
+	fname = a1c_basename(path);
+	if(!fname || symlink(path, fname)) {
 		if(errno == EEXIST) {
 			struct stat sb1, sb2;
 			if(stat(path, &sb1) == 0