aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--compat-linux.c53
-rw-r--r--compat.h31
-rw-r--r--expression.c3
-rw-r--r--lib.c19
-rw-r--r--lib.h2
-rw-r--r--tokenize.c4
7 files changed, 92 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index 33bfc80..0360edf 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,5 @@
+OS=linux
+
CC=gcc
CFLAGS=-O -g -Wall -Wwrite-strings
LDFLAGS=-g
@@ -11,7 +13,7 @@ LIB_H= token.h parse.h lib.h symbol.h scope.h expression.h target.h \
LIB_OBJS= target.o parse.o tokenize.o pre-process.o symbol.o lib.o scope.o \
expression.o show-parse.o evaluate.o expand.o inline.o linearize.o \
- sort.o
+ sort.o compat-$(OS).o
LIB_FILE= sparse.a
LIBS=$(LIB_FILE)
diff --git a/compat-linux.c b/compat-linux.c
new file mode 100644
index 0000000..afa278b
--- /dev/null
+++ b/compat-linux.c
@@ -0,0 +1,53 @@
+/*
+ * Sane compat.c for Linux
+ */
+#define _GNU_SOURCE
+
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "lib.h"
+#include "token.h"
+
+/*
+ * Allow old BSD naming too, it would be a pity to have to make a
+ * separate file just for this.
+ */
+#ifndef MAP_ANONYMOUS
+#define MAP_ANONYMOUS MAP_ANON
+#endif
+
+/*
+ * Our blob allocator enforces the strict CHUNK size
+ * requirement, as a portability check.
+ */
+void *blob_alloc(unsigned long size)
+{
+ void *ptr;
+
+ if (size & ~CHUNK)
+ die("internal error: bad allocation size (%d bytes)", size);
+ ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (ptr == MAP_FAILED)
+ ptr = NULL;
+ return ptr;
+}
+
+void blob_free(void *addr, unsigned long size)
+{
+ if (!size || (size & ~CHUNK) || ((unsigned long) addr & 512))
+ die("internal error: bad blob free (%d bytes at %p)", size, addr);
+ munmap(addr, size);
+}
+
+long double string_to_ld(const char *nptr, char **endptr)
+{
+ return strtold(nptr, endptr);
+}
+
+int identical_files(struct stream* s, struct stat *st, const char * name)
+{
+ return s->dev == st->st_dev && s->ino == st->st_ino;
+}
diff --git a/compat.h b/compat.h
new file mode 100644
index 0000000..fecfcb1
--- /dev/null
+++ b/compat.h
@@ -0,0 +1,31 @@
+#ifndef COMPAT_H
+#define COMPAT_H
+
+/*
+ * Various systems get these things wrong. So
+ * we create a small compat library for them.
+ *
+ * - zeroed anonymous mmap
+ * Missing in mingw
+ * - "string to long double" (C99 strtold())
+ * Missing in Solaris and mingw
+ * - checking for file identity (POSIX st_dev && st_ino comparison)
+ * mingw needs to check the name (st_dev/st_ino are zero)
+ */
+struct stream;
+struct stat;
+
+/*
+ * Our "blob" allocator works on chunks that are multiples
+ * of this size (the underlying allocator may be a mmap that
+ * cannot handle smaller chunks, for example, so trying to
+ * allocate blobs that aren't aligned is not going to work).
+ */
+#define CHUNK 32768
+
+void *blob_alloc(unsigned long size);
+void blob_free(void *addr, unsigned long size);
+long double string_to_ld(const char *nptr, char **endptr);
+int identical_files(struct stream* s, struct stat *st, const char * name);
+
+#endif
diff --git a/expression.c b/expression.c
index c5cff5c..f0ec572 100644
--- a/expression.c
+++ b/expression.c
@@ -8,7 +8,6 @@
*
* This is the expression parsing part of parsing C.
*/
-#define _ISOC99_SOURCE
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
@@ -204,7 +203,7 @@ Eoverflow:
show_token(token));
return;
Float:
- expr->fvalue = strtold(str, &end);
+ expr->fvalue = string_to_ld(str, &end);
if (str == end)
goto Enoint;
diff --git a/lib.c b/lib.c
index 9204c09..9d0fc75 100644
--- a/lib.c
+++ b/lib.c
@@ -14,7 +14,6 @@
#include <stdlib.h>
#include <string.h>
-#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -82,24 +81,6 @@ struct allocation_blob {
unsigned char data[];
};
-#define CHUNK 32768
-
-static void *blob_alloc (size_t size)
-{
- void *ptr;
- size = (size + 4095) & ~4095;
- ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- if (ptr == MAP_FAILED)
- ptr = NULL;
- return ptr;
-}
-
-static void blob_free (void *addr, size_t size)
-{
- size = (size + 4095) & ~4095;
- munmap(addr, size);
-}
-
struct allocator_struct {
const char *name;
struct allocation_blob *blobs;
diff --git a/lib.h b/lib.h
index c6ea1da..0c1e1f3 100644
--- a/lib.h
+++ b/lib.h
@@ -10,6 +10,8 @@
* Licensed under the Open Software License version 1.1
*/
+#include "compat.h"
+
extern unsigned int hexval(unsigned int c);
struct position {
diff --git a/tokenize.c b/tokenize.c
index 742997e..180b523 100644
--- a/tokenize.c
+++ b/tokenize.c
@@ -170,8 +170,8 @@ int init_stream(const char *name, int fd, const char **next_path)
for (i = 0; i < stream; i++) {
struct stream *s = input_streams + i;
- if (s->dev == st.st_dev && s->ino == st.st_ino &&
- s->constant == CONSTANT_FILE_YES &&
+ if (s->constant == CONSTANT_FILE_YES &&
+ identical_files(s, &st, name) &&
lookup_symbol(s->protect, NS_MACRO))
return -1;
}