Welcome to little lamb

Code » limb » commit 3172ea3

Add open_parsed_name() helper

author Olivier Brunel
2023-04-05 08:41:10 UTC
committer Olivier Brunel
2023-05-20 18:06:35 UTC
parent 5c80a28ff0b41de48dba3c471e655964cf2fe0e9

Add open_parsed_name() helper

To parse a string and return a file descriptor. Either the string begins
with a '++' in which case the first '+' is skipped, and the rest of the
string processed as a file name; or the string begins with a '+' and is
expected to have a number (of an fd) following, which is parsed and
returned; or the string doesn't begins with a '+' and is processed as a
file name.

So, either return the file descriptor indicated after a '+' or open the
file whose name is provided using the given open function.

src/doc/djbunix.h.0.md +3 -0
src/doc/djbunix.h/open_parsed_name.3.md +42 -0
src/liblimb/djbunix.h/open_parsed_name.c +23 -0
src/liblimb/include/limb/djbunix.h +4 -0

diff --git a/src/doc/djbunix.h.0.md b/src/doc/djbunix.h.0.md
index 9e6880e..0828df2 100644
--- a/src/doc/djbunix.h.0.md
+++ b/src/doc/djbunix.h.0.md
@@ -22,6 +22,9 @@ operations, file descriptors, environment, child processes, and so on.
 
 The following functions/macros are defined :
 
+: [open_parsed_name](3)
+:: Return the specified file descriptor, or that of the given file name.
+
 : [rm_rfat](3)
 :: Remove an entire directory entry, with relative path based on given file
 :: descriptor
diff --git a/src/doc/djbunix.h/open_parsed_name.3.md b/src/doc/djbunix.h/open_parsed_name.3.md
new file mode 100644
index 0000000..56fa5b3
--- /dev/null
+++ b/src/doc/djbunix.h/open_parsed_name.3.md
@@ -0,0 +1,42 @@
+% limb manual
+% open_parsed_name(3)
+
+# NAME
+
+open\_parsed\_name - return given file descriptor, or opened file
+
+# SYNOPSIS
+
+    #include <limb/djbunix.h>
+
+```pre hl
+typedef int (*open_fn) (const char *file)
+
+int open_parsed_name(const char *<em>name</em>, open_fn <em>open</em>)
+```
+
+# DESCRIPTION
+
+The `open_parsed_name`() function parses `name` which is either a file name, or
+a file descriptor.
+
+In the later case, it must begins with a plus-sign (`+`) before the number of
+the file descriptor, which will be returned.
+
+In the former case, the file name will simply be passed to `open` which shall
+open said file and return the resulting file descriptor, or -1 in case of error,
+setting `errno` to indicate the error..
+
+To specify a file whose name begins with a plus sign, simply use two plus-signs
+as beginning of the file.
+
+# RETURN VALUE
+
+Upon successful completion, this function return the specified file descriptor,
+or the file descriptor of the opened file. Otherwise, it returns -1 and sets
+`errno` to indicate the error.
+
+# ERRORS
+
+This function may fail for the errors described for [u160_scan](3) (when parsing
+the file descriptor), or those for `open`.
diff --git a/src/liblimb/djbunix.h/open_parsed_name.c b/src/liblimb/djbunix.h/open_parsed_name.c
new file mode 100644
index 0000000..7002149
--- /dev/null
+++ b/src/liblimb/djbunix.h/open_parsed_name.c
@@ -0,0 +1,23 @@
+/* This file is part of limb                           https://lila.oss/limb
+ * Copyright (C) 2023 Olivier Brunel                          jjk@jjacky.com */
+/* SPDX-License-Identifier: GPL-2.0-only */
+#include <limb/djbunix.h>
+#include <limb/u16.h>
+
+int
+open_parsed_name(const char *name, open_fn open)
+{
+    /* is this a file descriptor via +fd */
+    if (*name == '+') {
+        ++name;
+        /* another '+' would mean file name starts with a '+' */
+        if (*name != '+') {
+            u16 u;
+            if (!u160_scan(&u, name))
+                return -1;
+            return u;
+        }
+    }
+
+    return open(name);
+}
diff --git a/src/liblimb/include/limb/djbunix.h b/src/liblimb/include/limb/djbunix.h
index d9cf4d0..18f21f1 100644
--- a/src/liblimb/include/limb/djbunix.h
+++ b/src/liblimb/include/limb/djbunix.h
@@ -7,6 +7,10 @@
 #include <skalibs/djbunix.h>
 #include <skalibs/stralloc.h>
 
+typedef int (*open_fn) (const char *file);
+
+extern int open_parsed_name(const char *name, open_fn open);
+
 extern int rm_rfat(int fd, const char *name);
 extern int rm_rf_tmpat(int fd, const char *name, stralloc *sa);
 extern int rm_rf_in_tmpat(int fd, stralloc *sa, size_t offset);