[libc-commits] [libc] [libc][NFC] Add FieldTokenizer and FlatFileDatabase (PR #214720)
Jeff Bailey via libc-commits
libc-commits at lists.llvm.org
Thu Sep 3 00:08:34 PDT 2026
================
@@ -0,0 +1,200 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Generic flat-file database template engine.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_PWD_FLAT_FILE_DB_H
+#define LLVM_LIBC_SRC_PWD_FLAT_FILE_DB_H
+
+#include "hdr/errno_macros.h"
+#include "hdr/stdio_macros.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/CPP/functional.h"
+#include "src/__support/CPP/span.h"
+#include "src/__support/File/file.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace pwd {
+
+struct ReadLineResult {
+ size_t bytes_read;
+ bool truncated;
+};
+
+// Forward declaration of record parser for flat database files.
+template <typename EntryType>
+bool parse_line(cpp::span<char> line, EntryType *entry);
+
+// Generic flat colon-delimited database engine.
+template <typename EntryType> class FlatFileDatabase {
+public:
+ using Matcher = cpp::function<bool(const EntryType &)>;
+
+private:
+ const char *file_path;
+ File *file = nullptr;
+
+ // Reads a single line from the given file into the provided buffer, stripping
+ // any trailing '\n' and ensuring the result is null-terminated.
+ // Note: POSIX getline/getdelim cannot be used here because user database
+ // lookups (including reentrant _r variants) must operate in-place within a
+ // fixed, bounded buffer without dynamic heap allocations or realloc.
+ LIBC_INLINE static ErrorOr<ReadLineResult> read_line(File *f,
+ cpp::span<char> buf) {
+ if (!f || buf.size() < 2)
+ return Error(EINVAL);
+
+ f->lock();
+ size_t bytes_read = 0;
+ FileIOResult result(0);
+ bool truncated = false;
+
+ for (char &ch : buf.first(buf.size() - 1)) {
+ result = f->read_unlocked(&ch, 1);
+ if (result.has_error()) {
+ f->unlock();
+ return Error(result.error);
+ }
+ if (result.value != 1)
+ break;
+ ++bytes_read;
+ if (ch == '\n')
+ break;
+ }
+
+ auto read_span = buf.first(bytes_read);
+ if (result.value == 1 && !read_span.empty() && read_span.back() != '\n') {
----------------
kaladron wrote:
I'm a bit happier with the defence in depth versus some later refactoring, and it looks like it should amount to a register read at this point.
https://github.com/llvm/llvm-project/pull/214720
More information about the libc-commits
mailing list