Skip to content

Commit

Permalink
Replace macros with aliases on all platforms (btzy#121)
Browse files Browse the repository at this point in the history
This pull request is intended to address issues with creating wrappers in other languages, by having separate function declarations for native and UTF-8 versions for all platforms.
  • Loading branch information
ds5678 authored Dec 17, 2023
1 parent 83191b6 commit 6dc1272
Show file tree
Hide file tree
Showing 5 changed files with 217 additions and 94 deletions.
169 changes: 75 additions & 94 deletions src/include/nfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ extern "C" {

#include <stddef.h>

typedef char nfdu8char_t;

#ifdef _WIN32
/* denotes UTF-16 char */
typedef wchar_t nfdnchar_t;
#else
/* denotes UTF-8 char */
typedef char nfdnchar_t;
typedef nfdu8char_t nfdnchar_t;
#endif // _WIN32

/* opaque data structure -- see NFD_PathSet_* */
Expand Down Expand Up @@ -74,15 +76,30 @@ typedef enum {
NFD_CANCEL /* user pressed cancel */
} nfdresult_t;

typedef struct {
const nfdu8char_t* name;
const nfdu8char_t* spec;
} nfdu8filteritem_t;

#ifdef _WIN32
/* denotes UTF-16 Filter Item */
typedef struct {
const nfdnchar_t* name;
const nfdnchar_t* spec;
} nfdnfilteritem_t;
#else
/* denotes UTF-8 Filter Item */
typedef nfdu8filteritem_t nfdnfilteritem_t;
#endif // _WIN32

/* free a file path that was returned by the dialogs */
/* Note: use NFD_PathSet_FreePath to free path from pathset instead of this function */
/* Note: use NFD_PathSet_FreePathN to free path from pathset instead of this function */
NFD_API void NFD_FreePathN(nfdnchar_t* filePath);

/* free a file path that was returned by the dialogs */
/* Note: use NFD_PathSet_FreePathU8 to free path from pathset instead of this function */
NFD_API void NFD_FreePathU8(nfdu8char_t* filePath);

/* initialize NFD - call this for every thread that might use NFD, before calling any other NFD
* functions on that thread */
NFD_API nfdresult_t NFD_Init(void);
Expand All @@ -100,8 +117,18 @@ NFD_API nfdresult_t NFD_OpenDialogN(nfdnchar_t** outPath,
nfdfiltersize_t filterCount,
const nfdnchar_t* defaultPath);

/* single file open dialog */
/* It is the caller's responsibility to free `outPath` via NFD_FreePathU8() if this function returns
* NFD_OKAY */
/* If filterCount is zero, filterList is ignored (you can use NULL) */
/* If defaultPath is NULL, the operating system will decide */
NFD_API nfdresult_t NFD_OpenDialogU8(nfdu8char_t** outPath,
const nfdu8filteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdu8char_t* defaultPath);

/* multiple file open dialog */
/* It is the caller's responsibility to free `outPaths` via NFD_PathSet_Free() if this function
/* It is the caller's responsibility to free `outPaths` via NFD_PathSet_FreeN() if this function
* returns NFD_OKAY */
/* If filterCount is zero, filterList is ignored (you can use NULL) */
/* If defaultPath is NULL, the operating system will decide */
Expand All @@ -110,6 +137,16 @@ NFD_API nfdresult_t NFD_OpenDialogMultipleN(const nfdpathset_t** outPaths,
nfdfiltersize_t filterCount,
const nfdnchar_t* defaultPath);

/* multiple file open dialog */
/* It is the caller's responsibility to free `outPaths` via NFD_PathSet_FreeU8() if this function
* returns NFD_OKAY */
/* If filterCount is zero, filterList is ignored (you can use NULL) */
/* If defaultPath is NULL, the operating system will decide */
NFD_API nfdresult_t NFD_OpenDialogMultipleU8(const nfdpathset_t** outPaths,
const nfdu8filteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdu8char_t* defaultPath);

/* save dialog */
/* It is the caller's responsibility to free `outPath` via NFD_FreePathN() if this function returns
* NFD_OKAY */
Expand All @@ -121,12 +158,29 @@ NFD_API nfdresult_t NFD_SaveDialogN(nfdnchar_t** outPath,
const nfdnchar_t* defaultPath,
const nfdnchar_t* defaultName);

/* save dialog */
/* It is the caller's responsibility to free `outPath` via NFD_FreePathU8() if this function returns
* NFD_OKAY */
/* If filterCount is zero, filterList is ignored (you can use NULL) */
/* If defaultPath is NULL, the operating system will decide */
NFD_API nfdresult_t NFD_SaveDialogU8(nfdu8char_t** outPath,
const nfdu8filteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdu8char_t* defaultPath,
const nfdu8char_t* defaultName);

/* select folder dialog */
/* It is the caller's responsibility to free `outPath` via NFD_FreePathN() if this function returns
* NFD_OKAY */
/* If defaultPath is NULL, the operating system will decide */
NFD_API nfdresult_t NFD_PickFolderN(nfdnchar_t** outPath, const nfdnchar_t* defaultPath);

/* select folder dialog */
/* It is the caller's responsibility to free `outPath` via NFD_FreePathU8() if this function returns
* NFD_OKAY */
/* If defaultPath is NULL, the operating system will decide */
NFD_API nfdresult_t NFD_PickFolderU8(nfdu8char_t** outPath, const nfdu8char_t* defaultPath);

/* Get last error -- set when nfdresult_t returns NFD_ERROR */
/* Returns the last error that was set, or NULL if there is no error. */
/* The memory is owned by NFD and should not be freed by user code. */
Expand All @@ -149,20 +203,22 @@ typedef unsigned int nfdpathsetsize_t;
/* note that some paths might be invalid (NFD_ERROR will be returned by NFD_PathSet_GetPath), so we
* might not actually have this number of usable paths */
NFD_API nfdresult_t NFD_PathSet_GetCount(const nfdpathset_t* pathSet, nfdpathsetsize_t* count);
/* Gets the UTF-8 path at offset index */
/* Gets the native path at offset index */
/* It is the caller's responsibility to free `outPath` via NFD_PathSet_FreePathN() if this function
* returns NFD_OKAY */
NFD_API nfdresult_t NFD_PathSet_GetPathN(const nfdpathset_t* pathSet,
nfdpathsetsize_t index,
nfdnchar_t** outPath);
/* Gets the UTF-8 path at offset index */
/* It is the caller's responsibility to free `outPath` via NFD_PathSet_FreePathU8() if this function
* returns NFD_OKAY */
NFD_API nfdresult_t NFD_PathSet_GetPathU8(const nfdpathset_t* pathSet,
nfdpathsetsize_t index,
nfdu8char_t** outPath);
/* Free the path gotten by NFD_PathSet_GetPathN */
#ifdef _WIN32
#define NFD_PathSet_FreePathN NFD_FreePathN
#elif __APPLE__
#define NFD_PathSet_FreePathN NFD_FreePathN
#else
NFD_API void NFD_PathSet_FreePathN(const nfdnchar_t* filePath);
#endif // _WIN32, __APPLE__
/* Free the path gotten by NFD_PathSet_GetPathU8 */
NFD_API void NFD_PathSet_FreePathU8(const nfdu8char_t* filePath);

/* Gets an enumerator of the path set. */
/* It is the caller's responsibility to free `enumerator` via NFD_PathSet_FreeEnum() if this
Expand All @@ -173,74 +229,25 @@ NFD_API nfdresult_t NFD_PathSet_GetEnum(const nfdpathset_t* pathSet,
NFD_API void NFD_PathSet_FreeEnum(nfdpathsetenum_t* enumerator);
/* Gets the next item from the path set enumerator.
* If there are no more items, then *outPaths will be set to NULL. */
/* It is the caller's responsibility to free `*outPath` via NFD_PathSet_FreePath() if this
/* It is the caller's responsibility to free `*outPath` via NFD_PathSet_FreePathN() if this
* function returns NFD_OKAY and `*outPath` is not null */
NFD_API nfdresult_t NFD_PathSet_EnumNextN(nfdpathsetenum_t* enumerator, nfdnchar_t** outPath);
/* Gets the next item from the path set enumerator.
* If there are no more items, then *outPaths will be set to NULL. */
/* It is the caller's responsibility to free `*outPath` via NFD_PathSet_FreePathU8() if this
* function returns NFD_OKAY and `*outPath` is not null */
NFD_API nfdresult_t NFD_PathSet_EnumNextU8(nfdpathsetenum_t* enumerator, nfdu8char_t** outPath);

/* Free the pathSet */
NFD_API void NFD_PathSet_Free(const nfdpathset_t* pathSet);

#ifdef _WIN32

/* say that the U8 versions of functions are not just #defined to be the native versions */
/* say that the U8 versions of functions are not just __attribute__((alias(""))) to the native
* versions */
#define NFD_DIFFERENT_NATIVE_FUNCTIONS

typedef char nfdu8char_t;

typedef struct {
const nfdu8char_t* name;
const nfdu8char_t* spec;
} nfdu8filteritem_t;

/* UTF-8 compatibility functions */

/* free a file path that was returned */
NFD_API void NFD_FreePathU8(nfdu8char_t* outPath);

/* single file open dialog */
/* It is the caller's responsibility to free `outPath` via NFD_FreePathU8() if this function returns
* NFD_OKAY */
NFD_API nfdresult_t NFD_OpenDialogU8(nfdu8char_t** outPath,
const nfdu8filteritem_t* filterList,
nfdfiltersize_t count,
const nfdu8char_t* defaultPath);

/* multiple file open dialog */
/* It is the caller's responsibility to free `outPaths` via NFD_PathSet_Free() if this function
* returns NFD_OKAY */
NFD_API nfdresult_t NFD_OpenDialogMultipleU8(const nfdpathset_t** outPaths,
const nfdu8filteritem_t* filterList,
nfdfiltersize_t count,
const nfdu8char_t* defaultPath);

/* save dialog */
/* It is the caller's responsibility to free `outPath` via NFD_FreePathU8() if this function returns
* NFD_OKAY */
NFD_API nfdresult_t NFD_SaveDialogU8(nfdu8char_t** outPath,
const nfdu8filteritem_t* filterList,
nfdfiltersize_t count,
const nfdu8char_t* defaultPath,
const nfdu8char_t* defaultName);

/* select folder dialog */
/* It is the caller's responsibility to free `outPath` via NFD_FreePathU8() if this function returns
* NFD_OKAY */
NFD_API nfdresult_t NFD_PickFolderU8(nfdu8char_t** outPath, const nfdu8char_t* defaultPath);

/* Get the UTF-8 path at offset index */
/* It is the caller's responsibility to free `outPath` via NFD_FreePathU8() if this function returns
* NFD_OKAY */
NFD_API nfdresult_t NFD_PathSet_GetPathU8(const nfdpathset_t* pathSet,
nfdpathsetsize_t index,
nfdu8char_t** outPath);

/* Gets the next item from the path set enumerator.
* If there are no more items, then *outPaths will be set to NULL. */
/* It is the caller's responsibility to free `*outPath` via NFD_PathSet_FreePathU8() if this
* function returns NFD_OKAY and `*outPath` is not null */
NFD_API nfdresult_t NFD_PathSet_EnumNextU8(nfdpathsetenum_t* enumerator, nfdu8char_t** outPath);

#define NFD_PathSet_FreePathU8 NFD_FreePathU8
#endif // _WIN32

#ifdef NFD_NATIVE
typedef nfdnchar_t nfdchar_t;
Expand All @@ -266,32 +273,6 @@ typedef nfdu8filteritem_t nfdfilteritem_t;
#define NFD_PathSet_EnumNext NFD_PathSet_EnumNextU8
#endif // NFD_NATIVE

#else // _WIN32

/* the native charset is already UTF-8 */
typedef nfdnchar_t nfdchar_t;
typedef nfdnfilteritem_t nfdfilteritem_t;
#define NFD_FreePath NFD_FreePathN
#define NFD_OpenDialog NFD_OpenDialogN
#define NFD_OpenDialogMultiple NFD_OpenDialogMultipleN
#define NFD_SaveDialog NFD_SaveDialogN
#define NFD_PickFolder NFD_PickFolderN
#define NFD_PathSet_GetPath NFD_PathSet_GetPathN
#define NFD_PathSet_FreePath NFD_PathSet_FreePathN
#define NFD_PathSet_EnumNext NFD_PathSet_EnumNextN
typedef nfdnchar_t nfdu8char_t;
typedef nfdnfilteritem_t nfdu8filteritem_t;
#define NFD_FreePathU8 NFD_FreePathN
#define NFD_OpenDialogU8 NFD_OpenDialogN
#define NFD_OpenDialogMultipleU8 NFD_OpenDialogMultipleN
#define NFD_SaveDialogU8 NFD_SaveDialogN
#define NFD_PickFolderU8 NFD_PickFolderN
#define NFD_PathSet_GetPathU8 NFD_PathSet_GetPathN
#define NFD_PathSet_FreePathU8 NFD_PathSet_FreePathN
#define NFD_PathSet_EnumNextU8 NFD_PathSet_EnumNextN

#endif // _WIN32

#ifdef __cplusplus
}
#endif // __cplusplus
Expand Down
64 changes: 64 additions & 0 deletions src/nfd_cocoa.m
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,10 @@ void NFD_FreePathN(nfdnchar_t* filePath) {
NFDi_Free((void*)filePath);
}

void NFD_FreePathU8(nfdu8char_t* filePath) {
NFD_FreePathN(filePath);
}

static NSApplicationActivationPolicy old_app_policy;

nfdresult_t NFD_Init(void) {
Expand Down Expand Up @@ -236,6 +240,13 @@ nfdresult_t NFD_OpenDialogN(nfdnchar_t** outPath,
return result;
}

nfdresult_t NFD_OpenDialogU8(nfdu8char_t** outPath,
const nfdu8filteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdu8char_t* defaultPath) {
return NFD_OpenDialogN(outPath, filterList, filterCount, defaultPath);
}

nfdresult_t NFD_OpenDialogMultipleN(const nfdpathset_t** outPaths,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
Expand Down Expand Up @@ -270,6 +281,13 @@ nfdresult_t NFD_OpenDialogMultipleN(const nfdpathset_t** outPaths,
return result;
}

nfdresult_t NFD_OpenDialogMultipleU8(const nfdpathset_t** outPaths,
const nfdu8filteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdu8char_t* defaultPath) {
return NFD_OpenDialogMultipleN(outPaths, filterList, filterCount, defaultPath);
}

nfdresult_t NFD_SaveDialogN(nfdnchar_t** outPath,
const nfdnfilteritem_t* filterList,
nfdfiltersize_t filterCount,
Expand Down Expand Up @@ -306,6 +324,14 @@ nfdresult_t NFD_SaveDialogN(nfdnchar_t** outPath,
return result;
}

nfdresult_t NFD_SaveDialogU8(nfdu8char_t** outPath,
const nfdu8filteritem_t* filterList,
nfdfiltersize_t filterCount,
const nfdu8char_t* defaultPath,
const nfdu8char_t* defaultName) {
return NFD_SaveDialogN(outPath, filterList, filterCount, defaultPath, defaultName);
}

nfdresult_t NFD_PickFolderN(nfdnchar_t** outPath, const nfdnchar_t* defaultPath) {
nfdresult_t result = NFD_CANCEL;
@autoreleasepool {
Expand All @@ -332,6 +358,10 @@ nfdresult_t NFD_PickFolderN(nfdnchar_t** outPath, const nfdnchar_t* defaultPath)
return result;
}

nfdresult_t NFD_PickFolderU8(nfdu8char_t** outPath, const nfdu8char_t* defaultPath) {
return NFD_PickFolderN(outPath, defaultPath);
}

nfdresult_t NFD_PathSet_GetCount(const nfdpathset_t* pathSet, nfdpathsetsize_t* count) {
const NSArray* urls = (const NSArray*)pathSet;
*count = [urls count];
Expand All @@ -351,6 +381,36 @@ nfdresult_t NFD_PathSet_GetPathN(const nfdpathset_t* pathSet,
}
}

nfdresult_t NFD_PathSet_GetPathU8(const nfdpathset_t* pathSet,
nfdpathsetsize_t index,
nfdu8char_t** outPath) {
return NFD_PathSet_GetPathN(pathSet, index, outPath);
}

void NFD_PathSet_FreePathN(const nfdnchar_t* filePath) {
// const_cast not supported on Mac
union {
const nfdnchar_t* constPath;
nfdnchar_t* nonConstPath;
} pathUnion;

pathUnion.constPath = filePath;

NFD_FreePathN(pathUnion.nonConstPath);
}

void NFD_PathSet_FreePathU8(const nfdu8char_t* filePath) {
// const_cast not supported on Mac
union {
const nfdu8char_t* constPath;
nfdu8char_t* nonConstPath;
} pathUnion;

pathUnion.constPath = filePath;

NFD_FreePathU8(pathUnion.nonConstPath);
}

void NFD_PathSet_Free(const nfdpathset_t* pathSet) {
const NSArray* urls = (const NSArray*)pathSet;
[urls release];
Expand Down Expand Up @@ -389,3 +449,7 @@ nfdresult_t NFD_PathSet_EnumNextN(nfdpathsetenum_t* enumerator, nfdnchar_t** out
}
}
}

nfdresult_t NFD_PathSet_EnumNextU8(nfdpathsetenum_t* enumerator, nfdu8char_t** outPath) {
return NFD_PathSet_EnumNextN(enumerator, outPath);
}
Loading

0 comments on commit 6dc1272

Please sign in to comment.