moving from gitlab

This commit is contained in:
2026-05-15 13:26:54 -04:00
commit 7391c21087
33 changed files with 2539 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
#include <stdio.h>
int main(int argc, char *argv[]) {
float temp;
char unit;
printf("Enter temp and unit (25.0 C) ");
scanf("%f %c", &temp, &unit);
if (unit == 'C' || unit == 'c') {
printf("%.2fC is ", temp);
temp = temp * (9.0 / 5.0) + 32.0;
printf("%.2fF\n", temp);
} else if (unit == 'F' || unit == 'f') {
printf("%.2fF is ", temp);
temp = (temp - 32.0) * 5.0 / 9.0;
printf("%.2fC\n", temp);
} else {
printf("Unknown temperature unit. Use C or F\n");
}
return 0;
}
+47
View File
@@ -0,0 +1,47 @@
#include <stdio.h> // output to terminal
#include <stdlib.h> // has our atoi method
long factorial(int n);
int main(int argc, char **argv) {
// get first to arguments passed
// very first is name of program
printf("argv[0]: %s\n", argv[0]);
// argv[0] = ./nameofexecutable
// argv[1] will be our value to caluclate factorial
if (argc < 2) {
printf("error: value to calculate factorial is missing");
printf("\tUsage: ./factorial 3\n\twhere 3 is the value to calculate\n");
return -1;
}
// convert our char * to an int
int n = atoi(argv[1]);
printf("Factorial of %d is %ld\n", n, factorial(n));
return 0;
}
// use recursion first time through?
// then maybe show a simple for loop
long factorial(int n) {
// factorial is annotated as N!
// example: 5! = 5 x 4 x 3 x 2 x 1
// 0! = 1
// so properties of math yada yada..
// we can: 5! = 1 x 2 x 3 x 4 x 5
// we can use a basic loop and go all the way up to n
long answer = 1;
for (int i = 1; i <= n; i++) {
// answer = answer * i;
answer *= i;
}
return answer;
if (n == 1)
return 1;
return n * factorial(n - 1);
}
+39
View File
@@ -0,0 +1,39 @@
#include <stdio.h>
FILE *openFile(const char *filename);
void catFile(FILE *file);
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("error: missing file\nusage: cat <filename>\n");
return -1;
}
FILE *file = openFile(argv[1]);
if (!file) {
printf("error: file (%s) not found\n", argv[1]);
return -2;
}
catFile(file);
fclose(file);
return 0;
}
FILE *openFile(const char *filename) {
FILE *file;
file = fopen(filename, "r");
return file;
}
void catFile(FILE *file) {
char buf[512];
while (fgets(buf, 512, file)) {
printf("%s", buf);
}
}
+42
View File
@@ -0,0 +1,42 @@
[Verse 1]
We're no strangers to love
You know the rules and so do I (Do I)
A full commitment's what I'm thinking of
You wouldn't get this from any other guy
[Pre-Chorus]
I just wanna tell you how I'm feeling
Gotta make you understand
[Chorus]
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
[Verse 2]
We've known each other for so long
Your heart's been aching, but you're too shy to say it (To say it)
Inside, we both know what's been going on (Going on)
We know the game, and we're gonna play it
[Pre-Chorus]
And if you ask me how I'm feeling
Don't tell me you're too blind to see
[Chorus]
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
Never gonna give you up
Never gonna let you down
Never gonna run around and desert you
Never gonna make you cry
Never gonna say goodbye
Never gonna tell a lie and hurt you
+1000
View File
File diff suppressed because it is too large Load Diff
+72
View File
@@ -0,0 +1,72 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
unsigned int getSum(FILE *file);
char getFirstDigit(const char *line, size_t len);
char getLastDigit(const char *line, size_t len);
int main(int argc, char *argv[]) {
if (argc != 2) {
printf("error: missing file input\n");
return 1;
}
FILE *file = fopen(argv[1], "r");
if (file == NULL) {
printf("could not open file: %s\n", argv[1]);
return 1;
}
unsigned int sum = getSum(file);
printf("%d\n", sum);
fclose(file);
return 0;
}
unsigned int getSum(FILE *file) {
unsigned int sum = 0;
size_t len = 0;
size_t read;
char *line = NULL;
while ((read = getline(&line, &len, file)) != -1) {
printf("%s", line);
char first = getFirstDigit(line, read);
char last = getLastDigit(line, read);
printf("%c%c\n", first, last);
char digits[3] = {first, last, '\0'};
sum += atoi(digits);
}
free(line);
return sum;
}
char getFirstDigit(const char *line, size_t len) {
char digit;
for (int i = 0; i < len; i++) {
if (isdigit(line[i])) {
digit = (char)line[i];
break;
}
}
return digit;
}
char getLastDigit(const char *line, size_t len) {
char digit;
for (int i = len - 1; i >= 0; i--) {
if (isdigit(line[i])) {
digit = (char)line[i];
break;
}
}
return digit;
}
+4
View File
@@ -0,0 +1,4 @@
1abc2
pqr3stu8vwx
a1b2c3d4e5f
treb7uchet
+73
View File
@@ -0,0 +1,73 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
struct time {
unsigned int hours, minutes, seconds;
};
unsigned int timeToSeconds(struct time);
struct time secondsToTime(unsigned int);
void displayTime(unsigned int);
int main(int argc, char *argv[]) {
struct time t;
t.seconds = 0;
t.minutes = 0;
t.hours = 0;
char c;
if (argc == 1) {
printf("No time passed--using default: 1 min\n");
t.minutes = 1;
} else {
while ((c = getopt(argc, argv, "h:m:s:")) != -1) {
switch (c) {
case 'h':
t.hours = atoi(optarg);
break;
case 'm':
t.minutes = atoi(optarg);
break;
case 's':
t.seconds = atoi(optarg);
break;
}
}
}
unsigned int seconds = timeToSeconds(t);
while (seconds > 0) {
displayTime(seconds);
sleep(1);
seconds -= 1;
}
return 0;
}
unsigned int timeToSeconds(struct time t) {
unsigned int seconds = 0;
seconds = t.seconds;
seconds += t.minutes * 60;
seconds += t.hours * 60 * 60;
return seconds;
}
struct time secondsToTime(unsigned int seconds) {
struct time t;
t.hours = seconds / 3600;
t.minutes = (seconds - (3600 * t.hours)) / 60;
t.seconds = (seconds - (3600 * t.hours)) - (t.minutes * 60);
return t;
}
void displayTime(unsigned int seconds) {
system("clear");
struct time t = secondsToTime(seconds);
printf("%02d:%02d:%02d\n", t.hours, t.minutes, t.seconds);
}
+71
View File
@@ -0,0 +1,71 @@
#include <stdio.h>
#include <string.h>
void findreplace(char *str, const char *oldword, const char *newword);
int main(int argc, char *argv[]) {
// ./a.out filename oldWord newWord
if (argc != 4) {
printf("usage: %s filename oldword newword\n", argv[0]);
return 1;
}
char *filename = argv[1];
char *oldWord = argv[2];
char *newWord = argv[3];
if (!strcmp(oldWord, newWord)) {
printf("error: words are the same\n");
return 1;
}
FILE *file = fopen(filename, "r");
FILE *tmpf = fopen("tmp.txt", "w");
if (!file || !tmpf) {
printf("could not open files\n");
return 1;
}
size_t size = 256;
char buf[size];
// loop
while ((fgets(buf, size, file)) != NULL) {
//printf("%s", buf);
findreplace(buf, oldWord, newWord);
fputs(buf, tmpf);
}
fclose(file);
fclose(tmpf);
remove(filename);
rename("tmp.txt", filename);
return 0;
}
void findreplace(char *str, const char *oldword, const char *newword) {
char *pos, tmp[256];
int index = 0;
int oldLen = strlen(oldword);
while ((pos = strstr(str, oldword)) != NULL) {
strcpy(tmp, str);
index = pos - str;
str[index] = '\0';
strcat(str, newword);
strcat(str, tmp + index + oldLen);
}
}
+3
View File
@@ -0,0 +1,3 @@
Hello Thing
This is a text file about the Thing
This is my world
+9
View File
@@ -0,0 +1,9 @@
#include <stdlib.h>
#include <stdio.h>
//
int main(int argc, char *argv[]) {
return 0;
}
BIN
View File
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
create table Todos (
Id integer PRIMARY KEY NOT NULL,
Title varchar(128) NOT NULL,
Completed integer NOT NULL
);
insert into Todos values(NULL, 'code this app', 0);
insert into Todos values(NULL, 'finish this video', 0);
+241
View File
@@ -0,0 +1,241 @@
#include <sqlite3.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum ERR { OK, ERROR };
sqlite3 *setupDB();
enum ERR addTodo(sqlite3 *db);
enum ERR markComplete(sqlite3 *db);
enum ERR deleteTodo(sqlite3 *db);
enum ERR updateTodo(sqlite3 *db);
enum ERR listAll(sqlite3 *db);
int numberTodos(sqlite3 *db);
int completedTodos(sqlite3 *db);
void menu(sqlite3 *db);
int main(int argc, char **argv) {
sqlite3 *db = setupDB();
if (!db) {
return 1;
}
menu(db);
sqlite3_close(db);
return 0;
}
sqlite3 *setupDB() {
sqlite3 *db;
int rc = sqlite3_open("todo.db", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database %s\n", sqlite3_errmsg(db));
return NULL;
}
return db;
}
void menu(sqlite3 *db) {
printf("------------------------\n");
printf("T E R M I N A L T O D O\n\n");
char input;
int count, done;
while (1) {
if ((count = numberTodos(db)) == -1)
return;
if ((done = completedTodos(db)) == -1)
return;
printf("You currently have %d Todos.\n", count);
printf("You have completed %d Todos!\n\n", done);
printf("What would you like todo?\n");
printf("[A]dd, [L]ist, [C]omplete, [U]pdate, [R]emove, [Q]uit\n");
printf("> ");
input = getchar();
while (getchar() != '\n')
;
printf("\n");
enum ERR err;
switch (input) {
case 'A':
case 'a':
if ((err = addTodo(db)) == ERROR)
return;
break;
case 'L':
case 'l':
if ((err = listAll(db)) == ERROR)
return;
break;
case 'C':
case 'c':
if ((err = markComplete(db)) == ERROR)
return;
break;
case 'R':
case 'r':
if ((err = deleteTodo(db)) == ERROR)
return;
break;
case 'U':
case 'u':
if ((err = updateTodo(db)) == ERROR)
return;
break;
case 'Q':
case 'q':
printf("Thanks for using the TERMINAL TODO\nGoodbye.\n");
return;
}
}
}
enum ERR addTodo(sqlite3 *db) {
char todo[128];
char sql[256];
printf("\tenter todo: ");
fgets(todo, sizeof(todo), stdin);
int loc = strcspn(todo, "\n");
todo[loc] = '\0';
sprintf(sql, "insert into Todos(Id, Title, Completed) values(NULL, '%s', 0);",
todo);
char *errMsg = 0;
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "Could not write to DB: %s\n", errMsg);
sqlite3_free(errMsg);
return ERROR;
}
return OK;
}
enum ERR markComplete(sqlite3 *db) {
char sql[256], mark[4];
char *errMsg = 0;
printf("\tenter id to mark complete: ");
fgets(mark, sizeof(mark), stdin);
int id = atoi(mark);
sprintf(sql, "update Todos set Completed=1 where id=%d;", id);
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "Could not Complete TODO: %s\n", errMsg);
sqlite3_free(errMsg);
return ERROR;
}
return OK;
}
enum ERR deleteTodo(sqlite3 *db) {
char sql[256], mark[4];
char *errMsg;
printf("\tenter id to delete: ");
fgets(mark, sizeof(mark), stdin);
int id = atoi(mark);
sprintf(sql, "delete from Todos where id=%d;", id);
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "Could not delete: %s\n", errMsg);
sqlite3_free(errMsg);
return ERROR;
}
return OK;
}
enum ERR updateTodo(sqlite3 *db) {
char sql[256], mark[4], todo[128];
char *errMsg;
printf("\tenter id to edit: ");
fgets(mark, sizeof(mark), stdin);
int id = atoi(mark);
printf("\tenter new title for Todo: ");
fgets(todo, sizeof(todo), stdin);
todo[strcspn(todo, "\n")] = '\0';
sprintf(sql, "update Todos set Title='%s' where Id=%d;", todo, id);
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "Could not update Todo: %s\n", errMsg);
sqlite3_free(errMsg);
return ERROR;
}
return OK;
}
enum ERR listAll(sqlite3 *db) {
sqlite3_stmt *stmt;
const char *sql = "select * from Todos;";
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "Could not read DB: %s\n", sqlite3_errmsg(db));
return ERROR;
}
printf("%-5s%-25s%s\n", "Id", "Todo", "Completed");
printf("------------------------------------------------\n");
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
int id = sqlite3_column_int(stmt, 0);
char *todo = (char *)sqlite3_column_text(stmt, 1);
if (!todo) {
todo = "NULL";
}
int completed = sqlite3_column_int(stmt, 2);
char *done = "done";
if (!completed) {
done = "not";
}
printf("%-5d%-25s%s\n", id, todo, done);
printf("------------------------------------------------\n");
}
return OK;
}
int numberTodos(sqlite3 *db) {
int count = 0;
sqlite3_stmt *stmt;
const char *sql = "select count(*) from Todos;";
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "Could not get count from db: %s\n", sqlite3_errmsg(db));
return -1;
}
while ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
count = sqlite3_column_int(stmt, 0);
}
return count;
}
int completedTodos(sqlite3 *db) {
int count = 0;
sqlite3_stmt *stmt;
const char *sql = "select * from Todos where Completed=1;";
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "could not get number of complete todos: %s\n",
sqlite3_errmsg(db));
return -1;
}
while ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
count++;
}
return count;
}
+20
View File
@@ -0,0 +1,20 @@
#include <stdio.h>
void arrayInfo(int *array, int len);
int main(int argc, char *argv[]) {
int arr[] = {0, 1, 1, 2, 3, 5, 8, 13};
arrayInfo(arr, 8);
return 0;
}
void arrayInfo(int *array, int len) {
for (int i = 0; i < len; i++) {
// printf("array[%d] is %d\n", i, *(array + i));
printf("addr %p: %d\n", &(*(array + i)), array[i]);
}
}
+130
View File
@@ -0,0 +1,130 @@
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
};
void append(struct Node *head, int data);
void printList(struct Node *head);
void insertAfter(struct Node *head, int key, int data);
void deleteLast(struct Node *head);
void deleteNode(struct Node *head, int key);
int main(int argc, char *argv[]) {
struct Node *head = (struct Node *)malloc(sizeof(struct Node));
printList(head);
append(head, 1);
append(head, 1);
append(head, 2);
append(head, 3);
append(head, 5);
append(head, 8);
insertAfter(head, 3, 6);
printList(head);
deleteLast(head);
printList(head);
deleteNode(head, 2);
printList(head);
deleteNode(head, 9);
return 0;
}
void append(struct Node *head, int data) {
struct Node *newNode, *prev, *current = head;
newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = data;
while (current) {
prev = current;
current = current->next;
}
prev->next = newNode;
newNode->next = current;
}
void printList(struct Node *head) {
struct Node *current = head->next;
if (!current) {
printf("error: nothing to print, list is empty\n");
return;
}
printf("head->");
while (current) {
printf("%i->", current->data);
current = current->next;
}
printf("END\n");
}
void insertAfter(struct Node *head, int key, int data) {
struct Node *current = head;
while (current) {
if (current->data == key)
break;
current = current->next;
}
if (!current) {
printf("error: could not insertAfter. current is NULL\n");
return;
}
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = current->next;
current->next = newNode;
}
void deleteLast(struct Node *head) {
if (!head->next) {
printf("error: list is empty nothing to delete\n");
return;
}
struct Node *prev = NULL, *current = head;
while (current->next) {
prev = current;
current = current->next;
}
prev->next = NULL;
free(current);
}
void deleteNode(struct Node *head, int key) {
int found = 0;
struct Node *prev = NULL, *current = head;
while (current->next) {
if (current->data == key) {
found = 1;
break;
}
prev = current;
current = current->next;
}
// check
if (!found) {
printf("error: node %i not in list, nothing to delete\n", key);
return;
}
//
prev->next = current->next;
free(current);
}
+44
View File
@@ -0,0 +1,44 @@
#include <stdio.h>
#include <stdlib.h>
#define size_of(arr) (sizeof(arr) / sizeof(*arr))
#define DEBUG(x, args...) \
fprintf(stderr, "ERROR: %s:%u\n" x, __FILE__, __LINE__, ##args)
void cleanup1() { printf("cleanup1\n"); }
void cleanup2() { printf("cleanup2\n"); }
void cleanup3() { printf("cleanup3\n"); }
int main(int argc, char *argv[]) {
atexit(cleanup1);
int i = 10;
// while (i --> 0) {
// printf("%d\n", i);
// }
while ((i--) > 0) {
printf("%d\n", i);
}
int array[200];
printf("array[200] len: %ld\n", size_of(array));
DEBUG("Our array should be 200! %ld\n", size_of(array));
atexit(cleanup2);
int num = 11;
//(num & 1) ? printf("odd\n") : printf("even\n");
char *res = (num & 1) ? "odd" : "even";
printf("%s\n", res);
// if (num & 1) {
// printf("odd\n");
// } else {
// printf("even\n");
// }
atexit(cleanup3);
int x = 5;
printf("%d >> 1 = %d\n", x, x >> 1);
printf("%d << 1 = %d\n", x, x << 1);
return 0;
}
+78
View File
@@ -0,0 +1,78 @@
#include "APIKey.h"
#include "cJSON/cJSON.h"
#include "request.h"
#include <stdio.h>
#include <string.h>
void parseWeather(const char *data);
int main(int argc, char *argv[]) {
request req;
response res;
simpleHttpInit(&req);
char url[256] = "https://api.openweathermap.org/data/2.5/"
"weather?lat=51.52&lon=-0.10&units=imperial&appid=";
strcat(url, API_KEY);
// req.url = "https://catfact.ninja/fact";
req.url = url;
error err = simpleHttpRequest(&req, &res, JSON, GET);
if (err != NO_ERROR) {
printf("error: %s\n", simpleHttpErrorString(err));
return 1;
}
if (res.code != 200) {
printf("response code %ld\n", res.code);
printf("response body:\n%s\n", res.body);
return 1;
}
parseWeather(res.body);
simpleHttpClose(&req, &res);
return 0;
}
void parseWeather(const char *data) {
cJSON *json = cJSON_Parse(data);
if (!json) {
const char *err = cJSON_GetErrorPtr();
if (err) {
printf("%s\n", err);
} else {
printf("error parsing JSON\n");
}
return;
}
const cJSON *weatherArray = NULL;
const cJSON *weather = NULL;
const cJSON *main = NULL;
const cJSON *temp = NULL;
weatherArray = cJSON_GetObjectItemCaseSensitive(json, "weather");
cJSON_ArrayForEach(weather, weatherArray) {
cJSON *description =
cJSON_GetObjectItemCaseSensitive(weather, "description");
if (!cJSON_IsString(description)) {
printf("error parsing description\n");
return;
}
printf("Weather description: %s\n", description->valuestring);
}
main = cJSON_GetObjectItemCaseSensitive(json, "main");
if (!main) {
printf("Error parsing main\n");
return;
}
temp = cJSON_GetObjectItemCaseSensitive(main, "temp");
if (!temp) {
printf("error parsing temp\n");
return;
}
printf("Temp: %.2f\n", temp->valuedouble);
}
+21
View File
@@ -0,0 +1,21 @@
#include <stdio.h>
#include <sys/ioctl.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
struct winsize win;
/*
* unsigned short ws_row
* unsinged short ws_col
* unsighed short ws_xpixel
* unsinged short ws_ypixel
*/
ioctl(STDOUT_FILENO, TIOCGWINSZ, &win);
printf("Lines: %d\n", win.ws_row);
printf("chars: %d\n", win.ws_col);
printf("xpixel: %d\n", win.ws_xpixel);
printf("ypixel: %d\n", win.ws_ypixel);
return 0;
}
+26
View File
@@ -0,0 +1,26 @@
#include <stdio.h>
int len(int *arr) {
printf("sizeof arr: %d\n", (sizeof arr));
return sizeof arr / sizeof arr[0];
}
void printArray(int *arr, int len) {
for (int i=0; i<len; i++) {
printf("arr[%d] : %d\n", i, arr[i]);
}
}
int main(int argc, char *argv[]) {
constexpr int SIZE = 5;
int arr[SIZE] = { 0 };
//printf("sizeof arr: %d\n", (sizeof arr));
//printf("sizeof int * %d\n", (sizeof(int *)));
//int len = sizeof arr / sizeof arr[0];
printf("len : %d\n", len(arr));
printArray(arr, SIZE);
return 0;
}
+31
View File
@@ -0,0 +1,31 @@
#include <stdio.h>
int main(int argc, char **argv) {
FILE *file = fopen("words.txt", "r");
if (!file) {
fprintf(stderr, "Error opening file");
return -1;
}
char buffer[256];
int lineCount = 0, wordCount = 0;
while (fgets(buffer, sizeof(buffer), file)) {
lineCount++;
if (buffer[0] == '\n')
continue;
for (int i = 0; buffer[i] != '\0'; i++) {
if (buffer[i] == ' ' || buffer[i] == '\n') {
wordCount++;
}
}
}
printf("Number of Lines: %d\n", lineCount);
printf("Number of Words: %d\n", wordCount);
fclose(file);
return 0;
}
+5
View File
@@ -0,0 +1,5 @@
hey this is a file with words in it
it has newlines and spaces
lets a program to figure out the number of lines and words.
+31
View File
@@ -0,0 +1,31 @@
#include "math.h"
int add(int x, int y) { return x + y; }
int subtract(int x, int y) { return x - y; }
double divide(int x, int y) {
if (y == 0)
return 0.0;
return (double)x / y;
}
int mulitply(int x, int y) { return x * y; }
int doubleVal(int x) { return x * 2; }
int power(int x, int p) {
int val = 1;
for (int i = 1; i <= p; i++) {
val *= x;
}
return val;
}
double squareRoot(int x) {
double sqrt, val;
sqrt = divide(x, 2);
val = 0;
while (sqrt != val) {
val = sqrt;
sqrt = (x / val + val) / 2;
}
return sqrt;
}
+8
View File
@@ -0,0 +1,8 @@
int add(int x, int y);
int subtract(int x, int y);
double divide(int x, int y);
int mulitply(int x, int y);
int doubleVal(int x);
int power(int x, int p);
double squareRoot(int x);
+57
View File
@@ -0,0 +1,57 @@
#include "math.h"
#include <criterion/alloc.h>
#include <criterion/criterion.h>
#include <criterion/internal/new_asserts.h>
#include <criterion/new/assert.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
Test(basic, test1) { cr_assert(1 == 1); }
Test(basic, test2) { cr_expect(2 == 2); }
void setup() { printf("setup!\n"); }
void teardown() { printf("teardown\n"); }
Test(basic, setup_teardown, .init = setup, .fini = teardown) {
cr_assert(true);
}
Test(basic, signal, .signal = SIGSEGV) {
int arr[2] = {1, 2};
arr[2] = 3;
}
Test(basic, noSignal) {
int arr[2] = {1, 2};
arr[2] = 3;
}
Test(basic, fail) { cr_fail("this test will always fail until.."); }
Test(basic, pass) { cr_skip("feature is not implemented"); }
struct thing {
int *param;
};
Test(basic, memory) {
struct thing thing1 = {.param = cr_malloc(sizeof(int))};
// run tests...
cr_free(thing1.param);
}
Test(math, add) { cr_assert(add(1, 1) == 2); }
Test(math, sub) { cr_assert(subtract(5, 10) == -5); }
Test(math, mulitpy) { cr_assert(mulitply(2, 3) == 6); }
Test(math, sqrt25) { cr_assert(squareRoot(25) == 5.0); }
Test(math, sqrt2) {
double res = squareRoot(2);
printf("sqrt2 == %.5f\n", res);
cr_assert(epsilon_eq(flt, res, 1.4142135, 0.00001));
}
+101
View File
@@ -0,0 +1,101 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#define BUFFER_SIZE 1024
#define PORT 9090
char *parseRoute(const char *route) {
if (strcmp(route, "home") == 0) {
return "./static/index.html";
} else if (strcmp(route, "about") == 0) {
return "./static/about.html";
} else if (strcmp(route, "favicon.ico") == 0) {
return "./static/favicon.ico";
} else {
return "./static/notFound.html";
}
}
void sendHtml(int *sock, const char *route) {
// open our html file
FILE *html = fopen(route, "r");
if (!html) {
perror("Error opening html file");
return;
}
char buf[BUFFER_SIZE] = {0};
size_t read = 0;
char *header = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
send(*sock, header, strlen(header), 0);
while ((read = fread(buf, sizeof(buf[0]), BUFFER_SIZE, html)) > 0) {
send(*sock, buf, read, 0);
}
fclose(html);
}
int main() {
int serverSocket;
if ((serverSocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
struct sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(PORT);
if (bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof serverAddr) <
0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(serverSocket, 5) < 0) {
perror("listen failed");
exit(EXIT_FAILURE);
}
printf("Server listening on port %d\n", PORT);
while (1) {
struct sockaddr_in clientAddr;
socklen_t clientAddr_len = sizeof clientAddr;
int *clientSocket = malloc(sizeof(int));
if ((*clientSocket = accept(serverSocket, (struct sockaddr *)&clientAddr,
&clientAddr_len)) < 0) {
perror("accept failed");
continue;
}
printf("Connected\n");
char recBuf[BUFFER_SIZE] = {0};
recv(*clientSocket, recBuf, BUFFER_SIZE, 0);
// printf("%s\n", recBuf);
char *token = recBuf + 5;
char *route = strtok(token, " ");
const char *file = parseRoute(route);
sendHtml(clientSocket, file);
close(*clientSocket);
printf("disconnected client.\n\n");
}
close(serverSocket);
return 0;
}
+8
View File
@@ -0,0 +1,8 @@
all:
$(CC) -Wall server.c db.c -O2 -std=c23 -lpthread -lsqlite3 -o server
debug:
$(CC) -Wall -g server.c db.c -O0 -std=c23 -lpthread -lsqlite3 -o serverDebug
clean:
$(RM) -rf server serverDebug
+72
View File
@@ -0,0 +1,72 @@
#include "db.h"
#include <string.h>
#include <stdio.h>
sqlite3 *initDB() {
sqlite3 *db;
int rc = sqlite3_open("jokes.db", &db);
if (rc != SQLITE_OK) {
fprintf(stderr, "Cannot open database %s\n", sqlite3_errmsg(db));
return NULL;
}
return db;
}
char *GetJoke(sqlite3 *db) {
sqlite3_stmt *stmt;
char *sql ="select joke from Jokes order by random() limit 1;";
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "Could not read DB: %s\n", sqlite3_errmsg(db));
return NULL;
}
if (sqlite3_step(stmt) == SQLITE_ROW) {
char *data = (char *)sqlite3_column_text(stmt, 0);
char *joke = strdup(data);
sqlite3_finalize(stmt);
sqlite3_close(db);
return joke;
}
return NULL;
}
bool DeleteJoke(sqlite3 *db, int id) {
char sql[64];
char *errMsg;
sprintf(sql, "delete from Jokes where id=%d;", id);
int rc = sqlite3_exec(db, sql, 0, 0, &errMsg);
if (rc != SQLITE_OK) {
fprintf(stderr, "Could not delete: %s\n", errMsg);
sqlite3_free(errMsg);
return false;
}
return true;
}
bool NewJoke(sqlite3 *db, char *data) {
return true;
}
int JokeCount(sqlite3 *db) {
int count = 0;
sqlite3_stmt *stmt;
const char *sql = "select count(*) from Jokes;";
int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
fprintf(stderr, "Could not get count from db: %s\n", sqlite3_errmsg(db));
return -1;
}
while ((rc = sqlite3_step(stmt)) != SQLITE_DONE) {
count = sqlite3_column_int(stmt, 0);
}
return count;
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef DB_H
#define DB_H
#include <sqlite3.h>
sqlite3 *initDB();
char *GetJoke(sqlite3 *db);
bool DeleteJoke(sqlite3 *db, int id);
bool NewJoke(sqlite3 *db, char *data);
int JokeCount(sqlite3 *db);
#endif // !DB_H
+12
View File
@@ -0,0 +1,12 @@
create table Jokes (
Id integer PRIMARY KEY NOT NULL,
Joke text NOT NULL
);
insert into Jokes values(NULL, '!false its funny because its true');
insert into Jokes values(NULL, 'The best thing about a Boolean is that even if you are wrong, you are only off by a bit.');
insert into Jokes values(NULL, 'javascript');
insert into Jokes values(NULL, 'If you listen to a UNIX shell, can you hear the C?');
insert into Jokes values(NULL, 'My code never has bugs — it just develops random undocumented features.');
insert into Jokes values(NULL, 'I dont always test my code, but when I do, I do it in production.');
+219
View File
@@ -0,0 +1,219 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include "db.h"
#define BUF_SIZE 512
#define MAX 10
#define PORT 9000
sqlite3 *db;
enum method_t {
GET, DELETE, POST
};
typedef struct client_t {
int sock;
} client_t;
typedef struct request_t {
enum method_t method;
int sock;
char *endPoint;
} request_t;
void *handleClient(void *client);
void parseRequest(int sock, char *req);
void getJoke(request_t request);
void deleteJoke(request_t request);
void newJoke(request_t request, char *data);
int main(int argc, char *argv[]) {
db = initDB();
if (!db) {
perror("error init db");
return -1;
}
int serverSock = 0, clientSock;
struct sockaddr_in serverAddr, clientAddr;
pthread_t threadID = 1;
serverSock = socket(AF_INET, SOCK_STREAM, 0);
if (serverSock < 0) {
perror("listen socket failed");
return -1;
}
int on = 1;
if (setsockopt(serverSock, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) {
perror("listen setsockopt failed");
return -1;
}
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
serverAddr.sin_port = htons(PORT);
if (bind(serverSock, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
perror("failed to bind");
}
if (listen(serverSock, MAX) < 0) {
perror("failed to listen");
}
while(true) {
socklen_t clientLen = sizeof(clientAddr);
if ((clientSock = accept(serverSock, (struct sockaddr *)&clientAddr, &clientLen)) < 0) {
perror("could not accept client");
continue;
}
client_t *c = (client_t *)malloc(sizeof(client_t));
c->sock = clientSock;
if ((pthread_create(&threadID, NULL, handleClient, (void *)c)) < 0) {
perror("Could not create pthread");
close(clientSock);
continue;
}
pthread_join(threadID, NULL);
free(c);
}
close(serverSock);
return 0;
}
void *handleClient(void *c) {
client_t *client = (client_t*)c;
if (!client) {
perror("could not create our client_t");
return NULL;
}
int read = 0;
char buf[BUF_SIZE];
if ((read = recv(client->sock, buf, BUF_SIZE, 0)) <= 0) {
perror("Client disconnected");
close(client->sock);
return NULL;
}
parseRequest(client->sock, buf);
close(client->sock);
return NULL;
}
void parseRequest(int sock, char *req) {
request_t httpReq;
httpReq.sock = sock;
char *lines[10];
char *token = NULL;
int i = 0;
token = strtok(req, "\n");
lines[i++] = token;
while (token) {
token = strtok(NULL, "\n");
lines[i++] = token;
}
char topLine[BUF_SIZE];
strcpy(topLine, lines[0]);
// POST, GET, DELETE
char *request = strtok(lines[0], " ");
if (strcmp(request, "POST") == 0) {
httpReq.method = POST;
} else if (strcmp(request, "GET") == 0) {
httpReq.method = GET;
} else if (strcmp(request, "DELETE") == 0) {
httpReq.method = DELETE;
}
int len = strlen(request);
request = topLine + len;
char *endPoint = strtok(request, " ");
httpReq.endPoint = endPoint;
if (httpReq.method == GET) {
getJoke(httpReq);
} else if (httpReq.method == DELETE) {
deleteJoke(httpReq);
} else if (httpReq.method == POST) {
newJoke(httpReq, lines[7]);
}
}
void getJoke(request_t request) {
char *joke = GetJoke(db);
if (joke) {
send(request.sock, joke, strlen(joke), 0);
} else {
char *msg = "error getting the joke";
send(request.sock, msg, strlen(msg), 0);
}
}
void deleteJoke(request_t request) {
// /joke/{id}
char *val = request.endPoint + 6;
int id = atoi(val);
if (DeleteJoke(db, id)) {
char msg[128];
sprintf(msg, "deleted joke %d\n", id);
send(request.sock, msg, strlen(msg), 0);
} else {
char *msg = "error deleting the joke";
send(request.sock, msg, strlen(msg), 0);
}
}
void newJoke(request_t request, char *data) {
char *joke = strtok(data, ":");
joke = strtok(NULL, ":");
int len = strlen(joke);
joke[len-1] = '\0';
if (NewJoke(db, joke)) {
char msg[256];
sprintf(msg, "created new joke %s\n", joke);
send(request.sock, msg, strlen(msg), 0);
} else {
char *msg = "error creating new joke";
send(request.sock, msg, strlen(msg), 0);
}
}
+18
View File
@@ -0,0 +1,18 @@
MIT No Attribution
Copyright 2024 Travis Avey
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+12
View File
@@ -0,0 +1,12 @@
# C Tutorials
## Description
These are from my video tutorials on youtube, you can find [here](https://www.youtube.com/@aveydotdev)
## Contributing
If you find a mistake feel free to make a correction!
## License
MIT