]> Nishi Git Mirror - clover.git/commitdiff
works
authornishi <nishi@cc13bd98-b292-b64a-ad22-c0789b689ca7>
Sun, 5 May 2024 07:37:08 +0000 (07:37 +0000)
committernishi <nishi@cc13bd98-b292-b64a-ad22-c0789b689ca7>
Sun, 5 May 2024 07:37:08 +0000 (07:37 +0000)
git-svn-id: file:///raid/svn-main/nishi-clover/trunk@7 cc13bd98-b292-b64a-ad22-c0789b689ca7

clover.c
clover.conf

index 1a7eea5303fdb6a4a16483312077caf19a4ba031..d323e8ecddcbc5df6f2d9c5b46972009f3934add 100644 (file)
--- a/clover.c
+++ b/clover.c
@@ -39,7 +39,7 @@
 
 #include <expat.h>
 
-#define CLOVER_VERSION "0.00"
+#define CLOVER_VERSION "1.0"
 
 char* concat_str(const char* str1, const char* str2) {
        char* r = malloc(strlen(str1) + strlen(str2) + 1);
@@ -66,6 +66,9 @@ char* dup_str(const char* str) {
 char* input_dir;
 char* output_dir;
 char* title;
+char* icon;
+char* http_path;
+char* static_dir;
 
 int parse_config(const char* path) {
        FILE* f = fopen(path, "r");
@@ -102,11 +105,26 @@ int parse_config(const char* path) {
                                        free(input_dir);
                                        input_dir = dup_str(str + i);
                                }
+                       } else if(strcmp(str, "static") == 0) {
+                               if(found) {
+                                       free(static_dir);
+                                       static_dir = dup_str(str + i);
+                               }
                        } else if(strcmp(str, "title") == 0) {
                                if(found) {
                                        free(title);
                                        title = dup_str(str + i);
                                }
+                       } else if(strcmp(str, "icon") == 0) {
+                               if(found) {
+                                       free(icon);
+                                       icon = dup_str(str + i);
+                               }
+                       } else if(strcmp(str, "http-path") == 0) {
+                               if(found) {
+                                       free(http_path);
+                                       http_path = dup_str(str + i);
+                               }
                        }
                        free(str);
                        str = malloc(1);
@@ -124,14 +142,33 @@ int parse_config(const char* path) {
 }
 
 int typearr[1024];
+int typearr2[1024];
 int depth;
+int depth2;
+
+enum TYPES { ELEM_NONE, ELEM_METADATA, ELEM_TITLE, ELEM_PAGE, ELEM_ICON, ELEM_SHORTDESC };
+
+char* page_title;
+char* page_data;
+char* page_icon;
+char* page_shortdesc;
+bool page_index;
 
-enum TYPES { ELEM_NONE, ELEM_METADATA, ELEM_TITLE, ELEM_PAGE };
+char* page_title2;
+char* page_data2;
+char* page_icon2;
+char* page_shortdesc2;
+bool page_index2;
+bool page_do_not_index2;
 
 static void XMLCALL xml_startelem(void* user_data, const XML_Char* el, const XML_Char* attr[]) {
+       typearr[depth] = ELEM_NONE;
        if(strcmp(el, "metadata") == 0) typearr[depth] = ELEM_METADATA;
        if(strcmp(el, "title") == 0) typearr[depth] = ELEM_TITLE;
        if(strcmp(el, "page") == 0) typearr[depth] = ELEM_PAGE;
+       if(strcmp(el, "icon") == 0) typearr[depth] = ELEM_ICON;
+       if(strcmp(el, "short-description") == 0) typearr[depth] = ELEM_SHORTDESC;
+       if(strcmp(el, "index") == 0) page_index = true;
        if(depth == 0 && typearr[depth] != ELEM_METADATA) {
                fprintf(stderr, "toplevel must be metadata\n");
                exit(1);
@@ -139,10 +176,25 @@ static void XMLCALL xml_startelem(void* user_data, const XML_Char* el, const XML
        depth++;
 }
 
+static void XMLCALL xml_startelem2(void* user_data, const XML_Char* el, const XML_Char* attr[]) {
+       typearr2[depth2] = ELEM_NONE;
+       if(strcmp(el, "metadata") == 0) typearr2[depth2] = ELEM_METADATA;
+       if(strcmp(el, "title") == 0) typearr2[depth2] = ELEM_TITLE;
+       if(strcmp(el, "page") == 0) typearr2[depth2] = ELEM_PAGE;
+       if(strcmp(el, "icon") == 0) typearr2[depth2] = ELEM_ICON;
+       if(strcmp(el, "index") == 0) page_index2 = true;
+       if(strcmp(el, "do-not-index") == 0) page_do_not_index2 = true;
+       if(strcmp(el, "short-description") == 0) typearr2[depth2] = ELEM_SHORTDESC;
+       if(depth2 == 0 && typearr2[depth2] != ELEM_METADATA) {
+               fprintf(stderr, "toplevel must be metadata\n");
+               exit(1);
+       }
+       depth2++;
+}
+
 static void XMLCALL xml_endelem(void* user_data, const XML_Char* el) { depth--; }
 
-char* page_title;
-char* page_data;
+static void XMLCALL xml_endelem2(void* user_data, const XML_Char* el) { depth2--; }
 
 static void XMLCALL xml_elemdata(void* user_data, const XML_Char* data, int data_size) {
        if(data_size > 0) {
@@ -165,16 +217,137 @@ static void XMLCALL xml_elemdata(void* user_data, const XML_Char* data, int data
                        } else {
                                page_data = dup_str(str);
                        }
+               } else if(typearr[depth - 1] == ELEM_ICON) {
+                       if(page_icon != NULL) {
+                               char* tmp = page_icon;
+                               page_icon = concat_str(tmp, str);
+                               free(tmp);
+                       } else {
+                               page_icon = dup_str(str);
+                       }
+               } else if(typearr[depth - 1] == ELEM_SHORTDESC) {
+                       if(page_shortdesc != NULL) {
+                               char* tmp = page_shortdesc;
+                               page_shortdesc = concat_str(tmp, str);
+                               free(tmp);
+                       } else {
+                               page_shortdesc = dup_str(str);
+                       }
                }
                free(str);
        }
 }
 
+static void XMLCALL xml_elemdata2(void* user_data, const XML_Char* data, int data_size) {
+       if(data_size > 0) {
+               char* str = malloc(data_size + 1);
+               memcpy(str, data, data_size);
+               str[data_size] = 0;
+               if(typearr2[depth2 - 1] == ELEM_TITLE) {
+                       if(page_title2 != NULL) {
+                               char* tmp = page_title2;
+                               page_title2 = concat_str(tmp, str);
+                               free(tmp);
+                       } else {
+                               page_title2 = dup_str(str);
+                       }
+               } else if(typearr2[depth2 - 1] == ELEM_PAGE) {
+                       if(page_data2 != NULL) {
+                               char* tmp = page_data2;
+                               page_data2 = concat_str(tmp, str);
+                               free(tmp);
+                       } else {
+                               page_data2 = dup_str(str);
+                       }
+               } else if(typearr2[depth2 - 1] == ELEM_ICON) {
+                       if(page_icon2 != NULL) {
+                               char* tmp = page_icon2;
+                               page_icon2 = concat_str(tmp, str);
+                               free(tmp);
+                       } else {
+                               page_icon2 = dup_str(str);
+                       }
+               } else if(typearr2[depth2 - 1] == ELEM_SHORTDESC) {
+                       if(page_shortdesc2 != NULL) {
+                               char* tmp = page_shortdesc2;
+                               page_shortdesc2 = concat_str(tmp, str);
+                               free(tmp);
+                       } else {
+                               page_shortdesc2 = dup_str(str);
+                       }
+               }
+               free(str);
+       }
+}
+
+void scan_and_print(FILE* f, const char* path, const char* http){
+       DIR* dir = opendir(path);
+       if(dir != NULL){
+               struct dirent* d;
+               while((d = readdir(dir)) != NULL){
+                       if(strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) continue;
+                       char* p = concat3_str(path, "/", d->d_name);
+                       struct stat s;
+                       if(stat(p, &s) == 0){
+                               if(S_ISDIR(s.st_mode)){
+                                       char* new_http = concat3_str(http, d->d_name, "/");
+                                       scan_and_print(f, p, new_http);
+                                       free(new_http);
+                               }else if(strcmp(d->d_name, "metadata.xml") == 0){
+                                       page_title2 = NULL;
+                                       page_data2 = NULL;
+                                       page_icon2 = NULL;
+                                       page_shortdesc2 = NULL;
+                                       page_do_not_index2 = false;
+                                       FILE* fp = fopen(p, "r");
+                                       XML_Parser sparser = XML_ParserCreate(NULL);
+                                       XML_SetElementHandler(sparser, xml_startelem2, xml_endelem2);
+                                       XML_SetCharacterDataHandler(sparser, xml_elemdata2);
+                                       if(fp != NULL){
+                                               char* buf = malloc(1024);
+                                               int done;
+                                               do{
+                                                       int len = fread(buf, 1, 1024, fp);
+                                                       done = len < 1024;
+                                                       if(XML_Parse(sparser, buf, len, done) == XML_STATUS_ERROR){
+                                                               break;
+                                                       }
+                                               }while(!done);
+                                               free(buf);
+                                               fclose(fp);
+                                       }
+                                       XML_ParserFree(sparser);
+                                       if(!page_do_not_index2){
+                                               fprintf(f, "<dt><a href=\"%s%s\">", http_path, http);
+                                               if(page_icon2 != NULL) fprintf(f, "<img src=\"/static/%s\">", page_icon2);
+                                               if(page_icon2 != NULL) fprintf(f, "</a> ");
+                                               if(page_title2 != NULL) fprintf(f, "<b>%s </b>", page_title2);
+                                               if(page_icon2 == NULL) fprintf(f, "</a>");
+                                               fprintf(f, "</dt>\n");
+                                               if(page_shortdesc2 != NULL){
+                                                       fprintf(f, "<dd>%s</dd>\n", page_shortdesc2);
+                                               }
+                                       }
+                                       if(page_title2 != NULL) free(page_title2);
+                                       if(page_data2 != NULL) free(page_data2);
+                                       if(page_icon2 != NULL) free(page_icon2);
+                                       if(page_shortdesc2 != NULL) free(page_shortdesc2);
+                               }
+                       }
+                       free(p);
+               }
+               closedir(dir);
+       }
+}
+
 int parse_xml(const char* xml, const char* outdir) {
        printf("%s...\n", xml);
        depth = 0;
        page_title = NULL;
        page_data = NULL;
+       page_icon = NULL;
+       page_index = false;
+       page_shortdesc = NULL;
        XML_Parser parser = XML_ParserCreate(NULL);
        XML_SetElementHandler(parser, xml_startelem, xml_endelem);
        XML_SetCharacterDataHandler(parser, xml_elemdata);
@@ -212,8 +385,31 @@ int parse_xml(const char* xml, const char* outdir) {
                } else {
                        fprintf(f, "            <title>%s</title>\n", title);
                }
+               fprintf(f, "            <link rel=\"icon\" href=\"/static/%s\">\n", icon);
                fprintf(f, "    </head>\n");
                fprintf(f, "    <body>\n");
+               fprintf(f, "            <a href=\"%s\"><img src=\"/static/%s\"></a>\n", http_path, icon);
+               if(page_icon != NULL){
+                       char* from_path = concat3_str(static_dir, "/", page_icon);
+                       char* to_path = concat3_str(output_dir, "/static/", page_icon);
+                       FILE* from = fopen(from_path, "rb");
+                       FILE* to = fopen(to_path, "wb");
+                       if(from != NULL){
+                               char* buf = malloc(1024);
+                               int done = 0;
+                               do{
+                                       int len = fread(buf, 1, 1024, from);
+                                       fwrite(buf, 1, len, to);
+                                       done = len < 1024;
+                               }while(!done);
+                               free(buf);
+                               fclose(from);
+                       }
+                       fclose(to);
+                       free(from_path);
+                       free(to_path);
+                       fprintf(f, "            <img src=\"/static/%s\">\n", page_icon);
+               }
                if(page_title != NULL) {
                        fprintf(f, "            <h1>%s - %s</h1>\n", title, page_title);
                } else {
@@ -222,9 +418,15 @@ int parse_xml(const char* xml, const char* outdir) {
                if(page_data != NULL) {
                        fprintf(f, "%s\n", page_data);
                }
+               if(page_index){
+                       fprintf(f, "            <hr>\n");
+                       fprintf(f, "            <dl>\n");
+                       scan_and_print(f, input_dir, "");
+                       fprintf(f, "            </dl>\n");
+               }
                fprintf(f, "            <hr>\n");
                fprintf(f, "            <i>Last modified: %s</i><br>\n", lastmod);
-               fprintf(f, "            <i>Generated by Clover %s $Id$</i>\n", CLOVER_VERSION);
+               fprintf(f, "            <i>Generated by Clover %s</i>\n", CLOVER_VERSION);
                fprintf(f, "    </body>\n");
                fprintf(f, "</html>\n");
                fclose(f);
@@ -233,6 +435,8 @@ int parse_xml(const char* xml, const char* outdir) {
        free(html);
        if(page_title != NULL) free(page_title);
        if(page_data != NULL) free(page_data);
+       if(page_icon != NULL) free(page_icon);
+       if(page_shortdesc != NULL) free(page_shortdesc);
        return 0;
 }
 
@@ -270,6 +474,9 @@ int main(int argc, char** argv) {
        output_dir = dup_str("webroot");
        input_dir = dup_str("input");
        title = dup_str("Unnamed");
+       icon = dup_str("icon.png");
+       static_dir = dup_str("static");
+       http_path = dup_str("/");
        int r;
        if(argv[1] == NULL) {
                r = parse_config("clover.conf");
@@ -278,9 +485,33 @@ int main(int argc, char** argv) {
        }
        printf("Clover %s Copyright (c) 2024 Nishi\n", CLOVER_VERSION);
        printf("Using Expat %d.%d.%d\n", XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
-       printf(" Title: %s\n", title);
-       printf(" Input: %s\n", input_dir);
-       printf("Output: %s\n", output_dir);
+       printf("       Icon: %s\n", icon);
+       printf("      Title: %s\n", title);
+       printf("      Input: %s\n", input_dir);
+       printf("     Output: %s\n", output_dir);
+       printf("  HTTP Path: %s\n", http_path);
+       printf("Static Path: %s\n", static_dir);
+       char* staticp = concat_str(output_dir, "/static");
+       mkdir(staticp, 0775);
+       char* toicon = concat3_str(staticp, "/", icon);
+       FILE* ficon = fopen(toicon, "wb");
+       char* iconpath = concat3_str(static_dir, "/", icon);
+       FILE* from = fopen(iconpath, "rb");
+       if(from != NULL){
+               char* buf = malloc(1024);
+               int done = 0;
+               do{
+                       int len = fread(buf, 1, 1024, from);
+                       fwrite(buf, 1, len, ficon);
+                       done = len < 1024;
+               }while(!done);
+               free(buf);
+               fclose(from);
+       }
+       fclose(ficon);
+       free(toicon);
+       free(staticp);
+       free(iconpath);
        generate(input_dir, output_dir);
        if(r != 0) return r;
 }
index c6d40937999b36094de7ad9bb3297809b556b573..ed3b19c7d478d731a48514b6e7ed191f9c45c717 100644 (file)
@@ -1,4 +1,7 @@
 #comment
 title Example
 output webroot
+static static
 input example
+icon icon.gif
+http-path /