From 57c695563f1892ed8eb3d8841f70ccce9f01c53d Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 26 Mar 2014 22:35:25 +0100 Subject: [PATCH 1/1] Fixes to implement generation of markdown auto-generated documentation --- client/cmddata.c | 2 +- client/cmddata.h | 2 ++ client/cmdlf.c | 2 +- client/cmdmain.c | 12 +++++--- client/cmdmain.h | 3 +- client/cmdparser.c | 69 +++++++++++++++++++++++++++++++++++++++++++--- client/cmdparser.h | 1 + client/proxmark3.c | 62 ++++++++++++++++------------------------- 8 files changed, 104 insertions(+), 49 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index 265b0ed7..a7b80480 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -851,7 +851,7 @@ static command_t CommandTable[] = { {"help", CmdHelp, 1, "This help"}, {"amp", CmdAmp, 1, "Amplify peaks"}, - {"askdemod", Cmdaskdemod, 1, "<0|1> -- Attempt to demodulate simple ASK tags"}, + {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"}, {"autocorr", CmdAutoCorr, 1, " -- Autocorrelation over window"}, {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"}, {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"}, diff --git a/client/cmddata.h b/client/cmddata.h index 06ea18cc..2f86a941 100644 --- a/client/cmddata.h +++ b/client/cmddata.h @@ -11,6 +11,8 @@ #ifndef CMDDATA_H__ #define CMDDATA_H__ +command_t * CmdDataCommands(); + int CmdData(const char *Cmd); int CmdAmp(const char *Cmd); diff --git a/client/cmdlf.c b/client/cmdlf.c index 4e10b8f6..387e60d5 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -536,7 +536,7 @@ static command_t CommandTable[] = {"io", CmdLFIO, 1, "{ ioProx tags... }"}, {"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"}, {"indalaclone", CmdIndalaClone, 1, " ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"}, - {"read", CmdLFRead, 0, "['h'|] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, + {"read", CmdLFRead, 0, "['h' or ] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134, alternatively: f=12MHz/(divisor+1))"}, {"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"}, {"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"}, {"simman", CmdLFSimManchester, 0, " [GAP] Simulate arbitrary Manchester LF tag"}, diff --git a/client/cmdmain.c b/client/cmdmain.c index 59ab8bf5..fa358fac 100644 --- a/client/cmdmain.c +++ b/client/cmdmain.c @@ -45,17 +45,21 @@ static int cmd_tail;//Starts as 0 static command_t CommandTable[] = { - {"help", CmdHelp, 1, "This help. Use ' help' for details of the following commands:\n"}, + {"help", CmdHelp, 1, "This help. Use ' help' for details of a particular command."}, {"data", CmdData, 1, "{ Plot window / data buffer manipulation... }"}, - {"exit", CmdQuit, 1, "Exit program"}, {"hf", CmdHF, 1, "{ HF commands... }"}, {"hw", CmdHW, 1, "{ Hardware commands... }"}, {"lf", CmdLF, 1, "{ LF commands... }"}, - {"quit", CmdQuit, 1, "Quit program"}, - {"script", CmdScript, 1,"Run script"}, + {"script", CmdScript, 1,"{ Scripting commands }"}, + {"quit", CmdQuit, 1, "Exit program"}, + {"exit", CmdQuit, 1, "Exit program"}, {NULL, NULL, 0, NULL} }; +command_t* getTopLevelCommandTable() +{ + return CommandTable; +} int CmdHelp(const char *Cmd) { CmdsHelp(CommandTable); diff --git a/client/cmdmain.h b/client/cmdmain.h index ce4130bb..0cf2b35d 100644 --- a/client/cmdmain.h +++ b/client/cmdmain.h @@ -12,10 +12,11 @@ #define CMDMAIN_H__ #include "usb_cmd.h" - +#include "cmdparser.h" void UsbCommandReceived(UsbCommand *UC); void CommandReceived(char *Cmd); bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout); bool WaitForResponse(uint32_t cmd, UsbCommand* response); void clearCommandBuffer(); +command_t* getTopLevelCommandTable(); #endif diff --git a/client/cmdparser.c b/client/cmdparser.c index 48d044d5..c971092b 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -9,6 +9,7 @@ //----------------------------------------------------------------------------- #include +#include #include #include "ui.h" #include "cmdparser.h" @@ -21,16 +22,26 @@ void CmdsHelp(const command_t Commands[]) int i = 0; while (Commands[i].Name) { - if (offline == 0 || Commands[i].Offline) - PrintAndLog("%-16s %s", Commands[i].Name, Commands[i].Help); - if (offline == 2 && !Commands[i].Offline) - PrintAndLog("%-14s @ %s", Commands[i].Name, Commands[i].Help); + if(Commands[i].Offline) + { + PrintAndLog("%-16s \t%s", Commands[i].Name, Commands[i].Help); + }else + { + PrintAndLog("%-16s @\t%s", Commands[i].Name, Commands[i].Help); + } ++i; } } void CmdsParse(const command_t Commands[], const char *Cmd) { + if(strcmp( Cmd, "XX_internal_command_dump_XX") == 0) + {// Markdown dump children + dumpCommandsRecursive(Commands); + return; + } + + char cmd_name[32]; int len = 0; memset(cmd_name, 0, 32); @@ -62,3 +73,53 @@ void CmdsParse(const command_t Commands[], const char *Cmd) CmdsHelp(Commands); } } +//static int tablevel = 0; + +char pparent[512] = {0}; +char *parent = pparent; + +void dumpCommandsRecursive(const command_t cmds[]) +{ + if (cmds[0].Name == NULL) + return; + + int i = 0; + char* tabulation = "###"; + char* offline = "N"; + // First, dump all single commands, which are not a container for + // other commands + printf("command|offline|description\n"); + printf("-------|-------|-----------\n"); + + while (cmds[i].Name) + { + if(cmds[i].Help[0] == '{' && ++i) continue; + + if ( cmds[i].Offline) offline = "Y"; + printf("|`%s%s`|%s|`%s`|\n", parent, cmds[i].Name,offline, cmds[i].Help); + ++i; + } + printf("\n\n"); + i=0; + // Then, print the categories. These will go into subsections with their own tables + + while (cmds[i].Name) + { + if(cmds[i].Help[0] != '{' && ++i) continue; + + printf("%s %s%s\n\n %s\n\n", tabulation, parent, cmds[i].Name, cmds[i].Help); + + char currentparent[512] = {0}; + snprintf(currentparent, sizeof currentparent, "%s%s ", parent, cmds[i].Name); + char *old_parent = parent; + parent = currentparent; +// tablevel++; + // This is what causes the recursion, since commands Parse-implementation + // in turn calls the CmdsParse above. + cmds[i].Parse("XX_internal_command_dump_XX"); +// tablevel--; + parent = old_parent; + ++i; + } + +} diff --git a/client/cmdparser.h b/client/cmdparser.h index 28c2e66e..94aad884 100644 --- a/client/cmdparser.h +++ b/client/cmdparser.h @@ -25,5 +25,6 @@ typedef struct command_s void CmdsHelp(const command_t Commands[]); // Parse a command line void CmdsParse(const command_t Commands[], const char *Cmd); +void dumpCommandsRecursive(const command_t cmds[]); #endif diff --git a/client/proxmark3.c b/client/proxmark3.c index e40b4def..3c7e6451 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -23,6 +23,8 @@ #include "uart.h" #include "ui.h" #include "sleep.h" +#include "cmdparser.h" +#include "cmdmain.h" // a global mutex to prevent interlaced printing from different threads pthread_mutex_t print_lock; @@ -31,7 +33,6 @@ static serial_port sp; static UsbCommand txcmd; volatile static bool txcmd_pending = false; - void SendCommand(UsbCommand *c) { #if 0 printf("Sending %d bytes\n", sizeof(UsbCommand)); @@ -206,39 +207,25 @@ static void *main_loop(void *targ) { return NULL; } -#define DUMPHELP(cmd) \ - do { \ - printf("%s\n", cmd); \ - printf("---------------------------------------------\n"); \ - CommandReceived(cmd); \ - printf("\n"); \ - } while (0) +//static void dumpHelp(char *parent, ...) +//{ +// printf("## %s\n\n", parent); +// CommandReceived(parent); +// +// printf("\n"); +//} -static void dumphelp() +static void dumpAllHelp() { - offline=2; - printf("\n------------PROXMARK3 HELP DUMP--------------\n"); + offline=3; + printf("\n# Proxmark3 command dump\n\n"); printf("Some commands are available only if a Proxmark is actually connected,\n"); printf("Those commands are flagged with \"@\" in front of their description.\n"); printf("\n"); - DUMPHELP("help"); - DUMPHELP("data help"); - DUMPHELP("hf help"); - DUMPHELP("hf 14a help"); - DUMPHELP("hf 14b help"); - DUMPHELP("hf 15 help"); - DUMPHELP("hf epa help"); - DUMPHELP("hf legic help"); - DUMPHELP("hf iclass help"); - DUMPHELP("hf mf help"); - DUMPHELP("hw help"); - DUMPHELP("lf help"); - DUMPHELP("lf em4x help"); - DUMPHELP("lf hid help"); - DUMPHELP("lf ti help"); - DUMPHELP("lf hitag help"); - DUMPHELP("lf pcf7931 help"); - DUMPHELP("lf t55xx help"); + command_t *cmds = getTopLevelCommandTable(); + + dumpCommandsRecursive(cmds); + } int main(int argc, char* argv[]) { @@ -247,18 +234,17 @@ int main(int argc, char* argv[]) { if (argc < 2) { printf("syntax: %s \n\n",argv[0]); printf("\tLinux example:'%s /dev/ttyACM0'\n\n", argv[0]); - printf("help: %s -h\n\n", argv[0]); - printf("\tDump all interactive help at once\n"); + printf("help: %s -h\n\n", argv[0]); + printf("\tDump all interactive help at once\n"); return 1; } - if (strcmp(argv[1], "-h") == 0) { - printf("syntax: %s \n\n",argv[0]); - printf("\tLinux example:'%s /dev/ttyACM0'\n\n", argv[0]); - offline = 2; - dumphelp(); - return 0; - } + if (strcmp(argv[1], "-h") == 0) { + printf("syntax: %s \n\n",argv[0]); + printf("\tLinux example:'%s /dev/ttyACM0'\n\n", argv[0]); + dumpAllHelp(); + return 0; + } // Make sure to initialize struct main_loop_arg marg = { .usb_present = 0, -- 2.39.5