]> git.armaanb.net Git - mmenu.git/blob - mmenu.c
Improve parsing and general program
[mmenu.git] / mmenu.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdbool.h>
4 #include <string.h>
5
6 #include <Xm/Text.h>
7 #include <curl/curl.h>
8
9 struct MemoryStruct {
10         char *memory;
11         size_t size;
12 };
13
14 static size_t
15 memback(void *contents, size_t size, size_t nmemb, void *userp)
16 {
17         size_t realsize = size * nmemb;
18         struct MemoryStruct *mem = (struct MemoryStruct *)userp;
19
20         char *ptr = realloc(mem->memory, mem->size + realsize + 1);
21         if(!ptr) {
22                 /* out of memory! */
23                 printf("not enough memory (realloc returned NULL)\n");
24                 return 0;
25         }
26
27         mem->memory = ptr;
28         memcpy(&(mem->memory[mem->size]), contents, realsize);
29         mem->size += realsize;
30         mem->memory[mem->size] = 0;
31
32         return realsize;
33 }
34
35 int
36 main(int argc, char *argv[])
37 {
38         // Get webpage
39         CURL *curl = curl_easy_init();
40         CURLcode res;
41
42         if (!curl) {
43                 fprintf(stderr, "ERROR: Failed to initialize cURL\n");
44                 exit(1);
45         }
46
47         struct MemoryStruct chunk;
48         chunk.memory = malloc(1);  // will be grown as needed by the realloc above
49         chunk.size = 0; // no data at this point
50
51         curl_easy_setopt(curl, CURLOPT_URL,
52                         "https://nobilis.nobles.edu/skyworld/castlemenu.php");
53         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, memback);
54         curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
55         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
56
57         printf("INFO: Fetching wepage\n");
58         res = curl_easy_perform(curl);
59
60         if (res != CURLE_OK) {
61                 fprintf(stderr,"ERROR: Could not fetch webpage\n%s\n",
62                                 curl_easy_strerror(res));
63                 exit(2);
64         }
65
66         curl_easy_cleanup(curl);
67
68         // Parse HTML
69         printf("INFO: Parsing HTML\n");
70         bool intag = false;
71         char *outp = (char *) malloc(strlen(chunk.memory) + 1); // TODO: Realloc?
72         strcpy(outp, "");
73
74         // Extract text from between HTML tags
75         for (int i = 345; i < strlen(chunk.memory); i++) {
76                 char c = chunk.memory[i];
77                 if (c == '<') intag = true;
78                 if (!intag) strncat(outp, &c, 1);
79                 if (c == '>') intag = false;
80         }
81
82         // Strip empty newlines
83         char *nl = (char *) malloc(strlen(outp));
84         strncpy(nl, "\0", 1);
85         for (int i = 0; i < strlen(outp) - 1; i++) {
86                 if (outp[i] == '\n' && outp[i+1] == '\n') i+=4;
87                 strncat(nl, &outp[i], 1);
88         }
89
90         // Initialize motif
91         Widget             toplevel;
92         XtAppContext       app;
93         Widget             text_w;
94         Arg                args[4];
95
96         XtSetLanguageProc (NULL, NULL, NULL);
97         toplevel = XtVaOpenApplication (&app, "Castle Menu", NULL, 0, &argc, argv,
98                         NULL, sessionShellWidgetClass, NULL);
99
100         // Set textbox settings
101         int n = 0;
102         XtSetArg(args[n], XmNvalue, nl);                    n++;
103         XtSetArg(args[n], XmNeditable, False);              n++;
104         XtSetArg(args[n], XmNcolumns, 80);                  n++;
105         XtSetArg(args[n], XmNcursorPositionVisible, False); n++;
106         text_w = XmCreateScrolledText(toplevel, "text", args, n);
107         free(outp);
108         free(nl);
109
110         // Display everything
111         XtManageChild(text_w);
112         XtRealizeWidget(toplevel);
113         XtAppMainLoop(app);
114 }