]> git.armaanb.net Git - mmenu.git/blobdiff - mmenu.c
Rename MemoryStruct
[mmenu.git] / mmenu.c
diff --git a/mmenu.c b/mmenu.c
index bee2aae9e30291c284eff4a9da3ecf4b6ab0a2cd..fca9599b3bdcd64c58f807515e3f52cb1e1eca7e 100644 (file)
--- a/mmenu.c
+++ b/mmenu.c
@@ -1,50 +1,43 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdbool.h>
-#include <string.h>
 
 #include <Xm/Text.h>
 #include <curl/curl.h>
 
-struct MemoryStruct {
-  char *memory;
-  size_t size;
+struct memstruct {
+       char *memory;
+       size_t size;
 };
 
+int
+memfail(void)
+{
+       printf("ERROR: Out of memory\n");
+       exit(4);
+}
+
+
 static size_t
 memback(void *contents, size_t size, size_t nmemb, void *userp)
 {
-  size_t realsize = size * nmemb;
-  struct MemoryStruct *mem = (struct MemoryStruct *)userp;
-  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
-  if(!ptr) {
-    /* out of memory! */
-    printf("not enough memory (realloc returned NULL)\n");
-    return 0;
-  }
-  mem->memory = ptr;
-  memcpy(&(mem->memory[mem->size]), contents, realsize);
-  mem->size += realsize;
-  mem->memory[mem->size] = 0;
-  return realsize;
+       size_t realsize = size * nmemb;
+       struct memstruct *mem = (struct memstruct *)userp;
+
+       char *ptr = realloc(mem->memory, mem->size + realsize + 1);
+       if (!ptr) memfail();
+
+       mem->memory = ptr;
+       memcpy(&(mem->memory[mem->size]), contents, realsize);
+       mem->size += realsize;
+       mem->memory[mem->size] = 0;
+
+       return realsize;
 }
 
 int
 main(int argc, char *argv[])
 {
-       // Initialize motif
-       Widget             toplevel;
-       XtAppContext       app;
-       Widget             text_w;
-       Arg                args[2];
-
-       XtSetLanguageProc (NULL, NULL, NULL);
-       toplevel = XtVaOpenApplication (&app, "Castle Menu", NULL, 0, &argc, argv,
-                       NULL, sessionShellWidgetClass, NULL);
-
        // Get webpage
        CURL *curl = curl_easy_init();
        CURLcode res;
@@ -54,15 +47,15 @@ main(int argc, char *argv[])
                exit(1);
        }
 
-  struct MemoryStruct chunk;
-       chunk.memory = malloc(1);  /* will be grown as needed by the realloc above */
-       chunk.size = 0;    /* no data at this point */
+       struct memstruct chunk;
+       chunk.memory = malloc(1); // Grown as needed by the realloc in memback()
+       chunk.size = 0; // No data yet
 
        curl_easy_setopt(curl, CURLOPT_URL,
                        "https://nobilis.nobles.edu/skyworld/castlemenu.php");
-  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memback);
-  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
-  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+       curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memback);
+       curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+       curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
 
        printf("INFO: Fetching wepage\n");
        res = curl_easy_perform(curl);
@@ -74,40 +67,59 @@ main(int argc, char *argv[])
        }
 
        curl_easy_cleanup(curl);
-       
+
        // Parse HTML
        printf("INFO: Parsing HTML\n");
        bool intag = false;
-       char *outp = (char *) malloc(strlen(chunk.memory) + 1); // Realloc?
-       strcpy(outp, "");
-       for (int i = 345; i < strlen(chunk.memory); i++) {
+       char *outp = (char *) calloc(1, sizeof(char));
+       if (!outp) memfail();
+
+       // Extract text from between HTML tags
+       int j = 1;
+       for (int i = 345; (size_t)i < strlen(chunk.memory); i++) {
                char c = chunk.memory[i];
                if (c == '<') intag = true;
-               if (!intag) strncat(outp, &c, 1);
+               if (!intag) {
+                       j++;
+                       outp = (char *) realloc(outp, j);
+                       if (!outp) memfail();
+                       strncat(outp, &c, 1);
+               }
                if (c == '>') intag = false;
        }
-       strncat(outp, "\0", 1);
-
-       char *nl = outp;
-       strcpy(nl, "");
-       int old = 0;
-       /* for (int i = 0; i < 255; i++) { */
-       /*      if (old != 0 && i > 0) { */
-       /*              for (int j = old; j <= i; j++) { */
-       /*                      strncat(nl, outp, i - old); */
-       /*              } */
-       /*      } */
-       /*      if (outp[i] == '\n') */
-       /*              old = i; */
-       /* } */
-
-       // Display
+
+       // Strip empty newlines
+       char *nl = (char *) calloc(1, sizeof(char));
+       if (!nl) memfail();
+
+       for (int i = 0; (size_t)i < strlen(outp) - 1; i++) {
+               if (outp[i] == '\n' && outp[i+1] == '\n') i+=4;
+               nl = (char *) realloc(nl, i);
+               if (!nl) memfail();
+               strncat(nl, &outp[i], 1);
+       }
+
+       // Initialize motif
+       Widget       toplevel;
+       XtAppContext app;
+       Widget       text_w;
+       Arg          args[4];
+
+       XtSetLanguageProc(NULL, NULL, NULL);
+       toplevel = XtVaOpenApplication (&app, "Castle Menu", NULL, 0, &argc, argv,
+                       NULL, sessionShellWidgetClass, NULL);
+
+       // Set textbox settings
        int n = 0;
-       XtSetArg(args[0], XmNvalue, outp); n++;
-       XtSetArg(args[1], XmNeditable, False); n++;
-       text_w = XmCreateText(toplevel, "text", args, n);
+       XtSetArg(args[n], XmNvalue, nl);                    n++;
+       XtSetArg(args[n], XmNeditable, False);              n++;
+       XtSetArg(args[n], XmNcolumns, 80);                  n++;
+       XtSetArg(args[n], XmNcursorPositionVisible, False); n++;
+       text_w = XmCreateScrolledText(toplevel, "text", args, n);
        free(outp);
+       free(nl);
 
+       // Display everything
        XtManageChild(text_w);
        XtRealizeWidget(toplevel);
        XtAppMainLoop(app);