portability fixes


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@715 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/asn1c/sys-common.h b/asn1c/sys-common.h
index 3cf4590..8447c6d 100644
--- a/asn1c/sys-common.h
+++ b/asn1c/sys-common.h
@@ -24,17 +24,26 @@
  *
  * $Id$
  */
+#ifdef	HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>		/* for stat(2) */
-#include <unistd.h>
 #include <assert.h>
 #include <errno.h>
 
-#ifdef	HAVE_CONFIG_H
-#include "config.h"
+#ifdef	HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef	HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#ifdef	HAVE_SYS_STAT_H
+#include <sys/stat.h>		/* for stat(2) */
 #endif
 
 #ifndef	WIN32
diff --git a/config.h.in b/config.h.in
index 1910711..0133b2b 100644
--- a/config.h.in
+++ b/config.h.in
@@ -1,7 +1,7 @@
 /* config.h.in.  Generated from configure.in by autoheader.  */
 
-/* Define to 1 if you have the <errno.h> header file. */
-#undef HAVE_ERRNO_H
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
@@ -9,6 +9,9 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
+/* Define to 1 if you have the `mergesort' function. */
+#undef HAVE_MERGESORT
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
@@ -27,6 +30,9 @@
 /* Define to 1 if you have the `strtoll' function. */
 #undef HAVE_STRTOLL
 
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #undef HAVE_SYS_STAT_H
 
diff --git a/libasn1compiler/asn1c_compat.c b/libasn1compiler/asn1c_compat.c
index 1a402bf..ebc6d3f 100644
--- a/libasn1compiler/asn1c_compat.c
+++ b/libasn1compiler/asn1c_compat.c
@@ -1,24 +1,26 @@
 #include "asn1c_internal.h"
-#include <asn1c_compat.h>
-
-#ifdef	HAVE_SYS_PARAM_H
-#include <sys/param.h>	/* For MAXPATHLEN */
-#endif
+#include "asn1c_compat.h"
 
 #ifndef	MAXPATHLEN
 #define	MAXPATHLEN	1024
 #endif
 
 #ifndef	DEFFILEMODE	/* Normally in <sys/stat.h> */
+#ifdef	WIN32
+#define	DEFFILEMODE	0
+#else
 #define	DEFFILEMODE	(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
 #endif
+#endif
 
 FILE *
 asn1c_open_file(const char *name, const char *ext) {
 	int created = 1;
+#ifndef	WIN32
 	struct stat sb;
+#endif
 	char *fname;
-	int len;
+	size_t len;
 	FILE *fp;
 	int fd;
 
@@ -42,6 +44,7 @@
 		return NULL;
 	}
 
+#ifndef	WIN32
 	/*
 	 * Check sanity.
 	 */
@@ -53,6 +56,9 @@
 	}
 
 	(void)ftruncate(fd, 0);
+#else
+	_chsize(fd, 0);
+#endif	/* WIN32 */
 
 	/*
 	 * Convert file descriptor into file pointer.
diff --git a/libasn1compiler/asn1c_compat.h b/libasn1compiler/asn1c_compat.h
index e80e2e7..44ac438 100644
--- a/libasn1compiler/asn1c_compat.h
+++ b/libasn1compiler/asn1c_compat.h
@@ -1,10 +1,6 @@
 #ifndef	ASN1C_COMPAT_H
 #define	ASN1C_COMPAT_H
 
-#ifdef	HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 /*
  * Open the arbitrary file by its base name and extension.
  */
diff --git a/libasn1compiler/asn1c_internal.h b/libasn1compiler/asn1c_internal.h
index e6b1852..e32187f 100644
--- a/libasn1compiler/asn1c_internal.h
+++ b/libasn1compiler/asn1c_internal.h
@@ -7,16 +7,37 @@
 
 #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 <string.h>		/* for strlen(3) and memset(3) */
 #include <ctype.h>		/* for isalnum(3) */
+#include <sys/types.h>		/* for fstat(2) */
 #include <stdarg.h>
 #include <errno.h>
 #include <assert.h>
 
+#ifdef	HAVE_SYS_STAT_H
+#include <sys/stat.h>		/* for fstat(2) */
+#endif
+
+#ifdef	HAVE_UNISTD_H
+#include <unistd.h>		/* for unlink(2) */
+#endif
+
+#ifdef	WIN32
+#include <io.h>
+#define	open	_open
+#define	close	_close
+#define	alloca		_alloca
+#define	snprintf	_snprintf
+#define	vsnprintf	_vsnprintf
+#else
+#include <fcntl.h>		/* for open(2) */
+#include <glob.h>		/* for glob(3) */
+#endif
+
+#ifdef	HAVE_SYS_PARAM_H
+#include <sys/param.h>	/* For MAXPATHLEN */
+#endif
+
 #include "asn1compiler.h"
 
 typedef struct arg_s {
diff --git a/libasn1compiler/asn1c_misc.c b/libasn1compiler/asn1c_misc.c
index efdb6c5..51b9d94 100644
--- a/libasn1compiler/asn1c_misc.c
+++ b/libasn1compiler/asn1c_misc.c
@@ -32,7 +32,7 @@
 	va_list ap;
 	char *str;
 	char *nextstr;
-	int size;
+	size_t size;
 	char *p;
 
 	if(arg1 == NULL)
diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c
index 381404e..1abf242 100644
--- a/libasn1compiler/asn1c_save.c
+++ b/libasn1compiler/asn1c_save.c
@@ -76,11 +76,12 @@
 	if(dlist) {
 		char buf[8129];
 		char *dir_end;
-		int i = strlen(datadir);
+		size_t dlen = strlen(datadir);
+		int i;
 
-		assert(i < (int)(sizeof(buf) / 2 - 2));
-		memcpy(buf, datadir, i);
-		dir_end = buf + i;
+		assert(dlen < (sizeof(buf) / 2 - 2));
+		memcpy(buf, datadir, dlen);
+		dir_end = buf + dlen;
 		*dir_end++ = '/';
 
 		for(i = 0; i < dlist->el_count; i++) {
@@ -254,6 +255,35 @@
 	return 0;
 }
 
+/*
+ * Copy file for real.
+ */
+static int
+real_copy(const char *src, const char *dst) {
+	unsigned char buf[8192];
+	FILE *fpsrc, *fpdst;
+	size_t len;
+	int retval = 0;
+
+	fpsrc = fopen(src, "rb");
+	if(!fpsrc) { errno = EIO; return -1; }
+	fpdst = fopen(src, "wb");
+	if(!fpdst) { fclose(fpsrc); errno = EIO; return -1; }
+
+	while(!feof(fpsrc)) {
+		len = fread(buf, 1, sizeof(buf), fpsrc);
+		if(fwrite(buf, 1, len, fpsrc) != len) {
+			errno = EIO;
+			retval = -1;
+			break;
+		}
+	}
+
+	fclose(fpsrc);
+	fclose(fpdst);
+	return retval;
+}
+
 static int
 asn1c_copy_over(arg_t *arg, char *path) {
 	char *fname;
@@ -261,7 +291,13 @@
 	(void)arg;	/* Unused argument */
 
 	fname = a1c_basename(path);
-	if(!fname || symlink(path, fname)) {
+	if(!fname
+#ifdef	WIN32
+		|| real_copy(path, fname)
+#else
+		|| (1 ? symlink(path, fname) : real_copy(path, fname))
+#endif
+	) {
 		if(errno == EEXIST) {
 			struct stat sb1, sb2;
 			if(stat(path, &sb1) == 0
diff --git a/libasn1fix/asn1fix.c b/libasn1fix/asn1fix.c
index f120853..22cd367 100644
--- a/libasn1fix/asn1fix.c
+++ b/libasn1fix/asn1fix.c
@@ -1,10 +1,5 @@
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdarg.h>
-
-#include "asn1fix.h"
 #include "asn1fix_internal.h"
+#include "asn1fix.h"
 
 /* Print everything to stderr */
 static void _default_error_logger(int _severity, const char *fmt, ...);
diff --git a/libasn1fix/asn1fix_constraint.c b/libasn1fix/asn1fix_constraint.c
index 8c6c73c..9a32b49 100644
--- a/libasn1fix/asn1fix_constraint.c
+++ b/libasn1fix/asn1fix_constraint.c
@@ -1,6 +1,6 @@
-#include <asn1fix_internal.h>
-#include <asn1fix_constraint.h>
-#include <asn1fix_crange.h>
+#include "asn1fix_internal.h"
+#include "asn1fix_constraint.h"
+#include "asn1fix_crange.h"
 
 static void _remove_exceptions(arg_t *arg, asn1p_constraint_t *ct);
 static int _constraint_value_resolve(arg_t *arg, asn1p_module_t *mod, asn1p_value_t **value);
diff --git a/libasn1fix/asn1fix_constraint_compat.c b/libasn1fix/asn1fix_constraint_compat.c
index effa0ad..5eb93f0 100644
--- a/libasn1fix/asn1fix_constraint_compat.c
+++ b/libasn1fix/asn1fix_constraint_compat.c
@@ -1,5 +1,5 @@
-#include <asn1fix_internal.h>
-#include <asn1fix_crange.h>
+#include "asn1fix_internal.h"
+#include "asn1fix_crange.h"
 
 /*
  * Check that a specific constraint is compatible
diff --git a/libasn1fix/asn1fix_crange.c b/libasn1fix/asn1fix_crange.c
index 974aa21..1e6a0d0 100644
--- a/libasn1fix/asn1fix_crange.c
+++ b/libasn1fix/asn1fix_crange.c
@@ -1,6 +1,6 @@
-#include <asn1fix_internal.h>
-#include <asn1fix_constraint.h>
-#include <asn1fix_crange.h>
+#include "asn1fix_internal.h"
+#include "asn1fix_constraint.h"
+#include "asn1fix_crange.h"
 
 #undef	FATAL
 #define	FATAL(fmt, args...)	do {			\
diff --git a/libasn1fix/asn1fix_cstring.c b/libasn1fix/asn1fix_cstring.c
index b8a3883..9cbb42c 100644
--- a/libasn1fix/asn1fix_cstring.c
+++ b/libasn1fix/asn1fix_cstring.c
@@ -2,7 +2,7 @@
 
 struct _cstring_pattern {
 	char *start;
-	int length;
+	size_t length;
 };
 static int _asn1f_cstring_find_line_pattern(char *s, struct _cstring_pattern *);
 
@@ -55,7 +55,7 @@
 		case '\0':
 		default:
 			if(newline_found) {
-				cp->length = s - cp->start;
+				cp->length = (size_t)(s - cp->start);
 				return 1;
 			}
 
diff --git a/libasn1fix/asn1fix_export.h b/libasn1fix/asn1fix_export.h
index 5879b93..99d80b7 100644
--- a/libasn1fix/asn1fix_export.h
+++ b/libasn1fix/asn1fix_export.h
@@ -5,7 +5,7 @@
 #ifndef	_ASN1FIX_EXPORT_H_
 #define	_ASN1FIX_EXPORT_H_
 
-#include <asn1fix_tags.h>
+#include "asn1fix_tags.h"
 
 /*
  * Create a human-readable representation of a reference and value.
diff --git a/libasn1fix/asn1fix_internal.h b/libasn1fix/asn1fix_internal.h
index 040750d..6b15778 100644
--- a/libasn1fix/asn1fix_internal.h
+++ b/libasn1fix/asn1fix_internal.h
@@ -10,13 +10,29 @@
  */
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
 #include <ctype.h>		/* isupper() */
 #include <errno.h>
 #include <assert.h>
 
+#ifdef	HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
 #include <asn1parser.h>		/* Our lovely ASN.1 parser module */
-#include <asn1fix.h>
+#include "asn1fix.h"
+
+#ifdef	WIN32
+#define	EX_NOINPUT	66
+#define	EX_DATAERR	65
+#define	snprintf	_snprintf
+#define	strcasecmp	stricmp
+#endif
+
+#ifndef	ETOOMANYREFS
+#define	ETOOMANYREFS	144
+#endif
 
 /*
  * A definition of a function that will log error messages.
diff --git a/libasn1fix/asn1fix_misc.c b/libasn1fix/asn1fix_misc.c
index e9d156c..15a1686 100644
--- a/libasn1fix/asn1fix_misc.c
+++ b/libasn1fix/asn1fix_misc.c
@@ -19,11 +19,11 @@
 asn1f_printable_value(asn1p_value_t *v) {
 	static char buf[128];
 	static char *managedptr;
-	static int managedptr_len;
+	static size_t managedptr_len;
 	int ret;
 
 #define	ENSURE(len)	do {						\
-		int __len = (len);					\
+		size_t __len = (len);					\
 		if(__len >= managedptr_len) {				\
 			if(managedptr)					\
 				free(managedptr);			\
@@ -69,7 +69,7 @@
 		{
 			uint8_t *bitvector;
 			char *ptr;
-			int len;
+			size_t len;
 			int i;
 			/*
 			 * Compute number of bytes necessary
@@ -110,13 +110,13 @@
 			*ptr++ = '\'';
 			*ptr++ = (bits%8)?'B':'H';
 			*ptr++ = 'H';
-			assert((ptr - managedptr) == len);
+			assert(len == (size_t)(ptr - managedptr));
 			return managedptr;
 		}
 	case ATV_REFERENCED:
 		{
 			asn1p_ref_t *ref;
-			char reflen;
+			size_t reflen;
 			char *ptr;
 			int i;
 
@@ -141,7 +141,7 @@
 					*ptr++ = *nc;
 			}
 			*ptr++ = '\0';
-			assert(reflen == (ptr - managedptr));
+			assert(reflen == (size_t)(ptr - managedptr));
 			return managedptr;
 		}
 	case ATV_CHOICE_IDENTIFIER:
@@ -158,7 +158,7 @@
 
 			ret = snprintf(managedptr, managedptr_len + 1,
 				"%s: %s", cid, val);
-			assert(ret >= 0 && ret <= managedptr_len);
+			assert(ret >= 0 && (size_t)ret <= managedptr_len);
 			free(val);
 			return managedptr;
 		}
diff --git a/libasn1fix/check_fixer.c b/libasn1fix/check_fixer.c
index 7129a56..8808f28 100644
--- a/libasn1fix/check_fixer.c
+++ b/libasn1fix/check_fixer.c
@@ -1,15 +1,17 @@
 #undef	NDEBUG
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
+#include "asn1fix_internal.h"
+
+#ifdef	WIN32
+#include <io.h>
+#include <direct.h>
+#define	chdir _chdir
+#else
 #include <dirent.h>
-#include <errno.h>
 #include <sysexits.h>
+#endif
+#include <errno.h>
 
 #include "asn1fix.h"
-#include "asn1fix_internal.h"
 
 static int check(const char *fname,
 	enum asn1p_flags parser_flags,
@@ -19,12 +21,19 @@
 
 int
 main(int ac, char **av) {
+#ifdef	WIN32
+	intptr_t dir;
+	struct _finddata_t c_file;
+#else
 	struct dirent *dp;
 	DIR *dir;
+#endif
 	int failed = 0;
 	int completed = 0;
 	enum asn1p_flags parser_flags = A1P_NOFLAGS;
 	enum asn1f_flags fixer_flags  = A1F_NOFLAGS;
+	const char *filename;
+	int len;
 	int ret;
 
 	/*
@@ -44,8 +53,13 @@
 		fprintf(stderr, "Testing in ./tests...\n");
 		ret = chdir("../tests");
 		assert(ret == 0);
+#ifdef	WIN32
+		dir = _findfirst("*.asn1", &c_file);
+		assert(dir != -1L);
+#else
 		dir = opendir(".");
 		assert(dir);
+#endif	/* WIN32 */
 	} else {
 		dir = 0;
 	}
@@ -54,21 +68,31 @@
 	 * Scan every *.asn1 file and try to parse and fix it.
 	 */
 	if(dir) {
+#ifdef	WIN32
+		do {
+			filename = c_file.name;
+#else
 		while((dp = readdir(dir))) {
-			int len = strlen(dp->d_name);
-			if(len && strcmp(dp->d_name + len - 5, ".asn1") == 0) {
-				ret = check(dp->d_name,
-					parser_flags, fixer_flags);
+			filename = dp->d_name;
+#endif	/* WIN32 */
+			int len = strlen(filename);
+			if(len && strcmp(filename + len - 5, ".asn1") == 0) {
+				ret = check(filename, parser_flags,fixer_flags);
 				if(ret) {
-					fprintf(stderr,
-						"FAILED: %s\n",
-						dp->d_name);
+					fprintf(stderr, "FAILED: %s\n",
+						filename);
 					failed++;
 				}
 				completed++;
 			}
+#ifdef	WIN32
+		} while(_findnext(dir, &c_file) == 0);
+		_findclose(dir);
+#else
 		}
 		closedir(dir);
+#endif	/* WIN32 */
+
 
 		fprintf(stderr,
 			"Tests COMPLETED: %d\n"
diff --git a/libasn1parser/Makefile.in b/libasn1parser/Makefile.in
index ef80e29..cb9ebd0 100644
--- a/libasn1parser/Makefile.in
+++ b/libasn1parser/Makefile.in
@@ -447,9 +447,9 @@
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
+	-rm -f asn1p_l.c
 	-rm -f asn1p_y.c
 	-rm -f asn1p_y.h
-	-rm -f asn1p_l.c
 clean: clean-am
 
 clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
diff --git a/libasn1parser/asn1p_expr2uclass.h b/libasn1parser/asn1p_expr2uclass.h
index 8bb4f63..1fb6dbb 100644
--- a/libasn1parser/asn1p_expr2uclass.h
+++ b/libasn1parser/asn1p_expr2uclass.h
@@ -1,6 +1,10 @@
 #ifndef	ASN1_PARSER_EXPR2UCLASS_H
 #define	ASN1_PARSER_EXPR2UCLASS_H
 
+#ifndef	__GNUC__
+#define	__attribute__(x)	/* unused */
+#endif
+
 static int expr_type2uclass_value[ASN_EXPR_TYPE_MAX]
 		__attribute__ ((unused)) = {
 	[ ASN_BASIC_BOOLEAN ]		= 1,
diff --git a/libasn1parser/asn1p_expr_str.h b/libasn1parser/asn1p_expr_str.h
index d99f835..8e9545d 100644
--- a/libasn1parser/asn1p_expr_str.h
+++ b/libasn1parser/asn1p_expr_str.h
@@ -5,6 +5,10 @@
 #ifndef	ASN1_PARSER_EXPR_STR_H
 #define	ASN1_PARSER_EXPR_STR_H
 
+#ifndef	__GNUC__
+#define	__attribute__(x)	/* unused */
+#endif
+
 static char *asn1p_expr_type2str[] __attribute__ ((unused)) = {
 	[ ASN_CONSTR_SEQUENCE ]	 = "SEQUENCE",
 	[ ASN_CONSTR_CHOICE ]	 = "CHOICE",
diff --git a/libasn1parser/asn1p_list.h b/libasn1parser/asn1p_list.h
index 4a71fdd..9d5748c 100644
--- a/libasn1parser/asn1p_list.h
+++ b/libasn1parser/asn1p_list.h
@@ -37,11 +37,11 @@
 	for((var) = TQ_FIRST((head));			\
 		(var); (var) = TQ_NEXT((var), field))
 
+/* MSVC does not have typeof(), cannot prevent side effects! */
 #define	TQ_ADD(head, xel, field) do {			\
-	typeof(xel) __el = xel;				\
-	assert(TQ_NEXT((__el), field) == 0);		\
-        *(head)->tq_tail = (__el);			\
-        (head)->tq_tail = &TQ_NEXT((__el), field);	\
+	assert(TQ_NEXT((xel), field) == 0);		\
+        *(head)->tq_tail = (xel);			\
+        (head)->tq_tail = &TQ_NEXT((xel), field);	\
 	} while(0)
 
 /*
diff --git a/libasn1parser/asn1parser.c b/libasn1parser/asn1parser.c
index 6a3477d..c820cc4 100644
--- a/libasn1parser/asn1parser.c
+++ b/libasn1parser/asn1parser.c
@@ -35,7 +35,7 @@
 	}
 
 	if(size < 0)
-		size = strlen(buffer);
+		size = (int)strlen(buffer);
 
 	ybuf = asn1p__scan_bytes(buffer, size);
 	if(!ybuf) {
@@ -67,7 +67,9 @@
  */
 asn1p_t *
 asn1p_parse_file(const char *filename, enum asn1p_flags flags) {
+#ifndef	WIN32
 	struct stat sb;
+#endif
 	asn1p_t *a = 0;
 	void *ap;
 	FILE *fp;
@@ -84,6 +86,7 @@
 		return NULL;
 	}
 
+#ifndef	WIN32
 	if(fstat(fileno(fp), &sb)
 	|| !S_ISREG(sb.st_mode)) {
 		fclose(fp);
@@ -92,6 +95,7 @@
 		errno = EINVAL;
 		return NULL;
 	}
+#endif	/* WIN32 */
 
 	asn1p_lineno = 1;
 
diff --git a/libasn1parser/asn1parser.h b/libasn1parser/asn1parser.h
index ff7e410..d5a09a9 100644
--- a/libasn1parser/asn1parser.h
+++ b/libasn1parser/asn1parser.h
@@ -38,16 +38,16 @@
 #define	PRIuASN	"llu"	/* Or j? */
 #endif
 
-#include <asn1p_list.h>
-#include <asn1p_oid.h>		/* Object identifiers (OIDs) */
-#include <asn1p_ref.h>		/* References to custom types */
-#include <asn1p_value.h>	/* Value definition */
-#include <asn1p_param.h>	/* Parametrization */
-#include <asn1p_constr.h>	/* Type Constraints */
-#include <asn1p_xports.h>	/* IMports/EXports */
-#include <asn1p_module.h>	/* ASN.1 definition module */
-#include <asn1p_class.h>	/* CLASS-related stuff */
-#include <asn1p_expr.h>		/* A single ASN.1 expression */
+#include "asn1p_list.h"
+#include "asn1p_oid.h"		/* Object identifiers (OIDs) */
+#include "asn1p_ref.h"		/* References to custom types */
+#include "asn1p_value.h"	/* Value definition */
+#include "asn1p_param.h"	/* Parametrization */
+#include "asn1p_constr.h"	/* Type Constraints */
+#include "asn1p_xports.h"	/* IMports/EXports */
+#include "asn1p_module.h"	/* ASN.1 definition module */
+#include "asn1p_class.h"	/* CLASS-related stuff */
+#include "asn1p_expr.h"		/* A single ASN.1 expression */
 
 /*
  * Parser flags.
diff --git a/libasn1parser/expr-h.pl b/libasn1parser/expr-h.pl
index a66425a..ce916d7 100755
--- a/libasn1parser/expr-h.pl
+++ b/libasn1parser/expr-h.pl
@@ -9,6 +9,10 @@
 #ifndef	ASN1_PARSER_EXPR_STR_H
 #define	ASN1_PARSER_EXPR_STR_H
 
+#ifndef	__GNUC__
+#define	__attribute__(x)	/* unused */
+#endif
+
 static char *asn1p_expr_type2str[] __attribute__ ((unused)) = {
 EOM
 
diff --git a/libasn1print/asn1print.c b/libasn1print/asn1print.c
index 6752e3e..45738ae 100644
--- a/libasn1print/asn1print.c
+++ b/libasn1print/asn1print.c
@@ -111,27 +111,30 @@
 
 static int
 asn1print_oid(asn1p_oid_t *oid, enum asn1print_flags flags) {
+	size_t accum = 0;
 	int ac;
-	int accum = 0;
 
 	(void)flags;	/* Unused argument */
 
 	printf("{");
 	for(ac = 0; ac < oid->arcs_count; ac++) {
-		if(accum + strlen(oid->arcs[ac].name?:"") > 50) {
+		const char *arcname = oid->arcs[ac].name;
+
+		if(accum + strlen(arcname ? arcname : "") > 50) {
 			printf("\n\t");
 			accum = 0;
-		} else if(ac) printf(" ");
+		} else if(ac) {
+			printf(" ");
+		}
 
-		if(oid->arcs[ac].name) {
-			printf("%s", oid->arcs[ac].name);
+		if(arcname) {
+			printf("%s", arcname);
 			if(oid->arcs[ac].number >= 0) {
 				printf("(%" PRIdASN ")", oid->arcs[ac].number);
 			}
 			accum += strlen(oid->arcs[ac].name);
 		} else {
-			printf("%d",
-				(int)oid->arcs[ac].number);
+			printf("%" PRIdASN, oid->arcs[ac].number);
 		}
 		accum += 4;
 	}
diff --git a/skeletons/RELATIVE-OID.c b/skeletons/RELATIVE-OID.c
index b0f6f64..70291e2 100644
--- a/skeletons/RELATIVE-OID.c
+++ b/skeletons/RELATIVE-OID.c
@@ -220,7 +220,7 @@
 	/*
 	 * Replace buffer.
 	 */
-	roid->size = bp - buf;
+	roid->size = (int)(bp - buf);
 	bp = roid->buf;
 	roid->buf = buf;
 	if(bp) FREEMEM(bp);
diff --git a/skeletons/asn_codecs_prim.c b/skeletons/asn_codecs_prim.c
index 5fe09ad..42f5a40 100644
--- a/skeletons/asn_codecs_prim.c
+++ b/skeletons/asn_codecs_prim.c
@@ -55,10 +55,19 @@
 		return rval;
 	}
 
+	st->size = (int)length;
+	/* The following better be optimized away. */
+	if(sizeof(st->size) != sizeof(length)
+			&& (ber_tlv_len_t)st->size != length) {
+		st->size = 0;
+		rval.code = RC_FAIL;
+		rval.consumed = 0;
+		return rval;
+	}
+
 	st->buf = (uint8_t *)MALLOC(length + 1);
-	if(st->buf) {
-		st->size = length;
-	} else {
+	if(!st->buf) {
+		st->size = 0;
 		rval.code = RC_FAIL;
 		rval.consumed = 0;
 		return rval;
@@ -146,14 +155,14 @@
 };
 
 
-static int
+static ssize_t
 xer_decode__unexpected_tag(void *key, void *chunk_buf, size_t chunk_size) {
 	struct xdp_arg_s *arg = (struct xdp_arg_s *)key;
 	ssize_t decoded;
 
 	if(arg->decoded_something) {
 		if(xer_is_whitespace(chunk_buf, chunk_size))
-			return chunk_size;
+			return 0;	/* Skip it. */
 		/*
 		 * Decoding was done once already. Prohibit doing it again.
 		 */
diff --git a/skeletons/asn_system.h b/skeletons/asn_system.h
index 4626532..5a5eb9b 100644
--- a/skeletons/asn_system.h
+++ b/skeletons/asn_system.h
@@ -19,12 +19,15 @@
 #include <stdarg.h>	/* For va_start */
 #include <stddef.h>	/* for offsetof and ptrdiff_t */
 
+#ifdef	WIN32
+
+#define	 snprintf	_snprintf
+#define	 vsnprintf	_vsnprintf
+#define	alloca(size)	_alloca(size)
+
+#else	/* !WIN32 */
+
 #include <inttypes.h>	/* C99 specifies this file */
-
-#if	defined(sun)
-#include <ieeefp.h>	/* for finite(3) */
-#endif
-
 /*
  * 1. Earlier FreeBSD version didn't have <stdint.h>,
  * but <inttypes.h> was present.
@@ -34,15 +37,12 @@
 #if	(!defined(__FreeBSD__) || !defined(_SYS_INTTYPES_H_))
 #if	defined(sun)
 #include <alloca.h>	/* For alloca(3) */
+#include <ieeefp.h>	/* for finite(3) */
 #else
 #include <stdint.h>	/* SUSv2+ and C99 specify this file, for uintXX_t */
-#endif
+#endif	/* defined(sun) */
 #endif
 
-#ifdef	WIN32
-#define	 snprintf	_snprintf
-#define	 vsnprintf	_vsnprintf
-#define	alloca(size)	_alloca(size)
 #endif	/* WIN32 */
 
 #ifndef	__GNUC__
diff --git a/skeletons/ber_tlv_length.c b/skeletons/ber_tlv_length.c
index 1534d9b..4f1ea88 100644
--- a/skeletons/ber_tlv_length.c
+++ b/skeletons/ber_tlv_length.c
@@ -155,7 +155,7 @@
 
 	if(len <= 127) {
 		/* Encoded in 1 octet */
-		if(size) *buf = len;
+		if(size) *buf = (uint8_t)len;
 		return 1;
 	}
 
@@ -172,14 +172,14 @@
 	if(size < required_size)
 		return required_size + 1;
 
-	*buf++ = 0x80 | required_size;	/* Length of the encoding */
+	*buf++ = (uint8_t)(0x80 | required_size);  /* Length of the encoding */
 
 	/*
 	 * Produce the len encoding, space permitting.
 	 */
 	end = buf + required_size;
 	for(i -= 8; buf < end; i -= 8, buf++)
-		*buf = (len >> i);
+		*buf = (uint8_t)(len >> i);
 
 	return required_size + 1;
 }
diff --git a/skeletons/xer_decoder.c b/skeletons/xer_decoder.c
index 0de6e33..07a1936 100644
--- a/skeletons/xer_decoder.c
+++ b/skeletons/xer_decoder.c
@@ -276,7 +276,7 @@
 			 */
 			if(opt_unexpected_tag_decoder
 			&& opt_unexpected_tag_decoder(struct_key,
-					buf_ptr, ch_size) == 0) {
+					buf_ptr, ch_size) >= 0) {
 				/* Tag's processed fine */
 				ADVANCE(ch_size);
 				if(!ctx->phase) {