Skip to content

Instantly share code, notes, and snippets.

@lelandbatey
Created August 24, 2022 21:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lelandbatey/0822ce425dcac02a295faddf4100170d to your computer and use it in GitHub Desktop.
Save lelandbatey/0822ce425dcac02a295faddf4100170d to your computer and use it in GitHub Desktop.
Prints a detailed view of all arguments. When you're confused about args, substitute in `cmdinfo` for a hex dump of every arg.
// Compile with:
// gcc ./cmdinfo.c -lm -o cmdinfo
#include <stdio.h> /* printf(), fprintf() */
#include <string.h> /* strcmp() */
#include <math.h> /* log10(), ceil() */
// fwd decl to cease warnings
int print_arguments(FILE* outf, int argc, char *const *argv);
int xxdline(int lineno, char* input, int inputlen, char* outbuf);
char* cleanstr(char* str);
int main(int argc, char *const *argv){
FILE* outf = stdout;
if (argc == 2 && ((strcmp(argv[1], "-h")==0) || (strcmp(argv[1], "--help") ==0 ))) {
outf = stderr;
fprintf(outf, "Usage: %s [arguments]\n\n", argv[0]);
fprintf(outf, "Prints a detailed view of all arguments. A program for examining all\n");
fprintf(outf, "arguments provided as 'argv'. Useful to insert into scripts for\n");
fprintf(outf, "debugging purposes. The following is an example of the info this\n");
fprintf(outf, "program prints, but run against your '%s' argument:\n\n", argv[1]);
// Intentionally do not exit, we run against the 'help' flag as an example
}
if (argc == 0) {
return 0;
}
print_arguments(outf, argc, argv);
}
// print_arguments prints each argument in argv, one after another, one per
// line, with leading text explaining what's in that argument.
int print_arguments(FILE* outf, int argc, char *const *argv) {
int chwidth = ceil(log10(argc+1));
fprintf(outf, "#Number of arguments: %d, width of number of args: %d\n\n", argc, chwidth);
char fmt[30];
snprintf(fmt, 30, "Argument #%%0%dd: %%s\n", chwidth);
for (int i = 0; i < argc; i++) {
fprintf(outf, fmt, i, cleanstr(argv[i]));
int arglen = strlen(argv[i]);
for (int k = 0; k < arglen; k = k+16) {
char buf[70];
int linelen = arglen - k;
if (linelen>16) {
linelen=16;
}
xxdline(k/16, argv[i] + k, linelen, buf);
fprintf(outf, "%s\n", buf);
}
fprintf(outf, "\n");
}
return 0;
}
char chartodisp(char c) {
if ((c > 31) && (c < 127)) {
return c;
}
return '.';
}
// input is a buffer that's of inputlen in length, a maximum of 16.
// outbuf must be exactly 70 chars long
// lineno is the 0-index line that we're printing
int xxdline(int lineno, char* input, int inputlen, char* outbuf) {
int firstbyteofline = 16*lineno;
char buf[40];
memset(buf, ' ', 39);
buf[39] = '\0';
for (int i = 0; i< inputlen; i++) {
char byte = input[i];
int hexbyteloc = (i*2) + (i/2);
char b[3];
snprintf(b, 3, "%02x", byte);
buf[hexbyteloc+0] = b[0];
buf[hexbyteloc+1] = b[1];
}
char humchars[17];
memset(humchars, ' ', 16);
humchars[16] = '\0';
for (int i = 0; i< inputlen; i++) {
char c = chartodisp(input[i]);
humchars[i] = c;
}
snprintf(outbuf, 70, "%08x: %s | %s", firstbyteofline, buf, humchars);
}
char* cleanstr(char* str) {
char* newstr = strdup(str);
int ln = strlen(str);
for (int i = 0; i < ln; i++) {
newstr[i] = chartodisp(newstr[i]);
}
return newstr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment