aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@users.noreply.github.com>2020-05-26 14:43:00 -0400
committerGitHub <noreply@github.com>2020-05-26 14:43:00 -0400
commitdf0686fb8b6fefebda0548d39caad2622e2bce89 (patch)
treecbd2d92667a0ab45221a220948f6ee33b2926a1c
parentc205840e737b23614a686a9675b896106cee5c64 (diff)
parent065d39bff58c02719abf5a710b22d8355ff1b19d (diff)
downloadspmc-df0686fb8b6fefebda0548d39caad2622e2bce89.tar.gz
Merge pull request #38 from jhunkeler/from-file
From file
-rw-r--r--include/error_handler.h2
-rw-r--r--include/fs.h3
-rw-r--r--include/mirrors.h1
-rw-r--r--include/strlist.h3
-rw-r--r--lib/error_handler.c5
-rw-r--r--lib/fs.c98
-rw-r--r--lib/install.c16
-rw-r--r--lib/mirrors.c81
-rw-r--r--lib/strlist.c115
-rw-r--r--src/spm.c56
-rw-r--r--tests/test_strlist.c60
11 files changed, 313 insertions, 127 deletions
diff --git a/include/error_handler.h b/include/error_handler.h
index eaf6420..5e1639b 100644
--- a/include/error_handler.h
+++ b/include/error_handler.h
@@ -18,6 +18,7 @@
#define SPM_ERR_MANIFEST_EMPTY _SPM_ERR(8) // manifest file has no data
#define SPM_ERR_PARSE _SPM_ERR(9) // general parsing error
#define SPM_ERR_NOT_IMPLEMENTED _SPM_ERR(10) // not implemented (does exist on this platform)
+#define SPM_ERR_FETCH _SPM_ERR(11) // failed to download data (non-package)
extern int spmerrno;
extern const char *SPM_ERR_STRING[];
@@ -25,5 +26,6 @@ extern const char *SPM_ERR_STRING[];
void spmerrno_cause(const char *reason);
char *spm_strerror(int code);
void spm_perror(const char *msg);
+void spm_die(void);
#endif //SPM_ERROR_HANDLER_H
diff --git a/include/fs.h b/include/fs.h
index c41b649..81acd92 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -41,6 +41,5 @@ char *human_readable_size(uint64_t n);
char *expandpath(const char *_path);
char *spm_mkdtemp(const char *base, const char *name, const char *extended_path);
int touch(const char *path);
-
-
+char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn *readerFn);
#endif //SPM_FSTREE_H
diff --git a/include/mirrors.h b/include/mirrors.h
index c9c5c23..dd4b256 100644
--- a/include/mirrors.h
+++ b/include/mirrors.h
@@ -7,7 +7,6 @@
#define SPM_MIRROR_MAX 0xff
#define SPM_MIRROR_FILENAME "mirrorlist"
-char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn *readerFn);
char **mirror_list(const char *filename);
void mirror_list_free(char **m);
void mirror_clone(Manifest *info, char *dest);
diff --git a/include/strlist.h b/include/strlist.h
index 76b6d5f..55a784f 100644
--- a/include/strlist.h
+++ b/include/strlist.h
@@ -4,6 +4,7 @@
*/
#ifndef SPM_STRLIST_H
#define SPM_STRLIST_H
+#include "metadata.h"
typedef struct {
size_t num_alloc;
@@ -26,13 +27,13 @@ unsigned short strlist_item_as_ushort(StrList *pStrList, size_t index);
short strlist_item_as_short(StrList *pStrList, size_t index);
unsigned char strlist_item_as_uchar(StrList *pStrList, size_t index);
char strlist_item_as_char(StrList *pStrList, size_t index);
-unsigned char strlist_item_as_uchar(StrList *pStrList, size_t index);
char *strlist_item_as_str(StrList *pStrList, size_t index);
char *strlist_item(StrList *pStrList, size_t index);
void strlist_set(StrList *pStrList, size_t index, char *value);
size_t strlist_count(StrList *pStrList);
void strlist_reverse(StrList *pStrList);
void strlist_sort(StrList *pStrList, unsigned int mode);
+int strlist_append_file(StrList *pStrList, char *path, ReaderFn *readerFn);
void strlist_append_strlist(StrList *pStrList1, StrList *pStrList2);
void strlist_append(StrList *pStrList, char *str);
StrList *strlist_copy(StrList *pStrList);
diff --git a/lib/error_handler.c b/lib/error_handler.c
index 2ccb4e7..5130f3a 100644
--- a/lib/error_handler.c
+++ b/lib/error_handler.c
@@ -15,6 +15,7 @@ const char *SPM_ERR_STRING[] = {
"Manifest has no data",
"Parsing error",
"Not implemented",
+ "Failed to fetch data",
NULL,
};
@@ -55,3 +56,7 @@ void spm_perror(const char *msg) {
fprintf(stderr, "%s: %s\n", msg ? msg : "", spm_strerror(spmerrno));
}
+void spm_die(void) {
+ spm_perror("FATAL");
+ exit(1);
+}
diff --git a/lib/fs.c b/lib/fs.c
index 20a5999..e75c6a0 100644
--- a/lib/fs.c
+++ b/lib/fs.c
@@ -641,3 +641,101 @@ char *spm_mkdtemp(const char *base, const char *name, const char *extended_path)
return 0;
}
+
+char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn *readerFn) {
+ FILE *fp = NULL;
+ char **result = NULL;
+ char *buffer = NULL;
+ size_t lines = 0;
+ int use_stdin = 0;
+
+ if (strcmp(filename, "-") == 0) {
+ use_stdin = 1;
+ }
+
+ if (use_stdin) {
+ fp = stdin;
+ } else {
+ fp = fopen(filename, "r");
+ }
+
+ if (fp == NULL) {
+ perror(filename);
+ fprintf(SYSERROR);
+ return NULL;
+ }
+
+ // Allocate buffer
+ if ((buffer = calloc(BUFSIZ, sizeof(char))) == NULL) {
+ perror("line buffer");
+ fprintf(SYSERROR);
+ if (!use_stdin) {
+ fclose(fp);
+ }
+ return NULL;
+ }
+
+ // count number the of lines in the file
+ while ((fgets(buffer, BUFSIZ - 1, fp)) != NULL) {
+ lines++;
+ }
+
+ if (!lines) {
+ free(buffer);
+ if (!use_stdin) {
+ fclose(fp);
+ }
+ return NULL;
+ }
+
+ rewind(fp);
+
+ // Handle invalid start offset
+ if (start > lines) {
+ start = 0;
+ }
+
+ // Adjust line count when start offset is non-zero
+ if (start != 0 && start < lines) {
+ lines -= start;
+ }
+
+
+ // Handle minimum and maximum limits
+ if (limit == 0 || limit > lines) {
+ limit = lines;
+ }
+
+ // Populate results array
+ result = calloc(limit + 1, sizeof(char *));
+ for (size_t i = start; i < limit; i++) {
+ if (i < start) {
+ continue;
+ }
+
+ if (fgets(buffer, BUFSIZ - 1, fp) == NULL) {
+ break;
+ }
+
+ if (readerFn != NULL) {
+ int status = readerFn(i - start, &buffer);
+ // A status greater than zero indicates we should ignore this line entirely and "continue"
+ // A status less than zero indicates we should "break"
+ // A zero status proceeds normally
+ if (status > 0) {
+ i--;
+ continue;
+ } else if (status < 0) {
+ break;
+ }
+ }
+ result[i] = strdup(buffer);
+ memset(buffer, '\0', BUFSIZ);
+ }
+
+ free(buffer);
+ if (!use_stdin) {
+ fclose(fp);
+ }
+ return result;
+} \ No newline at end of file
diff --git a/lib/install.c b/lib/install.c
index 9fb80c2..282c662 100644
--- a/lib/install.c
+++ b/lib/install.c
@@ -201,16 +201,24 @@ int spm_do_install(SPM_Hierarchy *fs, ManifestList *mf, StrList *packages) {
ManifestPackage **requirements = NULL;
char source[PATH_MAX];
char *tmpdir = NULL;
+ size_t package_count;
+
+ package_count = strlist_count(packages);
+ if (package_count == 0) {
+ spmerrno = SPM_ERR_PKG_NOT_FOUND;
+ spmerrno_cause("EMPTY PACKAGE LIST");
+ return -1;
+ }
// Produce a dependency tree from requested package(s)
- for (size_t i = 0; i < strlist_count(packages); i++) {
+ for (size_t i = 0; i < package_count; i++) {
char *item = strlist_item(packages, i);
// Does the package exist in the manifest?
if (manifestlist_search(mf, item) == NULL) {
spmerrno = SPM_ERR_PKG_NOT_FOUND;
spmerrno_cause(item);
- break;
+ return -1;
}
requirements = resolve_dependencies(mf, item);
@@ -221,10 +229,6 @@ int spm_do_install(SPM_Hierarchy *fs, ManifestList *mf, StrList *packages) {
}
}
- if (spmerrno) {
- return -1;
- }
-
tmpdir = spm_mkdtemp(TMP_DIR, "spm_destroot", NULL);
if (tmpdir == NULL) {
perror("Could not create temporary destination root");
diff --git a/lib/mirrors.c b/lib/mirrors.c
index 6bc7aed..1c51845 100644
--- a/lib/mirrors.c
+++ b/lib/mirrors.c
@@ -1,87 +1,6 @@
#include "spm.h"
#include "url.h"
-char **file_readlines(const char *filename, size_t start, size_t limit, ReaderFn *readerFn) {
- FILE *fp = NULL;
- char **result = NULL;
- char *buffer = NULL;
- size_t lines = 0;
-
- if ((fp = fopen(filename, "r")) == NULL) {
- perror(filename);
- fprintf(SYSERROR);
- return NULL;
- }
-
- // Allocate buffer
- if ((buffer = calloc(BUFSIZ, sizeof(char))) == NULL) {
- perror("line buffer");
- fprintf(SYSERROR);
- fclose(fp);
- return NULL;
- }
-
- // count number the of lines in the file
- while ((fgets(buffer, BUFSIZ - 1, fp)) != NULL) {
- lines++;
- }
-
- if (!lines) {
- free(buffer);
- fclose(fp);
- return NULL;
- }
-
- rewind(fp);
-
- // Handle invalid start offset
- if (start > lines) {
- start = 0;
- }
-
- // Adjust line count when start offset is non-zero
- if (start != 0 && start < lines) {
- lines -= start;
- }
-
-
- // Handle minimum and maximum limits
- if (limit == 0 || limit > lines) {
- limit = lines;
- }
-
- // Populate results array
- result = calloc(limit + 1, sizeof(char *));
- for (size_t i = start; i < limit; i++) {
- if (i < start) {
- continue;
- }
-
- if (fgets(buffer, BUFSIZ - 1, fp) == NULL) {
- break;
- }
-
- if (readerFn != NULL) {
- int status = readerFn(i - start, &buffer);
- // A status greater than zero indicates we should ignore this line entirely and "continue"
- // A status less than zero indicates we should "break"
- // A zero status proceeds normally
- if (status > 0) {
- i--;
- continue;
- } else if (status < 0) {
- break;
- }
- }
- result[i] = strdup(buffer);
- memset(buffer, '\0', BUFSIZ);
- }
-
- free(buffer);
- fclose(fp);
- return result;
-}
-
/**
*
* @param filename
diff --git a/lib/strlist.c b/lib/strlist.c
index aac2755..f90cce4 100644
--- a/lib/strlist.c
+++ b/lib/strlist.c
@@ -4,6 +4,7 @@
*/
#include "spm.h"
#include "strlist.h"
+#include "url.h"
/**
*
@@ -46,21 +47,98 @@ void strlist_append(StrList *pStrList, char *str) {
pStrList->num_alloc++;
}
+static int reader_strlist_append_file(size_t lineno, char **line) {
+ (void)(lineno); // unused parameter
+ (void)(line); // unused parameter
+ return 0;
+}
+
/**
- * Produce a new copy of a `StrList`
- * @param pStrList `StrList`
- * @return `StrList` copy
+ * Append lines from a local file or remote URL (HTTP/s only)
+ * @param pStrList
+ * @param path file path or HTTP/s address
+ * @param readerFn pointer to a reader function (use NULL to retrieve all data)
+ * @return 0=success 1=no data, -1=error (spmerrno set)
*/
-StrList *strlist_copy(StrList *pStrList) {
- StrList *result = strlist_init();
- if (pStrList == NULL || result == NULL) {
- return NULL;
+int strlist_append_file(StrList *pStrList, char *_path, ReaderFn *readerFn) {
+ int retval = 0;
+ int is_remote = 0;
+ char *path = NULL;
+ char *filename = NULL;
+ char *from_file_tmpdir = NULL;
+ char **data = NULL;
+
+ if (readerFn == NULL) {
+ readerFn = reader_strlist_append_file;
}
- for (size_t i = 0; i < strlist_count(pStrList); i++) {
- strlist_append(result, strlist_item(pStrList, i));
+ path = strdup(_path);
+ if (path == NULL) {
+ spmerrno = errno;
+ retval = -1;
+ goto fatal;
}
- return result;
+
+ is_remote = (startswith(path, "http") || startswith(path, "https"));
+ if (is_remote) {
+ long response = 0;
+ char *fetched = NULL;
+ from_file_tmpdir = spm_mkdtemp(TMP_DIR, __FUNCTION__, NULL);
+
+ if (from_file_tmpdir == NULL) {
+ spmerrno = errno;
+ spmerrno_cause("file_from temp directory");
+ retval = -1;
+ goto fatal;
+ }
+
+ fetched = join((char *[]){from_file_tmpdir, basename(path), NULL}, DIRSEPS);
+ if ((response = fetch(path, fetched)) >= 400) {
+ spmerrno = SPM_ERR_FETCH;
+ char cause[PATH_MAX];
+ sprintf(cause, "HTTP(%ld): %s: %s", response, http_response_str(response), path);
+ spmerrno_cause(cause);
+ retval = -1;
+ goto fatal;
+ }
+
+ filename = strdup(fetched);
+ free(fetched);
+ } else {
+ filename = expandpath(path);
+ }
+
+ if (filename == NULL) {
+ spmerrno = errno;
+ retval = -1;
+ goto fatal;
+ }
+
+ data = file_readlines(filename, 0, 0, readerFn);
+ if (data == NULL) {
+ retval = 1;
+ goto fatal;
+ }
+
+ for (size_t record = 0; data[record] != NULL; record++) {
+ strlist_append(pStrList, data[record]);
+ free(data[record]);
+ }
+ free(data);
+
+fatal:
+ if (from_file_tmpdir != NULL) {
+ rmdirs(from_file_tmpdir);
+ free(from_file_tmpdir);
+ }
+ if (filename != NULL) {
+ free(filename);
+ }
+ if (path != NULL) {
+ free(path);
+ }
+
+ return retval;
}
/**
@@ -83,6 +161,23 @@ void strlist_append_strlist(StrList *pStrList1, StrList *pStrList2) {
}
/**
+ * Produce a new copy of a `StrList`
+ * @param pStrList `StrList`
+ * @return `StrList` copy
+ */
+StrList *strlist_copy(StrList *pStrList) {
+ StrList *result = strlist_init();
+ if (pStrList == NULL || result == NULL) {
+ return NULL;
+ }
+
+ for (size_t i = 0; i < strlist_count(pStrList); i++) {
+ strlist_append(result, strlist_item(pStrList, i));
+ }
+ return result;
+}
+
+/**
* Remove a record by index from a `StrList`
* @param pStrList
* @param index
diff --git a/src/spm.c b/src/spm.c
index 971d506..bdaab23 100644
--- a/src/spm.c
+++ b/src/spm.c
@@ -10,8 +10,9 @@ int RUNTIME_INSTALL = 0;
int RUNTIME_ROOTDIR = 0;
int RUNTIME_LIST = 0;
int RUNTIME_SEARCH = 0;
+char *program_name = NULL;
-void usage(const char *program_name) {
+void usage(void) {
printf("usage: %s [-hVvBIRrmMLS]\n"
" -h, --help show this help message\n"
" -V, --version show version\n"
@@ -30,8 +31,18 @@ void usage(const char *program_name) {
}
extern spm_vars SPM_GLOBAL;
+
+static int reader_install_strlist_append_file(size_t lineno, char **line) {
+ (void)(lineno); // unused parameter
+ (*line) = strip((*line));
+ if (isempty((*line)) || startswith((*line), "#") || startswith((*line), ";") || startswith((*line), "//")) {
+ return 1; // indicate "continue"
+ }
+ return 0; // indicate "ok"
+}
+
int main(int argc, char *argv[], char *arge[]) {
- char *program_name = strdup(argv[0]);
+ program_name = strdup(argv[0]);
// not much to see here yet
// at the moment this will all be random tests, for better or worse
@@ -53,7 +64,7 @@ int main(int argc, char *argv[], char *arge[]) {
memset(package_search_str, '\0', PATH_MAX);
if (argc < 2) {
- usage(program_name);
+ usage();
exit(1);
}
@@ -66,7 +77,7 @@ int main(int argc, char *argv[], char *arge[]) {
// options
if (*arg == '-' || strncmp(arg, "--", 2) == 0) {
if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) {
- usage(program_name);
+ usage();
exit(0);
}
else if (strcmp(arg, "-V") == 0 || strcmp(arg, "--version") == 0) {
@@ -85,7 +96,7 @@ int main(int argc, char *argv[], char *arge[]) {
else if (strcmp(arg, "-m") == 0 || strcmp(arg, "--manifest") == 0) {
if (arg_next == NULL) {
fprintf(stderr, "-m|--manifest requires a directory path\n");
- usage(program_name);
+ usage();
exit(1);
}
manifestlist_append(mf, arg_next);
@@ -116,7 +127,7 @@ int main(int argc, char *argv[], char *arge[]) {
RUNTIME_SEARCH = 1;
if (arg_next == NULL) {
fprintf(stderr, "--search requires a package name\n");
- usage(program_name);
+ usage();
exit(1);
}
strncpy(package_search_str, arg_next, strlen(arg_next));
@@ -126,7 +137,7 @@ int main(int argc, char *argv[], char *arge[]) {
RUNTIME_ROOTDIR = 1;
if (!arg_next) {
fprintf(stderr, "-r|--root requires a path\n");
- usage(program_name);
+ usage();
exit(1);
}
@@ -150,12 +161,29 @@ int main(int argc, char *argv[], char *arge[]) {
}
if ((argc - i) == 0) {
fprintf(stderr, "-R|--remove requires at least one package\n");
- usage(program_name);
+ usage();
exit(1);
}
strlist_append(packages, argv[i]);
}
}
+ else if (strcmp(arg, "-F") == 0 || strcmp(arg, "--from-file") == 0) {
+ RUNTIME_INSTALL = 1;
+ i++;
+ char *next = argv[i];
+ int retval = 0;
+
+ if (next == NULL || startswith(next, "--")) { // do not trap '-' (stdin)
+ fprintf(stderr, "-F|--from-file requires a file path\n");
+ usage();
+ exit(1);
+ }
+
+ retval = strlist_append_file(packages, next, reader_install_strlist_append_file);
+ if (retval < 0) {
+ spm_die();
+ }
+ }
else if (strcmp(arg, "-I") == 0 || strcmp(arg, "--install") == 0) {
RUNTIME_INSTALL = 1;
for (int p = 0; i < argc; p++) {
@@ -167,7 +195,7 @@ int main(int argc, char *argv[], char *arge[]) {
}
if ((argc - i) == 0) {
fprintf(stderr, "-I|--install requires at least one package\n");
- usage(program_name);
+ usage();
exit(1);
}
strlist_append(packages, next);
@@ -176,11 +204,15 @@ int main(int argc, char *argv[], char *arge[]) {
}
else {
printf("Unknown option: %s\n", arg);
- usage(program_name);
+ usage();
exit(1);
}
}
+ if (spmerrno) {
+ spm_die();
+ }
+
// Apply some default manifest locations; unless the user passes -M|--override-manifests
if (override_manifests == 0) {
// Remote package manifests have priority over the local package store
@@ -196,11 +228,11 @@ int main(int argc, char *argv[], char *arge[]) {
if (!RUNTIME_ROOTDIR && RUNTIME_INSTALL) {
fprintf(stderr, "-r|--root requires -I|--install\n");
- usage(program_name);
+ usage();
exit(1);
} else if (!RUNTIME_ROOTDIR && RUNTIME_REMOVE) {
fprintf(stderr, "-r|--root requires -R|--remove\n");
- usage(program_name);
+ usage();
exit(1);
}
diff --git a/tests/test_strlist.c b/tests/test_strlist.c
index fc1ec4b..f5463dc 100644
--- a/tests/test_strlist.c
+++ b/tests/test_strlist.c
@@ -41,6 +41,11 @@ enum truthValue {
uint64_max,
};
+char *testfile_truth[] = {
+ "a", "b", "c", "d", "e", "f", "g", "h",
+ NULL,
+};
+
int main(int argc, char *argv[]) {
const char *storyFmt = "expected story: '%s', but got '%s'\n";
@@ -48,13 +53,15 @@ int main(int argc, char *argv[]) {
union TestValue testValue = {0,};
StrList *strList = NULL;
StrList *strListCopy = NULL;
- StrList *strListNumbers = NULL;
StrList truthInit = {1, 0, NULL};
size_t used = 0;
size_t allocated = 0;
char intStr[255];
const int DATA_SIZE = (sizeof(DATA) / sizeof(char *)) - 1;
+ StrList *testfile_list = NULL;
+ char testfile[PATH_MAX];
+ char *testfile_data;
// Initialize string list and check initial state
strList = strlist_init();
@@ -101,13 +108,13 @@ int main(int argc, char *argv[]) {
myassert(strListCopy != NULL, "strlist_copy failed\n");
// Now compare the arrays to make sure they're identical
- myassert(strlist_cmp(strList, strListCopy) == 0, "strlist_copy result does not match original StrList contents");
+ myassert(strlist_cmp(strList, strListCopy) == 0, "strlist_copy result does not match original StrList contents\n");
// Sort the array to see if it works.
strlist_sort(strListCopy, SPM_SORT_LEN_ASCENDING);
// The array just got modified, so check to make sure they are NOT identical
- myassert(strlist_cmp(strList, strListCopy) == 1, "StrList data matches original StrList contents (after modification)");
+ myassert(strlist_cmp(strList, strListCopy) == 1, "StrList data matches original StrList contents (after modification)\n");
story = join(strListCopy->data, " ");
myassert(strcmp(story, story_truth_sort_asc) == 0, storyFmt, story_truth_sort_asc, story);
@@ -145,38 +152,63 @@ int main(int argc, char *argv[]) {
// NOTE: My focus is on 64-bit, so if you're compiling this on a 32-bit computer
// and these tests fail for you... That's a shame.
testValue.signed_char = strlist_item_as_char(strList, DATA_SIZE + int8_max);
- myassert(testValue.signed_char == INT8_MAX, "int8_max incorrect: %d", testValue.signed_char);
+ myassert(testValue.signed_char == INT8_MAX, "int8_max incorrect: %d\n", testValue.signed_char);
testValue.unsigned_char = strlist_item_as_uchar(strList, DATA_SIZE + uint8_max);
- myassert(testValue.unsigned_char == UINT8_MAX, "uint8_max incorrect: %d", testValue.unsigned_char);
+ myassert(testValue.unsigned_char == UINT8_MAX, "uint8_max incorrect: %d\n", testValue.unsigned_char);
testValue.signed_short = strlist_item_as_short(strList, DATA_SIZE + int16_max);
- myassert(testValue.signed_short == INT16_MAX, "int16_max incorrect: %d", testValue.signed_short);
+ myassert(testValue.signed_short == INT16_MAX, "int16_max incorrect: %d\n", testValue.signed_short);
testValue.unsigned_short = strlist_item_as_ushort(strList, DATA_SIZE + uint16_max);
- myassert(testValue.unsigned_short == UINT16_MAX, "uint16_max incorrect: %d", testValue.unsigned_short);
+ myassert(testValue.unsigned_short == UINT16_MAX, "uint16_max incorrect: %d\n", testValue.unsigned_short);
testValue.signed_int = strlist_item_as_int(strList, DATA_SIZE + int32_max);
- myassert(testValue.signed_int == INT32_MAX, "int32_max incorrect: %d", testValue.signed_int);
+ myassert(testValue.signed_int == INT32_MAX, "int32_max incorrect: %d\n", testValue.signed_int);
testValue.unsigned_int = strlist_item_as_uint(strList, DATA_SIZE + uint32_max);
- myassert(testValue.unsigned_int == UINT32_MAX, "uint32_max incorrect: %d", testValue.unsigned_int);
+ myassert(testValue.unsigned_int == UINT32_MAX, "uint32_max incorrect: %d\n", testValue.unsigned_int);
testValue.signed_long = strlist_item_as_long(strList, DATA_SIZE + int64_max);
- myassert(testValue.signed_long == INT64_MAX, "int64_max (long) incorrect: %ld", testValue.signed_long);
+ myassert(testValue.signed_long == INT64_MAX, "int64_max (long) incorrect: %ld\n", testValue.signed_long);
testValue.unsigned_long = strlist_item_as_ulong(strList, DATA_SIZE + uint64_max);
- myassert(testValue.unsigned_long == UINT64_MAX, "uint64_max (long) incorrect: %lu", testValue.unsigned_long);
+ myassert(testValue.unsigned_long == UINT64_MAX, "uint64_max (long) incorrect: %lu\n", testValue.unsigned_long);
testValue.signed_long_long = strlist_item_as_long_long(strList, DATA_SIZE + int64_max);
- myassert(testValue.signed_long_long == INT64_MAX, "int64_max (long long) incorrect: %lld", testValue.signed_long_long);
+ myassert(testValue.signed_long_long == INT64_MAX, "int64_max (long long) incorrect: %lld\n", testValue.signed_long_long);
testValue.unsigned_long_long = strlist_item_as_ulong_long(strList, DATA_SIZE + uint64_max);
- myassert(testValue.unsigned_long_long == UINT64_MAX, "uint64_max (long long) incorrect: %llu", testValue.unsigned_long_long);
+ myassert(testValue.unsigned_long_long == UINT64_MAX, "uint64_max (long long) incorrect: %llu\n", testValue.unsigned_long_long);
testValue.floating = strlist_item_as_float(strList, DATA_SIZE + uint64_max + 1);
- myassert(testValue.floating == MAXFLOAT, "floating point maximum incorrect: %f", testValue.floating);
+ myassert(testValue.floating == MAXFLOAT, "floating point maximum incorrect: %f\n", testValue.floating);
+
+ // Read a text file into a StrList
+ testfile_data = join(testfile_truth, "\n");
+ testfile_list = strlist_init();
+ char *base = strdup(basename(__FILE__));
+ sprintf(testfile, "%s.txt", base);
+ free(base);
+
+ if (exists(testfile)) {
+ unlink(testfile);
+ }
+
+ mock(testfile, testfile_data, sizeof(char), strlen(testfile_data));
+ strlist_append_file(testfile_list, testfile, NULL);
+
+ myassert(testfile_list != NULL, "testfile_list was not initialized\n");
+ size_t testfile_record_count = strlist_count(testfile_list);
+
+ for (size_t record = 0; record < testfile_record_count; record++) {
+ char *item = strlist_item(testfile_list, record);
+ char *orig = testfile_truth[record];
+ strip(item);
+ myassert(strcmp(orig, item) == 0, "item is '%s', expected '%s'", item, orig);
+ }
+ strlist_free(testfile_list);
strlist_free(strList);
return 0;
} \ No newline at end of file