Merge pull request #608 from RfidResearchGroup/emojis

emojis support
This commit is contained in:
Iceman 2020-03-16 10:42:24 +01:00 committed by GitHub
commit 0923a8c625
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 2070 additions and 22 deletions

View file

@ -178,7 +178,7 @@ int CmdHFTune(const char *Cmd) {
if (cmdp == 'h') return usage_hf_tune();
int iter = param_get32ex(Cmd, 0, 0, 10);
PrintAndLogEx(SUCCESS, "Measuring HF antenna, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit");
PrintAndLogEx(INFO, "Measuring HF antenna, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit");
PacketResponseNG resp;
clearCommandBuffer();
@ -218,7 +218,7 @@ int CmdHFTune(const char *Cmd) {
return PM3_ETIMEOUT;
}
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "Done.");
PrintAndLogEx(INFO, "Done.");
return PM3_SUCCESS;
}

View file

@ -253,7 +253,7 @@ static int CmdLFTune(const char *Cmd) {
//Validations
if (errors) return usage_lf_tune();
PrintAndLogEx(SUCCESS, "Measuring LF antenna at " _YELLOW_("%.2f") "kHz, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit", LF_DIV2FREQ(divisor));
PrintAndLogEx(INFO, "Measuring LF antenna at " _YELLOW_("%.2f") "kHz, click " _GREEN_("pm3 button") "or press " _GREEN_("Enter") "to exit", LF_DIV2FREQ(divisor));
uint8_t params[] = {1, 0};
params[1] = divisor;
@ -295,7 +295,7 @@ static int CmdLFTune(const char *Cmd) {
return PM3_ETIMEOUT;
}
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, "Done.");
PrintAndLogEx(INFO, "Done.");
return PM3_SUCCESS;
}

1862
client/emojis.h Normal file

File diff suppressed because it is too large Load diff

15
client/emojis_alt.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef EMOJIS_ALT_H__
#define EMOJIS_ALT_H__
typedef struct emoji_alt_s {
const char *alias;
const char *alttext;
} emoji_alt_t;
// emoji_alt_t array are expected to be NULL terminated
static emoji_alt_t EmojiAltTable[] = {
{":wink:", ";)"},
{NULL, NULL}
};
#endif

35
client/emojis_scrap_github.py Executable file
View file

@ -0,0 +1,35 @@
#!/usr/bin/env python3
# Mostly derived from https://github.com/mrowa44/emojify Copyright (c) 2015 Justyna Rachowicz
from urllib.request import urlopen
import json
EMOJI_JSON_URL = 'https://raw.githubusercontent.com/github/gemoji/master/db/emoji.json'
def print_emoji(emoji_json):
for alias in emoji_json['aliases']:
print(' {{":{0}:", "{1}"}},'.format(alias, emoji_json['emoji']))
print(
"""#ifndef EMOJIS_H__
#define EMOJIS_H__
typedef struct emoji_s {
const char *alias;
const char *emoji;
} emoji_t;
// emoji_t array are expected to be NULL terminated
static emoji_t EmojiTable[] = {""")
with urlopen(EMOJI_JSON_URL) as conn:
emojis_json = json.loads(conn.read().decode('utf-8'))
for emoji_json in emojis_json:
print_emoji(emoji_json)
print(
""" {NULL, NULL}
};
#endif""")

View file

@ -36,7 +36,7 @@ static void showBanner(void) {
PrintAndLogEx(NORMAL, " " _BLUE_("██████╗ ███╗ ███╗ ████╗ "));
PrintAndLogEx(NORMAL, " " _BLUE_("██╔══██╗████╗ ████║ ══█║"));
PrintAndLogEx(NORMAL, " " _BLUE_("██████╔╝██╔████╔██║ ████╔╝"));
PrintAndLogEx(NORMAL, " " _BLUE_("██╔═══╝ ██║╚██╔╝██║ ══█║") " iceman@icesql.net");
PrintAndLogEx(NORMAL, " " _BLUE_("██╔═══╝ ██║╚██╔╝██║ ══█║") " :snowflake: iceman@icesql.net");
PrintAndLogEx(NORMAL, " " _BLUE_("██║ ██║ ╚═╝ ██║ ████╔╝") " https://github.com/rfidresearchgroup/proxmark3/");
PrintAndLogEx(NORMAL, " " _BLUE_("╚═╝ ╚═╝ ╚═╝ ╚═══╝ ") "pre-release v4.0");
#else
@ -756,6 +756,7 @@ int main(int argc, char *argv[]) {
}
session.supports_colors = DetectWindowsAnsiSupport();
session.emoji_mode = ALTTEXT;
session.stdinOnTTY = isatty(STDIN_FILENO);
session.stdoutOnTTY = isatty(STDOUT_FILENO);
@ -766,8 +767,10 @@ int main(int argc, char *argv[]) {
// For info, grep --color=auto is doing sth like this, plus test getenv("TERM") != "dumb":
// struct stat tmp_stat;
// if ((fstat (STDOUT_FILENO, &tmp_stat) == 0) && (S_ISCHR (tmp_stat.st_mode)) && isatty(STDIN_FILENO))
if (session.stdinOnTTY && session.stdoutOnTTY)
if (session.stdinOnTTY && session.stdoutOnTTY) {
session.supports_colors = true;
session.emoji_mode = EMOJI;
}
#endif
// Let's take a baudrate ok for real UART, USB-CDC & BT don't use that info anyway
if (speed == 0)

View file

@ -31,6 +31,8 @@
# include <direct.h> // _mkdir
#endif
#include <time.h>
#include "emojis.h"
#include "emojis_alt.h"
session_arg_t session;
double CursorScaleFactor = 1;
@ -132,39 +134,66 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) {
if (g_showhints == 0 && level == HINT)
return;
char prefix[20] = {0};
char prefix[40] = {0};
char buffer[MAX_PRINT_BUFFER] = {0};
char buffer2[MAX_PRINT_BUFFER + 20] = {0};
char buffer2[MAX_PRINT_BUFFER + sizeof(prefix)] = {0};
char *token = NULL;
char *tmp_ptr = NULL;
FILE *stream = stdout;
const char *spinner[] = {_YELLOW_("[\\]"), _YELLOW_("[|]"), _YELLOW_("[/]"), _YELLOW_("[-]")};
const char *spinner_emoji[] = {" :clock1: ", " :clock2: ", " :clock3: ", " :clock4: ", " :clock5: ", " :clock6: ",
" :clock7: ", " :clock8: ", " :clock9: ", " :clock10: ", " :clock11: ", " :clock12: "};
switch (level) {
case ERR:
if (session.emoji_mode == EMOJI)
strncpy(prefix, " :rotating_light: ", sizeof(prefix) - 1);
else
strncpy(prefix, _RED_("[!!]"), sizeof(prefix) - 1);
stream = stderr;
break;
case FAILED:
if (session.emoji_mode == EMOJI)
strncpy(prefix, " :no_entry: ", sizeof(prefix) - 1);
else
strncpy(prefix, _RED_("[-]"), sizeof(prefix) - 1);
break;
case DEBUG:
if (session.emoji_mode == EMOJI)
strncpy(prefix, " :speech_balloon: ", sizeof(prefix) - 1);
else
strncpy(prefix, _BLUE_("[#]"), sizeof(prefix) - 1);
break;
case HINT:
case SUCCESS:
if (session.emoji_mode == EMOJI)
strncpy(prefix, " :star: ", sizeof(prefix) - 1);
else
strncpy(prefix, _GREEN_("[+]"), sizeof(prefix) - 1);
break;
case WARNING:
if (session.emoji_mode == EMOJI)
strncpy(prefix, " :warning: ", sizeof(prefix) - 1);
else
strncpy(prefix, _CYAN_("[!]"), sizeof(prefix) - 1);
break;
case INFO:
if (session.emoji_mode == EMOJI)
strncpy(prefix, " :information_source: ", sizeof(prefix) - 1);
else
strncpy(prefix, _YELLOW_("[=]"), sizeof(prefix) - 1);
break;
case INPLACE:
if (session.emoji_mode == EMOJI) {
strncpy(prefix, spinner_emoji[PrintAndLogEx_spinidx], sizeof(prefix) - 1);
PrintAndLogEx_spinidx++;
if (PrintAndLogEx_spinidx >= ARRAYLEN(spinner_emoji))
PrintAndLogEx_spinidx = 0;
} else {
strncpy(prefix, spinner[PrintAndLogEx_spinidx], sizeof(prefix) - 1);
PrintAndLogEx_spinidx++;
if (PrintAndLogEx_spinidx == ARRAYLEN(spinner))
if (PrintAndLogEx_spinidx >= ARRAYLEN(spinner))
PrintAndLogEx_spinidx = 0;
}
break;
case NORMAL:
// no prefixes for normal
@ -207,9 +236,11 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) {
} else {
snprintf(buffer2, sizeof(buffer2), "%s%s", prefix, buffer);
if (level == INPLACE) {
char buffer3[MAX_PRINT_BUFFER + 20] = {0};
char buffer3[sizeof(buffer2)] = {0};
char buffer4[sizeof(buffer2)] = {0};
memcpy_filter_ansi(buffer3, buffer2, sizeof(buffer2), !session.supports_colors);
fprintf(stream, "\r%s", buffer3);
memcpy_filter_emoji(buffer4, buffer3, sizeof(buffer3), session.emoji_mode);
fprintf(stream, "\r%s", buffer4);
fflush(stream);
} else {
fPrintAndLog(stream, "%s", buffer2);
@ -225,6 +256,7 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) {
static int logging = 1;
char buffer[MAX_PRINT_BUFFER] = {0};
char buffer2[MAX_PRINT_BUFFER] = {0};
char buffer3[MAX_PRINT_BUFFER] = {0};
// lock this section to avoid interlacing prints from different threads
pthread_mutex_lock(&print_lock);
@ -281,7 +313,8 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) {
bool filter_ansi = !session.supports_colors;
memcpy_filter_ansi(buffer2, buffer, sizeof(buffer), filter_ansi);
if (g_printAndLog & PRINTANDLOG_PRINT) {
fprintf(stream, "%s", buffer2);
memcpy_filter_emoji(buffer3, buffer2, sizeof(buffer2), session.emoji_mode);
fprintf(stream, "%s", buffer3);
fprintf(stream, " "); // cleaning prompt
fprintf(stream, "\n");
}
@ -356,6 +389,102 @@ void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter) {
}
}
static bool emojify_token(const char *token, uint8_t token_length, const char **emojified_token, uint8_t *emojified_token_length, emojiMode_t mode) {
int i = 0;
while (EmojiTable[i].alias) {
if ((strlen(EmojiTable[i].alias) == token_length) && (0 == memcmp(EmojiTable[i].alias, token, token_length))) {
switch (mode) {
case EMOJI: {
*emojified_token = EmojiTable[i].emoji;
*emojified_token_length = strlen(EmojiTable[i].emoji);
break;
}
case ALTTEXT: {
int j = 0;
*emojified_token_length = 0;
while (EmojiAltTable[j].alias) {
if ((strlen(EmojiAltTable[j].alias) == token_length) && (0 == memcmp(EmojiAltTable[j].alias, token, token_length))) {
*emojified_token = EmojiAltTable[j].alttext;
*emojified_token_length = strlen(EmojiAltTable[j].alttext);
break;
}
++j;
}
break;
}
default: {// ERASE
*emojified_token_length = 0;
break;
}
}
return true;
}
++i;
}
return false;
}
static bool token_charset(uint8_t c) {
if ((c >= '0') && (c <= '9')) return true;
if ((c >= 'a') && (c <= 'z')) return true;
if ((c >= 'A') && (c <= 'Z')) return true;
if ((c == '_') || (c == '+') || (c == '-')) return true;
return false;
}
void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode) {
if (mode == ALIAS) {
memcpy(dest, src, n);
} else {
// tokenize emoji
const char *emojified_token = NULL;
uint8_t emojified_token_length = 0;
char *current_token = NULL;
uint8_t current_token_length=0;
char current_char;
char *rdest = (char *)dest;
char *rsrc = (char *)src;
uint16_t si = 0;
for (uint16_t i = 0; i < n; i++) {
current_char = rsrc[i];
if (current_token_length == 0) {
// starting a new token.
if (current_char == ':') {
current_token = rsrc + i;
current_token_length = 1;
} else { // not starting a new token.
rdest[si++] = current_char;
}
} else {
// finishing the current token.
if (current_char == ':') {
// nothing changed? we still need the ending ':' as it might serve for an upcoming emoji
if (! emojify_token(current_token, current_token_length + 1, &emojified_token, &emojified_token_length, mode)) {
memcpy(rdest + si, current_token, current_token_length);
si += current_token_length;
current_token = rsrc + i;
current_token_length = 1;
} else {
memcpy(rdest + si, emojified_token, emojified_token_length);
si += emojified_token_length;
current_token_length = 0;
}
} else if (token_charset(current_char)) { // continuing the current token.
current_token_length++;
} else { // dropping the current token.
current_token_length++;
memcpy(rdest + si, current_token, current_token_length);
si += current_token_length;
current_token_length = 0;
}
}
}
memcpy(rdest + si, current_token, current_token_length);
si += current_token_length;
}
}
void iceIIR_Butterworth(int *data, const size_t len) {
int *output = (int *) calloc(sizeof(int) * len, sizeof(uint8_t));

View file

@ -17,10 +17,14 @@
#define _USE_MATH_DEFINES
typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t;
typedef enum emojiMode {ALIAS, EMOJI, ALTTEXT, ERASE} emojiMode_t;
typedef struct {
bool stdinOnTTY;
bool stdoutOnTTY;
bool supports_colors;
emojiMode_t emoji_mode;
bool pm3_present;
bool help_dump_mode;
} session_arg_t;
@ -31,7 +35,6 @@ extern session_arg_t session;
#define M_PI 3.14159265358979323846264338327
#endif
#define MAX_PRINT_BUFFER 2048
typedef enum logLevel {NORMAL, SUCCESS, INFO, FAILED, WARNING, ERR, DEBUG, INPLACE, HINT} logLevel_t;
void ShowGui(void);
void HideGraphWindow(void);
@ -41,6 +44,7 @@ void PrintAndLogOptions(const char *str[][2], size_t size, size_t space);
void PrintAndLogEx(logLevel_t level, const char *fmt, ...);
void SetFlushAfterWrite(bool value);
void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter);
void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode);
extern double CursorScaleFactor;
extern int PlotGridX, PlotGridY, PlotGridXdefault, PlotGridYdefault, GridOffset;