Adding src so far
This commit is contained in:
parent
6cf298cfea
commit
cf9e6955e8
88
.gitignore
vendored
88
.gitignore
vendored
|
@ -1,90 +1,12 @@
|
|||
# ---> C
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
build/
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
lib/
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# ---> C++
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
targets/
|
||||
|
||||
# ---> Gradle
|
||||
.gradle
|
||||
|
@ -120,9 +42,6 @@ gradle-app.setting
|
|||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Built Visual Studio Code Extensions
|
||||
*.vsix
|
||||
|
||||
# ---> Bazel
|
||||
# gitignore template for Bazel build system
|
||||
# website: https://bazel.build/
|
||||
|
@ -137,4 +56,3 @@ gradle-app.setting
|
|||
/.ijwb/
|
||||
/.aswb/
|
||||
/.clwb/
|
||||
|
||||
|
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"C_Cpp.default.cStandard": "c17"
|
||||
}
|
24
Makefile
Normal file
24
Makefile
Normal file
|
@ -0,0 +1,24 @@
|
|||
CFLAGS = -std=c17
|
||||
CPPFLAGS = -std=c++17
|
||||
APPS_DIR = ./apps
|
||||
TARGETS_DIR = ./targets
|
||||
OBJECTS_DIR = ./build
|
||||
LIBS_DIR = ./src
|
||||
INCLUDES = -I ./include
|
||||
TESTS_DIR = ./tests
|
||||
VPATH = $(TARGETS_DIR) $(OBJECTS_DIR) $(APPS_DIR) $(LIBS_DIR) $(TESTS_DIR)
|
||||
|
||||
main: main.c requests.o
|
||||
cc $(CFLAGS) $(INCLUDES) -lcurl $(APPS_DIR)/main.c $(LIBS_DIR)/requests.c -o $(TARGETS_DIR)/main
|
||||
|
||||
requests.o: requests.c
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c $(LIBS_DIR)/requests.c -o $(OBJECTS_DIR)/requests.o
|
||||
|
||||
test: test_requests
|
||||
$(TARGETS_DIR)/test_requests
|
||||
|
||||
test_requests: test_requests.cpp requests.o
|
||||
$(CXX) $(CPPFLAGS) $(INCLUDES) -lcurl -lgtest -lgtest_main $(TESTS_DIR)/test_requests.cpp $(OBJECTS_DIR)/requests.o -o $(TARGETS_DIR)/test_requests
|
||||
|
||||
clean:
|
||||
rm $(TARGETS_DIR)/* $(OBJECTS_DIR)/*
|
13
README.md
13
README.md
|
@ -1,3 +1,14 @@
|
|||
# c-rss
|
||||
|
||||
An RSS feed reader written in C
|
||||
An RSS feed reader written in C
|
||||
|
||||
I am re-learning C by writing an RSS feed reader from scratch. I plan on playing around with several build tools such as make, gradle, and bazel.
|
||||
|
||||
## Goals
|
||||
|
||||
* get better at C
|
||||
* get better at Makefiles
|
||||
* learn how to write gradle plugins
|
||||
* get better at SQL
|
||||
* compare make, gradle, and bazel
|
||||
* learn how to use gtest for C projects
|
||||
|
|
11
apps/main.c
Normal file
11
apps/main.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "requests.h"
|
||||
|
||||
int main(void) {
|
||||
printf("Hello, world!\n");
|
||||
requestInit();
|
||||
requestGet("https://google.com");
|
||||
requestCleanup();
|
||||
}
|
28
include/requests.h
Normal file
28
include/requests.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifndef __SHILLERBEN_REQUESTS__
|
||||
#define __SHILLERBEN_REQUESTS__
|
||||
|
||||
typedef struct GetRequestResult GetRequestResult;
|
||||
struct GetRequestResult {
|
||||
int errorCode;
|
||||
size_t size;
|
||||
size_t capacity;
|
||||
char *data;
|
||||
};
|
||||
|
||||
void requestsInit(void);
|
||||
void requestsCleanup(void);
|
||||
GetRequestResult requestGet(const char* url);
|
||||
|
||||
size_t _getRequestCb(char *buffer, size_t size, size_t nmemb, GetRequestResult *result);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
73
src/requests.c
Normal file
73
src/requests.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#include "requests.h"
|
||||
|
||||
void requestsInit(void) {
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
}
|
||||
|
||||
void requestsCleanup(void) {
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
GetRequestResult requestGet(const char* url) {
|
||||
printf("requestGet(%s)\n", url);
|
||||
|
||||
GetRequestResult result = {
|
||||
.errorCode = -1,
|
||||
.data = NULL,
|
||||
};
|
||||
|
||||
CURL *handle = curl_easy_init();
|
||||
CURLcode err;
|
||||
|
||||
err = curl_easy_setopt(handle, CURLOPT_URL, url);
|
||||
if (err) {
|
||||
printf("Failed to set url\n");
|
||||
return result;
|
||||
}
|
||||
err = curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, _getRequestCb);
|
||||
if (err) {
|
||||
printf("Failed to set callback function\n");
|
||||
return result;
|
||||
}
|
||||
err = curl_easy_setopt(handle, CURLOPT_WRITEDATA, &result);
|
||||
if (err) {
|
||||
printf("Failed to set callback data\n");
|
||||
return result;
|
||||
}
|
||||
result.errorCode = 0;
|
||||
result.size = 0;
|
||||
result.capacity = 1024;
|
||||
result.data = calloc(1024, sizeof(char));
|
||||
err = curl_easy_perform(handle);
|
||||
if (err) {
|
||||
printf("Error performing request\n");
|
||||
result.errorCode = -1;
|
||||
result.size = 0;
|
||||
free(result.data);
|
||||
result.data = NULL;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t _getRequestCb(char *buffer, size_t size, size_t nmemb, GetRequestResult *result) {
|
||||
size_t numBytes = size * nmemb;
|
||||
while (result->size + numBytes > result->capacity + 1 /*extra byte for null terminator*/) {
|
||||
size_t newCapacity = result->capacity * 2;
|
||||
char *newData = calloc(newCapacity, sizeof(char));
|
||||
memcpy(newData, result->data, result->size);
|
||||
free(result->data);
|
||||
result->data = newData;
|
||||
result->capacity = newCapacity;
|
||||
}
|
||||
memcpy(result->data + result->size, buffer, numBytes);
|
||||
result->size += numBytes;
|
||||
result->data[result->size] = '\0';
|
||||
return numBytes;
|
||||
}
|
16
tests/test_requests.cpp
Normal file
16
tests/test_requests.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include <string>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "requests.h"
|
||||
|
||||
TEST(RequestsTest, HttpsGetTest) {
|
||||
requestsInit();
|
||||
std::string expected = "<!DOCTYPE html>\n<html >\n<head><meta charset=\"utf-8\">\n<title>Ben Shiller</title>";
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
GetRequestResult result = requestGet("https://shillerben.com");
|
||||
// std::cout << "GET https://shillerben.com returned: " << result.data << '\n';
|
||||
ASSERT_EQ(strncmp(result.data, expected.c_str(), expected.size()), 0);
|
||||
free(result.data);
|
||||
}
|
||||
requestsCleanup();
|
||||
}
|
Loading…
Reference in New Issue
Block a user