coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2022-02-05 09:32:00
Commitb181413a6eccae60cac79c97db7d4c0d5194134f
Parent14d235f076b516804099624cc9d5cb453ffe3dd1

util: Replace "lib" with libutil

Diffstat

M CMakeLists.txt | 6 +++---
M src/base64.c | 6 +++---
M src/basename.c | 4 ++--
M src/cat.c | 4 ++--
M src/chmod.c | 6 +++---
M src/cksum.c | 4 ++--
M src/cp.c | 4 ++--
M src/dirname.c | 4 ++--
M src/env.c | 4 ++--
M src/head.c | 4 ++--
M src/id.c | 4 ++--
R src/lib/base64.c -> src/util/base64.c | 70 ++++++++++++++++++++++++++++++++++++++++------------------------------
R src/lib/base64.h -> src/util/base64.h | 13 ++++++++-----
R src/lib/error.c -> src/util/error.c | 17 ++++++++++++-----
D src/lib/error.h | 47 -----------------------------------------------
R src/lib/mode.c -> src/util/mode.c | 4 ++--
R src/lib/mode.h -> src/util/mode.h | 10 +++++-----
R src/lib/optget.c -> src/util/optget.c | 4 ++--
R src/lib/optget.h -> src/util/optget.h | 10 +++++-----
M src/link.c | 4 ++--
M src/logname.c | 2 +-
M src/mkdir.c | 6 +++---
M src/nice.c | 4 ++--
M src/od.c | 4 ++--
M src/orphan.c | 4 ++--
M src/pwd.c | 4 ++--
M src/rand.c | 4 ++--
M src/realpath.c | 4 ++--
M src/rmdir.c | 4 ++--
M src/sleep.c | 4 ++--
M src/sum.c | 4 ++--
M src/tee.c | 4 ++--
M src/time.c | 4 ++--
M src/touch.c | 4 ++--
M src/uname.c | 2 +-
M src/unlink.c | 4 ++--
A src/util/error.h | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A src/util/util.h | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
M src/wc.c | 4 ++--

39 files changed, 313 insertions, 161 deletions

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c9c3c12..4603db4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,11 +5,11 @@ SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
 SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
 SET(CMAKE_STATIC_LIBRARY_PREFIX "")
 
-FILE(GLOB LIBSRC ${PROJECT_SOURCE_DIR}/src/lib/*)
+FILE(GLOB SRC_UTIL ${PROJECT_SOURCE_DIR}/src/util/*)
 
-ADD_LIBRARY(lib STATIC ${LIBSRC})
+ADD_LIBRARY(libutil STATIC ${SRC_UTIL})
 
-LINK_LIBRARIES(lib)
+LINK_LIBRARIES(libutil)
 
 ADD_EXECUTABLE(base64   ${PROJECT_SOURCE_DIR}/src/base64.c)
 ADD_EXECUTABLE(basename ${PROJECT_SOURCE_DIR}/src/basename.c)
diff --git a/src/base64.c b/src/base64.c
index ebc1239..7950d89 100644
--- a/src/base64.c
+++ b/src/base64.c
@@ -34,9 +34,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 	TODO Improve or replace fgetb64.
 */
 
-#include "lib/base64.h"
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/base64.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <ctype.h>
 #include <stdbool.h>
diff --git a/src/basename.c b/src/basename.c
index 77bd9be..68112ac 100644
--- a/src/basename.c
+++ b/src/basename.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <stdio.h>
 
diff --git a/src/cat.c b/src/cat.c
index a152847..feec6d3 100644
--- a/src/cat.c
+++ b/src/cat.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <stdbool.h>
 #include <stdio.h>
diff --git a/src/chmod.c b/src/chmod.c
index 4afbbbd..459eefc 100644
--- a/src/chmod.c
+++ b/src/chmod.c
@@ -35,9 +35,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 	TODO Handle copying permission
 */
 
-#include "lib/error.h"
-#include "lib/mode.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/mode.h"
+#include "util/optget.h"
 
 #include <dirent.h>
 #include <sys/stat.h>
diff --git a/src/cksum.c b/src/cksum.c
index e1a6920..4e39a38 100644
--- a/src/cksum.c
+++ b/src/cksum.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <stdbool.h>
 #include <stdint.h>
diff --git a/src/cp.c b/src/cp.c
index 7f97dd6..3172799 100644
--- a/src/cp.c
+++ b/src/cp.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <sys/stat.h>
 
diff --git a/src/dirname.c b/src/dirname.c
index 94e229e..d0707d7 100644
--- a/src/dirname.c
+++ b/src/dirname.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <stdio.h>
 
diff --git a/src/env.c b/src/env.c
index 6f57f13..08769f4 100644
--- a/src/env.c
+++ b/src/env.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <unistd.h>
 
diff --git a/src/head.c b/src/head.c
index cb8c13c..216cb7d 100644
--- a/src/head.c
+++ b/src/head.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <stdbool.h>
 #include <stdint.h>
diff --git a/src/id.c b/src/id.c
index 39b0008..98a5a03 100644
--- a/src/id.c
+++ b/src/id.c
@@ -34,8 +34,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 	TODO Fix memory leak when listing supplementary groups (may be unfixable)
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <grp.h>
 #include <pwd.h>
diff --git a/src/link.c b/src/link.c
index e212a56..e0055bb 100644
--- a/src/link.c
+++ b/src/link.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <unistd.h>
 
diff --git a/src/logname.c b/src/logname.c
index 83a90a1..9f7a17a 100644
--- a/src/logname.c
+++ b/src/logname.c
@@ -17,7 +17,7 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
+#include "util/error.h"
 
 #include <unistd.h>
 
diff --git a/src/mkdir.c b/src/mkdir.c
index 0d3fbf3..0505a70 100644
--- a/src/mkdir.c
+++ b/src/mkdir.c
@@ -35,9 +35,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 	TODO Handle copying permissions
 */
 
-#include "lib/error.h"
-#include "lib/mode.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/mode.h"
+#include "util/optget.h"
 
 #include <sys/stat.h>
 
diff --git a/src/nice.c b/src/nice.c
index bb26a1c..89584d7 100644
--- a/src/nice.c
+++ b/src/nice.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <unistd.h>
 
diff --git a/src/od.c b/src/od.c
index 4e88085..d879a43 100644
--- a/src/od.c
+++ b/src/od.c
@@ -36,8 +36,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 	TODO Fix segfault when using standard input.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <errno.h>
 #include <limits.h>
diff --git a/src/orphan.c b/src/orphan.c
index caf1ac2..0f44110 100644
--- a/src/orphan.c
+++ b/src/orphan.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <fcntl.h>
 #include <unistd.h>
diff --git a/src/pwd.c b/src/pwd.c
index 434a99c..9c489de 100644
--- a/src/pwd.c
+++ b/src/pwd.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <unistd.h>
 
diff --git a/src/rand.c b/src/rand.c
index 1e00d5f..0d04cb8 100644
--- a/src/rand.c
+++ b/src/rand.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <stdint.h>
 #include <stdio.h>
diff --git a/src/realpath.c b/src/realpath.c
index 8fe0d56..ca6034c 100644
--- a/src/realpath.c
+++ b/src/realpath.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <stdbool.h>
 #include <stdio.h>
diff --git a/src/rmdir.c b/src/rmdir.c
index d06101f..4cee96e 100644
--- a/src/rmdir.c
+++ b/src/rmdir.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <unistd.h>
 
diff --git a/src/sleep.c b/src/sleep.c
index 92f9411..ad64da4 100644
--- a/src/sleep.c
+++ b/src/sleep.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <unistd.h>
 
diff --git a/src/sum.c b/src/sum.c
index f5f9e95..a2dfa88 100644
--- a/src/sum.c
+++ b/src/sum.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <stdbool.h>
 #include <stdint.h>
diff --git a/src/tee.c b/src/tee.c
index e28e8a9..bd40bd0 100644
--- a/src/tee.c
+++ b/src/tee.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <signal.h>
 #include <stdbool.h>
diff --git a/src/time.c b/src/time.c
index e869331..bb21ff5 100644
--- a/src/time.c
+++ b/src/time.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <sys/times.h>
 #include <sys/wait.h>
diff --git a/src/touch.c b/src/touch.c
index 3c7c567..18aeba7 100644
--- a/src/touch.c
+++ b/src/touch.c
@@ -36,8 +36,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 
 #define _XOPEN_SOURCE 700
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <fcntl.h>
 #include <sys/stat.h>
diff --git a/src/uname.c b/src/uname.c
index 4a59ad5..5251ae8 100644
--- a/src/uname.c
+++ b/src/uname.c
@@ -30,7 +30,7 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/optget.h"
+#include "util/optget.h"
 
 #include <sys/utsname.h>
 #include <unistd.h>
diff --git a/src/unlink.c b/src/unlink.c
index 455c580..01a6d33 100644
--- a/src/unlink.c
+++ b/src/unlink.c
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <unistd.h>
 
diff --git a/src/lib/base64.c b/src/util/base64.c
similarity index 65%
rename from src/lib/base64.c
rename to src/util/base64.c
index 8446847..91c774e 100644
--- a/src/lib/base64.c
+++ b/src/util/base64.c
@@ -1,5 +1,5 @@
-// base64.c, version 1.1.0
-// Base64 header file for OMKOV lib
+// util/base64.c, version 1.1.4
+// Base64 source file from libutil
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 
 static const uint8_t B64E[];
 static const uint8_t B64D[];
@@ -50,16 +51,18 @@ size_t b64encode(uint8_t *dst, uint8_t *src, size_t len) {
 		*o++ = B64E[i[2] & 0x3F]; i += 3;
 	}
 
-	if (len) {
+	switch (len) {
+	case 1: {
 		*o++ = B64E[i[0] >> 2];
-		
-		if (len == 1) {
-			*o++ = B64E[(i[0] & 0x03) << 4]; *o++ = '=';
-		}
-		else {
-			*o++ = B64E[((i[0] & 0x03) << 4) | (i[1] >> 4)];
-			*o++ = B64E[(i[1] & 0x0F) << 2];
-		} *o++ = '=';
+		*o++ = B64E[(i[0] & 0x03) << 4];
+		memset(o, '=', 2); o += 2; break;
+	}
+	case 2: {
+		*o++ = B64E[i[0] >> 2];
+		*o++ = B64E[((i[0] & 0x03) << 4) | (i[1] >> 4)];
+		*o++ = B64E[(i[1] & 0x0F) << 2];
+		*o++ = '='; break;
+	}
 	}
 
 	return o - dst;
@@ -67,39 +70,46 @@ size_t b64encode(uint8_t *dst, uint8_t *src, size_t len) {
 
 /* Decode Base64 */
 size_t b64decode(uint8_t *dst, uint8_t *src, size_t len) {
-	if (!len) { return 0; }
-	
-	register uint8_t *o = dst;
-	
-	bool pad1 = len % 4 || src[len - 1] == '=';
-	bool pad2 = pad1 && (len % 4 > 2 || src[len - 2] != '=');
+	register uint8_t *i = src, *o = dst;
 
-	size_t end = (len - pad1) / 4 << 2;
+	for (; src[len - 1] == '='; --len);
 
-	for (size_t j = 0; j != end; j += 4) {
-		*o++ = B64D[src[j + 0]] << 2 | B64D[src[j + 1]] >> 4;
-		*o++ = B64D[src[j + 1]] << 4 | B64D[src[j + 2]] >> 2;
-		*o++ = B64D[src[j + 2]] << 6 | B64D[src[j + 3]];
+	for (; len >= 4; len -= 4) {
+		*o++ = (B64D[i[0]] << 2) | (B64D[i[1]] >> 4);
+		*o++ = (B64D[i[1]] << 4) | (B64D[i[2]] >> 2);
+		*o++ = (B64D[i[2]] << 6) | (B64D[i[3]]); i += 4;
 	}
 
-	if (pad1) {
-		int n = B64D[src[end]] << 18 | B64D[src[end + 1]] << 12; *o++ = n >> 16;
-		if (pad2) { n |= B64D[src[end + 2]] << 6; *o++ = n >> 8 & 0xFF; }
-    }
+	switch (len) {
+	case 2: {
+		*o++ = (B64D[i[0]] << 2) | (B64D[i[1]] >> 4);
+		*o++ = (B64D[i[1]] << 4); break;
+	}
+	case 3: {
+		*o++ = (B64D[i[0]] << 2) | (B64D[i[1]] >> 4);
+		*o++ = (B64D[i[1]] << 4) | (B64D[i[2]] >> 2);
+		*o++ = (B64D[i[2]] << 6); break;
+	}
+	}
 
 	return o - dst;
 }
 
-static const uint8_t B64E[] =
-	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+static const uint8_t B64E[] = {
+	'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+	'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+	'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+	'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+};
 
 static const uint8_t B64D[] = {
 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
 	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62, 63, 62, 62, 63,
+	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0, 63,
 	52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0,  0,  0,  0,
 	 0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-	15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0, 63,
+	15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
 	 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
 	41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
 };
diff --git a/src/lib/base64.h b/src/util/base64.h
similarity index 87%
rename from src/lib/base64.h
rename to src/util/base64.h
index c56d726..f606ffe 100644
--- a/src/lib/base64.h
+++ b/src/util/base64.h
@@ -1,5 +1,5 @@
-// base64.h, version 1.1.0
-// Base64 header file for OMKOV lib
+// util/base64.h, version 1.1.4
+// Base64 header file from libutil
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
 
@@ -30,13 +30,16 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#ifndef OMKOV_LIB_BASE64_H_5YQ80JRV
-#define OMKOV_LIB_BASE64_H_5YQ80JRV
+#ifndef UTIL_BASE64_H_5YQ80JRV
+#define UTIL_BASE64_H_5YQ80JRV
 
 #include <stdint.h>
 #include <stdlib.h>
 
+#define B64ELEN(x) (((x + 2) / 3) * 4)
+#define B64DLEN(x) (((x + 3) / 4) * 3)
+
 extern size_t b64encode(uint8_t *dst, uint8_t *src, size_t len);
 extern size_t b64decode(uint8_t *dst, uint8_t *src, size_t len);
 
-#endif // OMKOV_LIB_BASE64_H_5YQ80JRV
+#endif // UTIL_BASE64_H_5YQ80JRV
diff --git a/src/lib/error.c b/src/util/error.c
similarity index 81%
rename from src/lib/error.c
rename to src/util/error.c
index e0c80d3..0e306e9 100644
--- a/src/lib/error.c
+++ b/src/util/error.c
@@ -1,5 +1,5 @@
-// error.c, version 1.0.2
-// Error source file for OMKOV lib
+// util/error.h, version 1.1.1
+// Error source file from libutil
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
 
@@ -43,19 +43,26 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 char *A0 = NULL;
 bool warned = false;
 
-/* Print an error message and exit */
+/* Print an error message and exit. */
 noreturn void error(int status, const char *format, ...) {
 	fflush(stdout); if (A0) { fputs(A0, stderr); fputs(": ", stderr); }
 	va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);
 	fputc('\n', stderr); exit(status);
 }
 
-/* Print a warning message and set the warned flag */
+/* Print a warning message and set the warned flag. */
 void warn(const char *format, ...) {
 	fflush(stdout); if (A0) { fputs(A0, stderr); fputs(": ", stderr); }
 	va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);
 	fputc('\n', stderr); warned = true; return;
 }
 
-/* Shorthand for strerror(errno) */
+/* Print a warning message but do not set the warned flag. */
+void alert(const char *format, ...) {
+	fflush(stdout); if (A0) { fputs(A0, stderr); fputs(": ", stderr); }
+	va_list ap; va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap);
+	fputc('\n', stderr); return;
+}
+
+/* Shorthand for strerror(errno). DEPRECIATED, use the SERR macro. */
 char *serr(void) { return strerror(errno); }
diff --git a/src/lib/error.h b/src/util/error.h
similarity index 56%
rename from src/lib/error.h
rename to src/util/error.h
index 16db9cf..794e5c3 100644
--- a/src/lib/error.h
+++ b/src/util/error.h
@@ -1,5 +1,5 @@
-// error.h, version 1.0.2
-// Error header file for OMKOV lib
+// util/error.h, version 1.1.1
+// Error header file from libutil
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
 
@@ -30,18 +30,58 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#ifndef OMKOV_LIB_ERROR_H_38W06M3W
-#define OMKOV_LIB_ERROR_H_38W06M3W
+#ifndef UTIL_ERROR_H_38W06M3W
+#define UTIL_ERROR_H_38W06M3W
 
+#include <errno.h>
 #include <stdbool.h>
 #include <stdnoreturn.h>
+#include <string.h>
+
+/* Warn and then return status */
+#define WARN_R(status, format, ...) do { \
+	warn(format, __VA_ARGS__); return status; \
+} while (0)
+
+/* Warn and then reset errno */
+#define WARN_E(format, ...) do { \
+	warn(format, __VA_ARGS__); errno = 0; \
+} while (0)
+
+/* Warn, reset errno, and then return status */
+#define WARN_RE(status, format, ...) do { \
+	warn(format, __VA_ARGS__); errno = 0; return status; \
+} while (0)
+
+/* Alert and then return status */
+#define ALERT_R(status, format, ...) do { \
+	alert(format, __VA_ARGS__); return status; \
+} while (0)
+
+/* Alert and then reset errno */
+#define ALERT_E(format, ...) do { \
+	alert(format, __VA_ARGS__); errno = 0; \
+} while (0)
+
+/* Alert, reset errno, and then return status */
+#define ALERT_RE(status, format, ...) do { \
+	alert(format, __VA_ARGS__); errno = 0; return status; \
+} while (0)
+
+/* Shorthand for strerror(serrno). */
+#define SERR (strerror(errno))
 
 extern char *A0;
 extern bool warned;
 
+/* Print an error message and exit. */
 extern noreturn void error(int status, const char *format, ...);
+/* Print a warning message and set the warned flag. */
 extern void warn(const char *format, ...);
+/* Print a warning message but do not set the warned flag. */
+extern void alert(const char *format, ...);
 
+/* Shorthand for strerror(errno). DEPRECIATED, use the SERR macro. */
 extern char *serr(void);
 
-#endif // OMKOV_LIB_ERROR_H_38W06M3W
+#endif // UTIL_ERROR_H_38W06M3W
diff --git a/src/lib/mode.c b/src/util/mode.c
similarity index 98%
rename from src/lib/mode.c
rename to src/util/mode.c
index 5714c8f..3d235ba 100644
--- a/src/lib/mode.c
+++ b/src/util/mode.c
@@ -1,5 +1,5 @@
-// mode.c, version 1.0.1
-// Mode source file for OMKOV lib
+// util/mode.c, version 1.0.2
+// Mode source file from libutil
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
 
diff --git a/src/lib/mode.h b/src/util/mode.h
similarity index 92%
rename from src/lib/mode.h
rename to src/util/mode.h
index 407dcd4..09c7dc0 100644
--- a/src/lib/mode.h
+++ b/src/util/mode.h
@@ -1,5 +1,5 @@
-// mode.h, version 1.0.1
-// Mode header file for OMKOV lib
+// util/mode.h, version 1.0.2
+// Mode header file from libutil
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
 
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#ifndef OMKOV_LIB_MODE_H_0C99POMA
-#define OMKOV_LIB_MODE_H_0C99POMA
+#ifndef UTIL_MODE_H_0C99POMA
+#define UTIL_MODE_H_0C99POMA
 
 #include <sys/types.h>
 
@@ -51,4 +51,4 @@ enum { MF_NULL, MF_NORM, MF_XIFX, MF_COPY };
 
 extern chmod_t *strmode(char *str);
 
-#endif // OMKOV_LIB_MODE_H_0C99POMA
+#endif // UTIL_MODE_H_0C99POMA
diff --git a/src/lib/optget.c b/src/util/optget.c
similarity index 98%
rename from src/lib/optget.c
rename to src/util/optget.c
index da61ebd..24d334d 100644
--- a/src/lib/optget.c
+++ b/src/util/optget.c
@@ -1,5 +1,5 @@
-// optget.h, version 1.6.0
-// optget source file for OMKOV lib
+// util/optget.h, version 1.6.1
+// optget source file from libutil
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
 
diff --git a/src/lib/optget.h b/src/util/optget.h
similarity index 91%
rename from src/lib/optget.h
rename to src/util/optget.h
index f83d132..e3065fb 100644
--- a/src/lib/optget.h
+++ b/src/util/optget.h
@@ -1,5 +1,5 @@
-// optget.h, version 1.6.0
-// optget header file for OMKOV lib
+// util/optget.h, version 1.6.1
+// optget header file from libutil
 // Copyright (C) 2020, Jakob Wakeling
 // All rights reserved.
 
@@ -30,8 +30,8 @@ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 */
 
-#ifndef OMKOV_LIB_OPTGET_H_W3LIZK1S
-#define OMKOV_LIB_OPTGET_H_W3LIZK1S
+#ifndef UTIL_OPTGET_H_W3LIZK1S
+#define UTIL_OPTGET_H_W3LIZK1S
 
 #define ARG_NUL 0
 #define ARG_REQ 1
@@ -52,4 +52,4 @@ extern const struct opt OPTGET_INIT;
 
 extern int optget(struct opt *opt, char *av[], int flags);
 
-#endif // OMKOV_LIB_OPTGET_H_W3LIZK1S
+#endif // UTIL_OPTGET_H_W3LIZK1S
diff --git a/src/util/util.h b/src/util/util.h
new file mode 100644
index 0000000..3b3d167
--- /dev/null
+++ b/src/util/util.h
@@ -0,0 +1,92 @@
+// util/util.h, version 1.0.0
+// Utility header file from libutil
+// Copyright (C) 2021, Jakob Wakeling
+// All rights reserved.
+
+/*
+OMKOV Permissive Licence, version 1.0
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+* Redistributions of source code must retain the above copyright notice, this
+  list of conditions and the following disclaimers.
+* Redistributions in binary form must reproduce the above copyright notice, this
+  list of conditions and the following disclaimers in the documentation and/or
+  other materials provided with the distribution.
+* Neither the names of the copyright holders, nor the names of its contributors
+  may be used to endorse or promote products derived from this Software without
+  specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT
+HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
+*/
+
+#ifndef UTIL_UTIL_H_KP8NS9DC
+#define UTIL_UTIL_H_KP8NS9DC
+
+#include <assert.h>
+#include <float.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+/* Type Definitions */
+typedef uint8_t   u8;
+typedef uint16_t  u16;
+typedef uint32_t  u32;
+typedef uint64_t  u64;
+typedef uintptr_t UINT;
+
+typedef int8_t   s8;
+typedef int16_t  s16;
+typedef int32_t  s32;
+typedef int64_t  s64;
+typedef intptr_t sint;
+
+typedef float       f32;
+typedef double      f64;
+typedef long double f128;
+
+/* Type Limits */
+#define U8_MIN   UINT8_MIN
+#define U8_MAX   UINT8_MAX
+#define U16_MIN  UINT16_MIN
+#define U16_MAX  UINT16_MAX
+#define U32_MIN  UINT32_MIN
+#define U32_MAX  UINT32_MAX
+#define U64_MIN  UINT64_MIN
+#define U64_MAX  UINT64_MAX
+#define UINT_MIN UINTPTR_MIN
+#define UINT_MAX UINTPTR_MAX
+
+#define S8_MIN   INT8_MIN
+#define S8_MAX   INT8_MAX
+#define S16_MIN  INT16_MIN
+#define S16_MAX  INT16_MAX
+#define S32_MIN  INT32_MIN
+#define S32_MAX  INT32_MAX
+#define S64_MIN  INT64_MIN
+#define S64_MAX  INT64_MAX
+#define SINT_MIN INTPTR_MIN
+#define SINT_MAX INTPTR_MAX
+
+#define F32_MIN  FLT_MIN
+#define F32_MAX  FLT_MAX
+#define F64_MIN  DBL_MIN
+#define F64_MAX  DBL_MAX
+#define F128_MIN LDBL_MIN
+#define F128_MAX LDBL_MAX
+
+/* Miscellaneous */
+#define BIT(x) (1 << (x))
+
+#endif // UTIL_UTIL_H_KP8NS9DC
diff --git a/src/wc.c b/src/wc.c
index d0a4970..4726a4b 100644
--- a/src/wc.c
+++ b/src/wc.c
@@ -34,8 +34,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 	FIXME See line 112.
 */
 
-#include "lib/error.h"
-#include "lib/optget.h"
+#include "util/error.h"
+#include "util/optget.h"
 
 #include <ctype.h>
 #include <locale.h>