betaur

A better AUR helper written in C
git clone git@nonplanar.org:betaur.git
Log | Files | Refs | README

commit 06fb984aacda08e8864df0d420163a00805b2d8c
Author: Bharatvaj Hemanth <bharatvaj@yahoo.com>
Date:   Fri, 27 Dec 2024 19:20:24 +0530

Brave New World

Diffstat:
A.gitignore | 3+++
AMakefile | 19+++++++++++++++++++
AREADME | 4++++
Aaur/package.h | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Aaur/request.c | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aaur/request.h | 43+++++++++++++++++++++++++++++++++++++++++++
Abetaur.c | 18++++++++++++++++++
Adependency.c | 77+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adependency.h | 37+++++++++++++++++++++++++++++++++++++
9 files changed, 304 insertions(+), 0 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -0,0 +1,3 @@ +betaur +*.o +tags diff --git a/Makefile b/Makefile @@ -0,0 +1,19 @@ +SRCS=dependency.c aur/request.c +HDRS=dependency.h aur/package.h +OBJS=$(SRCS:.c=.o) + +# TODO add pkg-config for libalpm +LDFLAGS=-lalpm +CFLAGS=-std=c99 -I. + +CC=gcc + +%.o: %.c %.h + $(CC) $(CFLAGS) -c -o $@ $< + +betaur: betaur.c ${OBJS} ${HDRS} + $(CC) $(LDFLAGS) betaur.c $(OBJS) -o $@ + +clean: + -rm *.o betaur + diff --git a/README b/README @@ -0,0 +1,4 @@ +betaur +====== + +A "better" aur helper writter in C99. diff --git a/aur/package.h b/aur/package.h @@ -0,0 +1,49 @@ +#ifndef __BETAUR_PACKAGE_H +#define __BETAUR_PACKAGE_H + +#include <time.h> + +typedef struct betaur_package { + char* name; + char* description; + char* maintainer; + char* pkgbase; + char* upstream_url; + char* aur_urlpath; + char* version; + + int package_id; + int pkgbase_id; + int votes; + double popularity; + + time_t out_of_date; + time_t submitted; + time_t modified; + + size_t conflicts_len; + char** conflicts; + size_t groups_len; + char** groups; + size_t licenses_len; + char** licenses; + size_t optdepends_len; + char** optdepends; + size_t replaces_len; + char** replaces; + size_t comaintainers_len; + char* comaintainers; + + size_t depends_len; + char** depends; + size_t makedepends_len; + char** makedepends; + size_t checkdepends_len; + char** checkdepends; +} betaur_package_t; + +inline bool betaur_package_equal(betaur_package_t* a, betaur_package_t* b) { + return a->package_id == b->package_id && a->pkgbase_id == b->pkgbase_id; +} + +#endif diff --git a/aur/request.c b/aur/request.c @@ -0,0 +1,54 @@ +#include <aur/request.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +betaur_searchby_t betaur_str_to_searchby(size_t searchby_len, const char* searchby) { +#define X(ENUM, STR) \ + if (searchby == #STR) \ + return ENUM; + + BETAUR_SEARCHBY_MAP(X) +#undef X + return BETAUR_INVALID; +} + +const char* betaur_searchby_to_str(betaur_searchby_t by) { + switch(by) { +#define X(ENUM, STR) \ + case ENUM: \ + return #STR; \ + break; + + BETAUR_SEARCHBY_MAP(X) +#undef X + default: + return ""; + } +} + + +bool betaur_http_search(betaur_searchby_t by, size_t arg_len, char* arg) { + // TODO stub: implement +#define BETAUR_SEARCH_API_STR "/rpc/v5/search/%.*s?by=%.*s" +#define BETAUR_SEARCH_API_LEN (sizeof(BETAUR_SEARCH_API_STR) - 8) + char* final_string; + const char* bystr = betaur_searchby_to_str(by); + size_t bystr_len = strlen(bystr); + size_t final_string_len = BETAUR_SEARCH_API_LEN + bystr_len + arg_len; + final_string = (char*) malloc(final_string_len); + + if( snprintf(final_string, final_string_len, BETAUR_SEARCH_API_STR, bystr_len, bystr, arg_len, arg) != final_string_len - 1) { + printf("FATAL: ERrro string not matching: %d\n", final_string_len); + return false; + // TODO throw error + } + final_string[final_string_len] = '\0'; + + // TODO call curl + + free(final_string); + return false; +} + +#undef BETAUR_SEARCHBY_MAP diff --git a/aur/request.h b/aur/request.h @@ -0,0 +1,43 @@ +#ifndef __AUR_REQUEST_H +#define __AUR_REQUEST_H + +#include <stddef.h> +#include <stdbool.h> + +/* Metadata fields */ +#define BETAUR_SEARCHBY_MAP(X) \ + X(BETAUR_INVALID, invalid) \ + X(BETAUR_NAME, name) \ + X(BETAUR_NAME_DESC, name-desc) \ + X(BETAUR_MAINTAINER, maintainer) \ + X(BETAUR_DEPENDS, depends) \ + X(BETAUR_MAKEDEPENDS, makedepends) \ + X(BETAUR_OPTDEPENDS, optdepends) \ + X(BETAUR_CHECKDEPENDS, checkdepends) \ + X(BETAUR_SUBMITTER, submitter) \ + X(BETAUR_PROVIDES, provides) \ + X(BETAUR_CONFLICTS, conflicts) \ + X(BETAUR_REPLACES, replaces) \ + X(BETAUR_KEYWORDS, keywords) \ + X(BETAUR_GROUPS, groups) \ + X(BETAUR_COMAINTAINERS, comaintainers) + +typedef enum { +#define X(ENUM, STR) ENUM, +BETAUR_SEARCHBY_MAP(X) +#undef X +} betaur_searchby_t; + +/* clone */ +char* betaur_clone_request_str(size_t baseurl_len, char* baseurl) { + char* clone_str = (char *) malloc(baseurl_len + clone_url_len + 1); + strcat(baseurl, reporname); +} + +/* info */ + +/* search */ +bool betaur_http_search(betaur_searchby_t by, size_t arg_len, char* arg); +betaur_searchby_t betaur_str_to_searchby(size_t searchby_len, const char* searchby); + +#endif diff --git a/betaur.c b/betaur.c @@ -0,0 +1,18 @@ +#include <stdio.h> +#include <string.h> +#include <assert.h> + +#include "dependency.h" +#include "aur/request.h" + +int main(int argc, char* argv[]) { + char* metadata_str = "pacman <= 0.2"; + + betaur_dependency_t* dep = betaur_dependency_create(strlen(metadata_str), metadata_str); + assert(dep != NULL); + printf("%.*s$\n", dep->name_len, dep->name); + printf("%.*s$\n", dep->version_len, dep->version); + + betaur_http_search(BETAUR_NAME, 6, "pacman"); + return 0; +} diff --git a/dependency.c b/dependency.c @@ -0,0 +1,77 @@ +#include <alpm.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "dependency.h" + +betaur_dependency_t* betaur_dependency_create(size_t depstring_len, char* depstring) { + betaur_dependency_t* bdep = (betaur_dependency_t *) malloc(sizeof(betaur_dependency_t)); + char* pos; + bdep->depstring = depstring; + bdep->name = depstring; + bdep->mod = BETAUR_ANY; + assert(bdep != NULL); + if (pos = strstr(depstring, "<=")) { + + bdep->mod = BETAUR_LE; + bdep->name_len = (size_t) (pos - depstring); + bdep->version = pos + 2; + bdep->version_len = (size_t) depstring_len - bdep->name_len - 2; + } else if (pos = strstr(depstring, ">=")) { + bdep->mod = BETAUR_GE; + bdep->name_len = (size_t) (pos - depstring); + bdep->version = pos + 2; + bdep->version_len = (size_t) depstring_len - bdep->name_len - 2; + } else { + for (pos = depstring; pos < (depstring + depstring_len); pos++) { + switch (*pos) { + case '<': + bdep->mod = BETAUR_LT; + break; + case '>': + bdep->mod = BETAUR_GT; + break; + case '=': + bdep->mod = BETAUR_EQ; + break; + } + } + if (bdep->mod != BETAUR_ANY) { + bdep->name_len = (size_t) (pos - depstring); + bdep->version = pos + 1; + bdep->version_len = (size_t) depstring_len - bdep->name_len - 1; + } else { + bdep->name = depstring; + } + } + + return bdep; +} + + +bool betaur_satisfied_by_version(betaur_dependency_t* bdep, const char* version) { + // FIXME we may need to make a copy here + // This will most probably crash when reading input from files + int vercmp = alpm_pkg_vercmp(version, bdep->version); + // TODO can't we just return vercmp??? hmmm... + switch(bdep->mod) { + case BETAUR_EQ: + return vercmp == 0; + case BETAUR_GE: + return vercmp >= 0; + case BETAUR_GT: + return vercmp > 0; + case BETAUR_LE: + return vercmp <= 0; + case BETAUR_LT: + return vercmp < 0; + default: + break; + } + return false; +} + +bool betaur_satisfied_by(betaur_package_t bpack) { + return false; +} diff --git a/dependency.h b/dependency.h @@ -0,0 +1,37 @@ +#ifndef __BETAUR_DEPENDENCY_H +#define __BETAUR_DEPENDENCY_H +#include <stddef.h> +#include <stdbool.h> + +#include "aur/package.h" + +typedef enum { + BETAUR_ANY, + BETAUR_EQ, + BETAUR_GE, + BETAUR_GT, + BETAUR_LE, + BETAUR_LT, +} betaur_mod; + +typedef struct betaur_dependency { + char* depstring; + size_t name_len; + char* name; + size_t version_len; + char* version; + betaur_mod mod; +} betaur_dependency_t; + +/* + * Create a memory that should be destroyed by the caller + * The returned struct is 'view' and does not create a memory for contents + * The input string should not have leading or trailing white spaces +*/ +betaur_dependency_t* betaur_dependency_create(size_t depstring_len, char* depstring); + +bool betaur_satisfied_by_version(betaur_dependency_t* bdep, const char* version); + +// TODO pass 'candidate' by reference as the parcel is huge +bool betaur_satisfied_by(betaur_package_t candidate); +#endif