[libc-commits] [libc] 99aea57 - [libc] Add very basic stdio FILE and fwrite

Alex Brachet via libc-commits libc-commits at lists.llvm.org
Tue Apr 14 01:03:19 PDT 2020


Author: Alex Brachet
Date: 2020-04-14T04:02:27-04:00
New Revision: 99aea5792841ba48ebc427e1326631a584fc8b42

URL: https://github.com/llvm/llvm-project/commit/99aea5792841ba48ebc427e1326631a584fc8b42
DIFF: https://github.com/llvm/llvm-project/commit/99aea5792841ba48ebc427e1326631a584fc8b42.diff

LOG: [libc] Add very basic stdio FILE and fwrite

Summary:
This patch adds a very basic `FILE` type and basic `fwrite`.

It also removes `snprintf` from `StdIO`'s function spec because `VarArgType` was causing the generation to fail.

Reviewers: sivachandra, PaulkaToast

Reviewed By: sivachandra

Subscribers: mgorny, MaskRay, tschuett, libc-commits

Differential Revision: https://reviews.llvm.org/D77626

Added: 
    libc/include/stdio.h.def
    libc/src/stdio/CMakeLists.txt
    libc/src/stdio/FILE.h
    libc/src/stdio/fwrite.cpp
    libc/src/stdio/fwrite.h
    libc/test/src/stdio/CMakeLists.txt
    libc/test/src/stdio/fwrite_test.cpp

Modified: 
    libc/config/linux/api.td
    libc/include/CMakeLists.txt
    libc/spec/stdc.td
    libc/src/CMakeLists.txt
    libc/test/src/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/libc/config/linux/api.td b/libc/config/linux/api.td
index f520947b998a..fe3064ddf227 100644
--- a/libc/config/linux/api.td
+++ b/libc/config/linux/api.td
@@ -18,6 +18,12 @@ def OffT : TypeDecl<"off_t"> {
   }];
 }
 
+def FILE : TypeDecl<"FILE"> {
+  let Decl = [{
+    typedef struct FILE FILE;
+  }];
+}
+
 def AssertMacro : MacroDef<"assert"> {
   let Defn = [{
     #undef assert
@@ -159,10 +165,11 @@ def StringAPI : PublicAPI<"string.h"> {
 def StdIOAPI : PublicAPI<"stdio.h"> {
   let TypeDeclarations = [
     SizeT,
+    FILE,
   ];
 
   let Functions = [
-    "snprintf",
+    "fwrite",
   ];
 }
 

diff  --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index 28b7ee0cd51b..ae2f2ffad5ff 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -75,6 +75,14 @@ add_gen_header(
     ../config/${LIBC_TARGET_OS}/signal.h.in
 )
 
+add_gen_header(
+  stdio
+  DEF_FILE stdio.h.def
+  GEN_HDR stdio.h
+  DEPENDS
+    llvm_libc_common_h
+)
+
 add_gen_header(
   stdlib
   DEF_FILE stdlib.h.def

diff  --git a/libc/include/stdio.h.def b/libc/include/stdio.h.def
new file mode 100644
index 000000000000..712053940e9b
--- /dev/null
+++ b/libc/include/stdio.h.def
@@ -0,0 +1,16 @@
+//===-- C standard library header stdio.h ---------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_STDIO_H
+#define LLVM_LIBC_STDIO_H
+
+#include <__llvm-libc-common.h>
+
+%%public_api()
+
+#endif // LLVM_LIBC_STDIO_H

diff  --git a/libc/spec/stdc.td b/libc/spec/stdc.td
index 39067bcdda12..46296456df24 100644
--- a/libc/spec/stdc.td
+++ b/libc/spec/stdc.td
@@ -18,6 +18,10 @@ def StdC : StandardSpec<"stdc"> {
 
   NamedType SigHandlerT = NamedType<"__sighandler_t">;
 
+  NamedType FILE = NamedType<"FILE">;
+  PtrType FILEPtr = PtrType<FILE>;
+  RestrictedPtrType FILERestrictedPtr = RestrictedPtrType<FILE>;
+
   HeaderSpec Assert = HeaderSpec<
       "assert.h",
       [
@@ -190,16 +194,17 @@ def StdC : StandardSpec<"stdc"> {
       [], // Macros
       [ // Types
           SizeTType,
+          FILE,
       ],
       [], // Enumerations
       [
           FunctionSpec<
-              "snprintf",
-              RetValSpec<IntType>,
-              [ArgSpec<CharPtr>,
-               ArgSpec<SizeTType>,
-               ArgSpec<ConstCharRestrictedPtr>,
-               ArgSpec<VarArgType>]
+              "fwrite",
+              RetValSpec<SizeTType>,
+              [ArgSpec<ConstVoidRestrictedPtr>,
+              ArgSpec<SizeTType>,
+              ArgSpec<SizeTType>,
+              ArgSpec<FILERestrictedPtr>]
           >,
       ]
   >;

diff  --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt
index 3ee30fd322ac..72b4bca34af2 100644
--- a/libc/src/CMakeLists.txt
+++ b/libc/src/CMakeLists.txt
@@ -2,6 +2,7 @@ add_subdirectory(assert)
 add_subdirectory(errno)
 add_subdirectory(math)
 add_subdirectory(signal)
+add_subdirectory(stdio)
 add_subdirectory(stdlib)
 add_subdirectory(string)
 # TODO: Add this target conditional to the target OS.

diff  --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
new file mode 100644
index 000000000000..337ee22c533d
--- /dev/null
+++ b/libc/src/stdio/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_entrypoint_object(
+  fwrite
+  SRCS
+    fwrite.cpp
+  HDRS
+    fwrite.h
+  DEPENDS
+    libc.src.threads.mtx_lock
+    libc.src.threads.mtx_unlock
+)

diff  --git a/libc/src/stdio/FILE.h b/libc/src/stdio/FILE.h
new file mode 100644
index 000000000000..54bc9b2c8731
--- /dev/null
+++ b/libc/src/stdio/FILE.h
@@ -0,0 +1,27 @@
+//===-- Internal definition of FILE -----------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDIO_FILE_H
+#define LLVM_LIBC_SRC_STDIO_FILE_H
+
+#include "include/threads.h"
+#include <stddef.h>
+
+namespace __llvm_libc {
+
+struct FILE {
+  mtx_t lock;
+
+  using write_function_t = size_t(FILE *, const char *, size_t);
+
+  write_function_t *write;
+};
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_FILE_H

diff  --git a/libc/src/stdio/fwrite.cpp b/libc/src/stdio/fwrite.cpp
new file mode 100644
index 000000000000..80cf50ca376e
--- /dev/null
+++ b/libc/src/stdio/fwrite.cpp
@@ -0,0 +1,30 @@
+//===-- Implementation of fwrite and fwrite_unlocked ------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/fwrite.h"
+#include "src/stdio/FILE.h"
+#include "src/threads/mtx_lock.h"
+#include "src/threads/mtx_unlock.h"
+
+namespace __llvm_libc {
+
+size_t fwrite_unlocked(const void *__restrict ptr, size_t size, size_t nmeb,
+                       __llvm_libc::FILE *__restrict stream) {
+  return stream->write(stream, reinterpret_cast<const char *>(ptr),
+                       size * nmeb);
+}
+
+size_t fwrite(const void *__restrict ptr, size_t size, size_t nmeb,
+              __llvm_libc::FILE *__restrict stream) {
+  __llvm_libc::mtx_lock(&stream->lock);
+  size_t written = fwrite_unlocked(ptr, size, nmeb, stream);
+  __llvm_libc::mtx_unlock(&stream->lock);
+  return written;
+}
+
+} // namespace __llvm_libc

diff  --git a/libc/src/stdio/fwrite.h b/libc/src/stdio/fwrite.h
new file mode 100644
index 000000000000..8a71ca105bb0
--- /dev/null
+++ b/libc/src/stdio/fwrite.h
@@ -0,0 +1,22 @@
+//===-- Implementation header of fwrite -------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC_STDIO_FWRITE_H
+#define LLVM_LIBC_SRC_STDIO_FWRITE_H
+
+#include "src/stdio/FILE.h"
+#include <stddef.h>
+
+namespace __llvm_libc {
+
+size_t fwrite(const void *__restrict ptr, size_t size, size_t nmeb,
+              __llvm_libc::FILE *__restrict stream);
+
+} // namespace __llvm_libc
+
+#endif // LLVM_LIBC_SRC_STDIO_FWRITE_H

diff  --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt
index 30c561634c39..209d00b6d7f9 100644
--- a/libc/test/src/CMakeLists.txt
+++ b/libc/test/src/CMakeLists.txt
@@ -1,6 +1,7 @@
 add_subdirectory(assert)
 add_subdirectory(errno)
 add_subdirectory(signal)
+add_subdirectory(stdio)
 add_subdirectory(stdlib)
 add_subdirectory(string)
 add_subdirectory(sys)

diff  --git a/libc/test/src/stdio/CMakeLists.txt b/libc/test/src/stdio/CMakeLists.txt
new file mode 100644
index 000000000000..1394b5647f47
--- /dev/null
+++ b/libc/test/src/stdio/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_libc_testsuite(libc_stdio_unittests)
+
+add_libc_unittest(
+  fwrite_test
+  SUITE
+    libc_stdio_unittests
+  SRCS
+    fwrite_test.cpp
+  DEPENDS
+    libc.src.stdio.fwrite
+    # TODO(sivachandra): remove private dependencies of fwrite
+    libc.src.threads.mtx_lock
+    libc.src.threads.mtx_unlock
+)

diff  --git a/libc/test/src/stdio/fwrite_test.cpp b/libc/test/src/stdio/fwrite_test.cpp
new file mode 100644
index 000000000000..2b7bf0f0a335
--- /dev/null
+++ b/libc/test/src/stdio/fwrite_test.cpp
@@ -0,0 +1,28 @@
+//===-- Unittests for fwrite ----------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "src/stdio/FILE.h"
+#include "src/stdio/fwrite.h"
+#include "utils/CPP/Array.h"
+#include "utils/UnitTest/Test.h"
+
+TEST(Stdio, FWriteBasic) {
+  struct StrcpyFile : __llvm_libc::FILE {
+    char *buf;
+  } f;
+  char array[6];
+  f.buf = array;
+  f.write = +[](__llvm_libc::FILE *file, const char *ptr, size_t size) {
+    StrcpyFile *strcpyFile = static_cast<StrcpyFile *>(file);
+    for (size_t i = 0; i < size; ++i)
+      strcpyFile->buf[i] = ptr[i];
+    return size;
+  };
+  EXPECT_EQ(fwrite("hello", 1, 6, &f), 6UL);
+  EXPECT_STREQ(array, "hello");
+}


        


More information about the libc-commits mailing list