Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save 13m0n4de/f2b4b8e71ce6a93530cbe9e4e45cbe71 to your computer and use it in GitHub Desktop.
Save 13m0n4de/f2b4b8e71ce6a93530cbe9e4e45cbe71 to your computer and use it in GitHub Desktop.
Chibicc Patch Enabling File Inclusion via HTTPS using CURL
From 80dc44045e764fcd438971fde323f2207165f091 Mon Sep 17 00:00:00 2001
From: 13m0n4de <[email protected]>
Date: Sat, 17 Feb 2024 22:08:56 +0800
Subject: [PATCH] Make it possible to include files over https
---
Makefile | 2 +-
main.c | 7 +++++++
preprocess.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index c22748c..49b553d 100644
--- a/Makefile
+++ b/Makefile
@@ -9,7 +9,7 @@ TESTS=$(TEST_SRCS:.c=.exe)
# Stage 1
chibicc: $(OBJS)
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lcurl
$(OBJS): chibicc.h
diff --git a/main.c b/main.c
index ffaabf4..d850c56 100644
--- a/main.c
+++ b/main.c
@@ -1,4 +1,5 @@
#include "chibicc.h"
+#include <curl/curl.h>
typedef enum {
FILE_NONE, FILE_C, FILE_ASM, FILE_OBJ, FILE_AR, FILE_DSO,
@@ -702,6 +703,10 @@ int main(int argc, char **argv) {
init_macros();
parse_args(argc, argv);
+ if (curl_global_init(CURL_GLOBAL_DEFAULT) != 0) {
+ error("Could not initialize Global cURL context. (Yes, your C compiler is using curl Kappa)");
+ }
+
if (opt_cc1) {
add_default_include_paths(argv[0]);
cc1();
@@ -785,6 +790,8 @@ int main(int argc, char **argv) {
continue;
}
+ curl_global_cleanup();
+
if (ld_args.len > 0)
run_linker(&ld_args, opt_o ? opt_o : "a.out");
return 0;
diff --git a/preprocess.c b/preprocess.c
index 2bef487..66332d4 100644
--- a/preprocess.c
+++ b/preprocess.c
@@ -23,6 +23,7 @@
// https://github.com/rui314/chibicc/wiki/cpp.algo.pdf
#include "chibicc.h"
+#include <curl/curl.h>
typedef struct MacroParam MacroParam;
struct MacroParam {
@@ -861,6 +862,52 @@ static Token *preprocess2(Token *tok) {
bool is_dquote;
char *filename = read_include_filename(&tok, tok->next, &is_dquote);
+ // Hacked by https://github.com/13m0n4de
+ // Available to everyone under Public Domain
+ if (strncmp("https://", filename, 8) == 0 && is_dquote) {
+ CURLU *url = curl_url();
+ if (curl_url_set(url, CURLUPART_URL, filename, 0)) {
+ error("Could not parse the include URL '%s'", filename);
+ }
+
+ char *path;
+ if (curl_url_get(url, CURLUPART_PATH, &path, 0)) {
+ error("Could not extract path from the include URL '%s'", filename);
+ }
+
+ curl_url_cleanup(url);
+
+ char *dir = dirname(tok->filename);
+ char *base = basename(path);
+ char download_path[strlen(dir) + strlen(base) + 2];
+ sprintf(download_path, "%s/%s", dir, base);
+
+ curl_free(path);
+
+ CURL *curl = curl_easy_init();
+ if (curl == NULL) {
+ error("Could not initialize cURL context");
+ }
+
+ FILE *download_file = fopen(download_path, "w");
+ if (download_file == NULL) {
+ error("Could not open file '%s': %s", download_path, strerror(errno));
+ }
+
+ curl_easy_setopt(curl, CURLOPT_URL, filename);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, download_file);
+ CURLcode res = curl_easy_perform(curl);
+ if (res != CURLE_OK) {
+ error("Could not download '%s': %s", filename, curl_easy_strerror(res));
+ }
+
+ curl_easy_cleanup(curl);
+ fclose(download_file);
+
+ tok = include_file(tok, download_path, start->next->next);
+ continue;
+ }
+
if (filename[0] != '/' && is_dquote) {
char *path = format("%s/%s", dirname(strdup(start->file->name)), filename);
if (file_exists(path)) {
--
2.43.0
@13m0n4de
Copy link
Author

The idea comes from: youtube.com/watch?v=4vSyqK3SK-0
This is the patch made for TinyCC, as seen in the video: rexim/a6636976d12f67ea530ece118a700317
Here is my new patch designed to support the latest version of TinyCC: https://gist.github.com/13m0n4de/84912522cce6db31da069baf1add04f8

This patch does the same job, only it's for Chibicc instead.

@13m0n4de
Copy link
Author

In this patch, it's necessary to use double quotes to enclose the HTTPS links instead of angle brackets.
This is because when chibicc tokenizes, it treats "//" and everything following it as a comment and removes it.
However, when parsed as a string, there's no issue.

Example:

#define STB_SPRINTF_IMPLEMENTATION
#include "https://raw.githubusercontent.com/nothings/stb/master/stb_sprintf.h"
#include <stdio.h>

int main() {
    char buffer[20];

    // Using functions defined by stb_sprintf.h
    stbsp_sprintf(buffer, "Hello %s", "NAVI");
    puts(buffer);

    return 0;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment