sfeed_jsonfeed: rename to sfeed_json + a few tweaks - randomcrap - random crap programs of varying quality
 (HTM) git clone git://git.codemadness.org/randomcrap
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 9cb7a64e11a02f5fc05f1fd439fe5d7f9be99551
 (DIR) parent 2c74d5b3ae88411b316b99630f5864c3137ccce9
 (HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
       Date:   Mon, 10 Apr 2023 16:26:05 +0200
       
       sfeed_jsonfeed: rename to sfeed_json + a few tweaks
       
       Diffstat:
         A sfeed/sfeed_json.1                  |      48 +++++++++++++++++++++++++++++++
         A sfeed/sfeed_json.c                  |     171 +++++++++++++++++++++++++++++++
         D sfeed/sfeed_jsonfeed.1              |      42 -------------------------------
         D sfeed/sfeed_jsonfeed.c              |     171 -------------------------------
       
       4 files changed, 219 insertions(+), 213 deletions(-)
       ---
 (DIR) diff --git a/sfeed/sfeed_json.1 b/sfeed/sfeed_json.1
       @@ -0,0 +1,48 @@
       +.Dd March 8, 2023
       +.Dt SFEED_JSON 1
       +.Os
       +.Sh NAME
       +.Nm sfeed_json
       +.Nd format feed data to JSON Feed
       +.Sh SYNOPSIS
       +.Nm
       +.Op Ar
       +.Sh DESCRIPTION
       +.Nm
       +formats feed data (TSV) from
       +.Xr sfeed 1
       +from stdin or for each
       +.Ar file
       +to stdout as JSON Feed data.
       +If one or more
       +.Ar file
       +arguments are specified then the basename of the
       +.Ar file
       +is used as the feed name in the output.
       +If no
       +.Ar file
       +arguments are specified and so the data is read from stdin then the feed name
       +is empty.
       +If
       +.Nm
       +is reading from one or more
       +.Ar file
       +arguments it will prefix the entry title with "[feed name] ".
       +.Sh EXIT STATUS
       +.Ex -std
       +.Sh EXAMPLES
       +.Bd -literal
       +curl -s 'https://codemadness.org/atom.xml' | sfeed | sfeed_json
       +.Ed
       +.Sh SEE ALSO
       +.Xr sfeed 1 ,
       +.Xr sfeed_atom 1 ,
       +.Xr sfeed 5
       +.Sh STANDARDS
       +.Rs
       +.%T JSON Feed Version 1.1
       +.%U https://www.jsonfeed.org/version/1.1/
       +.%D Nov, 2022
       +.Re
       +.Sh AUTHORS
       +.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org
 (DIR) diff --git a/sfeed/sfeed_json.c b/sfeed/sfeed_json.c
       @@ -0,0 +1,171 @@
       +#include <stdio.h>
       +#include <stdlib.h>
       +#include <string.h>
       +#include <unistd.h>
       +
       +#include "util.h"
       +
       +static char *line;
       +static size_t linesize;
       +static int firstitem = 1;
       +
       +/* Unescape / decode fields printed by string_print_encoded() */
       +static void
       +printcontent(const char *s)
       +{
       +        for (; *s; s++) {
       +                switch (*s) {
       +                case '\\':
       +                        s++;
       +                        switch (*s) {
       +                        case 'n':  fputs("\\n",  stdout); break;
       +                        case '\\': fputs("\\\\", stdout); break;
       +                        case 't':  fputs("\\t",  stdout); break;
       +                        }
       +                        break; /* ignore invalid escape sequence */
       +                case '"': fputs("\\\"", stdout); break;
       +                default:
       +                        putchar(*s);
       +                        break;
       +                }
       +        }
       +}
       +
       +static void
       +printfield(const char *s)
       +{
       +        for (; *s; s++) {
       +                if (*s == '\\')
       +                        fputs("\\\\", stdout);
       +                else if (*s == '"')
       +                        fputs("\\\"", stdout);
       +                else
       +                        putchar(*s);
       +        }
       +}
       +
       +static void
       +printfeed(FILE *fp, const char *feedname)
       +{
       +        char *fields[FieldLast], timebuf[32];
       +        struct tm parsedtm, *tm;
       +        time_t parsedtime;
       +        ssize_t linelen;
       +        int ch;
       +        char *p, *s;
       +
       +        while ((linelen = getline(&line, &linesize, fp)) > 0 &&
       +               !ferror(stdout)) {
       +                if (line[linelen - 1] == '\n')
       +                        line[--linelen] = '\0';
       +                parseline(line, fields);
       +
       +                if (!firstitem)
       +                        fputs(",\n", stdout);
       +                firstitem = 0;
       +
       +                fputs("{\n\t\"id\": \"", stdout);
       +                printfield(fields[FieldId]);
       +                fputs("\"", stdout);
       +
       +                parsedtime = 0;
       +                if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) &&
       +                    (tm = gmtime_r(&parsedtime, &parsedtm)) &&
       +                    strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ", tm)) {
       +                        fputs(",\n\t\"date_published\": \"", stdout);
       +                        fputs(timebuf, stdout);
       +                        fputs("\"", stdout);
       +                }
       +
       +                fputs(",\n\t\"title\": \"", stdout);
       +                if (feedname[0]) {
       +                        fputs("[", stdout);
       +                        printfield(feedname);
       +                        fputs("] ", stdout);
       +                }
       +                printfield(fields[FieldTitle]);
       +                fputs("\"", stdout);
       +
       +                if (fields[FieldLink][0]) {
       +                        fputs(",\n\t\"url\": \"", stdout);
       +                        printfield(fields[FieldLink]);
       +                        fputs("\"", stdout);
       +                }
       +
       +                if (fields[FieldAuthor][0]) {
       +                        fputs(",\n\t\"authors\": [{\"name\": \"", stdout);
       +                        printfield(fields[FieldAuthor]);
       +                        fputs("\"}]", stdout);
       +                }
       +
       +                if (fields[FieldCategory][0]) {
       +                        fputs(",\n\t\"tags\": [", stdout);
       +
       +                        for (p = s = fields[FieldCategory]; ; s++) {
       +                                if (*s == '|' || *s == '\0') {
       +                                        if (p != fields[FieldCategory])
       +                                                fputs(", ", stdout);
       +                                        ch = *s;
       +                                        *s = '\0'; /* temporary NUL terminate */
       +                                        fputs("\"", stdout);
       +                                        printfield(p);
       +                                        fputs("\"", stdout);
       +                                        *s = ch; /* restore */
       +                                        p = s + 1;
       +                                }
       +                                if (*s == '\0')
       +                                        break;
       +                        }
       +                        fputs("]", stdout);
       +                }
       +
       +                if (fields[FieldEnclosure][0]) {
       +                        fputs(",\n\t\"attachments\": [{\"url:\": \"", stdout);
       +                        printfield(fields[FieldEnclosure]);
       +                        fputs("\"}]", stdout);
       +                }
       +
       +                if (!strcmp(fields[FieldContentType], "html"))
       +                        fputs(",\n\t\"content_html\": \"", stdout);
       +                else
       +                        fputs(",\n\t\"content_text\": \"", stdout);
       +                printcontent(fields[FieldContent]);
       +                fputs("\"\n}", stdout);
       +        }
       +}
       +
       +int
       +main(int argc, char *argv[])
       +{
       +        FILE *fp;
       +        char *name;
       +        int i;
       +
       +        if (pledge(argc == 1 ? "stdio" : "stdio rpath", NULL) == -1)
       +                err(1, "pledge");
       +
       +        fputs("{\n"
       +              "\"version\": \"https://jsonfeed.org/version/1.1\",\n"
       +              "\"title\": \"Newsfeed\",\n"
       +              "\"items\": [\n", stdout);
       +
       +        if (argc == 1) {
       +                printfeed(stdin, "");
       +                checkfileerror(stdin, "<stdin>", 'r');
       +        } else {
       +                for (i = 1; i < argc; i++) {
       +                        if (!(fp = fopen(argv[i], "r")))
       +                                err(1, "fopen: %s", argv[i]);
       +                        name = ((name = strrchr(argv[i], '/'))) ? name + 1 : argv[i];
       +                        printfeed(fp, name);
       +                        checkfileerror(fp, argv[i], 'r');
       +                        checkfileerror(stdout, "<stdout>", 'w');
       +                        fclose(fp);
       +                }
       +        }
       +        fputs("]\n}\n", stdout);
       +
       +        checkfileerror(stdout, "<stdout>", 'w');
       +
       +        return 0;
       +}
 (DIR) diff --git a/sfeed/sfeed_jsonfeed.1 b/sfeed/sfeed_jsonfeed.1
       @@ -1,42 +0,0 @@
       -.Dd March 8, 2023
       -.Dt SFEED_JSONFEED 1
       -.Os
       -.Sh NAME
       -.Nm sfeed_jsonfeed
       -.Nd format feed data to JSON Feed 1.1
       -.Sh SYNOPSIS
       -.Nm
       -.Op Ar
       -.Sh DESCRIPTION
       -.Nm
       -formats feed data (TSV) from
       -.Xr sfeed 1
       -from stdin or for each
       -.Ar file
       -to stdout as JSON Feed 1.1 data.
       -If one or more
       -.Ar file
       -arguments are specified then the basename of the
       -.Ar file
       -is used as the feed name in the output.
       -If no
       -.Ar file
       -arguments are specified and so the data is read from stdin then the feed name
       -is empty.
       -If
       -.Nm
       -is reading from one or more
       -.Ar file
       -arguments it will prefix the entry title with "[feed name] ".
       -.Sh EXIT STATUS
       -.Ex -std
       -.Sh EXAMPLES
       -.Bd -literal
       -curl -s 'https://codemadness.org/atom.xml' | sfeed | sfeed_jsonfeed
       -.Ed
       -.Sh SEE ALSO
       -.Xr sfeed 1 ,
       -.Xr sfeed_atom 1 ,
       -.Xr sfeed 5
       -.Sh AUTHORS
       -.An Hiltjo Posthuma Aq Mt hiltjo@codemadness.org
 (DIR) diff --git a/sfeed/sfeed_jsonfeed.c b/sfeed/sfeed_jsonfeed.c
       @@ -1,171 +0,0 @@
       -#include <stdio.h>
       -#include <stdlib.h>
       -#include <string.h>
       -#include <unistd.h>
       -
       -#include "util.h"
       -
       -static char *line;
       -static size_t linesize;
       -static int firstitem = 1;
       -
       -/* Unescape / decode fields printed by string_print_encoded() */
       -static void
       -printcontent(const char *s)
       -{
       -        for (; *s; s++) {
       -                switch (*s) {
       -                case '\\':
       -                        s++;
       -                        switch (*s) {
       -                        case 'n':  fputs("\\n",  stdout); break;
       -                        case '\\': fputs("\\\\", stdout); break;
       -                        case 't':  fputs("\\t",  stdout); break;
       -                        }
       -                        break; /* ignore invalid escape sequence */
       -                case '"':  fputs("\\\"", stdout); break;
       -                default:
       -                        putchar(*s);
       -                        break;
       -                }
       -        }
       -}
       -
       -static void
       -printfield(const char *s)
       -{
       -        for (; *s; s++) {
       -                if (*s == '\\')
       -                        fputs("\\\\", stdout);
       -                else if (*s == '"')
       -                        fputs("\\\"", stdout);
       -                else
       -                        putchar(*s);
       -        }
       -}
       -
       -static void
       -printfeed(FILE *fp, const char *feedname)
       -{
       -        char *fields[FieldLast], timebuf[32];
       -        struct tm parsedtm, *tm;
       -        time_t parsedtime;
       -        ssize_t linelen;
       -        int ch;
       -        char *p, *s;
       -
       -        while ((linelen = getline(&line, &linesize, fp)) > 0 &&
       -               !ferror(stdout)) {
       -                if (line[linelen - 1] == '\n')
       -                        line[--linelen] = '\0';
       -                parseline(line, fields);
       -
       -                if (!firstitem)
       -                        fputs(",\n", stdout);
       -                firstitem = 0;
       -
       -                fputs("{\n\t\"id\": \"", stdout);
       -                printfield(fields[FieldId]);
       -                fputs("\"", stdout);
       -
       -                parsedtime = 0;
       -                if (!strtotime(fields[FieldUnixTimestamp], &parsedtime) &&
       -                    (tm = gmtime_r(&parsedtime, &parsedtm)) &&
       -                    strftime(timebuf, sizeof(timebuf), "%Y-%m-%dT%H:%M:%SZ", tm)) {
       -                        fputs(",\n\t\"date_published\": \"", stdout);
       -                            fputs(timebuf, stdout);
       -                        fputs("\"", stdout);
       -                }
       -
       -                fputs(",\n\t\"title\": \"", stdout);
       -                if (feedname[0]) {
       -                        fputs("[", stdout);
       -                        printfield(feedname);
       -                        fputs("] ", stdout);
       -                }
       -                printfield(fields[FieldTitle]);
       -                fputs("\"", stdout);
       -
       -                if (fields[FieldLink][0]) {
       -                        fputs(",\n\t\"url\": \"", stdout);
       -                        printfield(fields[FieldLink]);
       -                        fputs("\"", stdout);
       -                }
       -
       -                if (fields[FieldAuthor][0]) {
       -                        fputs(",\n\t\"authors\": [{\"name\": \"", stdout);
       -                        printfield(fields[FieldAuthor]);
       -                        fputs("\"}]", stdout);
       -                }
       -
       -                if (fields[FieldCategory][0]) {
       -                        fputs(",\n\t\"tags\": [", stdout);
       -
       -                        for (p = s = fields[FieldCategory]; ; s++) {
       -                                if (*s == '|' || *s == '\0') {
       -                                        if (p != fields[FieldCategory])
       -                                                fputs(", ", stdout);
       -                                        ch = *s;
       -                                        *s = '\0'; /* temporary NUL terminate */
       -                                        fputs("\"", stdout);
       -                                        printfield(p);
       -                                        fputs("\"", stdout);
       -                                        *s = ch; /* restore */
       -                                        p = s + 1;
       -                                }
       -                                if (*s == '\0')
       -                                        break;
       -                        }
       -                        fputs("]", stdout);
       -                }
       -
       -                if (fields[FieldEnclosure][0]) {
       -                        fputs(",\n\t\"attachments\": [{\"url:\": \"", stdout);
       -                        printfield(fields[FieldEnclosure]);
       -                        fputs("\"}]", stdout);
       -                }
       -
       -                if (!strcmp(fields[FieldContentType], "html"))
       -                        fputs(",\n\t\"content_html\": \"", stdout);
       -                else
       -                        fputs(",\n\t\"content_text\": \"", stdout);
       -                printcontent(fields[FieldContent]);
       -                fputs("\"\n}", stdout);
       -        }
       -}
       -
       -int
       -main(int argc, char *argv[])
       -{
       -        FILE *fp;
       -        char *name;
       -        int i;
       -
       -        if (pledge(argc == 1 ? "stdio" : "stdio rpath", NULL) == -1)
       -                err(1, "pledge");
       -
       -        fputs("{\n"
       -              "\"version\": \"https://jsonfeed.org/version/1.1\",\n"
       -              "\"title\": \"sfeed to jsonfeed 1.1\",\n"
       -              "\"items\": [\n", stdout);
       -
       -        if (argc == 1) {
       -                printfeed(stdin, "");
       -                checkfileerror(stdin, "<stdin>", 'r');
       -        } else {
       -                for (i = 1; i < argc; i++) {
       -                        if (!(fp = fopen(argv[i], "r")))
       -                                err(1, "fopen: %s", argv[i]);
       -                        name = ((name = strrchr(argv[i], '/'))) ? name + 1 : argv[i];
       -                        printfeed(fp, name);
       -                        checkfileerror(fp, argv[i], 'r');
       -                        checkfileerror(stdout, "<stdout>", 'w');
       -                        fclose(fp);
       -                }
       -        }
       -        fputs("]\n}\n", stdout);
       -
       -        checkfileerror(stdout, "<stdout>", 'w');
       -
       -        return 0;
       -}