From 5ea35e941f0aca6a33da303d456d09a5cc033dd6 Mon Sep 17 00:00:00 2001 From: Paul F-Y Date: Sun, 29 Apr 2018 12:42:21 -0400 Subject: [PATCH 1/8] keys in a C file so we don't end up with seven copies of the table in ndless_resources --- ndless-sdk/include/keys.h | 280 +++++++++++++++++++------------------- ndless-sdk/libndls/keys.c | 146 ++++++++++++++++++++ 2 files changed, 286 insertions(+), 140 deletions(-) create mode 100644 ndless-sdk/libndls/keys.c diff --git a/ndless-sdk/include/keys.h b/ndless-sdk/include/keys.h index 71f141c3..32b3cf8e 100644 --- a/ndless-sdk/include/keys.h +++ b/ndless-sdk/include/keys.h @@ -29,148 +29,148 @@ typedef struct { #define _KEY_DUMMY_ROW 0x1C #define _KEY_DUMMY_COL 0x400 -static const t_key KEY_NSPIRE_RET = KEY_(0x10, 0x001); -static const t_key KEY_NSPIRE_ENTER = KEY_(0x10, 0x002); -static const t_key KEY_NSPIRE_SPACE = KEYTPAD_(0x10, 0x004, 0x10, 0x10); -static const t_key KEY_NSPIRE_NEGATIVE = KEY_(0x10, 0x008); -static const t_key KEY_NSPIRE_Z = KEYTPAD_(0x10, 0x010, 0x10, 0x20); -static const t_key KEY_NSPIRE_PERIOD = KEYTPAD_(0x10, 0x20, 0x1A, 0x010); -static const t_key KEY_NSPIRE_Y = KEY_(0x10, 0x040); -static const t_key KEY_NSPIRE_0 = KEY_(0x10, 0x080); -static const t_key KEY_NSPIRE_X = KEYTPAD_(0x10, 0x100, 0x12, 0x001); -static const t_key KEY_NSPIRE_THETA = KEYTPAD_(0x10, 0x400, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); -static const t_key KEY_NSPIRE_COMMA = KEYTPAD_(0x12, 0x001, 0x1E, 0x400); -static const t_key KEY_NSPIRE_PLUS = KEYTPAD_(0x12, 0x002, 0x1C, 0x004); -static const t_key KEY_NSPIRE_W = KEYTPAD_(0x12, 0x004, 0x12, 0x002); -static const t_key KEY_NSPIRE_3 = KEY_(0x12, 0x008); -static const t_key KEY_NSPIRE_V = KEYTPAD_(0x12, 0x010, 0x12, 0x004); -static const t_key KEY_NSPIRE_2 = KEYTPAD_(0x12, 0x020, 0x1C, 0x010); -static const t_key KEY_NSPIRE_U = KEYTPAD_(0x12, 0x040, 0x12, 0x010); -static const t_key KEY_NSPIRE_1 = KEY_(0x12, 0x080); -static const t_key KEY_NSPIRE_T = KEYTPAD_(0x12, 0x100, 0x12, 0x020); -static const t_key KEY_NSPIRE_eEXP = KEYTPAD_(0x12, 0x200, 0x16, 0x200); -static const t_key KEY_NSPIRE_PI = KEYTPAD_(0x12, 0x400, 0x12, 0x100); -static const t_key KEY_NSPIRE_QUES = KEYTPAD_(0x14, 0x001, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); -static const t_key KEY_NSPIRE_QUESEXCL = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x10, 0x100); -static const t_key KEY_NSPIRE_MINUS = KEYTPAD_(0x14, 0x002, 0x1A, 0x004); -static const t_key KEY_NSPIRE_S = KEYTPAD_(0x14, 0x004, 0x12, 0x040); -static const t_key KEY_NSPIRE_6 = KEY_(0x14, 0x008); -static const t_key KEY_NSPIRE_R = KEYTPAD_(0x14, 0x010, 0x14, 0x001); -static const t_key KEY_NSPIRE_5 = KEYTPAD_(0x14, 0x020, 0x1A, 0x040); -static const t_key KEY_NSPIRE_Q = KEYTPAD_(0x14, 0x040, 0x14, 0x002); -static const t_key KEY_NSPIRE_4 = KEY_(0x14, 0x080); -static const t_key KEY_NSPIRE_P = KEYTPAD_(0x14, 0x100, 0x14, 0x004); -static const t_key KEY_NSPIRE_TENX = KEYTPAD_(0x14, 0x200, 0x12, 0x400); -static const t_key KEY_NSPIRE_EE = KEYTPAD_(0x14, 0x400, 0x14, 0x100); -static const t_key KEY_NSPIRE_COLON = KEYTPAD_(0x16, 0x001, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); -static const t_key KEY_NSPIRE_MULTIPLY = KEYTPAD_(0x16, 0x002, 0x18, 0x100); -static const t_key KEY_NSPIRE_O = KEYTPAD_(0x16, 0x004, 0x14, 0x010); -static const t_key KEY_NSPIRE_9 = KEY_(0x16, 0x008); -static const t_key KEY_NSPIRE_N = KEYTPAD_(0x16, 0x010, 0x14, 0x020); -static const t_key KEY_NSPIRE_8 = KEYTPAD_(0x16, 0x020, 0x1C, 0x040); -static const t_key KEY_NSPIRE_M = KEYTPAD_(0x16, 0x040, 0x14, 0x040); -static const t_key KEY_NSPIRE_7 = KEY_(0x16, 0x080); -static const t_key KEY_NSPIRE_L = KEYTPAD_(0x16, 0x100, 0x16, 0x001); -static const t_key KEY_NSPIRE_SQU = KEYTPAD_(0x16, 0x200, 0x14, 0x200); -static const t_key KEY_NSPIRE_II = KEYTPAD_(0x16, 0x400, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); -static const t_key KEY_NSPIRE_QUOTE = KEYTPAD_(0x18, 0x001, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); -static const t_key KEY_NSPIRE_DIVIDE = KEYTPAD_(0x18, 0x002, 0x16, 0x100); -static const t_key KEY_NSPIRE_K = KEYTPAD_(0x18, 0x004, 0x16, 0x002); -static const t_key KEY_NSPIRE_TAN = KEY_(0x18, 0x008); -static const t_key KEY_NSPIRE_J = KEYTPAD_(0x18, 0x010, 0x16, 0x004); -static const t_key KEY_NSPIRE_COS = KEYTPAD_(0x18, 0x020, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); -static const t_key KEY_NSPIRE_I = KEYTPAD_(0x18, 0x040, 0x16, 0x010); -static const t_key KEY_NSPIRE_SIN = KEYTPAD_(0x18, 0x080, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); -static const t_key KEY_NSPIRE_H = KEYTPAD_(0x18, 0x100, 0x16, 0x020); -static const t_key KEY_NSPIRE_EXP = KEYTPAD_(0x18, 0x200, 0x18, 0x200); -static const t_key KEY_NSPIRE_GTHAN = KEYTPAD_(0x18, 0x400, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); -static const t_key KEY_NSPIRE_APOSTROPHE = KEY_(0x1A, 0x001); -static const t_key KEY_NSPIRE_CAT = KEYTPAD_(0x1A, 0x002, 0x1A, 0x080); -static const t_key KEY_NSPIRE_FRAC = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x1A, 0x100); -static const t_key KEY_NSPIRE_G = KEYTPAD_(0x1A, 0x004, 0x16, 0x040); -static const t_key KEY_NSPIRE_RP = KEYTPAD_(0x1A, 0x008, 0x1A, 0x008); -static const t_key KEY_NSPIRE_F = KEYTPAD_(0x1A, 0x010, 0x18, 0x001); -static const t_key KEY_NSPIRE_LP = KEYTPAD_(0x1A, 0x020, 0x1A, 0x020); -static const t_key KEY_NSPIRE_E = KEYTPAD_(0x1A, 0x040, 0x18, 0x002); -static const t_key KEY_NSPIRE_VAR = KEYTPAD_(0x1A, 0x080, 0x1A, 0x002); -static const t_key KEY_NSPIRE_D = KEYTPAD_(0x1A, 0x100, 0x18, 0x004); -static const t_key KEY_NSPIRE_DEL = KEYTPAD_(0x1E, 0x100, 0x1A, 0x200); -static const t_key KEY_NSPIRE_LTHAN = KEYTPAD_(0x1A, 0x400, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); -static const t_key KEY_NSPIRE_FLAG = KEY_(0x1C, 0x001); -static const t_key KEY_NSPIRE_CLICK = KEYTPAD_ARROW_(0x1C, 0x002, TPAD_ARROW_CLICK); -static const t_key KEY_NSPIRE_C = KEYTPAD_(0x1C, 0x004, 0x18, 0x010); -static const t_key KEY_NSPIRE_HOME = KEYTPAD_(0x1C, 0x008, 0x10, 0x200); -static const t_key KEY_NSPIRE_B = KEYTPAD_(0x1C, 0x010, 0x18, 0x020); -static const t_key KEY_NSPIRE_MENU = KEY_(0x1C, 0x020); -static const t_key KEY_NSPIRE_A = KEYTPAD_(0x1C, 0x040, 0x18, 0x040); -static const t_key KEY_NSPIRE_ESC = KEY_(0x1C, 0x080); -static const t_key KEY_NSPIRE_BAR = KEY_(0x1C, 0x100); -static const t_key KEY_NSPIRE_TAB = KEY_(0x1C, 0x200); -static const t_key KEY_NSPIRE_EQU = KEYTPAD_(0x1E, 0x400, 0x18, 0x080); -static const t_key KEY_NSPIRE_UP = KEYTPAD_ARROW_(0x1E, 0x001, TPAD_ARROW_UP); -static const t_key KEY_NSPIRE_UPRIGHT = KEYTPAD_ARROW_(0x1E, 0x002, TPAD_ARROW_UPRIGHT); -static const t_key KEY_NSPIRE_RIGHT = KEYTPAD_ARROW_(0x1E, 0x004, TPAD_ARROW_RIGHT); -static const t_key KEY_NSPIRE_RIGHTDOWN = KEYTPAD_ARROW_(0x1E, 0x008, TPAD_ARROW_RIGHTDOWN); -static const t_key KEY_NSPIRE_DOWN = KEYTPAD_ARROW_(0x1E, 0x010, TPAD_ARROW_DOWN); -static const t_key KEY_NSPIRE_DOWNLEFT = KEYTPAD_ARROW_(0x1E, 0x020, TPAD_ARROW_DOWNLEFT); -static const t_key KEY_NSPIRE_LEFT = KEYTPAD_ARROW_(0x1E, 0x040, TPAD_ARROW_LEFT); -static const t_key KEY_NSPIRE_LEFTUP = KEYTPAD_ARROW_(0x1E, 0x080, TPAD_ARROW_LEFTUP); -static const t_key KEY_NSPIRE_SHIFT = KEYTPAD_(0x1A, 0x200, 0x1E, 0x100); -static const t_key KEY_NSPIRE_CTRL = KEY_(0x1E, 0x200); -static const t_key KEY_NSPIRE_DOC = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x1C, 0x008); -static const t_key KEY_NSPIRE_TRIG = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x12, 0x200); -static const t_key KEY_NSPIRE_SCRATCHPAD = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x1A, 0x400); +extern const t_key KEY_NSPIRE_RET; +extern const t_key KEY_NSPIRE_ENTER; +extern const t_key KEY_NSPIRE_SPACE; +extern const t_key KEY_NSPIRE_NEGATIVE; +extern const t_key KEY_NSPIRE_Z; +extern const t_key KEY_NSPIRE_PERIOD; +extern const t_key KEY_NSPIRE_Y; +extern const t_key KEY_NSPIRE_0; +extern const t_key KEY_NSPIRE_X; +extern const t_key KEY_NSPIRE_THETA; +extern const t_key KEY_NSPIRE_COMMA; +extern const t_key KEY_NSPIRE_PLUS; +extern const t_key KEY_NSPIRE_W; +extern const t_key KEY_NSPIRE_3; +extern const t_key KEY_NSPIRE_V; +extern const t_key KEY_NSPIRE_2; +extern const t_key KEY_NSPIRE_U; +extern const t_key KEY_NSPIRE_1; +extern const t_key KEY_NSPIRE_T; +extern const t_key KEY_NSPIRE_eEXP; +extern const t_key KEY_NSPIRE_PI; +extern const t_key KEY_NSPIRE_QUES; +extern const t_key KEY_NSPIRE_QUESEXCL; +extern const t_key KEY_NSPIRE_MINUS; +extern const t_key KEY_NSPIRE_S; +extern const t_key KEY_NSPIRE_6; +extern const t_key KEY_NSPIRE_R; +extern const t_key KEY_NSPIRE_5; +extern const t_key KEY_NSPIRE_Q; +extern const t_key KEY_NSPIRE_4; +extern const t_key KEY_NSPIRE_P; +extern const t_key KEY_NSPIRE_TENX; +extern const t_key KEY_NSPIRE_EE; +extern const t_key KEY_NSPIRE_COLON; +extern const t_key KEY_NSPIRE_MULTIPLY; +extern const t_key KEY_NSPIRE_O; +extern const t_key KEY_NSPIRE_9; +extern const t_key KEY_NSPIRE_N; +extern const t_key KEY_NSPIRE_8; +extern const t_key KEY_NSPIRE_M; +extern const t_key KEY_NSPIRE_7; +extern const t_key KEY_NSPIRE_L; +extern const t_key KEY_NSPIRE_SQU; +extern const t_key KEY_NSPIRE_II; +extern const t_key KEY_NSPIRE_QUOTE; +extern const t_key KEY_NSPIRE_DIVIDE; +extern const t_key KEY_NSPIRE_K; +extern const t_key KEY_NSPIRE_TAN; +extern const t_key KEY_NSPIRE_J; +extern const t_key KEY_NSPIRE_COS; +extern const t_key KEY_NSPIRE_I; +extern const t_key KEY_NSPIRE_SIN; +extern const t_key KEY_NSPIRE_H; +extern const t_key KEY_NSPIRE_EXP; +extern const t_key KEY_NSPIRE_GTHAN; +extern const t_key KEY_NSPIRE_APOSTROPHE; +extern const t_key KEY_NSPIRE_CAT; +extern const t_key KEY_NSPIRE_FRAC; +extern const t_key KEY_NSPIRE_G; +extern const t_key KEY_NSPIRE_RP; +extern const t_key KEY_NSPIRE_F; +extern const t_key KEY_NSPIRE_LP; +extern const t_key KEY_NSPIRE_E; +extern const t_key KEY_NSPIRE_VAR; +extern const t_key KEY_NSPIRE_D; +extern const t_key KEY_NSPIRE_DEL; +extern const t_key KEY_NSPIRE_LTHAN; +extern const t_key KEY_NSPIRE_FLAG; +extern const t_key KEY_NSPIRE_CLICK; +extern const t_key KEY_NSPIRE_C; +extern const t_key KEY_NSPIRE_HOME; +extern const t_key KEY_NSPIRE_B; +extern const t_key KEY_NSPIRE_MENU; +extern const t_key KEY_NSPIRE_A; +extern const t_key KEY_NSPIRE_ESC; +extern const t_key KEY_NSPIRE_BAR; +extern const t_key KEY_NSPIRE_TAB; +extern const t_key KEY_NSPIRE_EQU; +extern const t_key KEY_NSPIRE_UP; +extern const t_key KEY_NSPIRE_UPRIGHT; +extern const t_key KEY_NSPIRE_RIGHT; +extern const t_key KEY_NSPIRE_RIGHTDOWN; +extern const t_key KEY_NSPIRE_DOWN; +extern const t_key KEY_NSPIRE_DOWNLEFT; +extern const t_key KEY_NSPIRE_LEFT; +extern const t_key KEY_NSPIRE_LEFTUP; +extern const t_key KEY_NSPIRE_SHIFT; +extern const t_key KEY_NSPIRE_CTRL; +extern const t_key KEY_NSPIRE_DOC; +extern const t_key KEY_NSPIRE_TRIG; +extern const t_key KEY_NSPIRE_SCRATCHPAD; /* TI-84+ Keypad Mappings */ -static const t_key KEY_84_DOWN = KEY_(0x10, 0x001); -static const t_key KEY_84_LEFT = KEY_(0x10, 0x002); -static const t_key KEY_84_RIGHT = KEY_(0x10, 0x004); -static const t_key KEY_84_UP = KEY_(0x10, 0x008); -static const t_key KEY_84_ENTER = KEY_(0x12, 0x001); -static const t_key KEY_84_PLUS = KEY_(0x12, 0x002); -static const t_key KEY_84_MINUS = KEY_(0x12, 0x004); -static const t_key KEY_84_MULTIPLY = KEY_(0x12, 0x008); -static const t_key KEY_84_DIVIDE = KEY_(0x12, 0x010); -static const t_key KEY_84_EXP = KEY_(0x12, 0x020); -static const t_key KEY_84_CLEAR = KEY_(0x12, 0x040); -static const t_key KEY_84_NEGATIVE = KEY_(0x14, 0x001); -static const t_key KEY_84_3 = KEY_(0x14, 0x002); -static const t_key KEY_84_6 = KEY_(0x14, 0x004); -static const t_key KEY_84_9 = KEY_(0x14, 0x008); -static const t_key KEY_84_RP = KEY_(0x14, 0x010); -static const t_key KEY_84_TAN = KEY_(0x14, 0x020); -static const t_key KEY_84_VARS = KEY_(0x14, 0x040); -static const t_key KEY_84_PERIOD = KEY_(0x16, 0x001); -static const t_key KEY_84_2 = KEY_(0x16, 0x002); -static const t_key KEY_84_5 = KEY_(0x16, 0x004); -static const t_key KEY_84_8 = KEY_(0x16, 0x008); -static const t_key KEY_84_LP = KEY_(0x16, 0x010); -static const t_key KEY_84_COS = KEY_(0x16, 0x020); -static const t_key KEY_84_PRGM = KEY_(0x16, 0x040); -static const t_key KEY_84_STAT = KEY_(0x16, 0x080); -static const t_key KEY_84_0 = KEY_(0x18, 0x001); -static const t_key KEY_84_1 = KEY_(0x18, 0x002); -static const t_key KEY_84_4 = KEY_(0x18, 0x004); -static const t_key KEY_84_7 = KEY_(0x18, 0x008); -static const t_key KEY_84_COMMA = KEY_(0x18, 0x010); -static const t_key KEY_84_SIN = KEY_(0x18, 0x020); -static const t_key KEY_84_APPS = KEY_(0x18, 0x040); -static const t_key KEY_84_X = KEY_(0x18, 0x080); -static const t_key KEY_84_STO = KEY_(0x1A, 0x002); -static const t_key KEY_84_LN = KEY_(0x1A, 0x004); -static const t_key KEY_84_LOG = KEY_(0x1A, 0x008); -static const t_key KEY_84_SQU = KEY_(0x1A, 0x010); -static const t_key KEY_84_INV = KEY_(0x1A, 0x020); -static const t_key KEY_84_MATH = KEY_(0x1A, 0x040); -static const t_key KEY_84_ALPHA = KEY_(0x1A, 0x080); -static const t_key KEY_84_GRAPH = KEY_(0x1C, 0x001); -static const t_key KEY_84_TRACE = KEY_(0x1C, 0x002); -static const t_key KEY_84_ZOOM = KEY_(0x1C, 0x004); -static const t_key KEY_84_WIND = KEY_(0x1C, 0x008); -static const t_key KEY_84_YEQU = KEY_(0x1C, 0x010); -static const t_key KEY_84_2ND = KEY_(0x1C, 0x020); -static const t_key KEY_84_MODE = KEY_(0x1C, 0x040); -static const t_key KEY_84_DEL = KEY_(0x1C, 0x080); +extern const t_key KEY_84_DOWN; +extern const t_key KEY_84_LEFT; +extern const t_key KEY_84_RIGHT; +extern const t_key KEY_84_UP; +extern const t_key KEY_84_ENTER; +extern const t_key KEY_84_PLUS; +extern const t_key KEY_84_MINUS; +extern const t_key KEY_84_MULTIPLY; +extern const t_key KEY_84_DIVIDE; +extern const t_key KEY_84_EXP; +extern const t_key KEY_84_CLEAR; +extern const t_key KEY_84_NEGATIVE; +extern const t_key KEY_84_3; +extern const t_key KEY_84_6; +extern const t_key KEY_84_9; +extern const t_key KEY_84_RP; +extern const t_key KEY_84_TAN; +extern const t_key KEY_84_VARS; +extern const t_key KEY_84_PERIOD; +extern const t_key KEY_84_2; +extern const t_key KEY_84_5; +extern const t_key KEY_84_8; +extern const t_key KEY_84_LP; +extern const t_key KEY_84_COS; +extern const t_key KEY_84_PRGM; +extern const t_key KEY_84_STAT; +extern const t_key KEY_84_0; +extern const t_key KEY_84_1; +extern const t_key KEY_84_4; +extern const t_key KEY_84_7; +extern const t_key KEY_84_COMMA; +extern const t_key KEY_84_SIN; +extern const t_key KEY_84_APPS; +extern const t_key KEY_84_X; +extern const t_key KEY_84_STO; +extern const t_key KEY_84_LN; +extern const t_key KEY_84_LOG; +extern const t_key KEY_84_SQU; +extern const t_key KEY_84_INV; +extern const t_key KEY_84_MATH; +extern const t_key KEY_84_ALPHA; +extern const t_key KEY_84_GRAPH; +extern const t_key KEY_84_TRACE; +extern const t_key KEY_84_ZOOM; +extern const t_key KEY_84_WIND; +extern const t_key KEY_84_YEQU; +extern const t_key KEY_84_2ND; +extern const t_key KEY_84_MODE; +extern const t_key KEY_84_DEL; #endif // !KEYS_H diff --git a/ndless-sdk/libndls/keys.c b/ndless-sdk/libndls/keys.c new file mode 100644 index 00000000..e26ee9de --- /dev/null +++ b/ndless-sdk/libndls/keys.c @@ -0,0 +1,146 @@ +#include + +const t_key KEY_NSPIRE_RET = KEY_(0x10, 0x001); +const t_key KEY_NSPIRE_ENTER = KEY_(0x10, 0x002); +const t_key KEY_NSPIRE_SPACE = KEYTPAD_(0x10, 0x004, 0x10, 0x10); +const t_key KEY_NSPIRE_NEGATIVE = KEY_(0x10, 0x008); +const t_key KEY_NSPIRE_Z = KEYTPAD_(0x10, 0x010, 0x10, 0x20); +const t_key KEY_NSPIRE_PERIOD = KEYTPAD_(0x10, 0x20, 0x1A, 0x010); +const t_key KEY_NSPIRE_Y = KEY_(0x10, 0x040); +const t_key KEY_NSPIRE_0 = KEY_(0x10, 0x080); +const t_key KEY_NSPIRE_X = KEYTPAD_(0x10, 0x100, 0x12, 0x001); +const t_key KEY_NSPIRE_THETA = KEYTPAD_(0x10, 0x400, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); +const t_key KEY_NSPIRE_COMMA = KEYTPAD_(0x12, 0x001, 0x1E, 0x400); +const t_key KEY_NSPIRE_PLUS = KEYTPAD_(0x12, 0x002, 0x1C, 0x004); +const t_key KEY_NSPIRE_W = KEYTPAD_(0x12, 0x004, 0x12, 0x002); +const t_key KEY_NSPIRE_3 = KEY_(0x12, 0x008); +const t_key KEY_NSPIRE_V = KEYTPAD_(0x12, 0x010, 0x12, 0x004); +const t_key KEY_NSPIRE_2 = KEYTPAD_(0x12, 0x020, 0x1C, 0x010); +const t_key KEY_NSPIRE_U = KEYTPAD_(0x12, 0x040, 0x12, 0x010); +const t_key KEY_NSPIRE_1 = KEY_(0x12, 0x080); +const t_key KEY_NSPIRE_T = KEYTPAD_(0x12, 0x100, 0x12, 0x020); +const t_key KEY_NSPIRE_eEXP = KEYTPAD_(0x12, 0x200, 0x16, 0x200); +const t_key KEY_NSPIRE_PI = KEYTPAD_(0x12, 0x400, 0x12, 0x100); +const t_key KEY_NSPIRE_QUES = KEYTPAD_(0x14, 0x001, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); +const t_key KEY_NSPIRE_QUESEXCL = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x10, 0x100); +const t_key KEY_NSPIRE_MINUS = KEYTPAD_(0x14, 0x002, 0x1A, 0x004); +const t_key KEY_NSPIRE_S = KEYTPAD_(0x14, 0x004, 0x12, 0x040); +const t_key KEY_NSPIRE_6 = KEY_(0x14, 0x008); +const t_key KEY_NSPIRE_R = KEYTPAD_(0x14, 0x010, 0x14, 0x001); +const t_key KEY_NSPIRE_5 = KEYTPAD_(0x14, 0x020, 0x1A, 0x040); +const t_key KEY_NSPIRE_Q = KEYTPAD_(0x14, 0x040, 0x14, 0x002); +const t_key KEY_NSPIRE_4 = KEY_(0x14, 0x080); +const t_key KEY_NSPIRE_P = KEYTPAD_(0x14, 0x100, 0x14, 0x004); +const t_key KEY_NSPIRE_TENX = KEYTPAD_(0x14, 0x200, 0x12, 0x400); +const t_key KEY_NSPIRE_EE = KEYTPAD_(0x14, 0x400, 0x14, 0x100); +const t_key KEY_NSPIRE_COLON = KEYTPAD_(0x16, 0x001, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); +const t_key KEY_NSPIRE_MULTIPLY = KEYTPAD_(0x16, 0x002, 0x18, 0x100); +const t_key KEY_NSPIRE_O = KEYTPAD_(0x16, 0x004, 0x14, 0x010); +const t_key KEY_NSPIRE_9 = KEY_(0x16, 0x008); +const t_key KEY_NSPIRE_N = KEYTPAD_(0x16, 0x010, 0x14, 0x020); +const t_key KEY_NSPIRE_8 = KEYTPAD_(0x16, 0x020, 0x1C, 0x040); +const t_key KEY_NSPIRE_M = KEYTPAD_(0x16, 0x040, 0x14, 0x040); +const t_key KEY_NSPIRE_7 = KEY_(0x16, 0x080); +const t_key KEY_NSPIRE_L = KEYTPAD_(0x16, 0x100, 0x16, 0x001); +const t_key KEY_NSPIRE_SQU = KEYTPAD_(0x16, 0x200, 0x14, 0x200); +const t_key KEY_NSPIRE_II = KEYTPAD_(0x16, 0x400, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); +const t_key KEY_NSPIRE_QUOTE = KEYTPAD_(0x18, 0x001, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); +const t_key KEY_NSPIRE_DIVIDE = KEYTPAD_(0x18, 0x002, 0x16, 0x100); +const t_key KEY_NSPIRE_K = KEYTPAD_(0x18, 0x004, 0x16, 0x002); +const t_key KEY_NSPIRE_TAN = KEY_(0x18, 0x008); +const t_key KEY_NSPIRE_J = KEYTPAD_(0x18, 0x010, 0x16, 0x004); +const t_key KEY_NSPIRE_COS = KEYTPAD_(0x18, 0x020, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); +const t_key KEY_NSPIRE_I = KEYTPAD_(0x18, 0x040, 0x16, 0x010); +const t_key KEY_NSPIRE_SIN = KEYTPAD_(0x18, 0x080, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); +const t_key KEY_NSPIRE_H = KEYTPAD_(0x18, 0x100, 0x16, 0x020); +const t_key KEY_NSPIRE_EXP = KEYTPAD_(0x18, 0x200, 0x18, 0x200); +const t_key KEY_NSPIRE_GTHAN = KEYTPAD_(0x18, 0x400, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); +const t_key KEY_NSPIRE_APOSTROPHE = KEY_(0x1A, 0x001); +const t_key KEY_NSPIRE_CAT = KEYTPAD_(0x1A, 0x002, 0x1A, 0x080); +const t_key KEY_NSPIRE_FRAC = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x1A, 0x100); +const t_key KEY_NSPIRE_G = KEYTPAD_(0x1A, 0x004, 0x16, 0x040); +const t_key KEY_NSPIRE_RP = KEYTPAD_(0x1A, 0x008, 0x1A, 0x008); +const t_key KEY_NSPIRE_F = KEYTPAD_(0x1A, 0x010, 0x18, 0x001); +const t_key KEY_NSPIRE_LP = KEYTPAD_(0x1A, 0x020, 0x1A, 0x020); +const t_key KEY_NSPIRE_E = KEYTPAD_(0x1A, 0x040, 0x18, 0x002); +const t_key KEY_NSPIRE_VAR = KEYTPAD_(0x1A, 0x080, 0x1A, 0x002); +const t_key KEY_NSPIRE_D = KEYTPAD_(0x1A, 0x100, 0x18, 0x004); +const t_key KEY_NSPIRE_DEL = KEYTPAD_(0x1E, 0x100, 0x1A, 0x200); +const t_key KEY_NSPIRE_LTHAN = KEYTPAD_(0x1A, 0x400, _KEY_DUMMY_ROW, _KEY_DUMMY_COL); +const t_key KEY_NSPIRE_FLAG = KEY_(0x1C, 0x001); +const t_key KEY_NSPIRE_CLICK = KEYTPAD_ARROW_(0x1C, 0x002, TPAD_ARROW_CLICK); +const t_key KEY_NSPIRE_C = KEYTPAD_(0x1C, 0x004, 0x18, 0x010); +const t_key KEY_NSPIRE_HOME = KEYTPAD_(0x1C, 0x008, 0x10, 0x200); +const t_key KEY_NSPIRE_B = KEYTPAD_(0x1C, 0x010, 0x18, 0x020); +const t_key KEY_NSPIRE_MENU = KEY_(0x1C, 0x020); +const t_key KEY_NSPIRE_A = KEYTPAD_(0x1C, 0x040, 0x18, 0x040); +const t_key KEY_NSPIRE_ESC = KEY_(0x1C, 0x080); +const t_key KEY_NSPIRE_BAR = KEY_(0x1C, 0x100); +const t_key KEY_NSPIRE_TAB = KEY_(0x1C, 0x200); +const t_key KEY_NSPIRE_EQU = KEYTPAD_(0x1E, 0x400, 0x18, 0x080); +const t_key KEY_NSPIRE_UP = KEYTPAD_ARROW_(0x1E, 0x001, TPAD_ARROW_UP); +const t_key KEY_NSPIRE_UPRIGHT = KEYTPAD_ARROW_(0x1E, 0x002, TPAD_ARROW_UPRIGHT); +const t_key KEY_NSPIRE_RIGHT = KEYTPAD_ARROW_(0x1E, 0x004, TPAD_ARROW_RIGHT); +const t_key KEY_NSPIRE_RIGHTDOWN = KEYTPAD_ARROW_(0x1E, 0x008, TPAD_ARROW_RIGHTDOWN); +const t_key KEY_NSPIRE_DOWN = KEYTPAD_ARROW_(0x1E, 0x010, TPAD_ARROW_DOWN); +const t_key KEY_NSPIRE_DOWNLEFT = KEYTPAD_ARROW_(0x1E, 0x020, TPAD_ARROW_DOWNLEFT); +const t_key KEY_NSPIRE_LEFT = KEYTPAD_ARROW_(0x1E, 0x040, TPAD_ARROW_LEFT); +const t_key KEY_NSPIRE_LEFTUP = KEYTPAD_ARROW_(0x1E, 0x080, TPAD_ARROW_LEFTUP); +const t_key KEY_NSPIRE_SHIFT = KEYTPAD_(0x1A, 0x200, 0x1E, 0x100); +const t_key KEY_NSPIRE_CTRL = KEY_(0x1E, 0x200); +const t_key KEY_NSPIRE_DOC = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x1C, 0x008); +const t_key KEY_NSPIRE_TRIG = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x12, 0x200); +const t_key KEY_NSPIRE_SCRATCHPAD = KEYTPAD_(_KEY_DUMMY_ROW, _KEY_DUMMY_COL, 0x1A, 0x400); + +/* TI-84+ Keypad Mappings */ +const t_key KEY_84_DOWN = KEY_(0x10, 0x001); +const t_key KEY_84_LEFT = KEY_(0x10, 0x002); +const t_key KEY_84_RIGHT = KEY_(0x10, 0x004); +const t_key KEY_84_UP = KEY_(0x10, 0x008); +const t_key KEY_84_ENTER = KEY_(0x12, 0x001); +const t_key KEY_84_PLUS = KEY_(0x12, 0x002); +const t_key KEY_84_MINUS = KEY_(0x12, 0x004); +const t_key KEY_84_MULTIPLY = KEY_(0x12, 0x008); +const t_key KEY_84_DIVIDE = KEY_(0x12, 0x010); +const t_key KEY_84_EXP = KEY_(0x12, 0x020); +const t_key KEY_84_CLEAR = KEY_(0x12, 0x040); +const t_key KEY_84_NEGATIVE = KEY_(0x14, 0x001); +const t_key KEY_84_3 = KEY_(0x14, 0x002); +const t_key KEY_84_6 = KEY_(0x14, 0x004); +const t_key KEY_84_9 = KEY_(0x14, 0x008); +const t_key KEY_84_RP = KEY_(0x14, 0x010); +const t_key KEY_84_TAN = KEY_(0x14, 0x020); +const t_key KEY_84_VARS = KEY_(0x14, 0x040); +const t_key KEY_84_PERIOD = KEY_(0x16, 0x001); +const t_key KEY_84_2 = KEY_(0x16, 0x002); +const t_key KEY_84_5 = KEY_(0x16, 0x004); +const t_key KEY_84_8 = KEY_(0x16, 0x008); +const t_key KEY_84_LP = KEY_(0x16, 0x010); +const t_key KEY_84_COS = KEY_(0x16, 0x020); +const t_key KEY_84_PRGM = KEY_(0x16, 0x040); +const t_key KEY_84_STAT = KEY_(0x16, 0x080); +const t_key KEY_84_0 = KEY_(0x18, 0x001); +const t_key KEY_84_1 = KEY_(0x18, 0x002); +const t_key KEY_84_4 = KEY_(0x18, 0x004); +const t_key KEY_84_7 = KEY_(0x18, 0x008); +const t_key KEY_84_COMMA = KEY_(0x18, 0x010); +const t_key KEY_84_SIN = KEY_(0x18, 0x020); +const t_key KEY_84_APPS = KEY_(0x18, 0x040); +const t_key KEY_84_X = KEY_(0x18, 0x080); +const t_key KEY_84_STO = KEY_(0x1A, 0x002); +const t_key KEY_84_LN = KEY_(0x1A, 0x004); +const t_key KEY_84_LOG = KEY_(0x1A, 0x008); +const t_key KEY_84_SQU = KEY_(0x1A, 0x010); +const t_key KEY_84_INV = KEY_(0x1A, 0x020); +const t_key KEY_84_MATH = KEY_(0x1A, 0x040); +const t_key KEY_84_ALPHA = KEY_(0x1A, 0x080); +const t_key KEY_84_GRAPH = KEY_(0x1C, 0x001); +const t_key KEY_84_TRACE = KEY_(0x1C, 0x002); +const t_key KEY_84_ZOOM = KEY_(0x1C, 0x004); +const t_key KEY_84_WIND = KEY_(0x1C, 0x008); +const t_key KEY_84_YEQU = KEY_(0x1C, 0x010); +const t_key KEY_84_2ND = KEY_(0x1C, 0x020); +const t_key KEY_84_MODE = KEY_(0x1C, 0x040); +const t_key KEY_84_DEL = KEY_(0x1C, 0x080); + + From 8cafb6e9b41e33d301e39f7f0c0a761dff124437 Mon Sep 17 00:00:00 2001 From: Paul F-Y Date: Sun, 29 Apr 2018 12:44:30 -0400 Subject: [PATCH 2/8] Don't search filesystem for ndless.cfg every time --- ndless-sdk/libndls/config.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ndless-sdk/libndls/config.c b/ndless-sdk/libndls/config.c index f865e277..df9d7265 100644 --- a/ndless-sdk/libndls/config.c +++ b/ndless-sdk/libndls/config.c @@ -119,8 +119,17 @@ void cfg_open_file(const char *filepath) { kv_num = kv_index; } +static char cfg_path[FILENAME_MAX] = {0}; + static int cfg_locate_cfg_file(char *dst_path, size_t dst_path_size) { - return locate("ndless.cfg.tns", dst_path, dst_path_size); + if(cfg_path[0] == 0) snprintf(cfg_path, FILENAME_MAX, "%s%s", get_documents_dir(), "ndless/ndless.cfg.tns"); + if(access(cfg_path, F_OK) == -1) { + int l = locate("ndless.cfg.tns", cfg_path, FILENAME_MAX); + if(l != 0) return l; + } + if(strlen(cfg_path)+1 > dst_path_size) return 1; + strlcpy(dst_path, cfg_path, dst_path_size); + return 0; } void cfg_open(void) { From 134ae5e350cbbf87b1a2cb88c2e470d9363fe2eb Mon Sep 17 00:00:00 2001 From: Paul F-Y Date: Sun, 29 Apr 2018 13:47:18 -0400 Subject: [PATCH 3/8] support absolute paths in ndless.cfg --- ndless/src/resources/ploaderhook.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/ndless/src/resources/ploaderhook.c b/ndless/src/resources/ploaderhook.c index ebc5eda2..d3c51231 100644 --- a/ndless/src/resources/ploaderhook.c +++ b/ndless/src/resources/ploaderhook.c @@ -261,8 +261,13 @@ int ld_exec_with_args(const char *path, int argsn, char *args[], void **resident char prgm_name[FILENAME_MAX + 4]; strcpy(prgm_name, prgm_name_noext); strcat(prgm_name, ".tns"); - struct assoc_file_each_cb_ctx context = {prgm_name, prgm_path, &isassoc}; - file_each("/", assoc_file_each_cb, &context); + if(prgm_name[0] == '/') { + strlcpy(prgm_path, prgm_name, FILENAME_MAX); + isassoc = 1; + } else { + struct assoc_file_each_cb_ctx context = {prgm_name, prgm_path, &isassoc}; + file_each("/", assoc_file_each_cb, &context); + } } cfg_close(); } From b4ea94c5a7f1290c31eb1379a794a8d822a3f823 Mon Sep 17 00:00:00 2001 From: Paul F-Y Date: Sun, 13 May 2018 14:57:33 -0400 Subject: [PATCH 4/8] Significant changes to the config parser and to file association code As a result, ndless will write the location it has found the associated program to ndless.cfg. This significantly speeds opening programs with association, since it avoids trawling through the entire filesystem each time. --- ndless-sdk/include/libndls.h | 15 ++- ndless-sdk/libndls/config.c | 209 +++++++++++++++++++++-------- ndless/src/resources/ploaderhook.c | 35 ++++- 3 files changed, 198 insertions(+), 61 deletions(-) diff --git a/ndless-sdk/include/libndls.h b/ndless-sdk/include/libndls.h index 92d6ada5..40a387cf 100644 --- a/ndless-sdk/include/libndls.h +++ b/ndless-sdk/include/libndls.h @@ -102,10 +102,23 @@ BOOL isKeyPressed(const t_key *key); void wait_key_pressed(void); void wait_no_key_pressed(void); /* config.c */ +struct cfg_entry { + char key[15]; +// short val_offset; + size_t value_sz; + char *value; +}; + void cfg_open(void); void cfg_open_file(const char *filepath); void cfg_close(void); -char *cfg_get(const char *key); +// get/put only work if cfg file is open +struct cfg_entry *cfg_get_entry(const char *key); +void cfg_put_entry(struct cfg_entry *entr, const char *val); +const char *cfg_get(const char *key); +void cfg_put(const char *key, const char *val); +void cfg_put_fileext(const char *ext, const char *prgm); +// register opens cfg file as always void cfg_register_fileext(const char *ext, const char *prgm); void cfg_register_fileext_file(const char *fielpath, const char *ext, const char *prgm); #define nl_hassyscall(x) _nl_hassyscall(e_##x) diff --git a/ndless-sdk/libndls/config.c b/ndless-sdk/libndls/config.c index df9d7265..18a97b84 100644 --- a/ndless-sdk/libndls/config.c +++ b/ndless-sdk/libndls/config.c @@ -22,42 +22,75 @@ ****************************************************************************/ #include - /* The config file is open whenever needed with cfg_open, and must be closed. * Each line of the file contains a key/value pair (key=value). * The key and the value are trimmed when read. * A comment can be added at the end of a line (# comment). * Invalid lines are ignored. */ - -static char *file_content = NULL; // if not NULL, the config file is open. NULL terminated. -static size_t file_size; + +static char open_file[FILENAME_MAX] = {0}; static unsigned max_kv_num; static unsigned kv_num; -static unsigned short (*kv_offsets)[2]; // [line_offset][key_offset, value_offset]. Offsets from file_content. +static unsigned cmt_num; +static struct cfg_entry *cfg_entries; +static char **cfg_comments; +static BOOL cfg_changed; + +void cfg_save_file(const char *filepath) { + FILE *file = fopen(filepath, "wb"); + if(!file) return; + + unsigned i; + for(i = 0; i < kv_num; i++) { + struct cfg_entry *n_entr = &cfg_entries[i]; + if(cfg_comments[i]) { + fprintf(file, "%s=%s #%s\n", n_entr->key, n_entr->value, cfg_comments[i]); + } else { + fprintf(file, "%s=%s\n", n_entr->key, n_entr->value); + } + } + fclose(file); +} void cfg_close(void) { - if (!file_content) return; - free(file_content); - file_content = NULL; - free(kv_offsets); + if (!open_file[0]) return; + if(cfg_changed) { + cfg_save_file(open_file); + } + unsigned i; + for(i = 0; i < kv_num; i++) { + free(cfg_entries[i].value); + } + cfg_changed = 0; + free(cfg_entries); + for(i = 0; i < cmt_num; i++) { + if(cfg_comments[i]) free(cfg_comments[i]); + } + free(cfg_comments); + open_file[0] = '\0'; + cfg_entries = NULL; + cfg_comments = NULL; +} + + +static unsigned pow2_roundup(unsigned x) { + return 1<<(32 - __builtin_clz(x - 1)); } // Only for tests. cfg_open() should be used. void cfg_open_file(const char *filepath) { - if (file_content) return; + if (open_file[0]) return; FILE *file = fopen(filepath, "rb"); if (!file) return; #define MAX_CFG_FILE_SIZE 10000 fseek(file, 0, SEEK_END); - file_size = ftell(file); - if (!file_size) goto close_quit; - file_content = malloc(file_size + 1); // +1 for the NULL char + size_t file_size = ftell(file); + char *file_content = malloc(file_size + 1); // +1 for the NULL char if (!file_content) goto close_quit; rewind(file); if (fread(file_content, 1, file_size, file) != file_size) { free(file_content); - file_content = NULL; close_quit: fclose(file); return; @@ -72,16 +105,22 @@ void cfg_open_file(const char *filepath) { if (file_content[i] == '\n') line_num++; } - max_kv_num = line_num; - kv_offsets = malloc(max_kv_num * sizeof(unsigned short)*2); - if (!kv_offsets) { + max_kv_num = line_num == 0 ? 1 : pow2_roundup(line_num); + cfg_entries = malloc(max_kv_num * sizeof(struct cfg_entry)); + cfg_comments = calloc(max_kv_num, sizeof(char *)); + if (!cfg_entries) { + free(file_content); cfg_close(); return; } + cfg_changed = 0; char *str = file_content; unsigned kv_index = 0; char *end_of_file = file_content + file_size; - // fill up kv_offsets[][] + if(line_num == 0) { + goto loop_end; + } + // fill up cfg_entries[] while (1) { char *kv = str; char *end_of_pair = strpbrk(str, "#\r\n"); // in case of Windows end of line, will be considered as an empty line, but not really a problem @@ -102,8 +141,13 @@ void cfg_open_file(const char *filepath) { str = value; while (*str != 0 && *str != ' ') str++; if (*str == ' ') *str = 0; // remove the spaces after the value - kv_offsets[kv_index][0] = kv - file_content; - kv_offsets[kv_index++][1] = value - file_content; + struct cfg_entry *entry = &cfg_entries[kv_index++]; + strlcpy(entry->key, kv, 15); + size_t val_len = strlen(value) + 1; + entry->value_sz = pow2_roundup(val_len); + entry->value = malloc(entry->value_sz); + strlcpy(entry->value, value, entry->value_sz); + // printf("entry %s=%s\n", entry->key, entry->value); if (kv_index >= max_kv_num) break; // too many key-value pairs } } @@ -111,12 +155,22 @@ void cfg_open_file(const char *filepath) { str = end_of_pair; // next key value if (str >= end_of_file) break; // end of file if (has_comment) { - str = strpbrk(str, "\n"); // skip it + char *ns = strpbrk(str, "\n"); + if(value) { + if(!ns) ns = end_of_file; + char *cmt = cfg_comments[kv_index - 1] = malloc(ns - str + 1); + memcpy(cmt, str, ns - str); + cmt[ns - str] = '\0'; + } + str = ns; // skip it if (!str) break; // end of file str++; } } - kv_num = kv_index; + loop_end: + cmt_num = kv_num = kv_index; + strlcpy(open_file, filepath, FILENAME_MAX); + free(file_content); } static char cfg_path[FILENAME_MAX] = {0}; @@ -127,57 +181,106 @@ static int cfg_locate_cfg_file(char *dst_path, size_t dst_path_size) { int l = locate("ndless.cfg.tns", cfg_path, FILENAME_MAX); if(l != 0) return l; } - if(strlen(cfg_path)+1 > dst_path_size) return 1; - strlcpy(dst_path, cfg_path, dst_path_size); + size_t actual_path_len = strlen(cfg_path); + if(actual_path_len+1 > dst_path_size) return 1; + memcpy(dst_path, cfg_path, actual_path_len); + dst_path[actual_path_len] = 0; return 0; } void cfg_open(void) { - char path[300]; + char path[FILENAME_MAX]; if (cfg_locate_cfg_file(path, sizeof(path))) return; cfg_open_file(path); } -// Returns the value associated to the key. NULL if not found. -char *cfg_get(const char *key) { +struct cfg_entry *cfg_get_entry(const char *key) { unsigned i; - if (!file_content) return NULL; + if (!open_file[0]) return NULL; for (i = 0; i < kv_num; i++) { - if (!strcmp(key, kv_offsets[i][0] + file_content)) - return kv_offsets[i][1] + file_content; + struct cfg_entry *e = &cfg_entries[i]; + //printf("%s, %s\n", key, e->key); + if (!strcmp(key, e->key)) { + return e; + } } return NULL; } -// Only for tests. cfg_register_filext() should be used. -void cfg_register_fileext_file(const char *filepath, const char *ext, const char *prgm) { - char key[15] = "ext."; - cfg_open_file(filepath); - strncat(key, ext, 15 - 4 - 1); - if (cfg_get(key)) { - cfg_close(); - return; +// Returns the value associated to the key. NULL if not found. +const char *cfg_get(const char *key) { + struct cfg_entry *e = cfg_get_entry(key); + return e == NULL ? NULL : e->value; +} + +static int strict_strcmp(const char *a, const char *b) { + size_t l1 = strlen(a); + size_t l2 = strlen(b); + return memcmp(a, b, (l1 < l2 ? l1 : l2)+1); +} + +void cfg_put_entry(struct cfg_entry *entr, const char *val) { + if(strict_strcmp(entr->value, val)) { + size_t vl = strlen(val) + 1; + if(vl > entr->value_sz || vl <= entr->value_sz / 2) { + entr->value_sz = pow2_roundup(vl); + entr->value = realloc(entr->value, entr->value_sz); + } + strlcpy(entr->value, val, entr->value_sz); + //printf("accepted change %s=%s\n", entr->key, val); + cfg_changed = 1; } - cfg_close(); - FILE *file = fopen(filepath, "a+b"); - if (!file) return; - fseek(file, 0, SEEK_END); - if (ftell(file) > 0) { - fseek(file, -1, SEEK_END); - if (fgetc(file) != '\n') { - fseek(file, 0, SEEK_END); - fputc('\n', file); +} + +void cfg_put(const char *key, const char *val) { + struct cfg_entry *entr; + if((entr = cfg_get_entry(key))) { + cfg_put_entry(entr, val); + } else { + if(kv_num == max_kv_num) { + max_kv_num *= 2; + cfg_entries = realloc(cfg_entries, max_kv_num * sizeof(struct cfg_entry)); } + struct cfg_entry *n_entr = &cfg_entries[kv_num++]; + strlcpy(n_entr->key, key, 15); + size_t vl = strlen(val) + 1; + n_entr->value_sz = pow2_roundup(vl); + n_entr->value = malloc(n_entr->value_sz); + strlcpy(n_entr->value, val, n_entr->value_sz); + cfg_changed = 1; + } +} + +void cfg_put_fileext(const char *ext, const char *prgm) { + char key[15] = "ext."; + strlcat(key, ext, 15); + struct cfg_entry *entr; + if((entr = cfg_get_entry(key))) { + size_t pl = strlen(prgm); + size_t vl = strlen(entr->value); + if(pl > vl || entr->value[0] != '/' || strcmp(entr->value + (vl - pl), prgm)) { + cfg_put_entry(entr, prgm); + } + } else { + cfg_put(key, prgm); } - fseek(file, 0, SEEK_END); - fprintf(file, "%s=%s\n", key, prgm); - fclose(file); +} + +// Only for tests. cfg_register_fileext() should be used. +void cfg_register_fileext_file(const char *filepath, const char *ext, const char *prgm) { + cfg_open_file(filepath); + cfg_put_fileext(ext, prgm); + cfg_close(); } // ext without leading '.' void cfg_register_fileext(const char *ext, const char *prgm) { - char path[300]; - if (!cfg_locate_cfg_file(path, sizeof(path))) - cfg_register_fileext_file(path, ext, prgm); + if (open_file[0] == 0) { + char path[300]; + if (!cfg_locate_cfg_file(path, sizeof(path))) + cfg_register_fileext_file(path, ext, prgm); + } else { + cfg_put_fileext(ext, prgm); + } } diff --git a/ndless/src/resources/ploaderhook.c b/ndless/src/resources/ploaderhook.c index d3c51231..bf8227c0 100644 --- a/ndless/src/resources/ploaderhook.c +++ b/ndless/src/resources/ploaderhook.c @@ -256,17 +256,38 @@ int ld_exec_with_args(const char *path, int argsn, char *args[], void **resident char ext_key[4 + MAX_EXT_LEN + 1]; // ext.extension strcpy(ext_key, "ext"); strcat(ext_key, ext); - char *prgm_name_noext = cfg_get(ext_key); - if (prgm_name_noext) { - char prgm_name[FILENAME_MAX + 4]; + struct cfg_entry *entr = cfg_get_entry(ext_key); + if (entr) { + char *prgm_name_noext = entr->value; + //printf("prgm_name_noext=%s\n", prgm_name_noext); + char _prgm_name[FILENAME_MAX + 4]; + char *prgm_name = _prgm_name; strcpy(prgm_name, prgm_name_noext); strcat(prgm_name, ".tns"); - if(prgm_name[0] == '/') { - strlcpy(prgm_path, prgm_name, FILENAME_MAX); - isassoc = 1; - } else { + BOOL abs_path = prgm_name[0] == '/'; + if(abs_path) { + if(access(prgm_name, F_OK) != -1) { + strlcpy(prgm_path, prgm_name, FILENAME_MAX); + isassoc = 1; + //printf("got abs path=%s\n", prgm_path); + } else { + prgm_name = strrchr(prgm_name, '/') + 1; + } + } + + if(!isassoc) { struct assoc_file_each_cb_ctx context = {prgm_name, prgm_path, &isassoc}; file_each("/", assoc_file_each_cb, &context); + if(isassoc) { + char *dot = strrchr(prgm_path, '.'); + if(dot) *dot = '\0'; + //printf("found abs path=%s\n", prgm_path); + cfg_put_entry(entr, prgm_path); + if(dot) *dot = '.'; + } else { + //printf("resetting config to rel path=%s\n", prgm_name); + cfg_put_entry(entr, strrchr(prgm_name_noext, '/')+1); + } } } cfg_close(); From e71bc4162d7c375a8d0f207fbb4fdfa53220f5ad Mon Sep 17 00:00:00 2001 From: Paul F-Y Date: Sun, 13 May 2018 17:22:18 -0400 Subject: [PATCH 5/8] removed debugging prints --- ndless-sdk/libndls/config.c | 3 --- ndless/src/resources/ploaderhook.c | 4 ---- 2 files changed, 7 deletions(-) diff --git a/ndless-sdk/libndls/config.c b/ndless-sdk/libndls/config.c index 18a97b84..c7f5761b 100644 --- a/ndless-sdk/libndls/config.c +++ b/ndless-sdk/libndls/config.c @@ -147,7 +147,6 @@ void cfg_open_file(const char *filepath) { entry->value_sz = pow2_roundup(val_len); entry->value = malloc(entry->value_sz); strlcpy(entry->value, value, entry->value_sz); - // printf("entry %s=%s\n", entry->key, entry->value); if (kv_index >= max_kv_num) break; // too many key-value pairs } } @@ -200,7 +199,6 @@ struct cfg_entry *cfg_get_entry(const char *key) { if (!open_file[0]) return NULL; for (i = 0; i < kv_num; i++) { struct cfg_entry *e = &cfg_entries[i]; - //printf("%s, %s\n", key, e->key); if (!strcmp(key, e->key)) { return e; } @@ -228,7 +226,6 @@ void cfg_put_entry(struct cfg_entry *entr, const char *val) { entr->value = realloc(entr->value, entr->value_sz); } strlcpy(entr->value, val, entr->value_sz); - //printf("accepted change %s=%s\n", entr->key, val); cfg_changed = 1; } } diff --git a/ndless/src/resources/ploaderhook.c b/ndless/src/resources/ploaderhook.c index bf8227c0..a2b617cc 100644 --- a/ndless/src/resources/ploaderhook.c +++ b/ndless/src/resources/ploaderhook.c @@ -259,7 +259,6 @@ int ld_exec_with_args(const char *path, int argsn, char *args[], void **resident struct cfg_entry *entr = cfg_get_entry(ext_key); if (entr) { char *prgm_name_noext = entr->value; - //printf("prgm_name_noext=%s\n", prgm_name_noext); char _prgm_name[FILENAME_MAX + 4]; char *prgm_name = _prgm_name; strcpy(prgm_name, prgm_name_noext); @@ -269,7 +268,6 @@ int ld_exec_with_args(const char *path, int argsn, char *args[], void **resident if(access(prgm_name, F_OK) != -1) { strlcpy(prgm_path, prgm_name, FILENAME_MAX); isassoc = 1; - //printf("got abs path=%s\n", prgm_path); } else { prgm_name = strrchr(prgm_name, '/') + 1; } @@ -281,11 +279,9 @@ int ld_exec_with_args(const char *path, int argsn, char *args[], void **resident if(isassoc) { char *dot = strrchr(prgm_path, '.'); if(dot) *dot = '\0'; - //printf("found abs path=%s\n", prgm_path); cfg_put_entry(entr, prgm_path); if(dot) *dot = '.'; } else { - //printf("resetting config to rel path=%s\n", prgm_name); cfg_put_entry(entr, strrchr(prgm_name_noext, '/')+1); } } From 757349d3184877e49268af51c3b7ce3ddb7155ba Mon Sep 17 00:00:00 2001 From: Paul F-Y Date: Sun, 13 May 2018 17:40:57 -0400 Subject: [PATCH 6/8] style changes, use PATH_MAX rather than FILENAME_MAX --- ndless-sdk/libndls/config.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ndless-sdk/libndls/config.c b/ndless-sdk/libndls/config.c index c7f5761b..247e5b9b 100644 --- a/ndless-sdk/libndls/config.c +++ b/ndless-sdk/libndls/config.c @@ -22,6 +22,7 @@ ****************************************************************************/ #include +#include /* The config file is open whenever needed with cfg_open, and must be closed. * Each line of the file contains a key/value pair (key=value). * The key and the value are trimmed when read. @@ -29,7 +30,7 @@ * Invalid lines are ignored. */ -static char open_file[FILENAME_MAX] = {0}; +static char open_file[PATH_MAX] = {0}; static unsigned max_kv_num; static unsigned kv_num; static unsigned cmt_num; @@ -168,16 +169,16 @@ void cfg_open_file(const char *filepath) { } loop_end: cmt_num = kv_num = kv_index; - strlcpy(open_file, filepath, FILENAME_MAX); + strlcpy(open_file, filepath, PATH_MAX); free(file_content); } -static char cfg_path[FILENAME_MAX] = {0}; +static char cfg_path[PATH_MAX] = {0}; static int cfg_locate_cfg_file(char *dst_path, size_t dst_path_size) { - if(cfg_path[0] == 0) snprintf(cfg_path, FILENAME_MAX, "%s%s", get_documents_dir(), "ndless/ndless.cfg.tns"); + if(cfg_path[0] == 0) snprintf(cfg_path, PATH_MAX, "%s%s", get_documents_dir(), "ndless/ndless.cfg.tns"); if(access(cfg_path, F_OK) == -1) { - int l = locate("ndless.cfg.tns", cfg_path, FILENAME_MAX); + int l = locate("ndless.cfg.tns", cfg_path, PATH_MAX); if(l != 0) return l; } size_t actual_path_len = strlen(cfg_path); @@ -188,7 +189,7 @@ static int cfg_locate_cfg_file(char *dst_path, size_t dst_path_size) { } void cfg_open(void) { - char path[FILENAME_MAX]; + char path[PATH_MAX]; if (cfg_locate_cfg_file(path, sizeof(path))) return; cfg_open_file(path); @@ -199,9 +200,8 @@ struct cfg_entry *cfg_get_entry(const char *key) { if (!open_file[0]) return NULL; for (i = 0; i < kv_num; i++) { struct cfg_entry *e = &cfg_entries[i]; - if (!strcmp(key, e->key)) { + if (strcmp(key, e->key) == 0) return e; - } } return NULL; } @@ -231,8 +231,8 @@ void cfg_put_entry(struct cfg_entry *entr, const char *val) { } void cfg_put(const char *key, const char *val) { - struct cfg_entry *entr; - if((entr = cfg_get_entry(key))) { + struct cfg_entry *entr = cfg_get_entry(key); + if(entr != NULL) { cfg_put_entry(entr, val); } else { if(kv_num == max_kv_num) { From 93ae8c366555ce27a717c9fc32b14fa894fac63a Mon Sep 17 00:00:00 2001 From: Paul F-Y Date: Sun, 13 May 2018 17:43:50 -0400 Subject: [PATCH 7/8] moved cfg_path inside fuction, removed old struct member --- ndless-sdk/include/libndls.h | 1 - ndless-sdk/libndls/config.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ndless-sdk/include/libndls.h b/ndless-sdk/include/libndls.h index 40a387cf..15b1530b 100644 --- a/ndless-sdk/include/libndls.h +++ b/ndless-sdk/include/libndls.h @@ -104,7 +104,6 @@ void wait_no_key_pressed(void); /* config.c */ struct cfg_entry { char key[15]; -// short val_offset; size_t value_sz; char *value; }; diff --git a/ndless-sdk/libndls/config.c b/ndless-sdk/libndls/config.c index 247e5b9b..c8236222 100644 --- a/ndless-sdk/libndls/config.c +++ b/ndless-sdk/libndls/config.c @@ -173,9 +173,10 @@ void cfg_open_file(const char *filepath) { free(file_content); } -static char cfg_path[PATH_MAX] = {0}; static int cfg_locate_cfg_file(char *dst_path, size_t dst_path_size) { + static char cfg_path[PATH_MAX] = {0}; + if(cfg_path[0] == 0) snprintf(cfg_path, PATH_MAX, "%s%s", get_documents_dir(), "ndless/ndless.cfg.tns"); if(access(cfg_path, F_OK) == -1) { int l = locate("ndless.cfg.tns", cfg_path, PATH_MAX); From 9c9c119f6a184c2ceab69aec20b1f9f870f21fcf Mon Sep 17 00:00:00 2001 From: Paul F-Y Date: Mon, 14 May 2018 00:08:34 -0400 Subject: [PATCH 8/8] renamed cfg_put_entry, removed strict_strcmp, fixed writing comments --- ndless-sdk/include/libndls.h | 5 +++-- ndless-sdk/libndls/config.c | 29 ++++++++++++----------------- ndless/src/resources/ploaderhook.c | 4 ++-- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/ndless-sdk/include/libndls.h b/ndless-sdk/include/libndls.h index 15b1530b..e6609108 100644 --- a/ndless-sdk/include/libndls.h +++ b/ndless-sdk/include/libndls.h @@ -104,6 +104,7 @@ void wait_no_key_pressed(void); /* config.c */ struct cfg_entry { char key[15]; + // don't write to value_sz or value; instead, use cfg_set_value size_t value_sz; char *value; }; @@ -113,9 +114,9 @@ void cfg_open_file(const char *filepath); void cfg_close(void); // get/put only work if cfg file is open struct cfg_entry *cfg_get_entry(const char *key); -void cfg_put_entry(struct cfg_entry *entr, const char *val); +void cfg_set_value(struct cfg_entry *entr, const char *val); const char *cfg_get(const char *key); -void cfg_put(const char *key, const char *val); +struct cfg_entry *cfg_put(const char *key, const char *val); void cfg_put_fileext(const char *ext, const char *prgm); // register opens cfg file as always void cfg_register_fileext(const char *ext, const char *prgm); diff --git a/ndless-sdk/libndls/config.c b/ndless-sdk/libndls/config.c index c8236222..e82c75b2 100644 --- a/ndless-sdk/libndls/config.c +++ b/ndless-sdk/libndls/config.c @@ -45,7 +45,7 @@ void cfg_save_file(const char *filepath) { unsigned i; for(i = 0; i < kv_num; i++) { struct cfg_entry *n_entr = &cfg_entries[i]; - if(cfg_comments[i]) { + if(i < cmt_num && cfg_comments[i]) { fprintf(file, "%s=%s #%s\n", n_entr->key, n_entr->value, cfg_comments[i]); } else { fprintf(file, "%s=%s\n", n_entr->key, n_entr->value); @@ -213,14 +213,8 @@ const char *cfg_get(const char *key) { return e == NULL ? NULL : e->value; } -static int strict_strcmp(const char *a, const char *b) { - size_t l1 = strlen(a); - size_t l2 = strlen(b); - return memcmp(a, b, (l1 < l2 ? l1 : l2)+1); -} - -void cfg_put_entry(struct cfg_entry *entr, const char *val) { - if(strict_strcmp(entr->value, val)) { +void cfg_set_value(struct cfg_entry *entr, const char *val) { + if(strcmp(entr->value, val)) { size_t vl = strlen(val) + 1; if(vl > entr->value_sz || vl <= entr->value_sz / 2) { entr->value_sz = pow2_roundup(vl); @@ -231,23 +225,24 @@ void cfg_put_entry(struct cfg_entry *entr, const char *val) { } } -void cfg_put(const char *key, const char *val) { +struct cfg_entry *cfg_put(const char *key, const char *val) { struct cfg_entry *entr = cfg_get_entry(key); if(entr != NULL) { - cfg_put_entry(entr, val); + cfg_set_value(entr, val); } else { if(kv_num == max_kv_num) { max_kv_num *= 2; cfg_entries = realloc(cfg_entries, max_kv_num * sizeof(struct cfg_entry)); } - struct cfg_entry *n_entr = &cfg_entries[kv_num++]; - strlcpy(n_entr->key, key, 15); + struct cfg_entry *entr = &cfg_entries[kv_num++]; + strlcpy(entr->key, key, 15); size_t vl = strlen(val) + 1; - n_entr->value_sz = pow2_roundup(vl); - n_entr->value = malloc(n_entr->value_sz); - strlcpy(n_entr->value, val, n_entr->value_sz); + entr->value_sz = pow2_roundup(vl); + entr->value = malloc(entr->value_sz); + strlcpy(entr->value, val, entr->value_sz); cfg_changed = 1; } + return entr; } void cfg_put_fileext(const char *ext, const char *prgm) { @@ -258,7 +253,7 @@ void cfg_put_fileext(const char *ext, const char *prgm) { size_t pl = strlen(prgm); size_t vl = strlen(entr->value); if(pl > vl || entr->value[0] != '/' || strcmp(entr->value + (vl - pl), prgm)) { - cfg_put_entry(entr, prgm); + cfg_set_value(entr, prgm); } } else { cfg_put(key, prgm); diff --git a/ndless/src/resources/ploaderhook.c b/ndless/src/resources/ploaderhook.c index a2b617cc..2e3167d7 100644 --- a/ndless/src/resources/ploaderhook.c +++ b/ndless/src/resources/ploaderhook.c @@ -279,10 +279,10 @@ int ld_exec_with_args(const char *path, int argsn, char *args[], void **resident if(isassoc) { char *dot = strrchr(prgm_path, '.'); if(dot) *dot = '\0'; - cfg_put_entry(entr, prgm_path); + cfg_set_value(entr, prgm_path); if(dot) *dot = '.'; } else { - cfg_put_entry(entr, strrchr(prgm_name_noext, '/')+1); + cfg_set_value(entr, strrchr(prgm_name_noext, '/')+1); } } }