add_custom_target(libc_stdio_unittests)

add_libc_unittest(
  fileop_test
  SUITE
    libc_stdio_unittests
  SRCS
    fileop_test.cpp
  DEPENDS
    libc.include.stdio
    libc.src.errno.errno
    libc.src.stdio.clearerr
    libc.src.stdio.fclose
    libc.src.stdio.feof
    libc.src.stdio.ferror
    libc.src.stdio.fflush
    libc.src.stdio.fopen
    libc.src.stdio.fputs
    libc.src.stdio.fread
    libc.src.stdio.fseek
    libc.src.stdio.fwrite
)

add_libc_unittest(
  ungetc_test
  SUITE
    libc_stdio_unittests
  SRCS
    ungetc_test.cpp
  DEPENDS
    libc.include.stdio
    libc.src.stdio.fclose
    libc.src.stdio.fopen
    libc.src.stdio.fread
    libc.src.stdio.fseek
    libc.src.stdio.fwrite
    libc.src.stdio.ungetc
)

add_libc_unittest(
  setbuf_test
  SUITE
    libc_stdio_unittests
  SRCS
    setbuf_test.cpp
  DEPENDS
    libc.include.stdio
    libc.src.stdio.fclose
    libc.src.stdio.fopen
    libc.src.stdio.fread
    libc.src.stdio.fwrite
    libc.src.stdio.setbuf
    libc.src.stdio.ungetc
)

add_libc_unittest(
  setvbuf_test
  SUITE
    libc_stdio_unittests
  SRCS
    setvbuf_test.cpp
  DEPENDS
    libc.include.stdio
    libc.src.errno.errno
    libc.src.stdio.fclose
    libc.src.stdio.fopen
    libc.src.stdio.fread
    libc.src.stdio.fwrite
    libc.src.stdio.setvbuf
)

add_libc_unittest(
  unlocked_fileop_test
  SUITE
    libc_stdio_unittests
  SRCS
    unlocked_fileop_test.cpp
  DEPENDS
    libc.include.stdio
    libc.src.errno.errno
    libc.src.stdio.clearerr_unlocked
    libc.src.stdio.fclose
    libc.src.stdio.feof_unlocked
    libc.src.stdio.ferror_unlocked
    libc.src.stdio.flockfile
    libc.src.stdio.fopen
    libc.src.stdio.fread_unlocked
    libc.src.stdio.funlockfile
    libc.src.stdio.fwrite_unlocked
)

add_libc_unittest(
  fopencookie_test
  SUITE
    libc_stdio_unittests
  SRCS
    fopencookie_test.cpp
  DEPENDS
    libc.include.stdio
    libc.include.stdlib
    libc.src.errno.errno
    libc.src.stdio.clearerr
    libc.src.stdio.fclose
    libc.src.stdio.feof
    libc.src.stdio.ferror
    libc.src.stdio.fflush
    libc.src.stdio.fopencookie
    libc.src.stdio.fread
    libc.src.stdio.fseek
    libc.src.stdio.fwrite
  LINK_LIBRARIES
    LibcMemoryHelpers
)

add_fp_unittest(
  sprintf_test
  UNIT_TEST_ONLY
  SUITE
    libc_stdio_unittests
  SRCS
    sprintf_test.cpp
  DEPENDS
    libc.src.stdio.sprintf
    libc.src.__support.FPUtil.fp_bits
    libc.src.__support.FPUtil.platform_defs
)

add_libc_unittest(
  snprintf_test
  SUITE
    libc_stdio_unittests
  SRCS
    snprintf_test.cpp
  DEPENDS
    libc.src.stdio.snprintf
)

list(APPEND fprintf_test_deps
      libc.src.stdio.fprintf
)
if(LLVM_LIBC_FULL_BUILD)
# In fullbuild mode, fprintf's tests use the internal FILE for other functions.
 list(APPEND fprintf_test_deps
      libc.src.stdio.fclose
      libc.src.stdio.ferror
      libc.src.stdio.fopen
      libc.src.stdio.fread
  )
else()
# Else in overlay mode they use the system's FILE.
 set(fprintf_test_copts "-DLIBC_COPT_PRINTF_USE_SYSTEM_FILE")
endif()

add_libc_unittest(
  fprintf_test
  SUITE
    libc_stdio_unittests
  SRCS
    fprintf_test.cpp
  DEPENDS
    ${fprintf_test_deps}
  COMPILE_OPTIONS
    ${fprintf_test_copts}
)

add_libc_unittest(
  printf_test
  SUITE
    libc_stdio_unittests
  SRCS
    printf_test.cpp
  DEPENDS
    libc.src.stdio.printf
)

add_libc_unittest(
  fscanf_test
  SUITE
    libc_stdio_unittests
  SRCS
    fscanf_test.cpp
  DEPENDS
    libc.src.stdio.fscanf
    libc.src.stdio.fclose
    libc.src.stdio.ferror
    libc.src.stdio.fopen
    libc.src.stdio.fwrite
    libc.src.__support.CPP.string_view
)

add_libc_unittest(
  sscanf_test
  SUITE
    libc_stdio_unittests
  SRCS
    sscanf_test.cpp
  DEPENDS
    libc.src.stdio.sscanf
  LINK_LIBRARIES
    LibcFPTestHelpers
)

add_libc_test(
  puts_test
  SUITE
    libc_stdio_unittests
  SRCS
    puts_test.cpp
  DEPENDS
    libc.src.stdio.puts
)

add_libc_test(
  fputs_test
  SUITE
    libc_stdio_unittests
  SRCS
    fputs_test.cpp
  DEPENDS
    libc.src.stdio.fputs
)

add_libc_test(
  fopen_test
  SUITE
    libc_stdio_unittests
  SRCS
    fopen_test.cpp
  DEPENDS
    libc.src.stdio.fputs
    libc.src.stdio.fclose
    libc.src.stdio.fopen
)

add_libc_unittest(
  putc_test
  SUITE
    libc_stdio_unittests
  SRCS
    putc_test.cpp
  DEPENDS
    libc.src.stdio.putc
    libc.src.stdio.fclose
    libc.src.stdio.ferror
    libc.src.stdio.fopen
    libc.src.stdio.fread
)

if(${LIBC_TARGET_OS} STREQUAL "linux")
  add_libc_unittest(
    remove_test
    SUITE
      libc_stdio_unittests
    SRCS
      remove_test.cpp
    DEPENDS
      libc.include.unistd
      libc.src.errno.errno
      libc.src.fcntl.open
      libc.src.stdio.remove
      libc.src.sys.stat.mkdirat
      libc.src.unistd.access
      libc.src.unistd.close
  )
endif()

add_libc_unittest(
  fgetc_test
  SUITE
    libc_stdio_unittests
  SRCS
    fgetc_test.cpp
  DEPENDS
    libc.include.stdio
    libc.src.errno.errno
    libc.src.stdio.fclose
    libc.src.stdio.feof
    libc.src.stdio.ferror
    libc.src.stdio.fgetc
    libc.src.stdio.fopen
    libc.src.stdio.fwrite
    libc.src.stdio.getc
)

add_libc_unittest(
  fgetc_unlocked_test
  SUITE
    libc_stdio_unittests
  SRCS
    fgetc_unlocked_test.cpp
  DEPENDS
    libc.include.stdio
    libc.src.errno.errno
    libc.src.stdio.fclose
    libc.src.stdio.ferror
    libc.src.stdio.ferror_unlocked
    libc.src.stdio.feof
    libc.src.stdio.feof_unlocked
    libc.src.stdio.fgetc_unlocked
    libc.src.stdio.flockfile
    libc.src.stdio.fopen
    libc.src.stdio.funlockfile
    libc.src.stdio.fwrite
    libc.src.stdio.getc_unlocked
)

add_libc_unittest(
  fgets_test
  SUITE
    libc_stdio_unittests
  SRCS
    fgets_test.cpp
  DEPENDS
    libc.include.stdio
    libc.src.errno.errno
    libc.src.stdio.fclose
    libc.src.stdio.feof
    libc.src.stdio.ferror
    libc.src.stdio.fgets
    libc.src.stdio.fopen
    libc.src.stdio.fwrite
)

add_libc_unittest(
  ftell_test
  SUITE
    libc_stdio_unittests
  SRCS
    ftell_test.cpp
  DEPENDS
    libc.include.stdio
    libc.src.stdio.fclose
    libc.src.stdio.fflush
    libc.src.stdio.fopen
    libc.src.stdio.fread
    libc.src.stdio.fseek
    libc.src.stdio.ftell
    libc.src.stdio.fwrite
    libc.src.stdio.setvbuf
)

# Create an output directory for any temporary test files.
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/testdata)

if(LIBC_TARGET_ARCHITECTURE_IS_GPU)
  return()
endif()

add_subdirectory(printf_core)
add_subdirectory(scanf_core)
add_subdirectory(testdata)
