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