#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
struct fatfs_ctx;
#define __FAT_ACCESS_H__

#define __FAT_DEFS_H__

#define __FAT_OPTS_H__
#define FATFS_IS_LITTLE_ENDIAN      1
#define FATFS_MAX_LONG_FILENAME     260
#define FATFS_MAX_OPEN_FILES        2
#define FAT_BUFFER_SECTORS          1
#define FAT_BUFFERS                 1
#define FATFS_INC_WRITE_SUPPORT     1
#define FATFS_INC_LFN_SUPPORT       1
#define FATFS_DIR_LIST_SUPPORT      1
#define FATFS_INC_TIME_DATE_SUPPORT 0
#define FATFS_INC_FORMAT_SUPPORT    1
#define FAT_SECTOR_SIZE             512

#define __FAT_TYPES_H__
#define FATFS_DEF_UINT32_AS_INT
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
#define NULL         0
#define FAT_HTONS(n) (n)
#define FAT_HTONL(n) (n)
#define STRUCT_PACK
#define STRUCT_PACK_BEGIN
#define STRUCT_PACK_END
#define STRUCT_PACKED                 __attribute__ ((packed))
#define BS_JMPBOOT                    0
#define BS_OEMNAME                    3
#define BPB_BYTSPERSEC                11
#define BPB_SECPERCLUS                13
#define BPB_RSVDSECCNT                14
#define BPB_NUMFATS                   16
#define BPB_ROOTENTCNT                17
#define BPB_TOTSEC16                  19
#define BPB_MEDIA                     21
#define BPB_FATSZ16                   22
#define BPB_SECPERTRK                 24
#define BPB_NUMHEADS                  26
#define BPB_HIDDSEC                   28
#define BPB_TOTSEC32                  32
#define BS_FAT_DRVNUM                 36
#define BS_FAT_BOOTSIG                38
#define BS_FAT_VOLID                  39
#define BS_FAT_VOLLAB                 43
#define BS_FAT_FILSYSTYPE             54
#define BPB_FAT32_FATSZ32             36
#define BPB_FAT32_EXTFLAGS            40
#define BPB_FAT32_FSVER               42
#define BPB_FAT32_ROOTCLUS            44
#define BPB_FAT32_FSINFO              48
#define BPB_FAT32_BKBOOTSEC           50
#define BS_FAT32_DRVNUM               64
#define BS_FAT32_BOOTSIG              66
#define BS_FAT32_VOLID                67
#define BS_FAT32_VOLLAB               71
#define BS_FAT32_FILSYSTYPE           82
#define FAT_TYPE_FAT12                1
#define FAT_TYPE_FAT16                2
#define FAT_TYPE_FAT32                3
#define SIGNATURE_POSITION            510
#define SIGNATURE_VALUE               0xAA55
#define PARTITION1_TYPECODE_LOCATION  450
#define FAT32_TYPECODE1               0x0B
#define FAT32_TYPECODE2               0x0C
#define PARTITION1_LBA_BEGIN_LOCATION 454
#define PARTITION1_SIZE_LOCATION      458
#define FAT_DIR_ENTRY_SIZE            32
#define FAT_SFN_SIZE_FULL             11
#define FAT_SFN_SIZE_PARTIAL          8
#define FILE_ATTR_READ_ONLY           0x01
#define FILE_ATTR_HIDDEN              0x02
#define FILE_ATTR_SYSTEM              0x04
#define FILE_ATTR_SYSHID              0x06
#define FILE_ATTR_VOLUME_ID           0x08
#define FILE_ATTR_DIRECTORY           0x10
#define FILE_ATTR_ARCHIVE             0x20
#define FILE_ATTR_LFN_TEXT            0x0F
#define FILE_HEADER_BLANK             0x00
#define FILE_HEADER_DELETED           0xE5
#define FILE_TYPE_DIR                 0x10
#define FILE_TYPE_FILE                0x20
#define FAT_TIME_HOURS_SHIFT          11
#define FAT_TIME_HOURS_MASK           0x1F
#define FAT_TIME_MINUTES_SHIFT        5
#define FAT_TIME_MINUTES_MASK         0x3F
#define FAT_TIME_SECONDS_SHIFT        0
#define FAT_TIME_SECONDS_MASK         0x1F
#define FAT_TIME_SECONDS_SCALE        2
#define FAT_DATE_YEAR_SHIFT           9
#define FAT_DATE_YEAR_MASK            0x7F
#define FAT_DATE_MONTH_SHIFT          5
#define FAT_DATE_MONTH_MASK           0xF
#define FAT_DATE_DAY_SHIFT            0
#define FAT_DATE_DAY_MASK             0x1F
#define FAT_DATE_YEAR_OFFSET          1980
#define FAT32_LAST_CLUSTER            0xFFFFFFFF
#define FAT32_INVALID_CLUSTER         0xFFFFFFFF
STRUCT_PACK_BEGIN
struct fat_dir_entry STRUCT_PACK {
  uint8 Name[11];
  uint8 Attr;
  uint8 NTRes;
  uint8 CrtTimeTenth;
  uint8 CrtTime[2];
  uint8 CrtDate[2];
  uint8 LstAccDate[2];
  uint16 FstClusHI;
  uint8 WrtTime[2];
  uint8 WrtDate[2];
  uint16 FstClusLO;
  uint32 FileSize;
} STRUCT_PACKED;
STRUCT_PACK_END
#define FAT_INIT_OK                   0
#define FAT_INIT_MEDIA_ACCESS_ERROR   (-1)
#define FAT_INIT_INVALID_SECTOR_SIZE  (-2)
#define FAT_INIT_INVALID_SIGNATURE    (-3)
#define FAT_INIT_ENDIAN_ERROR         (-4)
#define FAT_INIT_WRONG_FILESYS_TYPE   (-5)
#define FAT_INIT_WRONG_PARTITION_TYPE (-6)
#define FAT_INIT_STRUCT_PACKING       (-7)
#define FAT_DIR_ENTRIES_PER_SECTOR    (FAT_SECTOR_SIZE / FAT_DIR_ENTRY_SIZE)
typedef int (*fn_diskio_read) (struct fatfs_ctx* ctx, uint32 sector, uint8* buffer,
                               uint32 sector_count);
typedef int (*fn_diskio_write) (struct fatfs_ctx* ctx, uint32 sector, uint8* buffer,
                                uint32 sector_count);
struct disk_if {
  fn_diskio_read read_media;
  fn_diskio_write write_media;
};
struct fat_buffer;
struct fat_buffer {
  uint8 sector[FAT_SECTOR_SIZE * FAT_BUFFER_SECTORS];
  uint32 address;
  int dirty;
  uint8* ptr;
  struct fat_buffer* next;
};
typedef enum eFatType { FAT_TYPE_16, FAT_TYPE_32 } tFatType;
struct fatfs {
  uint8 sectors_per_cluster;
  uint32 cluster_begin_lba;
  uint32 rootdir_first_cluster;
  uint32 rootdir_first_sector;
  uint32 rootdir_sectors;
  uint32 fat_begin_lba;
  uint16 fs_info_sector;
  uint32 lba_begin;
  uint32 fat_sectors;
  uint32 next_free_cluster;
  uint16 root_entry_count;
  uint16 reserved_sectors;
  uint8 num_of_fats;
  tFatType fat_type;
  struct disk_if disk_io;
  void (*fl_lock) (void);
  void (*fl_unlock) (void);
  struct fat_buffer currentsector;
  struct fat_buffer* fat_buffer_head;
  struct fat_buffer fat_buffers[FAT_BUFFERS];
};
struct fs_dir_list_status {
  uint32 sector;
  uint32 cluster;
  uint8 offset;
};
struct fs_dir_ent {
  char filename[FATFS_MAX_LONG_FILENAME];
  uint8 is_dir;
  uint32 cluster;
  uint32 size;
};
int fatfs_init (struct fatfs_ctx* ctx, struct fatfs* fs);
uint32 fatfs_lba_of_cluster (struct fatfs* fs, uint32 Cluster_Number);
int fatfs_sector_reader (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Startcluster,
                         uint32 offset, uint8* target);
int fatfs_sector_read (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 lba, uint8* target,
                       uint32 count);
int fatfs_sector_write (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 lba, uint8* target,
                        uint32 count);
int fatfs_read_sector (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 cluster, uint32 sector,
                       uint8* target);
int fatfs_write_sector (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 cluster, uint32 sector,
                        uint8* target);
void fatfs_show_details (struct fatfs* fs);
uint32 fatfs_get_root_cluster (struct fatfs* fs);
uint32 fatfs_get_file_entry (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Cluster,
                             char* nametofind, struct fat_dir_entry* sfEntry);
int fatfs_sfn_exists (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Cluster, char* shortname);
int fatfs_update_file_length (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Cluster,
                              char* shortname, uint32 fileLength);
int fatfs_mark_file_deleted (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 Cluster,
                             char* shortname);
void fatfs_list_directory_start (struct fatfs* fs, struct fs_dir_list_status* dirls,
                                 uint32 StartCluster);
int fatfs_list_directory_next (struct fatfs_ctx* ctx, struct fatfs* fs,
                               struct fs_dir_list_status* dirls, struct fs_dir_ent* entry);
int fatfs_update_timestamps (struct fat_dir_entry* directoryEntry, int create, int modify,
                             int access);

#define __FAT_FORMAT_H__
int fatfs_format (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 volume_sectors, const char* name);
int fatfs_format_fat16 (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 volume_sectors,
                        const char* name);
int fatfs_format_fat32 (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 volume_sectors,
                        const char* name);

#define __FAT_MISC_H__
#define MAX_LONGFILENAME_ENTRIES 20
#define MAX_LFN_ENTRY_LENGTH     13
#define GET_32BIT_WORD(buffer, location)                                                           \
  (((uint32)buffer[location + 3] << 24) + ((uint32)buffer[location + 2] << 16) +                   \
   ((uint32)buffer[location + 1] << 8) + (uint32)buffer[location + 0])
#define GET_16BIT_WORD(buffer, location)                                                           \
  (((uint16)buffer[location + 1] << 8) + (uint16)buffer[location + 0])
#define SET_32BIT_WORD(buffer, location, value)                                                    \
  {                                                                                                \
    buffer[location + 0] = (uint8)((value) & 0xFF);                                                \
    buffer[location + 1] = (uint8)((value >> 8) & 0xFF);                                           \
    buffer[location + 2] = (uint8)((value >> 16) & 0xFF);                                          \
    buffer[location + 3] = (uint8)((value >> 24) & 0xFF);                                          \
  }
#define SET_16BIT_WORD(buffer, location, value)                                                    \
  {                                                                                                \
    buffer[location + 0] = (uint8)((value) & 0xFF);                                                \
    buffer[location + 1] = (uint8)((value >> 8) & 0xFF);                                           \
  }
struct lfn_cache {
  uint8 String[MAX_LONGFILENAME_ENTRIES][MAX_LFN_ENTRY_LENGTH];
  uint8 Null;
  uint8 no_of_strings;
};
void fatfs_lfn_cache_init (struct lfn_cache* lfn, int wipeTable);
void fatfs_lfn_cache_entry (struct lfn_cache* lfn, uint8* entryBuffer);
char* fatfs_lfn_cache_get (struct lfn_cache* lfn);
int fatfs_entry_lfn_text (struct fat_dir_entry* entry);
int fatfs_entry_lfn_invalid (struct fat_dir_entry* entry);
int fatfs_entry_lfn_exists (struct lfn_cache* lfn, struct fat_dir_entry* entry);
int fatfs_entry_sfn_only (struct fat_dir_entry* entry);
int fatfs_entry_is_dir (struct fat_dir_entry* entry);
int fatfs_entry_is_file (struct fat_dir_entry* entry);
int fatfs_lfn_entries_required (char* filename);
void fatfs_filename_to_lfn (char* filename, uint8* buffer, int entry, uint8 sfnChk);
void fatfs_sfn_create_entry (char* shortfilename, uint32 size, uint32 startCluster,
                             struct fat_dir_entry* entry, int dir);
int fatfs_lfn_create_sfn (char* sfn_output, char* filename);
int fatfs_lfn_generate_tail (char* sfn_output, char* sfn_input, uint32 tailNum);
void fatfs_convert_from_fat_time (uint16 fat_time, int* hours, int* minutes, int* seconds);
void fatfs_convert_from_fat_date (uint16 fat_date, int* day, int* month, int* year);
uint16 fatfs_convert_to_fat_time (int hours, int minutes, int seconds);
uint16 fatfs_convert_to_fat_date (int day, int month, int year);
void fatfs_print_sector (uint32 sector, uint8* data);

#define __FILESTRING_H__
int fatfs_total_path_levels (char* path);
int fatfs_get_substring (char* Path, int levelreq, char* output, int max_len);
int fatfs_split_path (char* FullPath, char* Path, int max_path, char* FileName, int max_filename);
int fatfs_compare_names (char* strA, char* strB);
int fatfs_string_ends_with_slash (char* path);
int fatfs_get_sfn_display_name (char* out, char* in);
int fatfs_get_extension (char* filename, char* out, int maxlen);
int fatfs_create_path_string (char* path, char* filename, char* out, int maxlen);

#define __FAT_CACHE_H__

#define __FAT_FILELIB_H__

#define __FAT_LIST_H__
#define FAT_ASSERT(x)
#define FAT_INLINE
struct fat_list;
struct fat_node {
  struct fat_node* previous;
  struct fat_node* next;
};
struct fat_list {
  struct fat_node* head;
  struct fat_node* tail;
};
#define fat_list_entry(p, t, m) p ? ((t*)((char*)(p) - (char*)(&((t*)0)->m))) : 0
#define fat_list_next(l, p)     (p)->next
#define fat_list_prev(l, p)     (p)->previous
#define fat_list_first(l)       (l)->head
#define fat_list_last(l)        (l)->tail
#define fat_list_for_each(l, p) for ((p) = (l)->head; (p); (p) = (p)->next)
static FAT_INLINE void fat_list_init (struct fat_list* list) {
  FAT_ASSERT (list);
  list->head = list->tail = 0;
}
static FAT_INLINE void fat_list_remove (struct fat_list* list, struct fat_node* node) {
  FAT_ASSERT (list);
  FAT_ASSERT (node);
  if (!node->previous)
    list->head = node->next;
  else
    node->previous->next = node->next;
  if (!node->next)
    list->tail = node->previous;
  else
    node->next->previous = node->previous;
}
static FAT_INLINE void fat_list_insert_after (struct fat_list* list, struct fat_node* node,
                                              struct fat_node* new_node) {
  FAT_ASSERT (list);
  FAT_ASSERT (node);
  FAT_ASSERT (new_node);
  new_node->previous = node;
  new_node->next = node->next;
  if (!node->next)
    list->tail = new_node;
  else
    node->next->previous = new_node;
  node->next = new_node;
}
static FAT_INLINE void fat_list_insert_before (struct fat_list* list, struct fat_node* node,
                                               struct fat_node* new_node) {
  FAT_ASSERT (list);
  FAT_ASSERT (node);
  FAT_ASSERT (new_node);
  new_node->previous = node->previous;
  new_node->next = node;
  if (!node->previous)
    list->head = new_node;
  else
    node->previous->next = new_node;
  node->previous = new_node;
}
static FAT_INLINE void fat_list_insert_first (struct fat_list* list, struct fat_node* node) {
  FAT_ASSERT (list);
  FAT_ASSERT (node);
  if (!list->head) {
    list->head = node;
    list->tail = node;
    node->previous = 0;
    node->next = 0;
  } else
    fat_list_insert_before (list, list->head, node);
}
static FAT_INLINE void fat_list_insert_last (struct fat_list* list, struct fat_node* node) {
  FAT_ASSERT (list);
  FAT_ASSERT (node);
  if (!list->tail)
    fat_list_insert_first (list, node);
  else
    fat_list_insert_after (list, list->tail, node);
}
static FAT_INLINE int fat_list_is_empty (struct fat_list* list) {
  FAT_ASSERT (list);
  return !list->head;
}
static FAT_INLINE struct fat_node* fat_list_pop_head (struct fat_list* list) {
  struct fat_node* node;
  FAT_ASSERT (list);
  node = fat_list_first (list);
  if (node)
    fat_list_remove (list, node);
  return node;
}
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
#define EOF      (-1)
struct sFL_FILE;
struct cluster_lookup {
  uint32 ClusterIdx;
  uint32 CurrentCluster;
};
typedef struct sFL_FILE {
  uint32 parentcluster;
  uint32 startcluster;
  uint32 bytenum;
  uint32 filelength;
  int filelength_changed;
  char path[FATFS_MAX_LONG_FILENAME];
  char filename[FATFS_MAX_LONG_FILENAME];
  uint8 shortfilename[11];
  struct cluster_lookup last_fat_lookup;
  uint8 file_data_sector[FAT_SECTOR_SIZE];
  uint32 file_data_address;
  int file_data_dirty;
  uint8 flags;
#define FILE_READ   (1 << 0)
#define FILE_WRITE  (1 << 1)
#define FILE_APPEND (1 << 2)
#define FILE_BINARY (1 << 3)
#define FILE_ERASE  (1 << 4)
#define FILE_CREATE (1 << 5)
  struct fat_node list_node;
} FL_FILE;
void fl_init (struct fatfs_ctx* ctx);
void fl_attach_locks (struct fatfs_ctx* ctx, void (*lock) (void), void (*unlock) (void));
int fl_attach_media (struct fatfs_ctx* ctx, fn_diskio_read rd, fn_diskio_write wr);
void fl_shutdown (struct fatfs_ctx* ctx);
void* fl_fopen (struct fatfs_ctx* ctx, const char* path, const char* modifiers);
void fl_fclose (struct fatfs_ctx* ctx, void* file);
int fl_fflush (struct fatfs_ctx* ctx, void* file);
int fl_fgetc (struct fatfs_ctx* ctx, void* file);
char* fl_fgets (struct fatfs_ctx* ctx, char* s, int n, void* f);
int fl_fputc (struct fatfs_ctx* ctx, int c, void* file);
int fl_fputs (struct fatfs_ctx* ctx, const char* str, void* file);
int fl_fwrite (struct fatfs_ctx* ctx, const void* data, int size, int count, void* file);
int fl_fread (struct fatfs_ctx* ctx, void* data, int size, int count, void* file);
int fl_fseek (struct fatfs_ctx* ctx, void* file, long offset, int origin);
int fl_fgetpos (struct fatfs_ctx* ctx, void* file, uint32* position);
long fl_ftell (struct fatfs_ctx* ctx, void* f);
int fl_feof (struct fatfs_ctx* ctx, void* f);
int fl_remove (struct fatfs_ctx* ctx, const char* filename);
typedef struct fs_dir_list_status FL_DIR;
typedef struct fs_dir_ent fl_dirent;
FL_DIR* fl_opendir (struct fatfs_ctx* ctx, const char* path, FL_DIR* dir);
int fl_readdir (struct fatfs_ctx* ctx, FL_DIR* dirls, fl_dirent* entry);
int fl_closedir (struct fatfs_ctx* ctx, FL_DIR* dir);
void fl_listdirectory (struct fatfs_ctx* ctx, const char* path);
int fl_createdirectory (struct fatfs_ctx* ctx, const char* path);
int fl_is_dir (struct fatfs_ctx* ctx, const char* path);
int fl_format (struct fatfs_ctx* ctx, uint32 volume_sectors, const char* name);
int fatfs_cache_init (struct fatfs* fs, FL_FILE* file);
int fatfs_cache_get_next_cluster (struct fatfs* fs, FL_FILE* file, uint32 clusterIdx,
                                  uint32* pNextCluster);
int fatfs_cache_set_next_cluster (struct fatfs* fs, FL_FILE* file, uint32 clusterIdx,
                                  uint32 nextCluster);

#define __FAT_TABLE_H__
void fatfs_fat_init (struct fatfs* fs);
int fatfs_fat_purge (struct fatfs_ctx* ctx, struct fatfs* fs);
uint32 fatfs_find_next_cluster (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 current_cluster);
void fatfs_set_fs_info_next_free_cluster (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 newValue);
int fatfs_find_blank_cluster (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 start_cluster,
                              uint32* free_cluster);
int fatfs_fat_set_cluster (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 cluster,
                           uint32 next_cluster);
int fatfs_fat_add_cluster_to_chain (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 start_cluster,
                                    uint32 newEntry);
int fatfs_free_cluster_chain (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 start_cluster);
uint32 fatfs_count_free_clusters (struct fatfs_ctx* ctx, struct fatfs* fs);

#define __FAT_WRITE_H__
int fatfs_add_file_entry (struct fatfs_ctx* ctx, struct fatfs* fs, uint32 dirCluster,
                          char* filename, char* shortfilename, uint32 startCluster, uint32 size,
                          int dir);
int fatfs_add_free_space (struct fatfs_ctx* ctx, struct fatfs* fs, uint32* startCluster,
                          uint32 clusters);
int fatfs_allocate_free_space (struct fatfs_ctx* ctx, struct fatfs* fs, int newFile,
                               uint32* startCluster, uint32 size);
#pragma clang diagnostic pop
