-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
--- /dev/null
+#------------------------------------------------------------------------------
+# 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}
+
--- /dev/null
+#------------------------------------------------------------------------------
+# 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
--- /dev/null
+/* Includes
+ *****************************************************************************/
+#include <util.h>
+
+/* 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;
+}
--- /dev/null
+#ifndef UTIL_H
+#define UTIL_H
+
+/* Standard Macros and Types */
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <errno.h>
+
+/* Usefule Standard Functions */
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+/* 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