#ifndef UTILS_H_1#define UTILS_H_23#include <stdio.h>4#include <stdint.h>56// defines78// printing size_t varies by compiler9#if defined(_MSC_VER) || defined(__MINGW32__)10#define SIZE_T_FORMAT "%Iu"11#else12#define SIZE_T_FORMAT "%zu"13#endif1415#define KB 102416#define MB (1024 * KB)1718// number of elements in statically declared array19#define DIM(S_ARR_) (sizeof(S_ARR_) / sizeof(S_ARR_[0]))2021#define MIN(A_, B_) ((A_) < (B_) ? (A_) : (B_))22#define MAX(A_, B_) ((A_) > (B_) ? (A_) : (B_))2324// align value to N-byte boundary25#define ALIGN(VAL_, ALIGNMENT_) (((VAL_) + ((ALIGNMENT_) - 1)) & ~((ALIGNMENT_) - 1))2627// read/write u32/16 big/little endian28#define read_u32_be(buf) (unsigned int)(((buf)[0] << 24) + ((buf)[1] << 16) + ((buf)[2] << 8) + ((buf)[3]))29#define read_u32_le(buf) (unsigned int)(((buf)[1] << 24) + ((buf)[0] << 16) + ((buf)[3] << 8) + ((buf)[2]))30#define write_u32_be(buf, val) do { \31(buf)[0] = ((val) >> 24) & 0xFF; \32(buf)[1] = ((val) >> 16) & 0xFF; \33(buf)[2] = ((val) >> 8) & 0xFF; \34(buf)[3] = (val) & 0xFF; \35} while(0)36#define read_u16_be(buf) (((buf)[0] << 8) + ((buf)[1]))37#define write_u16_be(buf, val) do { \38(buf)[0] = ((val) >> 8) & 0xFF; \39(buf)[1] = ((val)) & 0xFF; \40} while(0)4142// Windows compatibility43#if defined(_MSC_VER) || defined(__MINGW32__)44#include <direct.h>45#define mkdir(DIR_, PERM_) _mkdir(DIR_)46#ifndef strcasecmp47#define strcasecmp(A, B) stricmp(A, B)48#endif49#endif5051// typedefs5253#define MAX_DIR_FILES 12854typedef struct55{56char *files[MAX_DIR_FILES];57int count;58} dir_list;5960typedef enum61{62ENCODING_RAW,63ENCODING_U8,64ENCODING_U16,65ENCODING_U32,66ENCODING_U64,67} write_encoding;6869// global verbosity setting70extern int g_verbosity;7172#define ERROR(...) fprintf(stderr, __VA_ARGS__)73#define INFO(...) if (g_verbosity) printf(__VA_ARGS__)7475// functions7677// convert two bytes in big-endian to signed int78int read_s16_be(unsigned char *buf);7980// convert four bytes in big-endian to float81float read_f32_be(unsigned char *buf);8283// determine if value is power of 284// returns 1 if val is power of 2, 0 otherwise85int is_power2(unsigned int val);8687// print buffer as raw binary, hex u8, hex u16, hex u32, hex u64. pads to encoding size88// fp: file pointer89// encoding: encoding type to use (see write_encoding)90// buf: buffer to read bytes from91// length: length of buffer to print92int fprint_write_output(FILE *fp, write_encoding encoding, const uint8_t *buf, int length);9394// perform byteswapping to convert from v64 to z64 ordering95void swap_bytes(unsigned char *data, long length);9697// reverse endian to convert from n64 to z64 ordering98void reverse_endian(unsigned char *data, long length);99100// get size of file without opening it;101// returns file size or negative on error102long filesize(const char *file_name);103104// update file timestamp to now, creating it if it doesn't exist105void touch_file(const char *filename);106107// read entire contents of file into buffer108// returns file size or negative on error109long read_file(const char *file_name, unsigned char **data);110111// write buffer to file112// returns number of bytes written out or -1 on failure113long write_file(const char *file_name, unsigned char *data, long length);114115// generate an output file name from input name by replacing file extension116// in_name: input file name117// out_name: buffer to write output name in118// extension: new file extension to use119void generate_filename(const char *in_name, char *out_name, char *extension);120121// extract base filename from file path122// name: path to file123// returns just the file name after the last '/'124char *basename(const char *name);125126// make a directory if it doesn't exist127// dir_name: name of the directory128void make_dir(const char *dir_name);129130// copy a file from src_name to dst_name. will not make directories131// src_name: source file name132// dst_name: destination file name133long copy_file(const char *src_name, const char *dst_name);134135// list a directory, optionally filtering files by extension136// dir: directory to list files in137// extension: extension to filter files by (NULL if no filtering)138// list: output list and count139void dir_list_ext(const char *dir, const char *extension, dir_list *list);140141// free associated date from a directory list142// list: directory list filled in by dir_list_ext() call143void dir_list_free(dir_list *list);144145// determine if a string ends with another string146// str: string to check if ends with 'suffix'147// suffix: string to see if 'str' ends with148// returns 1 if 'str' ends with 'suffix'149int str_ends_with(const char *str, const char *suffix);150151#endif // UTILS_H_152153154