From ae7aa73dd529b84ad75c7a3c75461be1d7c18454 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 26 Mar 2014 22:08:55 +0100 Subject: [PATCH 1/7] Add option -h to dump complete set of supported commands Usage: ./proxmark3 -h Display both offline & online commands, online commands are flagged. git-svn-id: https://proxmark3.googlecode.com/svn/trunk@850 ef4ab9da-24cd-11de-8aaa-f3a34680c41f --- client/cmdparser.c | 4 +++- client/proxmark3.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index 7ea1bf470..48d044d59 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -21,8 +21,10 @@ void CmdsHelp(const command_t Commands[]) int i = 0; while (Commands[i].Name) { - if (!offline || Commands[i].Offline) + 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); ++i; } } diff --git a/client/proxmark3.c b/client/proxmark3.c index 91bc7b314..e40b4defe 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -206,15 +206,59 @@ 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() +{ + offline=2; + printf("\n------------PROXMARK3 HELP DUMP--------------\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"); +} + int main(int argc, char* argv[]) { srand(time(0)); 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"); 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; + } // Make sure to initialize struct main_loop_arg marg = { .usb_present = 0, From 57c695563f1892ed8eb3d8841f70ccce9f01c53d Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Wed, 26 Mar 2014 22:35:25 +0100 Subject: [PATCH 2/7] 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 265b0ed74..a7b804809 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 06ea18cc6..2f86a9417 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 4e10b8f62..387e60d58 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 59ab8bf5f..fa358fac8 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 ce4130bb5..0cf2b35d4 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 48d044d59..c971092b2 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 28c2e66ef..94aad884c 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 e40b4defe..3c7e64516 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, From b5727175c08599f0f483edbfcfc534ff7f050d77 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 26 Mar 2014 22:29:41 +0100 Subject: [PATCH 3/7] Fix offline column in help dump --- client/cmdparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index c971092b2..7c3c60cc3 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -85,7 +85,6 @@ void dumpCommandsRecursive(const command_t cmds[]) 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"); @@ -93,6 +92,7 @@ void dumpCommandsRecursive(const command_t cmds[]) while (cmds[i].Name) { + char* offline = "N"; if(cmds[i].Help[0] == '{' && ++i) continue; if ( cmds[i].Offline) offline = "Y"; From 6f5dd6010ec48f56724029a414db1ee3594ab810 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 26 Mar 2014 22:44:25 +0100 Subject: [PATCH 4/7] Fix description in help dump --- client/proxmark3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/proxmark3.c b/client/proxmark3.c index 3c7e64516..3b30b3cb5 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -219,8 +219,8 @@ static void dumpAllHelp() { 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("Some commands are available only if a Proxmark is actually connected.\n"); + printf("Check column \"offline\" for their availability.\n"); printf("\n"); command_t *cmds = getTopLevelCommandTable(); From dec8e8bd9f67643c07af9b06f9d6e9e1a2fb9191 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 26 Mar 2014 23:35:53 +0100 Subject: [PATCH 5/7] Provide option -m for markdown help dump, -h for text dump --- client/cmdparser.c | 46 +++++++++++++++++++++++++++++----------------- client/cmdparser.h | 2 +- client/proxmark3.c | 34 ++++++++++++++++++---------------- 3 files changed, 48 insertions(+), 34 deletions(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index 7c3c60cc3..3820de176 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -36,12 +36,15 @@ void CmdsHelp(const command_t Commands[]) void CmdsParse(const command_t Commands[], const char *Cmd) { if(strcmp( Cmd, "XX_internal_command_dump_XX") == 0) - {// Markdown dump children - dumpCommandsRecursive(Commands); + {// Help dump children + dumpCommandsRecursive(Commands, 0); + return; + } + if(strcmp( Cmd, "XX_internal_command_dump_markdown_XX") == 0) + {// Markdown help dump children + dumpCommandsRecursive(Commands, 1); return; } - - char cmd_name[32]; int len = 0; memset(cmd_name, 0, 32); @@ -73,30 +76,38 @@ 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[]) +void dumpCommandsRecursive(const command_t cmds[], int markdown) { - if (cmds[0].Name == NULL) + if (cmds[0].Name == NULL) return; int i = 0; - char* tabulation = "###"; + int w_cmd=25; + int w_off=8; // First, dump all single commands, which are not a container for // other commands - printf("command|offline|description\n"); - printf("-------|-------|-----------\n"); + if (markdown) { + printf("command|offline|description\n"); + printf("-------|-------|-----------\n"); + } else { + printf("%-*s|%-*s|%s\n",w_cmd,"command",w_off,"offline","description"); + printf("%-*s|%-*s|%s\n",w_cmd,"-------",w_off,"-------","-----------"); + } while (cmds[i].Name) { - char* offline = "N"; + char* cmd_offline = "N"; 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); + if ( cmds[i].Offline) cmd_offline = "Y"; + if (markdown) + printf("|`%s%s`|%s|`%s`|\n", parent, cmds[i].Name,cmd_offline, cmds[i].Help); + else + printf("%s%-*s|%-*s|%s\n", parent, w_cmd-(int)strlen(parent), cmds[i].Name, w_off, cmd_offline, cmds[i].Help); ++i; } printf("\n\n"); @@ -107,17 +118,18 @@ void dumpCommandsRecursive(const command_t cmds[]) { if(cmds[i].Help[0] != '{' && ++i) continue; - printf("%s %s%s\n\n %s\n\n", tabulation, parent, cmds[i].Name, cmds[i].Help); + printf("### %s%s\n\n %s\n\n", 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--; + if (markdown) + cmds[i].Parse("XX_internal_command_dump_markdown_XX"); + else + cmds[i].Parse("XX_internal_command_dump_XX"); parent = old_parent; ++i; } diff --git a/client/cmdparser.h b/client/cmdparser.h index 94aad884c..b7997ecce 100644 --- a/client/cmdparser.h +++ b/client/cmdparser.h @@ -25,6 +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[]); +void dumpCommandsRecursive(const command_t cmds[], int markdown); #endif diff --git a/client/proxmark3.c b/client/proxmark3.c index 3b30b3cb5..528cae341 100644 --- a/client/proxmark3.c +++ b/client/proxmark3.c @@ -215,17 +215,14 @@ static void *main_loop(void *targ) { // printf("\n"); //} -static void dumpAllHelp() +static void dumpAllHelp(int markdown) { - offline=3; - printf("\n# Proxmark3 command dump\n\n"); - printf("Some commands are available only if a Proxmark is actually connected.\n"); + printf("\n%sProxmark3 command dump%s\n\n",markdown?"# ":"",markdown?"":"\n======================"); + printf("Some commands are available only if a Proxmark is actually connected.%s\n",markdown?" ":""); printf("Check column \"offline\" for their availability.\n"); printf("\n"); command_t *cmds = getTopLevelCommandTable(); - - dumpCommandsRecursive(cmds); - + dumpCommandsRecursive(cmds, markdown); } int main(int argc, char* argv[]) { @@ -234,17 +231,22 @@ 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"); + printf("markdown: %s -m\n\n", argv[0]); + printf("\tDump all interactive help at once in markdown syntax\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]); - dumpAllHelp(); - 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(0); + return 0; + } + if (strcmp(argv[1], "-m") == 0) { + dumpAllHelp(1); + return 0; + } // Make sure to initialize struct main_loop_arg marg = { .usb_present = 0, From 46782176fc6af10c082d4eaf2e45689d9517be19 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 26 Mar 2014 23:51:22 +0100 Subject: [PATCH 6/7] Restore original inline help behavior as we've now separate fcts for -h/-m --- client/cmdparser.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index 3820de176..845915f64 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -22,13 +22,8 @@ void CmdsHelp(const command_t Commands[]) int i = 0; while (Commands[i].Name) { - 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); - } + if (!offline || Commands[i].Offline) + PrintAndLog("%-16s %s", Commands[i].Name, Commands[i].Help); ++i; } } From 19e2a10de5cdf7f6f366e5f43f0cacc662ff800a Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 27 Mar 2014 16:49:37 +0100 Subject: [PATCH 7/7] Markdown help: use fixed column width --- client/cmdparser.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/cmdparser.c b/client/cmdparser.c index 845915f64..6910e86a5 100644 --- a/client/cmdparser.c +++ b/client/cmdparser.c @@ -86,8 +86,8 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown) // First, dump all single commands, which are not a container for // other commands if (markdown) { - printf("command|offline|description\n"); - printf("-------|-------|-----------\n"); + printf("|%-*s|%-*s|%s\n",w_cmd,"command",w_off,"offline","description"); + printf("|%-*s|%-*s|%s\n",w_cmd,"-------",w_off,"-------","-----------"); } else { printf("%-*s|%-*s|%s\n",w_cmd,"command",w_off,"offline","description"); printf("%-*s|%-*s|%s\n",w_cmd,"-------",w_off,"-------","-----------"); @@ -100,7 +100,7 @@ void dumpCommandsRecursive(const command_t cmds[], int markdown) if ( cmds[i].Offline) cmd_offline = "Y"; if (markdown) - printf("|`%s%s`|%s|`%s`|\n", parent, cmds[i].Name,cmd_offline, cmds[i].Help); + printf("|`%s%-*s`|%-*s|`%s`\n", parent, w_cmd-(int)strlen(parent)-2, cmds[i].Name, w_off, cmd_offline, cmds[i].Help); else printf("%s%-*s|%-*s|%s\n", parent, w_cmd-(int)strlen(parent), cmds[i].Name, w_off, cmd_offline, cmds[i].Help); ++i;