read a file

master
Andrew Kelley 2015-08-05 16:22:21 -07:00
parent e66c34980c
commit 899c9fe94e
6 changed files with 300 additions and 50 deletions

View File

@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8)
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
"Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
project(zig C)
project(zig C CXX)
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
set(ZIG_VERSION_MAJOR 0)
@ -21,7 +21,8 @@ include_directories(
)
set(ZIG_SOURCES
"${CMAKE_SOURCE_DIR}/src/main.c"
"${CMAKE_SOURCE_DIR}/src/main.cpp"
"${CMAKE_SOURCE_DIR}/src/util.cpp"
)
set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")
@ -30,10 +31,13 @@ configure_file (
${CONFIGURE_OUT_FILE}
)
# GTFO, -lstdc++ !!
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-unused-variable -Wno-unused-but-set-variable")
set(EXE_CFLAGS "-std=c11 -Werror -Wall -Werror=strict-prototypes -Werror=old-style-definition -Werror=missing-prototypes")
set(TEST_CFLAGS "-std=c99 -Werror -Wall")
set(EXE_CFLAGS "-std=c++11 -Werror -Wall -Werror=strict-prototypes -Werror=old-style-definition -Werror=missing-prototypes")
add_executable(zig ${ZIG_SOURCES})

89
src/list.hpp Normal file
View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2015 Andrew Kelley
*
* This file is part of zig, which is MIT licensed.
* See http://opensource.org/licenses/MIT
*/
#ifndef GROOVE_LIST_HPP
#define GROOVE_LIST_HPP
#include "util.hpp"
#include <assert.h>
template<typename T>
struct GrooveList {
void deinit() {
deallocate(items);
}
void append(T item) {
int err = ensure_capacity(length + 1);
if (err)
return err;
items[length++] = item;
return 0;
}
// remember that the pointer to this item is invalid after you
// modify the length of the list
const T & at(int index) const {
assert(index >= 0);
assert(index < length);
return items[index];
}
T & at(int index) {
assert(index >= 0);
assert(index < length);
return items[index];
}
T pop() {
assert(length >= 1);
return items[--length];
}
void add_one() {
return resize(length + 1);
}
const T & last() const {
assert(length >= 1);
return items[length - 1];
}
T & last() {
assert(length >= 1);
return items[length - 1];
}
void resize(int new_length) {
assert(new_length >= 0);
int err = ensure_capacity(new_length);
if (err)
return err;
length = new_length;
return 0;
}
void clear() {
length = 0;
}
void ensure_capacity(int new_capacity) {
int better_capacity = max(capacity, 16);
while (better_capacity < new_capacity)
better_capacity = better_capacity * 2;
if (better_capacity != capacity) {
items = reallocate_nonzero(items, better_capacity);
capacity = better_capacity;
}
return 0;
}
T * items;
int length;
int capacity;
};
#endif

View File

@ -1,46 +0,0 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
static int usage(char *arg0) {
fprintf(stderr, "Usage: %s --output outfile code.zig\n"
"Other options:\n"
"--version print version number and exit\n"
, arg0);
return EXIT_FAILURE;
}
int main(int argc, char **argv) {
char *arg0 = argv[0];
char *in_file = NULL;
char *out_file = NULL;
for (int i = 1; i < argc; i += 1) {
char *arg = argv[i];
if (arg[0] == '-' && arg[1] == '-') {
if (strcmp(arg, "--version") == 0) {
printf("%s\n", ZIG_VERSION_STRING);
return EXIT_SUCCESS;
} else if (i + 1 >= argc) {
return usage(arg0);
} else {
i += 1;
if (strcmp(arg, "--output") == 0) {
out_file = argv[i];
} else {
return usage(arg0);
}
}
} else if (!in_file) {
in_file = arg;
} else {
return usage(arg0);
}
}
if (!in_file || !out_file)
return usage(arg0);
fprintf(stderr, "in: %s out: %s\n", in_file, out_file);
return EXIT_SUCCESS;
}

106
src/main.cpp Normal file
View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 2015 Andrew Kelley
*
* This file is part of zig, which is MIT licensed.
* See http://opensource.org/licenses/MIT
*/
#include "config.h"
#include "util.hpp"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <limits.h>
#include <stdint.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
struct Buf {
int len;
char ptr[0];
};
static Buf *alloc_buf(int size) {
Buf *buf = (Buf *)allocate_nonzero<char>(sizeof(Buf) + size + 1);
buf->len = size;
buf->ptr[buf->len] = 0;
return buf;
}
static int usage(char *arg0) {
fprintf(stderr, "Usage: %s --output outfile code.zig\n"
"Other options:\n"
"--version print version number and exit\n"
, arg0);
return EXIT_FAILURE;
}
static struct Buf *fetch_file(FILE *f) {
int fd = fileno(f);
struct stat st;
if (fstat(fd, &st))
zig_panic("unable to stat file: %s", strerror(errno));
off_t big_size = st.st_size;
if (big_size > INT_MAX)
zig_panic("file too big");
int size = (int)big_size;
Buf *buf = alloc_buf(size);
size_t amt_read = fread(buf->ptr, 1, buf->len, f);
if (amt_read != (size_t)buf->len)
zig_panic("error reading: %s", strerror(errno));
return buf;
}
int main(int argc, char **argv) {
char *arg0 = argv[0];
char *in_file = NULL;
char *out_file = NULL;
for (int i = 1; i < argc; i += 1) {
char *arg = argv[i];
if (arg[0] == '-' && arg[1] == '-') {
if (strcmp(arg, "--version") == 0) {
printf("%s\n", ZIG_VERSION_STRING);
return EXIT_SUCCESS;
} else if (i + 1 >= argc) {
return usage(arg0);
} else {
i += 1;
if (strcmp(arg, "--output") == 0) {
out_file = argv[i];
} else {
return usage(arg0);
}
}
} else if (!in_file) {
in_file = arg;
} else {
return usage(arg0);
}
}
if (!in_file || !out_file)
return usage(arg0);
FILE *in_f;
if (strcmp(in_file, "-") == 0) {
in_f = stdin;
} else {
in_f = fopen(in_file, "rb");
if (!in_f)
zig_panic("unable to open %s for reading: %s\n", in_file, strerror(errno));
}
struct Buf *in_data = fetch_file(in_f);
fprintf(stderr, "%s\n", in_data->ptr);
//tokenize(in_data);
return EXIT_SUCCESS;
}

46
src/util.cpp Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright (c) 2015 Andrew Kelley
*
* This file is part of zig, which is MIT licensed.
* See http://opensource.org/licenses/MIT
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include "util.hpp"
void zig_panic(const char *format, ...) {
va_list ap;
va_start(ap, format);
vfprintf(stderr, format, ap);
fprintf(stderr, "\n");
va_end(ap);
abort();
}
char *zig_alloc_sprintf(int *len, const char *format, ...) {
va_list ap, ap2;
va_start(ap, format);
va_copy(ap2, ap);
int len1 = vsnprintf(nullptr, 0, format, ap);
assert(len1 >= 0);
size_t required_size = len1 + 1;
char *mem = allocate<char>(required_size);
if (!mem)
return nullptr;
int len2 = vsnprintf(mem, required_size, format, ap2);
assert(len2 == len1);
va_end(ap2);
va_end(ap);
if (len)
*len = len1;
return mem;
}

51
src/util.hpp Normal file
View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2015 Andrew Kelley
*
* This file is part of zig, which is MIT licensed.
* See http://opensource.org/licenses/MIT
*/
#ifndef ZIG_UTIL_HPP
#define ZIG_UTIL_HPP
#include <stdlib.h>
#include <string.h>
#include <assert.h>
void zig_panic(const char *format, ...)
__attribute__((cold))
__attribute__ ((noreturn))
__attribute__ ((format (printf, 1, 2)));
template<typename T>
__attribute__((malloc)) static inline T *allocate_nonzero(size_t count) {
T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));
if (!ptr)
zig_panic("allocation failed");
return ptr;
}
template<typename T>
__attribute__((malloc)) static inline T *allocate(size_t count) {
T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));
if (!ptr)
zig_panic("allocation failed");
return ptr;
}
template<typename T>
static inline T *reallocate_nonzero(T * old, size_t new_count) {
T *ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
if (!ptr)
zig_panic("allocation failed");
return ptr;
}
char *zig_alloc_sprintf(int *len, const char *format, ...)
__attribute__ ((format (printf, 2, 3)));
template <typename T, long n>
constexpr long array_length(const T (&)[n]) {
return n;
}
#endif