Compare commits
No commits in common. "29fbcca9874277757d19615ed15dc09afd288060" and "cfb2aaabef9fd6a2e9477b12978671bdd2473cb1" have entirely different histories.
29fbcca987
...
cfb2aaabef
8 changed files with 0 additions and 251 deletions
|
|
@ -1,94 +0,0 @@
|
||||||
#include <assert.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Pack header data into a byte.
|
|
||||||
* 3 bits are used for type (2^3 = 8 different types)
|
|
||||||
* 5 bits are used for length (2^5 = 32 max length, unit is up to you)
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
Ok = 0,
|
|
||||||
OversizedType,
|
|
||||||
OversizedLen,
|
|
||||||
} Result;
|
|
||||||
|
|
||||||
#define TYPE_LEN (4)
|
|
||||||
#define LEN (4)
|
|
||||||
|
|
||||||
Result msg_create_header(uint8_t type, uint8_t len, uint8_t *out);
|
|
||||||
void msg_parse_header(uint8_t header, uint8_t *type_out, uint8_t *len_out);
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
assert(TYPE_LEN + LEN <= 8);
|
|
||||||
uint8_t maxlen = (1 << LEN) - 1;
|
|
||||||
uint8_t maxtype = (1 << TYPE_LEN) - 1;
|
|
||||||
|
|
||||||
{
|
|
||||||
uint8_t hdr;
|
|
||||||
Result res = msg_create_header(3, 8, &hdr);
|
|
||||||
|
|
||||||
if (res == OversizedType)
|
|
||||||
printf("The type is out of range");
|
|
||||||
if (res == OversizedLen)
|
|
||||||
printf("The length is out of range");
|
|
||||||
|
|
||||||
printf("Header: 0x%02X\n", hdr);
|
|
||||||
printf("Error: %d\n", res);
|
|
||||||
|
|
||||||
uint8_t plen, ptype;
|
|
||||||
msg_parse_header(hdr, &ptype, &plen);
|
|
||||||
printf("Type: %d\n", ptype);
|
|
||||||
printf("Len: %d\n", plen);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
printf("Max len: %d\n", maxlen);
|
|
||||||
printf("Max type: %d\n", maxtype);
|
|
||||||
|
|
||||||
uint8_t hdr;
|
|
||||||
Result res = msg_create_header(maxtype, maxlen, &hdr);
|
|
||||||
assert(res == Ok);
|
|
||||||
|
|
||||||
uint8_t plen, ptype;
|
|
||||||
msg_parse_header(hdr, &ptype, &plen);
|
|
||||||
printf("plen: %d\n", plen);
|
|
||||||
printf("ptype: %d\n", ptype);
|
|
||||||
assert(ptype == maxtype);
|
|
||||||
assert(plen == maxlen);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 1000; i++) {
|
|
||||||
uint8_t len = arc4random() % maxlen;
|
|
||||||
uint8_t type = arc4random() % maxtype;
|
|
||||||
uint8_t hdr;
|
|
||||||
Result res = msg_create_header(type, len, &hdr);
|
|
||||||
assert(res == Ok);
|
|
||||||
|
|
||||||
uint8_t plen, ptype;
|
|
||||||
msg_parse_header(hdr, &ptype, &plen);
|
|
||||||
assert(ptype == type);
|
|
||||||
assert(plen == len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Result msg_create_header(uint8_t type, uint8_t len, uint8_t *out) {
|
|
||||||
if (type > (1 << TYPE_LEN) - 1)
|
|
||||||
return OversizedType;
|
|
||||||
|
|
||||||
if (len > (1 << LEN) - 1)
|
|
||||||
return OversizedLen;
|
|
||||||
|
|
||||||
*out = (type << LEN) | (len & (0xFF >> TYPE_LEN));
|
|
||||||
|
|
||||||
return Ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
void msg_parse_header(uint8_t header, uint8_t *type_out, uint8_t *len_out) {
|
|
||||||
*type_out = (header >> LEN) & ((1 << LEN) - 1);
|
|
||||||
*len_out = header & (0xFF >> TYPE_LEN);
|
|
||||||
}
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
CC = gcc
|
|
||||||
CFLAGS = -Wall -O2
|
|
||||||
|
|
||||||
TARGET = main.elf
|
|
||||||
SRC = main.c conf.c
|
|
||||||
|
|
||||||
#LDFLAGS =
|
|
||||||
|
|
||||||
$(TARGET): $(SRC)
|
|
||||||
@echo CC $@
|
|
||||||
@$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f $(TARGET)
|
|
||||||
|
|
@ -1,80 +0,0 @@
|
||||||
#include "conf.h"
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define MAX_LINE 256
|
|
||||||
#define MAX_VAL 128
|
|
||||||
|
|
||||||
/* Trim leading/trailing whitespace */
|
|
||||||
static char *trim(char *str) {
|
|
||||||
char *end;
|
|
||||||
|
|
||||||
while (isspace((unsigned char)*str)) str++;
|
|
||||||
if (*str == 0)
|
|
||||||
return str; // only spaces
|
|
||||||
|
|
||||||
end = str + strnlen(str, MAX_VAL) - 1;
|
|
||||||
|
|
||||||
while (end > str && isspace((unsigned char)*end)) end--;
|
|
||||||
end[1] = '\0';
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load INI-style config */
|
|
||||||
Config *config_load(const char *filename) {
|
|
||||||
FILE *f = fopen(filename, "r");
|
|
||||||
if (!f)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
Config *cfg = calloc(1, sizeof(Config));
|
|
||||||
char line[MAX_LINE];
|
|
||||||
|
|
||||||
while (fgets(line, sizeof(line), f)) {
|
|
||||||
char *s = trim(line);
|
|
||||||
|
|
||||||
// Skip empty or comment lines
|
|
||||||
if (*s == '\0' || *s == '#' || *s == ';')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
char *eq = strchr(s, '=');
|
|
||||||
if (!eq)
|
|
||||||
continue; // invalid line, skip
|
|
||||||
|
|
||||||
*eq = '\0';
|
|
||||||
char *key = trim(s);
|
|
||||||
char *val = trim(eq + 1);
|
|
||||||
|
|
||||||
ConfigEntry *entry = malloc(sizeof(ConfigEntry));
|
|
||||||
entry->key = strndup(key, MAX_VAL);
|
|
||||||
entry->value = strndup(val, MAX_VAL);
|
|
||||||
entry->next = cfg->head;
|
|
||||||
cfg->head = entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return cfg;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get value for a key */
|
|
||||||
const char *config_get(Config *cfg, const char *key) {
|
|
||||||
for (ConfigEntry *e = cfg->head; e; e = e->next) {
|
|
||||||
if (strncmp(e->key, key, MAX_VAL) == 0)
|
|
||||||
return e->value;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the config struct */
|
|
||||||
void config_free(Config *cfg) {
|
|
||||||
ConfigEntry *e = cfg->head;
|
|
||||||
while (e) {
|
|
||||||
ConfigEntry *next = e->next;
|
|
||||||
free(e->key);
|
|
||||||
free(e->value);
|
|
||||||
free(e);
|
|
||||||
e = next;
|
|
||||||
}
|
|
||||||
free(cfg);
|
|
||||||
}
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
typedef struct ConfigEntry {
|
|
||||||
char *key;
|
|
||||||
char *value;
|
|
||||||
struct ConfigEntry *next;
|
|
||||||
} ConfigEntry;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ConfigEntry *head;
|
|
||||||
} Config;
|
|
||||||
|
|
||||||
Config *config_load(const char *filename);
|
|
||||||
const char *config_get(Config *cfg, const char *key);
|
|
||||||
void config_free(Config *cfg);
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
# Example INI file
|
|
||||||
username = testuser
|
|
||||||
password = secret123
|
|
||||||
|
|
||||||
; comments work too
|
|
||||||
timeout = 30
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
# Example INI file
|
|
||||||
username = testuser ; inline
|
|
||||||
password = secret123 # Comment
|
|
||||||
|
|
||||||
; comments work too
|
|
||||||
[aa]
|
|
||||||
timeout = 30
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
#include "conf.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
// Example usage
|
|
||||||
int main(void) {
|
|
||||||
Config *cfg = config_load("config.ini");
|
|
||||||
if (!cfg) {
|
|
||||||
fprintf(stderr, "Failed to load config.ini\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *user = config_get(cfg, "username");
|
|
||||||
const char *pass = config_get(cfg, "password");
|
|
||||||
|
|
||||||
printf("Username: %s\n", user ? user : "(not set)");
|
|
||||||
printf("Password: %s\n", pass ? pass : "(not set)");
|
|
||||||
|
|
||||||
config_free(cfg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
17
winsz.c
17
winsz.c
|
|
@ -1,17 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct winsize w;
|
|
||||||
|
|
||||||
if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) == -1) {
|
|
||||||
perror("ioctl");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Rows (height): %d\n", w.ws_row);
|
|
||||||
printf("Cols (width): %d\n", w.ws_col);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue