diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | compat-linux.c | 53 | ||||
-rw-r--r-- | compat.h | 31 | ||||
-rw-r--r-- | expression.c | 3 | ||||
-rw-r--r-- | lib.c | 19 | ||||
-rw-r--r-- | lib.h | 2 | ||||
-rw-r--r-- | tokenize.c | 4 |
7 files changed, 92 insertions, 24 deletions
@@ -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; @@ -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; @@ -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 { @@ -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; } |