Skip to content

Commit

Permalink
Merge pull request #270 from keyboardio/f/api-version
Browse files Browse the repository at this point in the history
Introduce KALEIDOSCOPE_API_VERSION
  • Loading branch information
obra committed Jan 29, 2018
2 parents 8f2ecca + 78cc806 commit 086b16f
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions src/Kaleidoscope.h
Expand Up @@ -35,6 +35,36 @@ extern HARDWARE_IMPLEMENTATION KeyboardHardware;
#define VERSION "locally-built"
#endif

/** Kaleidoscope API (major) version.
*
* The API is guaranteed to be backwards compatible for the entire duration of a
* major version. However, breaking changes may come, and result in a major
* version bump. To help migration, the `KALEIDOSCOPE_API_VERSION` macro can be
* used to check the major version provided by the Kaleidoscope we are compiling
* against. This can be used to error out with a helpful message, or change how
* the API is used - it is entirely up to the plugin or sketch author. The point
* of this macro is to let them easily check the version.
*/
#define KALEIDOSCOPE_API_VERSION 1

/** Required Kaleidoscope major version.
*
* For the sake of convenience, defining `KALEIDOSCOPE_REQUIRED_API_VERSION`
* before including `Kaleidoscope.h` itself will result in comparing its value
* to `KALEIDOSCOPE_API_VERSION`. If they differ, a helpful error message is
* printed.
*
* Done so that a new API version would result in a helpful error message,
* instead of cryptic compile errors.
*/
#if defined(KALEIDOSCOPE_REQUIRED_API_VERSION) && (KALEIDOSCOPE_REQUIRED_API_VERSION != KALEIDOSCOPE_API_VERSION)
#define xstr(a) str(a)

This comment has been minimized.

Copy link
@algernon

algernon Feb 19, 2018

Contributor

It's a hack. We have KALEIDOSCOPE_REQUIRED_API_VERSION, a #define, which resolves to a number. In the static_assert, we want to use it as part of a string, so we have to stringify it somehow. We can't use # KALEIDOSCOPE_REQUIRED_API_VERSION, because that would stringify the macro name, not its value. So we use this double-macro trick, to expand the version macro first, then stringify it.

Yes, it is ugly, but it works.

#define str(a) #a
static_assert(KALEIDOSCOPE_REQUIRED_API_VERSION == KALEIDOSCOPE_API_VERSION,
"Kaleidoscope API version mismatch! We have version " xstr(KALEIDOSCOPE_API_VERSION)
" available, but version " xstr(KALEIDOSCOPE_REQUIRED_API_VERSION) " is required.");
#endif

const uint8_t KEYMAP_SIZE
__attribute__((deprecated("Kaleidoscope.setup() does not require KEYMAP_SIZE anymore."))) = 0;

Expand Down

3 comments on commit 086b16f

@noseglasses
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@noseglasses
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cited from the page linked above:

Why is this important? Well when a macro is scanned and expanding, it creates a disabling context. This disabling context will cause a token, that refers to the currently expanding macro, to be painted blue. Thus, once its painted blue, the macro will no longer expand. This is why macros don't expand recursively. However, a disabling context only exists during one scan, so by deferring an expansion we can prevent our macros from becoming painted blue.

It explains why str() and xstr() are required to stringify.

@obra
Copy link
Member Author

@obra obra commented on 086b16f Feb 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guys, both of you need to take a step back. I'm going to be deleting some replies in this thread as off-topic.

I know I've been an absentee project lead for the last 6 or 7 weeks. I'm really sorry about that. Between baby and shipping and unavoidable travel, I've had my hands more than full. I'm going to try to keep more on top of things.

Please sign in to comment.