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/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;
+}
+