diff --git a/src/parser.c b/src/parser.c index eab7a8d..5cbfe16 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,8 +10,8 @@ #include #include #include +#include #include -#include int construct_url(char *buf, size_t buflen, char const *input, char const *platform) @@ -141,32 +141,16 @@ parse_tldrpage(char const *input) int print_tldrpage(char const *input, char const *poverride) { - int islinux; - int isdarwin; - int issun; char *output; char url[URLBUFSIZ]; - struct utsname sys; char const *platform; char const *homedir; size_t len; char directory[STRBUFSIZ]; struct stat sb; - uname(&sys); - islinux = strcmp(sys.sysname, "Linux") == 0; - isdarwin = strcmp(sys.sysname, "Darwin") == 0; - issun = strcmp(sys.sysname, "SunOS") == 0; - if (poverride == NULL) { - if (islinux) - platform = "linux"; - else if (isdarwin) - platform = "osx"; - else if (issun) - platform = "sunos"; - else - platform = "common"; + platform = getplatform(); } else { platform = poverride; if (strcmp(platform, "linux") != 0 && strcmp(platform, "osx") != 0 && @@ -226,6 +210,78 @@ print_tldrpage(char const *input, char const *poverride) return 0; } +int +print_tldrlist(char const *poverride) +{ + char const *platform; + char const *homedir; + size_t len; + char directory[STRBUFSIZ]; + + if (poverride == NULL) { + platform = getplatform(); + } else { + platform = poverride; + if (strcmp(platform, "linux") != 0 && strcmp(platform, "osx") != 0 && + strcmp(platform, "common") != 0 && strcmp(platform, "sunos") != 0) { + fprintf(stderr, "Error: platform %s is unsupported\n", platform); + fprintf( + stderr, "Supported platforms: linux / osx / sunos / common\n"); + exit(EXIT_FAILURE); + } + } + + homedir = gethome(); + if (homedir == NULL) + return 1; + + len = 0; + if (sstrncat(directory, &len, STRBUFSIZ, homedir, strlen(homedir))) + return 1; + if (sstrncat(directory, &len, STRBUFSIZ, TLDR_EXT, TLDR_EXT_LEN)) + return 1; + + if (strcmp(platform, "common") != 0) { + parse_tldrlist(directory, platform); + fprintf(stdout, "\n"); + } + + parse_tldrlist(directory, "common"); + + return 0; +} + +int +parse_tldrlist(char const *path, char const *platform) +{ + struct dirent *entry; + DIR *directory; + char fullpath[STRBUFSIZ]; + size_t len; + + len = 0; + if (sstrncat(fullpath, &len, STRBUFSIZ, path, strlen(path))) + return 1; + if (sstrncat(fullpath, &len, STRBUFSIZ, platform, strlen(platform))) + return 1; + + fprintf(stdout, "%s", ANSI_BOLD_ON); + fprintf(stdout, "Pages for %s\n", platform); + fprintf(stdout, "%s", ANSI_BOLD_OFF); + + directory = opendir(fullpath); + + while((entry = readdir(directory))) { + len = strlen(entry->d_name); + if (strcmp(entry->d_name + (len - 3), ".md") != 0) + continue; + + fprintf(stdout, "%.*s\n", (int) len - 3, entry->d_name); + } + + return 0; +} + int print_localpage(char const *path) { diff --git a/src/tldr.c b/src/tldr.c index 397a6a7..01e7a61 100644 --- a/src/tldr.c +++ b/src/tldr.c @@ -31,6 +31,7 @@ static int verbose_flag; static int update_flag; static int clear_flag; static int platform_flag; +static int list_flag; static int render_flag; static char pbuf[STRBUFSIZ]; static struct option long_options[] = { @@ -41,6 +42,7 @@ static struct option long_options[] = { { "update", no_argument, &update_flag, 1 }, { "clear-cache", no_argument, &clear_flag, 1 }, { "platform", required_argument, 0, 'p' }, + { "list", no_argument, &list_flag, 'l'}, { "render", required_argument, 0, 'r'}, {0, 0, 0, 0 } }; @@ -108,7 +110,7 @@ main(int argc, char **argv) } /* show help, if platform was supplied, but no further argument */ - missing_arg = (platform_flag && (optind == argc)); + missing_arg = (platform_flag && !list_flag && (optind == argc)); if (help_flag || missing_arg) { print_usage(argv[0]); return EXIT_SUCCESS; @@ -131,6 +133,14 @@ main(int argc, char **argv) print_version(argv[0]); return EXIT_SUCCESS; } + if (list_flag) { + if (!has_localdb()) + update_localdb(verbose_flag); + + if (print_tldrlist(pbuf[0] != 0 ? pbuf : NULL)) + return EXIT_FAILURE; + return EXIT_SUCCESS; + } if (render_flag) { if (print_localpage(pbuf)) return EXIT_FAILURE; @@ -193,6 +203,7 @@ print_usage(char const *arg) fprintf(stdout, " %-20s %-30s\n", "-h, --help", "print this help and exit"); fprintf(stdout, " %-20s %-30s\n", "-u, --update", "update local database"); fprintf(stdout, " %-20s %-30s\n", "-c, --clear-cache", "clear local database"); + fprintf(stdout, " %-20s %-30s\n", "-l, --list", "list all entries in the local databse"); fprintf(stdout, " %-20s %-30s\n", "-p, --platform=PLATFORM", "select platform, supported are linux / osx / sunos / common"); fprintf(stdout, " %-20s %-30s\n", "-r, --render=PATH", diff --git a/src/tldr.h b/src/tldr.h index 04dd5f7..57c42f7 100644 --- a/src/tldr.h +++ b/src/tldr.h @@ -68,6 +68,8 @@ int construct_path (char *buf, size_t buflen, char const *home, char const *input, char const *platform); int parse_tldrpage (char const *input); int print_tldrpage (char const *input, char const *platform); +int print_tldrlist (char const *platform); +int parse_tldrlist (char const *path, char const *platform); int print_localpage (char const *path); /* utils.c */ @@ -77,6 +79,7 @@ double rround (double arg); int rm (char const *path, int options); int unzip (char const *path, char const *outpath); char const *gethome (void); +char const *getplatform (void); int sstrncat (char *dest, size_t *pos, size_t max, char const *src, size_t len); #endif /* TLDR_H */ diff --git a/src/utils.c b/src/utils.c index 10500c5..a839cde 100644 --- a/src/utils.c +++ b/src/utils.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -37,6 +38,22 @@ gethome(void) return homedir; } +char const * +getplatform(void) +{ + struct utsname sys; + uname(&sys); + + if (strcmp(sys.sysname, "Linux") == 0) + return "linux"; + else if (strcmp(sys.sysname, "Darwin") == 0) + return "osx"; + else if (strcmp(sys.sysname, "SunOS") == 0) + return "sunos"; + else + return "common"; +} + int sstrncat(char *dest, size_t *pos, size_t max, char const *src, size_t len) {