init here

This commit is contained in:
2025-11-26 21:32:41 +03:00
commit 33c97acade
91 changed files with 9155 additions and 0 deletions

46
си/pstruya.c Normal file
View File

@@ -0,0 +1,46 @@
#include "pstruya.h"
typedef struct {
struya_vnutr__TStruya routine;
TTagPair arg;
} tri_thread_launch_compound;
void* tri_thread_wrapper(void* arg) {
tri_thread_launch_compound* compound = (tri_thread_launch_compound*) arg;
compound->routine.func(compound->routine.receiver, compound->arg);
free(compound);
return NULL;
}
int64_t tri_thread_create(struya_vnutr__TStruya routine, TTagPair arg) {
pthread_t thread;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 512 * 1024);
tri_thread_launch_compound* compound = malloc(sizeof(tri_thread_launch_compound));
compound->routine = routine;
compound->arg = arg;
int result = pthread_create(&thread, &attr, tri_thread_wrapper, (void*) compound);
if (result != 0) {
return 0;
}
return (int64_t)(uintptr_t)thread;
}
void tri_thread_join(int64_t thread) {
if (!thread) return;
pthread_join((pthread_t)(uintptr_t)thread, NULL);
}
void tri_thread_detach(int64_t thread) {
if (!thread) return;
pthread_detach((pthread_t)(uintptr_t)thread);
}

14
си/pstruya.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef STRUYA_H
#define STRUYA_H
#include "rt_api.h"
#include "struya_vnutr.h"
#include <pthread.h>
#include <stdlib.h>
int64_t tri_thread_create(struya_vnutr__TStruya routine, TTagPair arg);
void tri_thread_join(int64_t thread);
void tri_thread_detach(int64_t thread);
#endif // STRUYA_H

160
си/sckulya.c Normal file
View File

@@ -0,0 +1,160 @@
#include "sckulya.h"
int64_t tri_sqlite_open(TString filename, TString *error) {
sqlite3* out_db = 0;
int rc = sqlite3_open((const char*) filename->body, &out_db);
if(rc != SQLITE_OK) {
if(out_db) {
sqlite3_close(out_db);
}
const char* msg = sqlite3_errmsg(out_db);
if(!msg) {
msg = "Unknown error";
}
int64_t len = (int64_t)strlen(msg);
*error = tri_newString(len, len, (char*)msg);
}
sqlite3_busy_timeout(out_db, 5000);
return (int64_t) out_db;
}
int tri_sqlite_close(int64_t db) {
if (!db) return SQLITE_MISUSE;
return sqlite3_close((sqlite3*) db);
}
void tri_sqlite_exec(int64_t db, TString query, TString *error) {
char* errmsg = NULL;
int rc = sqlite3_exec((sqlite3*) db, (const char*) query->body, NULL, NULL, &errmsg);
if (errmsg) {
int64_t len = (int64_t)strlen(errmsg);
*error = tri_newString(len, len, errmsg);
sqlite3_free(errmsg);
}
}
void escape_and_append (const unsigned char *s, char* buf, size_t* len) {
for (; *s; ++s) {
char esc = 0;
switch (*s) {
case '\\': esc = '\\'; break;
case '\b': esc = 'b'; break;
case '\f': esc = 'f'; break;
case '\n': esc = 'n'; break;
case '\r': esc = 'r'; break;
case '\t': esc = 't'; break;
default: break;
}
if (esc) {
buf[(*len)++] = '\\';
buf[(*len)++] = esc;
} else {
buf[(*len)++] = *s;
}
}
};
int tri_sqlite_query(int64_t db, TString query, TString *result, TString *error) {
sqlite3_stmt *stmt = NULL;
int rc = sqlite3_prepare_v2((sqlite3*)db, (const char*) query->body, -1, &stmt, NULL);
if (rc != SQLITE_OK) {
if (error) {
const char *msg = sqlite3_errmsg((sqlite3*)db);
if (!msg) msg = "Unknown error";
int64_t len = (int64_t)strlen(msg);
*error = tri_newString(len, len, (char*)msg);
}
return rc;
}
size_t cap = 1024;
size_t len = 0;
char *buf = malloc(cap);
if (!buf) {
sqlite3_finalize(stmt);
if (error) *error = tri_newString(0,0,"Out of memory");
return SQLITE_NOMEM;
}
buf[len++] = '[';
int first_row = 1;
while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
if (!first_row) { buf[len++] = ','; } else first_row = 0;
buf[len++] = '{';
int ncol = sqlite3_column_count(stmt);
for (int i = 0; i < ncol; ++i) {
if (i) { buf[len++] = ','; }
const char *colname = sqlite3_column_name(stmt, i);
/* "colname": */
// strlen(colname) + 4;
buf[len++] = '\"';
escape_and_append((const unsigned char*)colname, buf, &len);
buf[len++] = '\"';
buf[len++] = ':';
int type = sqlite3_column_type(stmt, i);
if (type == SQLITE_INTEGER) {
long long v = sqlite3_column_int64(stmt, i);
char tmp[32];
int n = snprintf(tmp, sizeof(tmp), "%lld", v);
memcpy(buf + len, tmp, n); len += n;
} else if (type == SQLITE_FLOAT) {
double v = sqlite3_column_double(stmt, i);
char tmp[64];
int n = snprintf(tmp, sizeof(tmp), "%g", v);
memcpy(buf + len, tmp, n); len += n;
} else if (type == SQLITE_NULL) {
memcpy(buf + len, "null", 4); len += 4;
} else {
const unsigned char *txt = sqlite3_column_text(stmt, i);
if (!txt) {
memcpy(buf + len, "null", 4); len += 4;
} else {
buf[len++] = '\"';
escape_and_append(txt, buf, &len);
buf[len++] = '\"';
}
}
}
buf[len++] = '}';
}
/* finalize and handle errors */
if (rc != SQLITE_DONE) {
const char *msg = sqlite3_errmsg((sqlite3*)db);
if (error) {
if (!msg) msg = "Unknown error";
int64_t mlen = (int64_t)strlen(msg);
*error = tri_newString(mlen, mlen, (char*)msg);
}
sqlite3_finalize(stmt);
free(buf);
return rc;
}
buf[len++] = ']';
buf[len] = '\0';
sqlite3_finalize(stmt);
if (result) {
*result = tri_newString((int64_t)len, (int64_t)len, buf);
}
free(buf);
return SQLITE_OK;
}

17
си/sckulya.h Normal file
View File

@@ -0,0 +1,17 @@
#ifndef SCKULYA_H
#define SCKULYA_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rt_api.h"
#include <sqlite3.h>
int64_t tri_sqlite_open(TString filename, TString *error);
int tri_sqlite_close(int64_t db);
void tri_sqlite_exec(int64_t db, TString query, TString *error);
int tri_sqlite_query(int64_t db, TString query, TString *result, TString *error);
#endif // SCKULYA_H

34
си/stdin.c Normal file
View File

@@ -0,0 +1,34 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "rt_api.h"
TString stdin_read_to_string(int bytes) {
if (bytes <= 0) {
return tri_newString(0, 0, "");
}
char* buffer = (char*)malloc((size_t)bytes + 1);
if (!buffer) {
return tri_newString(0, 0, "");
}
ssize_t bytes_read = read(0, buffer, (size_t)bytes);
if (bytes_read < 0) {
bytes_read = 0;
}
TString string = tri_newString((int64_t)bytes_read, (int64_t)bytes_read, buffer);
free(buffer);
return string;
}
// Writes TString data to STDERR (fd 2)
void stderr_write_string(TString data) {
if (!data) return;
char* datastring = (char*)data->body;
if (!datastring) return;
write(2, datastring, (size_t)strlen(datastring));
}

9
си/stdin.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef STDIN_H
#define STDIN_H
#include "rt_api.h"
TString stdin_read_to_string(int bytes);
void stderr_write_string(TString data);
#endif // STDIN_H

121
си/suckit.c Normal file
View File

@@ -0,0 +1,121 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "rt_api.h"
int create_socket_fd(int port) {
int server_fd;
struct sockaddr_in address;
int opt = 1;
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
perror("setsockopt SO_REUSEADDR");
exit(EXIT_FAILURE);
}
#ifdef SO_REUSEPORT
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)) < 0) {
perror("setsockopt SO_REUSEPORT");
exit(EXIT_FAILURE);
}
#endif
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
if (bind(server_fd, (struct sockaddr*)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
return server_fd;
}
int accept_socket(int fd) {
int server_fd = fd;
struct sockaddr_in client_addr;
socklen_t addrlen = sizeof(client_addr);
int new_socket = accept(server_fd, (struct sockaddr*)&client_addr, &addrlen);
if (new_socket < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
return new_socket;
}
void write_string(int socket, TString data) {
char* datastring = (char*) data->body;
write(socket, datastring, strlen(datastring));
}
void close_socket(int socket){
close(socket);
}
TString read_to_string(int socket, int bytes) {
char* buffer = malloc(bytes + 1);
int bytes_read = read(socket, buffer, bytes);
if(bytes_read < 0) {
bytes_read = 0;
}
TString string = tri_newString(bytes_read, bytes_read, buffer);
free(buffer);
return string;
}
int connect_socket(TString host, int port) {
char* chost = (char*) host->body;
struct addrinfo hints;
struct addrinfo* res = NULL;
char portstr[16];
snprintf(portstr, sizeof(portstr), "%d", port);
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
int gai = getaddrinfo(chost, portstr, &hints, &res);
if (gai != 0) {
perror("getaddrinfo");
return -1;
}
int sockfd = -1;
for (struct addrinfo* p = res; p != NULL; p = p->ai_next) {
sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
if (sockfd < 0) continue;
if (connect(sockfd, p->ai_addr, p->ai_addrlen) == 0) {
break; // connected
}
close(sockfd);
sockfd = -1;
}
freeaddrinfo(res);
return sockfd;
}

13
си/suckit.h Normal file
View File

@@ -0,0 +1,13 @@
#ifndef SUCKIT_H
#define SUCKIT_H
#include "rt_api.h"
int create_socket_fd(int port);
int accept_socket(int fd);
void write_string(int socket, TString data);
void close_socket(int socket);
TString read_to_string(int socket, int bytes);
int connect_socket(TString host, int port);
#endif // SUCKIT_H