--- /dev/null
+/*
+ compiler.h (09.06.13)
+ Compiler-specific definitions. Note that unknown compiler is not a
+ showstopper.
+
+ Copyright (C) 2010-2013 Andrew Nayenko
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef COMPILER_H_INCLUDED
+#define COMPILER_H_INCLUDED
+
+#if __STDC_VERSION__ < 199901L
+#error C99-compliant compiler is required
+#endif
+
+#if defined(__GNUC__) /* this includes Clang */
+
+#define PRINTF __attribute__((format(printf, 1, 2)))
+#define NORETURN __attribute((noreturn))
+#define PACKED __attribute__((packed))
+
+#else
+
+#define PRINTF
+#define NORETURN
+#define PACKED
+
+#endif
+
+#define CONCAT2(a, b) a ## b
+#define CONCAT1(a, b) CONCAT2(a, b)
+#define STATIC_ASSERT(cond) \
+ static inline void CONCAT1(static_assert, __LINE__)(void) \
+ {switch (0) {case 0: case cond:;}}
+
+#endif /* ifndef COMPILER_H_INCLUDED */
#include <stdbool.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include "compiler.h"
#include "exfatfs.h"
#include "version.h"
extern int exfat_errors;
-void exfat_bug(const char* format, ...)
- __attribute__((format(printf, 1, 2), noreturn));
-void exfat_error(const char* format, ...)
- __attribute__((format(printf, 1, 2)));
-void exfat_warn(const char* format, ...)
- __attribute__((format(printf, 1, 2)));
-void exfat_debug(const char* format, ...)
- __attribute__((format(printf, 1, 2)));
+void exfat_bug(const char* format, ...) PRINTF NORETURN;
+void exfat_error(const char* format, ...) PRINTF;
+void exfat_warn(const char* format, ...) PRINTF;
+void exfat_debug(const char* format, ...) PRINTF;
struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode);
int exfat_close(struct exfat_dev* dev);
uint8_t __unused2[397]; /* 0x71 always 0 */
le16_t boot_signature; /* the value of 0xAA55 */
}
-__attribute__((__packed__));
+PACKED;
+STATIC_ASSERT(sizeof(struct exfat_super_block) == 512);
#define EXFAT_ENTRY_VALID 0x80
#define EXFAT_ENTRY_CONTINUED 0x40
uint8_t type; /* any of EXFAT_ENTRY_xxx */
uint8_t data[31];
}
-__attribute__((__packed__));
+PACKED;
+STATIC_ASSERT(sizeof(struct exfat_entry) == 32);
#define EXFAT_ENAME_MAX 15
le32_t start_cluster;
le64_t size; /* in bytes */
}
-__attribute__((__packed__));
+PACKED;
+STATIC_ASSERT(sizeof(struct exfat_entry_bitmap) == 32);
struct exfat_entry_upcase /* upper case translation table */
{
le32_t start_cluster;
le64_t size; /* in bytes */
}
-__attribute__((__packed__));
+PACKED;
+STATIC_ASSERT(sizeof(struct exfat_entry_upcase) == 32);
struct exfat_entry_label /* volume label */
{
uint8_t length; /* number of characters */
le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */
}
-__attribute__((__packed__));
+PACKED;
+STATIC_ASSERT(sizeof(struct exfat_entry_label) == 32);
#define EXFAT_ATTRIB_RO 0x01
#define EXFAT_ATTRIB_HIDDEN 0x02
uint8_t mtime_cs; /* latest modification time in cs */
uint8_t __unknown2[10];
}
-__attribute__((__packed__));
+PACKED;
+STATIC_ASSERT(sizeof(struct exfat_entry_meta1) == 32);
#define EXFAT_FLAG_ALWAYS1 (1u << 0)
#define EXFAT_FLAG_CONTIGUOUS (1u << 1)
le32_t start_cluster;
le64_t size; /* in bytes, equals to real_size */
}
-__attribute__((__packed__));
+PACKED;
+STATIC_ASSERT(sizeof(struct exfat_entry_meta2) == 32);
struct exfat_entry_name /* file or directory name */
{
uint8_t __unknown;
le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */
}
-__attribute__((__packed__));
+PACKED;
+STATIC_ASSERT(sizeof(struct exfat_entry_name) == 32);
#endif /* ifndef EXFATFS_H_INCLUDED */