From: Michael D. Lowis Date: Fri, 1 Jan 2016 16:07:31 +0000 (-0500) Subject: Initial commit. Can read a file's contents and write it to stdout X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=111bf627839289b2c7968677c7a40215d647cedb;p=projs%2Ftide.git Initial commit. Can read a file's contents and write it to stdout --- diff --git a/LICENSE b/LICENSE.md similarity index 96% rename from LICENSE rename to LICENSE.md index 9a1cb02..060aa51 100644 --- a/LICENSE +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2016, mikedlowis-prototypes +Copyright (c) 2016, Michael D. Lowis All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..50ba670 --- /dev/null +++ b/Makefile @@ -0,0 +1,79 @@ +#------------------------------------------------------------------------------ +# Build Configuration +#------------------------------------------------------------------------------ +# name and version +PROJNAME = edit +VERSION = 0.0.1 + +# tools +CC = c99 +LD = ${CC} + +# flags +INCS = -Isource/ +CPPFLAGS = -D_XOPEN_SOURCE=700 +CFLAGS = ${INCS} ${CPPFLAGS} +LDFLAGS = ${LIBS} + +# commands +COMPILE = @echo CC $@; ${CC} ${CFLAGS} -c -o $@ $< +LINK = @echo LD $@; ${LD} -o $@ $^ ${LDFLAGS} +CLEAN = @rm -f + +#------------------------------------------------------------------------------ +# Build-Specific Macros +#------------------------------------------------------------------------------ +# library macros +BIN = ${PROJNAME} +DEPS = ${OBJS:.o=.d} +OBJS = source/main.o + +# distribution dir and tarball settings +DISTDIR = ${PROJNAME}-${VERSION} +DISTTAR = ${DISTDIR}.tar +DISTGZ = ${DISTTAR}.gz +DISTFILES = config.mk LICENSE.md Makefile README.md source + +# load user-specific settings +-include config.mk + +#------------------------------------------------------------------------------ +# Phony Targets +#------------------------------------------------------------------------------ +.PHONY: all options tests + +all: options ${BIN} + +options: + @echo "Toolchain Configuration:" + @echo " CC = ${CC}" + @echo " CFLAGS = ${CFLAGS}" + @echo " LD = ${LD}" + @echo " LDFLAGS = ${LDFLAGS}" + +dist: clean + @echo DIST ${DISTGZ} + @mkdir -p ${DISTDIR} + @cp -R ${DISTFILES} ${DISTDIR} + @tar -cf ${DISTTAR} ${DISTDIR} + @gzip ${DISTTAR} + @rm -rf ${DISTDIR} + +clean: + ${CLEAN} ${DEPS} + ${CLEAN} ${BIN} ${OBJS} + ${CLEAN} ${OBJS:.o=.gcno} ${OBJS:.o=.gcda} + ${CLEAN} ${DISTTAR} ${DISTGZ} + +#------------------------------------------------------------------------------ +# Target-Specific Rules +#------------------------------------------------------------------------------ +.c.o: + ${COMPILE} + +${BIN}: ${OBJS} + ${LINK} + +# load dependency files +-include ${DEPS} + diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..2176092 --- /dev/null +++ b/config.mk @@ -0,0 +1,17 @@ +#------------------------------------------------------------------------------ +# User and Platform Specific Configuration Options +#------------------------------------------------------------------------------ +# Override the tools used with platform specific ones +#CC = cc +#LD = ${CC} +#AR = ar + +# GCC dependency generation +#COMPILE += && gcc ${INCS} -MM -MT $@ -MF ${@:.o=.d} ${<:.o=.c} + +# Enable output of debug symbols +#CFLAGS += -g + +# Enable output of coverage information +#CFLAGS += --coverage +#LDFLAGS += --coverage diff --git a/source/main.c b/source/main.c new file mode 100644 index 0000000..96d79b4 --- /dev/null +++ b/source/main.c @@ -0,0 +1,80 @@ +/* Includes + *****************************************************************************/ +#include + +/* Type Definitions + *****************************************************************************/ +typedef struct Line { + struct Line* prev; + struct Line* next; + size_t length; + char* text; +} Line; + +typedef struct { + char* name; + Line* first; + Line* last; +} File; + +/* Globals + *****************************************************************************/ +File Curr_File = { .name = NULL, .first = NULL, .last = NULL }; + +/* Declarations + *****************************************************************************/ +static void setup(void); +static void cleanup(void); +static void load(char* fname); +static void edit(void); + +/* Definitions + *****************************************************************************/ +static void setup(void) +{ +} + +static void cleanup(void) +{ +} + +static void load(char* fname) +{ + FILE* file = efopen(fname, "r"); + while (!feof(file)) { + Line* line = (Line*)ecalloc(1,sizeof(Line)); + line->text = efreadline(file); + if (Curr_File.first == NULL) { + Curr_File.first = line; + Curr_File.last = line; + } else { + Curr_File.last->next = line; + line->prev = Curr_File.last; + Curr_File.last = line; + } + } +} + +static void edit(void) +{ + Line* line = Curr_File.first; + while (line) { + printf("%s", line->text); + line = line->next; + } +} + +/* Main Routine + *****************************************************************************/ +int main(int argc, char** argv) +{ + setup(); + if (argc > 1) { + load(argv[1]); + edit(); + } else { + die("no filename provided"); + } + cleanup(); + return EXIT_SUCCESS; +} diff --git a/source/util.h b/source/util.h new file mode 100644 index 0000000..7c5ea5d --- /dev/null +++ b/source/util.h @@ -0,0 +1,105 @@ +#ifndef UTIL_H +#define UTIL_H + +/* Standard Macros and Types */ +#include +#include +#include +#include + +/* Usefule Standard Functions */ +#include +#include +#include +#include +#include + +/* Generic Death Function */ +static void die(const char* msgfmt, ...) +{ + va_list args; + va_start(args, msgfmt); + fprintf(stderr, "Error: "); + vfprintf(stderr, msgfmt, args); + fprintf(stderr, "\n"); + va_end(args); + exit(EXIT_FAILURE); +} + +/* Signal Handling */ +static void esignal(int sig, void (*func)(int)) +{ + errno = 0; + func = signal(sig, func); + if (func == SIG_ERR || errno > 0) + die("failed to register signal handler for signal %d", sig); +} + +static int eraise(int sig) +{ + int ret; + if ((ret = raise(sig)) != 0) + die("failed to raise signal %d", sig); + return ret; +} + +/* Dynamic Allocation */ +static void* ecalloc(size_t num, size_t size) +{ + void* ret; + if (NULL == (ret = calloc(num,size))) + die("out of memory"); + return ret; +} + +static void* emalloc(size_t size) +{ + void* ret; + if (NULL == (ret = malloc(size))) + die("out of memory"); + return ret; +} + +static void* erealloc(void* ptr, size_t size) +{ + void* ret; + if (NULL == (ret = realloc(ptr,size))) + die("out of memory"); + return ret; +} + +/* File Handling */ +static FILE* efopen(const char* filename, const char* mode) +{ + FILE* file; + errno = 0; + if (NULL == (file = fopen(filename, mode)) || errno != 0) + die("failed to open file: %s", filename); + return file; +} + +static char* efreadline(FILE* input) +{ + size_t size = 8; + size_t index = 0; + char* str = (char*)emalloc(size); + memset(str, 0, 8); + if (feof(input)) { + free(str); + return NULL; + } + while(true) { + char ch = fgetc(input); + if (ch == EOF) break; + str[index++] = ch; + str[index] = '\0'; + if (index+1 >= size) { + size = size << 1; + str = erealloc(str, size); + } + if (ch == '\n') break; + } + return str; +} + +#endif