Add the programs ␀ and pack
[minish.git] / src / words.h
blobd229dd602e77f632d7b43e91eb06ad822feacf40
1 #ifndef WORDS_H
2 #define WORDS_H
4 #define _POSIX_C_SOURCE 200809L
5 #include <stdbool.h>
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9 #include "try.h"
11 typedef struct {
12 char* word;
13 size_t len;
14 bool eof;
15 } ReadWord;
17 typedef struct {
18 size_t size;
19 size_t len;
20 char** words;
21 } Words;
23 static char** alloc(size_t const size) {
24 return try_malloc(size * sizeof(char*));
27 static bool adjust(size_t const len, size_t* const size) {
28 if (len >= *size) {
29 out_of_memory_if(*size == SIZE_MAX);
30 if (*size > SIZE_MAX / 2u) {
31 *size = SIZE_MAX;
32 } else {
33 *size *= 2u;
35 return true;
37 return false;
40 static Words new() {
41 Words const words = {
42 .size = 2u * sizeof(*words.words),
43 .len = 0u,
44 .words = alloc(2u),
46 return words;
49 static void push(Words words[static const 1], char* const s) {
50 if (adjust(words->len * sizeof(*words->words), &words->size)) {
51 words->words = try_realloc(words->words, words->size);
53 words->words[words->len++] = s;
56 static bool read_char(int const fd, char* const c) {
57 ssize_t const len = read(fd, c, 1u);
58 if (len == -1) {
59 pexit("read()");
61 return len;
64 static ReadWord read_word(int const fd) {
65 ReadWord w;
66 w.len = 0u;
67 char c;
68 w.eof = !read_char(fd, &c);
69 if (w.eof) {
70 w.word = NULL;
71 } else {
72 size_t size = 2u;
73 w.word = try_malloc(size);
74 w.word[0] = c;
75 do {
76 if (!read_char(fd, &c)) {
77 c = '\0';
78 w.eof = true;
80 if (adjust(w.len, &size)) {
81 w.word = try_realloc(w.word, size);
83 w.word[++w.len] = c;
84 } while (c);
86 return w;
89 #endif