1
0

backlog of changes from the uconsole

This commit is contained in:
dtb 2025-03-07 05:36:27 -07:00
parent 55bb27a1de
commit 9846c7ad27
50 changed files with 1207 additions and 726 deletions

View File

@ -15,6 +15,7 @@
* nybbles 4--|4--|4--|4--|4--|4--|
* bits 111111111111111111111111 */
#include <complex.h>
#if __STDC_VERSION__ >= 199901L
/* C99 type definitions */
# include <stdint.h>
@ -42,6 +43,7 @@ struct Intel4004_State {
Nybble acc; /* Accumulator */
Nybble reg[16]; /* R0 through RF */
Word pc[4]; /* PC0 through PC3 */
Word *cc; /* Current PC */
Byte *rom;
Byte *ram;
};
@ -117,11 +119,38 @@ enum Intel4004_Instruction {
/* INVALID 0xFF 0b 1111 1111 */
};
#define INTEL4004_THIS_OP (state->rom[*state->cc])
#define INTEL4004_NEXT_OP (state->rom[*state->cc + 1])
#define INTEL4004_INC_OP do{ ++*state->cc; }while(0)
#define INTEL4004_INC2_OP do{ *state->cc += 2; }while(0)
/* <http://e4004.szyc.org/>-style naming */
#define INTEL4004_PL (*state->cc & 0x00F)
#define INTEL4004_PM ((*state->cc & 0x0F0) >> 4)
#define INTEL4004_PH ((*state->cc & 0xF00) >> 8)
/* Also see the Intel MCS-4 Assembly Language Programming Manual (1973). */
/* From the datasheet. */
void Intel4004_RESET(struct Intel4004_State *state){
Nybble i;
state->carry = 0;
state->test = 0;
state->acc = 0;
for(i = 0; i <= (sizeof state->reg) / (sizeof *state->reg); ++i)
state->reg[i] = 0;
for(i = 0; i <= (sizeof state->pc) / (sizeof *state->pc); ++i)
state->pc[i] = 0;
state->cc = &state->pc[0];
return;
}
/* Does nothing. */
void Intel4004_NOP(struct Intel4004_State *state){ /* 0b 0000 0000 */
++*state->pc;
INTEL4004_INC_OP;
return;
}
@ -141,16 +170,16 @@ void Intel4004_NOP(struct Intel4004_State *state){ /* 0b 0000 0000 */
* If *state->pc & 0x08, a one test flag satisfies the condition. */
void Intel4004_JCN(struct Intel4004_State *state){ /* 0b 0001 CCCC */
*state->pc =
!INTEL4004_JCN_COND_ISINVERT(state->rom[*state->pc])
&& ( (INTEL4004_JCN_COND_ISACCZERO(state->rom[*state->pc])
*state->cc =
!INTEL4004_JCN_COND_ISINVERT(INTEL4004_THIS_OP)
&& ( (INTEL4004_JCN_COND_ISACCZERO(INTEL4004_THIS_OP)
&& state->acc == 0)
|| (INTEL4004_JCN_COND_ISCARRYON(state->rom[*state->pc])
|| (INTEL4004_JCN_COND_ISCARRYON(INTEL4004_THIS_OP)
&& state->carry == 1)
|| (INTEL4004_JCN_COND_ISTESTON(state->rom[*state->pc])
|| (INTEL4004_JCN_COND_ISTESTON(INTEL4004_THIS_OP)
&& state->test == 1))
? state->rom[*state->pc + 1]
: *state->pc + 2;
? state->rom[*state->cc + 1]
: *state->cc + 2;
return;
}
@ -166,14 +195,13 @@ void Intel4004_JCN(struct Intel4004_State *state){ /* 0b 0001 CCCC */
/* Fetches an immediate byte from ROM. */
void Intel4004_FIM(struct Intel4004_State *state){ /* 0b 0010 RRR0 */
state->reg[INTEL4004_REGPAIR(state->rom[*state->pc])]
= HIGH_NYBBLE(state->rom[*state->pc + 1]);
state->reg[INTEL4004_REGPAIR(INTEL4004_THIS_OP)]
= HIGH_NYBBLE(INTEL4004_NEXT_OP);
state->reg[INTEL4004_REGPAIR(state->rom[*state->pc]) + 1]
= LOW_NYBBLE(state->rom[*state->pc + 1]);
*state->pc += 2;
state->reg[INTEL4004_REGPAIR(INTEL4004_THIS_OP) + 1]
= LOW_NYBBLE(INTEL4004_NEXT_OP);
INTEL4004_INC2_OP;
return;
}
@ -182,3 +210,37 @@ void Intel4004_SRC(struct Intel4004_State *state){ /* 0b 0010 RRR1 */
void Intel4004_FIN(struct Intel4004_State *state){ /* 0b 0011 RRR0 */
}
/* Loads the immediate value in the low nybble of the opcode into the
* accumulator. */
void Intel4004_LDM(struct Intel4004_State *state){ /* 0b 1101 DDDD */
state->acc = LOW_NYBBLE(INTEL4004_THIS_OP);
INTEL4004_INC_OP;
return;
}
void Intel4004_BBL(struct Intel4004_State *state){ /* 0b 1100 DDDD */
/* <http://e4004.szyc.org/> lists 0b 1100 RRRR, most likely as a typo. I found
* 0b 1100 DDDD on the Intel 4004 datasheet. */
return Intel4004_LDM(state);
}
/* Clears the carry bit. */
void Intel4004_CLC(struct Intel4004_State *state){ /* 0b 1111 0001 */
state->carry = 0;
INTEL4004_INC_OP;
return;
}
/* Clears both the accumulator and the carry bit. */
void Intel4004_CLB(struct Intel4004_State *state){ /* 0b 1111 0000 */
state->acc = 0;
return Intel4004_CLC(state);
}

73
Wip/bitch/gtk4.c Normal file
View File

@ -0,0 +1,73 @@
#include <gtk/gtk.h>
#define BUF 100
static GtkApplication *app;
static void activate(GtkApplication *app, gpointer user_data);
static void button_pressed(GtkWidget *button, gpointer data);
static void
activate(GtkApplication *app, gpointer user_data){
GtkWidget *box;
GtkWidget *button;
int c;
char *s;
GtkWidget *scrolledwindow;
GtkWidget *window;
window = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(window), "Bitch");
gtk_window_set_default_size(GTK_WINDOW(window), h, v);
scrolledwindow = gtk_scrolled_window_new();
gtk_scrolled_window_set_overlay_scrolling(GTK_SCROLLED_WINDOW(scrolledwindow), 1);
gtk_window_set_child(GTK_WINDOW(window), scrolledwindow);
box = gtk_list_box_new();
//gtk_widget_set_halign(box, GTK_ALIGN_CENTER);
//gtk_widget_set_valign(box, GTK_ALIGN_CENTER);
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrolledwindow), box);
for(;;){
if(sip() == NULL)
break;
button = gtk_button_new_with_label(buf);
g_signal_connect(
button, "clicked", G_CALLBACK(button_pressed), NULL
);
gtk_list_box_insert(GTK_LIST_BOX(box), button, -1);
}
gtk_window_present(GTK_WINDOW(window));
return;
}
static void
button_pressed(GtkWidget *button, gpointer data){
switch(f){
case 'w':
g_print("%s\n", gtk_button_get_label(GTK_BUTTON(button)));
break;
case 'x':
system(gtk_button_get_label(GTK_BUTTON(button)));
break;
}
if(shy)
g_application_quit(G_APPLICATION(app));
return;
}
int setup(){
app = gtk_application_new(
"org.trinity.femaledog", G_APPLICATION_FLAGS_NONE
);
g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
status = g_application_run(G_APPLICATION(app), 1, fake_argv);
g_object_unref(app);
return status;
}

42
Wip/bitch/motif.c Normal file
View File

@ -0,0 +1,42 @@
#include <Xm/Xm.h>
#include <Xm/PushB.h>
static XtAppContext app_context;
static void activate(void);
static void button_pressed(
Widget w, XtPointer client_data, XmPushButtonCallbackStruct *cbs
);
void setup(void){
Widget button;
Widget top_wid;
top_wid = XtVaAppInitialize(
&app_context, "Bitch", NULL, 0, &fake_argc, fake_argv, NULL,
NULL
);
for(;;){
if(sip() == NULL)
break;
button = XmCreatePushButton(top_wid, buf, NULL, 0);
XtManageChild(button);
XtAddCallback(button, XmNactivateCallback, button_pressed, NULL);
}
XtRealizeWidget(top_wid);
XtAppMainLoop(app_context);
}
static void
button_pressed(
Widget w,
XtPointer client_data,
XmPushButtonCallbackStruct *cbs
){
printf("pressed\n");
if(shy)
XtAppSetExitFlag(app_context);
}

65
Wip/bitswap/bitswap.c Normal file
View File

@ -0,0 +1,65 @@
#include <stdio.h> /* fgetc(3), fprintf(3), fputc(3), stderr, stdin, stdout,
* EOF */
#include <sysexits.h> /* EX_OK, EX_USAGE */
#include <unistd.h> /* getopt(3) */
/* untested */
int
usage(char *argv0) {
(void)fprintf(stderr, "Usage: %s\n", argv0);
return EX_USAGE;
}
int main(int argc, char *argv[]){
int c;
{
int c;
while ((c = getopt(argc, argv, "")) != -1) {
switch (c) {
default: return usage(argv[0]);
}
}
}
#if 0
// Swapping algorithm: For example, say c is 0b0101_0101 */
// /* <<< <<<< */
// c <<= 7; /* Now 0b010_1010_1000_0000 */
// /* ^ >^ */
// c |= (c & (1 << 8)) >> 2; /* Now 0b010_1010_1000_0000 */
// /* ^> >>^ */
// c |= (c & (1 << 9)) >> 4; /* Now 0b010_1010_1010_0000 */
// /* ^>> >>>^ */
// c |= (c & (1 << 10)) >> 6; /* Now 0b010_1010_1010_0000 */
// /* ^>>> >>>> ^ */
// c |= (c & (1 << 11)) >> 8; /* Now 0b010_1010_1010_1000 */
// /* ^ >>>> >>>> >^ */
// c |= (c & (1 << 12)) >> 10; /* Now 0b010_1010_1010_1000 */
// /* ^> >>>> >>>> >>^ */
// c |= (c & (1 << 13)) >> 12; /* Now 0b010_1010_1010_1010 */
// /* ^>> >>>> >>>> >>>^ */
// c |= (c & (1 << 14)) >> 14; /* Now 0b010_1010_1010_1010 */
// /* & 0b000_0000_1111_1111 */
// c &= 0xFF; /* Now 0b1010_1010 */
#endif
{
int c;
int i;
while ((c = fgetc(stdin)) != EOF) {
for (c <<= 7, i = 8; i <= 14; ++i)
{ c |= (c & (1 << i)) >> ((i - 7) * 2); }
if (fputc(c, stdout) == EOF)
{ perror(argv[0]); return EX_IOERR; }
}
if (ferror(stdin) != 0) { perror(argv[0]); return EX_IOERR; }
}
return EX_OK;
}

View File

@ -1,55 +0,0 @@
int
isblank(int c){
return c == '\t'
|| c == ' ';
}
int
isspace(int c){
return isblank(c)
|| c == '\n'
|| c == '\v'
|| c == '\f'
|| c == '\r';
}
int
isgraph(int c){ return c >= '!' && c <= '~'; }
int
isprint(int c){ return c == ' ' || isgraph(c); }
int
iscntrl(int c){ return !isprint(c); }
int
isdigit(int c){ return c >= '0' && c <= '9'; }
int
islower(int c){ return c >= 'a' && c <= 'z'; }
int
isupper(int c){ return c >= 'A' && c <= 'Z'; }
int
isxdigit(int c){
return
isdigit(c)
|| (c >= 'a' && c <= 'f')
|| (c >= 'A' && c <= 'F');
}
int
isalpha(int c){ return islower(c) || isupper(c); }
int
isalnum(int c){ return isalpha(c) || isdigit(c) };
int
ispunct(int c){ return c != ' ' && !isalnum(c) };
int
tolower(int c){ return c - isupper(c) * ('A' - 'a'); }
int
toupper(int c){ return c + islower(c) * ('A' - 'a'); }

View File

@ -1,17 +0,0 @@
#ifndef _CTYPE_H
# define CTYPE_H
int isblank(int c);
int isspace(int c);
int isgraph(int c);
int isprint(int c);
int iscntrl(int c);
int isdigit(int c);
int islower(int c);
int isupper(int c);
int isxdigit(int c);
int isalpha(int c);
int isalnum(int c);
int ispunct(int c);
int tolower(int c);
int toupper(int c);
#endif /* ifndef _CTYPE_H */

View File

@ -1,53 +0,0 @@
char *
strchr(const char *s, int c){
char *r;
for(r = s; ; ++r){
if(*r == c)
return r;
if(*r == '\0')
return NULL;
}
}
char *
strrchr(const char *s, int c){
char *r;
char *p;
for(p = s, r = NULL; ; ++p){
if(*p == c)
r = p;
if(*p == '\0')
break;
}
return r;
}
char *
strchrnul(const char *s, int c){
char *r;
for(r = s; ; ++r)
if(*r == c || r == '\0')
return r;
}
size_t
strlen(const char *s){
size_t r;
for(r = 0; s[r] != '\0'; ++r);
return r;
}
size_t
strnlen(const char *s, size_t maxlen){
size_t r;
for(r = 0; s[r] != '\0' && r < maxlen; ++r);
return r;
}

View File

@ -1,8 +0,0 @@
#ifndef _STRING_H
# define _STRING_H
char * strchr(const char *s, int c);
char * strrchr(const char *s, int c);
char *strchrnul(const char *s, int c);
size_t strlen(const char *s);
size_t strnlen(const char *s, size_t maxlen);
#endif /* ifndef _STRING_H */

View File

@ -1,12 +1,26 @@
#include <stdio.h>
#include <stdio.h> /* fprintf(3), stderr */
#include <stdlib.h>
#include <unistd.h> /* getopt(3) */
/* The philosophical bits - /should this be a shell script?/ -
* are more complicated than the actual program. sed(1) is not currently a part
* of this project so there shouldn't be reliance on it. */
static int lines = 10; /* POSIX.1 */
static char *program_name = "head";
int main(int argc, char *argv[]){
char *argv0 = argv[0];
size_t i;
int c;
extern char *optarg;
extern int opterr, optind, optopt;
if(argc > 0)
program_name = argv[0];
while((c = getopt(argc, argv, "n:")) != -1)
switch(c){
case 'n':
break;
default:
#ifdef IGIT /* parse -[digit] options */
#endif /* ifdef IGIT */
usage: fprintf(stderr, "Usage: %s (-n [lines]) (file...)\n",
program_name);
return EX_USAGE;
}

View File

@ -9,3 +9,5 @@ def main(buffer, command):
except Exception as err:
print("%s" % str(err))
return buffer
bang = main

View File

@ -3,10 +3,7 @@ import sys
from buffer import Buffer
from get_command import get_command
def version():
print("it.py line editor; ALPHA 2021")
return None
#$
def main(buffer, supplied_command):
if supplied_command != [] and len(supplied_command) > 1:
command = supplied_command[1:]
@ -21,7 +18,8 @@ def main(buffer, supplied_command):
if command == []:
continue
if command[0] in buffer.modules.keys() or buffer.import_module_(command[0]):
if (command[0] in buffer.modules.keys()
or buffer.import_module_(command[0])):
buffer = buffer.modules[command[0]].main(buffer, command)
if type(buffer) is int:
break

View File

@ -3,57 +3,59 @@
char **
getpaths(void)
{
char *p;
char **q;
char *path;
size_t path_s;
char *path_temp;
char **paths;
size_t paths_s;
if((path_temp = getenv(PATH_NAME)) == NULL){
errno = ENOMEM; /* Cannot allocate memory */
return NULL;
{
char *path_temp;
size_t path_s;
if((path_temp = getenv(PATH_NAME)) == NULL)
goto bail;
/* How long is path? */
for(path_s = 0; path_temp[path_s] != '\0'; ++path_s);
/* path_s has the size of the path string, not including the null
* terminator */
/* getenv's return value mustn't be modified so copy it into memory we
* control */
if((path = malloc((sizeof *path) * (path_s + 1))) == NULL)
goto bail;
memcpy(path, path_temp, path_s + 1);
}
/* How long is path? */
for(path_s = 0; path_temp[path_s] != '\0'; ++path_s);
/* path_s has the size of the path string, not including the null
* terminator */
{
char *p;
char **q;
size_t paths_s;
/* getenv's return value mustn't be modified so copy it into memory we
* control */
if((path = malloc(sizeof(char) * (path_s + 1))) == NULL){
errno = ENOMEM; /* Cannot allocate memory */
return NULL;
}
memcpy(path, path_temp, path_s + 1);
path_temp = NULL;
path_s = 0; /* This shouldn't be necessary anymore */
/* How many paths in $PATH? */
for(paths_s = 1, p = path; *p != '\0'; paths_s += *p++ == PATH_DELIMITER);
/* How many paths in $PATH? */
for(paths_s = 1, p = path; *p != '\0'; paths_s += *p++ == PATH_DELIMITER);
if((paths = malloc((sizeof *paths) * (paths_s + 1))) == NULL)
goto bail1;
if((paths = malloc(sizeof(char *) * (paths_s + 1))) == NULL){
free(path);
errno = ENOMEM; /* Cannot allocate memory */
return NULL;
}
/* Replace all instances of the path delimiter with 0, and then put the
* next path beginning into paths. */
/* This way we can get multiple strings out of one span of memory. */
for(*paths = p = path, q = paths + 1; *p != '\0';)
if(*p++ == PATH_DELIMITER){
*(p - 1) = '\0';
*q++ = p;
}
/* Replace all instances of the path delimiter with 0, and then put the
* next path beginning into paths. */
/* This way we can get multiple strings out of one span of memory. */
for(*paths = p = path, q = paths + 1; *p != '\0';)
if(*p++ == PATH_DELIMITER){
*(p - 1) = '\0';
*q++ = p;
}
paths[path_s] = NULL;
paths[path_s] = NULL;
}
/* Because paths[0] will always be path, we can just free(*paths) at
* the end and discard path */
path = NULL;
return paths;
bail1: free(path);
bail: errno = ENOMEM; /* Cannot allocate memory */
return NULL;
}

102
Wip/lsd/Makefile Normal file
View File

@ -0,0 +1,102 @@
include hyperlinks.mk
all: fhs learn
fhs:
# Filesystem Hierarchy Standard 3.0, 2015
# https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.pdf
# section 3.2
mkdir -p "$(PREFIX)/bin"
mkdir -p "$(PREFIX)/boot"
mkdir -p "$(PREFIX)/dev"
mkdir -p "$(PREFIX)/etc"
mkdir -p "$(PREFIX)/lib"
mkdir -p "$(PREFIX)/media"
mkdir -p "$(PREFIX)/mnt"
mkdir -p "$(PREFIX)/opt"
mkdir -p "$(PREFIX)/run"
mkdir -p "$(PREFIX)/sbin"
mkdir -p "$(PREFIX)/srv"
mkdir -p "$(PREFIX)/tmp"
mkdir -p "$(PREFIX)/usr"
mkdir -p "$(PREFIX)/var"
# section 3.7.4
mkdir -p "$(PREFIX)/etc/opt"
# section 4.2
mkdir -p "$(PREFIX)/usr/bin"
mkdir -p "$(PREFIX)/usr/lib"
mkdir -p "$(PREFIX)/usr/local"
mkdir -p "$(PREFIX)/usr/sbin"
mkdir -p "$(PREFIX)/usr/share"
# section 4.3
mkdir -p "$(PREFIX)/usr/include"
mkdir -p "$(PREFIX)/var/spool"
mkdir -p "$(PREFIX)/var/tmp"
mkdir -p "$(PREFIX)/var/lock"
ln -s "$(PREFIX)/usr/spool" "$(PREFIX)/var/spool"
ln -s "$(PREFIX)/usr/tmp" "$(PREFIX)/var/tmp"
ln -s "$(PREFIX)/usr/spool/locks" "$(PREFIX)/var/lock"
# section 4.6
mkdir -p "$(PREFIX)/usr/lib"
# section 4.9
mkdir -p "$(PREFIX)/usr/local"
# section 4.9.2
mkdir -p "$(PREFIX)/usr/local/bin"
#mkdir -p "$(PREFIX)/usr/local/etc" # see section 4.9.3
mkdir -p "$(PREFIX)/usr/local/games"
mkdir -p "$(PREFIX)/usr/local/include"
mkdir -p "$(PREFIX)/usr/local/lib"
mkdir -p "$(PREFIX)/usr/local/man"
mkdir -p "$(PREFIX)/usr/local/sbin"
mkdir -p "$(PREFIX)/usr/local/share"
mkdir -p "$(PREFIX)/usr/local/src"
# section 4.9.3
ln -s "$(PREFIX)/usr/local/etc" "$(PREFIX)/etc/local"
# section 4.11.6
mkdir -p "$(PREFIX)/usr/share/man"
# section 4.11.7
mkdir -p "$(PREFIX)/usr/share/misc"
# section 4.12
mkdir -p "$(PREFIX)/usr/src"
# section 5.2
mkdir -p "$(PREFIX)/var/lib"
mkdir -p "$(PREFIX)/var/local"
mkdir -p "$(PREFIX)/var/log"
mkdir -p "$(PREFIX)/var/opt"
#mkdir -p "$(PREFIX)/var/run" # see section 5.13.2
# section 5.8.2
mkdir -p "$(PREFIX)/var/lib/misc"
# section 5.13.2
ln -s "$(PREFIX)/var/run" "$(PREFIX)/run"
# section 6.1.10
mkdir -p "$(PREFIX)/var/spool/cron"
$(PREFIX)/usr/src/linux: fhs
git clone "$(LINUX_UPSTREAM_GIT)" "$(PREFIX)/usr/src/linux.tmp"
mv "$(PREFIX)/usr/src/linux.tmp" "$(PREFIX)/usr/src/linux"
$(PREFIX)/usr/src/musl: fhs
git clone "$(MUSL_UPSTREAM_GIT)" "$(PREFIX)/usr/src/musl.tmp"
mv "$(PREFIX)/usr/src/musl.tmp" "$(PREFIX)/usr/src/musl"
musl: $(PREFIX)/usr/src/musl
cd "$(PREFIX)/usr/src/musl"
./configure --prefix="$(PREFIX)"
$(MAKE) install
.PHONY: all

4
Wip/lsd/hyperlinks.mk Normal file
View File

@ -0,0 +1,4 @@
GCC_UPSTREAM_GIT=git://gcc.gnu.org/git/gcc.git
LINUX_UPSTREAM_GIT=git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
MUSL_UPSTREAM_GIT=git://git.musl-libc.org/musl
PKGSRC_UPSTREAM_HTTPS=https://cdn.netbsd.org/pub/pkgsrc/current/pkgsrc.tar.xz

65
Wip/lsd/trilsd.7 Normal file
View File

@ -0,0 +1,65 @@
.TH TRINITX 7
.SH PRONUNCIATION
"Try LSD"
.SH SYNOPSIS
.I TriLSD
is a UNIX-like software distribution built upon the Linux kernel and the
musl C standard library, with nearly all configuration options left to the
user's own device.
.SH BASE SYSTEM
A
.I TriLSD
system always has the following packages:
dash,
the GNU compiler collection,
GNU make,
musl,
and
linux and util-linux.
.PP
In addition,
.I TriLSD
needs a core utilities package.
The GNU coreutils are a popular choice but Busybox or your own may be used.
.PP
.I TriLSD
also needs an initialization system.
OpenRC is the suggested choice but others may be used.
SystemD is discouraged; it's mentioned for its popularity and frowned upon for
its generally lax security.
.SH INSTALLATION
To install
.I TriLSD
most of the POSIX specified utilities including awk, git(1), GNU make, and a C
compiler that can build the GNU compiler collection must be installed.
.PP
For the installation process see
.RB try (1)
.SH PACKAGE MANAGEMENT
.I TriLSD
does not come with a package manager; the user may choose whatever
system-independent package manager they prefer.
.SH CONTRIBUTING
Pay attention to projects' guidelines for distributions.
.PP
musl guidelines: https://wiki.musl-libc.org/guidelines-for-distributions.html
.SH HISTORY
The
.I TriLSD
project was started 2021-12-28 as Trinitx.
.SH COPYRIGHT
.I TriLSD
documentation and all in-house tools are part of the public domain.
Components of the distribution are of course subject to their own licenses.
.SH SEE ALSO
.RB try (1)

8
Wip/rss/Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "rss"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@ -1,37 +0,0 @@
# pig\_birth
Initializes the pig.
# pig\_feed
Refreshes all the feed in the pigpen.
# pig\_fetch
Fetches the feed for the pigpen.
Not intended to be called on its own.
# pig\_latin
Prints internal pig details for a given feed file.
# pig\_name
Prints the file name for a given pig feed.
# pig\_pen
Prints the location of the pigpen, which houses all stowed pig feed.
A given feed will be stored as `"$(pig_pen)/$(pig_name)`.
# pig\_recall
Prints the contents of a given feed URL.
If the URL isn't already stowed, stows it before printing.
# pig\_stow
Stows fetched feed in the pigpen.

View File

@ -1,19 +0,0 @@
#!/bin/sh
set -e
argv0="$0"
depend(){
if ! command -v "$1" >/dev/null 2>&1; then
printf "%s: %s: Could not find dependency.\n" "$argv0" "$1" \
1>&2
exit 69 # sysexits(3) EX_UNAVAILABLE
fi
return 0
}
depend curl
depend jq
depend xq
mkdir "$(pig_pen)"

View File

@ -1,7 +0,0 @@
#!/bin/sh
for file in "$(pig_pen)"/*; do
pig_latin "$file" \
| jq '.feed_url' \
| xargs pig_stow &
done

View File

@ -1,3 +0,0 @@
#!/bin/sh
curl -so - -- "$1"

View File

@ -1,10 +0,0 @@
#!/bin/sh
while str isvalue "$1"; do
case "$1" in
*xml)
xq '.feed.pig' <"$1" ;;
*json)
jq '.feed.pig' <"$1" ;;
esac
done

View File

@ -1,4 +0,0 @@
#!/bin/sh
printf "%s\n" "$1" \
| tr -cd '[:alnum:]'

View File

@ -1,15 +0,0 @@
#!/bin/sh
set -e
str isvalue "$1" \
&& printf "Usage: %s\n" "$0" 1>&2 \
&& exit 64 \
|| str isvalue "$PIGPEN" \
&& printf "%s\n" "$PIGPEN" \
&& exit 0 \
|| str isvalue "$XDG_CONFIG_HOME" \
&& printf "%s\n" "$XDG_CONFIG_HOME" \
&& exit 0 \
|| printf "%s/.pigpen\n" "$HOME" \
&& exit 0 \
|| exit 1

View File

@ -1,7 +0,0 @@
#!/bin/sh
set -e
filename="$(pig_pen)/$(pig_name "$1")"
test -e "$filename" || pig_stow "$1"
cat "$filename"

View File

@ -1,18 +0,0 @@
#!/bin/sh
set -e
while str isvalue "$1"; do
pig_fetch "$1" | xq -x "$(
printf '.
* { feed: { pig: {
feed_url: "%b",
pet_sound: "oink",
stow_date: "%b",
version: "0"
} } }' "$1" "$(date '+%Y-%m-%dT%T')"\
| tr -d '[:space:]' \
)" >"$(pig_pen)/$(pig_name "$1")"
shift
done

9
Wip/rss/src/main.rs Normal file
View File

@ -0,0 +1,9 @@
use json;
fn feed() {
}
fn stow(title: String) {
}
fn main() {
}

View File

@ -1,182 +0,0 @@
#!/bin/sh
set -e
argv0="$0"
PIGPEN="$(pig_pen)"
latin(){
case "$1" in
*json) jq '.feed.pig' <"$1" ;;
*xml) xq '.feed.pig' <"$1" ;;
esac
}
list_channels(){
pscat \
[ sh -c "for file in \"$PIGPEN\"/*.xml; \
do xq '{(.feed.link[0].\"@href\"): .feed.title}' \"\$file\"; \
done 2>/dev/null" ] \
[ sh -c "for file in \"$PIGPEN\"/*.json; \
do jq '{(.feed.link[0].\"@href\"): .feed.title}' \"\$file\"; \
done 2>/dev/null" ] \
[ printf "\n" ] \
| sed \
-e '/{/d' \
-e '/}/d' \
-e 's/^ \"//g' \
-e 's/\": \"/ /g' \
-e 's/\,$//g' \
-e 's/\"$//g'
}
list_videos(){
file="$(printf "$PIGPEN"/$( \
list_channels \
| sed "/$1/q" \
| tail -n 1 \
| cut -f 1 \
| xargs pig_name \
)*)"
case "$file" in
*json)
jq \
'reduce .feed.entry[] as $item (
{};
. + { ($item.link."@href"): $item.title }
)' "$file"
;;
*xml)
xq \
'reduce .feed.entry[] as $item (
{};
. + { ($item.link."@href"): $item.title }
)' "$file"
;;
*)
printf "No file found!\n" 1>&2
true
;;
esac | sed \
-e '1d' \
-e '$d' \
-e 's/\": \"/ /g' \
-e 's/^ \"//g' \
-e 's/\,$//g' \
-e 's/\"$//g' # this is really hacky
}
stow(){
name="$PIGPEN/$(pig_name "$1")"
pig_fetch "$1" | xq "$(
date '+%Y-%m-%dT%T' \
| xargs printf '
. * { feed: { pig: {
feed_url: "%b",
pet_sound: "choo",
stow_date: "%b",
version: "0"
} } }' "$1" \
)" >"$name.json"
rm -f "$name.xml"
}
watch(){
youtube-dl -F "$1"
printf "Pick a format [22]: "
input="$(head -n 1 | tr -d '\n')"
str isalnum "$input" \
&& str isdigit $input \
|| input=22 \
&& youtube-dl -f $input "$1" -o - \
| mpv -
}
usage(){
printf "\
Usage: %s
list_channels
list_videos [channel name]
listen [video URL]
refresh (channel name...)
subscribe [channel URL...]
watch [video URL]
watch_latest [channel name]
" "$argv0" 1>&2
}
case "$1" in
list_channels)
! str isvalue "$2" \
|| usage
list_channels
;;
list_videos) # do something with youtube-dl?
list_videos "$2"
;;
listen)
str isvalue "$2" \
|| usage
while str isvalue "$2"
do youtube-dl "$2" -f bestaudio -o - \
| mpv -
shift
done
;;
refresh)
if ! str isvalue "$2"
then for file in "$PIGPEN"/*
do stow "$( \
latin "$file" \
| jq -r '.feed_url' \
)"
done
else
while str isvalue "$2"
do stow "$( \
latin "$( \
list_channels \
| grep "$2" \
| cut -f 2 \
)" | jq '.feed_url' \
)"
shift
done
fi
;;
subscribe)
str isvalue "$2" \
|| usage
while str isvalue "$2"
do stow "http://www.youtube.com/feeds/videos.xml?channel_id=$(
youtube-dl \
--get-filename \
--playlist-items 1 \
-o '%(channel_id)s' \
"$2" \
)"
shift
done
;;
watch) # needs work
str isvalue "$2" \
|| usage
while str isvalue "$2"
do watch "$2"
done
;;
watch_latest)
str isvalue "$2" \
|| usage
watch "$( \
list_videos "$2" \
| head -n 1 \
| cut -f 1 \
)"
;;
*) usage ;;
esac
exit 0

View File

@ -1,13 +1,8 @@
TARGETS = sysexits sysexits.h
CFLAGS = -I..
all: sysexits sysexits.h
all: $(TARGETS)
clean:
rm -f $(TARGETS)
%: %.c
$(CC) $(CFLAGS) -o $@ $@.c
sysexits: sysexits.c
sysexits.h: sysexits
./sysexits >sysexits.h
.PHONY: all

View File

@ -1,6 +1,5 @@
#include <stdio.h>
#include <unistd.h>
#include "arraylen.h"
/* Thanks to u/smcameron on Reddit. */
@ -12,7 +11,7 @@
* technicality.
* I implemented sysexits(3) in the enum method before reading the BSD 4.0
* source to see how they did it. */
#define ENUM 1
#define DEFINE 1
static char *program_name = "sysexits";

21
Wip/sysexits/sysexits.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _SYSEXITS_H
# define _SYSEXITS_H
enum{
EX_OK = 0,
EX_USAGE = 64,
EX_DATAERR = 65,
EX_NOINPUT = 66,
EX_NOUSER = 67,
EX_NOHOST = 68,
EX_UNAVAILABLE = 69,
EX_SOFTWARE = 70,
EX_OSERR = 71,
EX_OSFILE = 72,
EX_CANTCREAT = 73,
EX_IOERR = 74,
EX_TEMPFAIL = 75,
EX_PROTOCOL = 76,
EX_NOPERM = 77,
EX_CONFIG = 78
};
#endif /* ifndef _SYSEXITS_H */

View File

@ -1,3 +0,0 @@
- move executables somewhere in path
- `$ toki_update` to fetch dictionary
- `$ toki_sitelen` to tokiponize

View File

@ -1,5 +0,0 @@
#!/bin/sh
set -e
toki_ucsur "$@" | utf8

View File

@ -1,23 +1,22 @@
Comic Book Archives (CB7, CBR, CBZ)
<http://justsolve.archiveteam.org/wiki/Comic_Book_Archive>
<https://en.wikipedia.org/wiki/Comic_book_archive>
A Comic Book Archive is just an archive with a bunch of sequentially-named
images in it which collate ASCIIbetically to the order in which they should be
read. Each image corresponds to a page presented by a comic book reader and a
Comic Book Archive represents a digital comic book.
No guarantees can be made regarding image format, image names (though you can
expect them to match [:digit:]*\..*; that is, a bunch of numbers followed by a
file extension), archive attributes (compression or metadata), or what is in
archives besides the images. In fact, when a comic book only has one image, the
most common type of file in a comic book archive may not be an image at all.
No guarantees can be made regarding image format, image names, archive
attributes (compression or metadata), or what is in archives besides the
images. In fact, when a comic book only has one image, the most common type of
file in a comic book archive may not be an image at all.
The extension corresponds to what type of archive is being used. I haven't seen
an extension that hasn't fit within DOS 8.3, which makes sense as amateur
skiddies and repackers mostly use Windows.
<http://justsolve.archiveteam.org/wiki/Comic_Book_Archive>
<https://en.wikipedia.org/wiki/Comic_book_archive>
Here's a table of Comic Book Archive types. I can't imagine this list is
comprehensive but I can't find more on-line.
____________________
@ -32,10 +31,12 @@ comprehensive but I can't find more on-line.
I normalize the files I get to the following settings:
ARCHIVE: PKzip. DEFLATE algorithm. No other configuration.
ARCHIVE: PKzip. DEFLATE algorithm. No other configuration and no
subdirectories. ($ zip -jZ DEFLATE)
CONTENTS: ONLY images. Whatever encoding in which I found them.
Sequential naming starting from one, with leading zeroes to ensure file
names are all the same length.
names are all the same length. e.g. 5 pages are 1-5.ext, but 15 are
01-15.ext
<https://en.wikipedia.org/wiki/7-Zip>
7-Zip is free and open source. There are a number of implementations and you

View File

@ -1,6 +1,6 @@
#!/bin/sh
set -e
set -ex
usage(){
printf 'Usage: %s [files...]\n' "$0"
@ -22,9 +22,10 @@ else trap 'rm -rf "$d"; trap - EXIT; exit' EXIT INT HUP
fi
while test -n "$1"; do
unrar x -op"$d" "$1"
zip -jZ deflate "$1".cbz "$d"/*
rm "$d"/*
# unrar x -op"$d" "$1"
bsdtar xf "$1" -C "$d"
zip -jrZ deflate "$1".cbz "$d"/*
rm -r "$d"/*
shift
done

View File

@ -10,49 +10,79 @@ usage(){
test -n "$2" \
|| usage
d="$(mktemp -d || printf '%s/.cbzcat' "$HOME/")"
trap 'rm -rf "$d"; trap - EXIT; exit' EXIT INT HUP
mkdir -p "$d"/x
d="$(mktemp -d || printf '%s/.cbzcat\n' "$HOME/")"
if test -n "$DEBUG"; then
printf 'Using temporary directory %s\n' "$d"
set -x
else
trap 'rm -rf "$d"; trap - EXIT; exit' EXIT INT HUP
fi
i=1 # index
il=1 # index length in digits
parallel \
test -e {} \
::: "$@" \
|| usage
for f in "$@"; do
test -e "$f" \
|| usage
parallel --bar \
unzip -qqd "$d/"{#} {} \
::: "$@"
unzip -d "$d"/x "$f"
# num is created by the shell (parallel in this case) before the pipeline is
# run, so we have to compensate for it already being in the directory when the
# files are listed
parallel \
rm -f {}/*.xml \; \
ls {} \
\| grep -v \
-e '^num$' \
\| wc -l \
\>{}/num \; \
printf '0\\n' \
'>>'{}/prevs \; \
::: "$d"/*
rm -f "$d"/x/*.xml
parallel \
test {1/} -lt {2/} \
'&&' dd \
'<'{1}/num \
'>>'{2}/prevs \
'2>'/dev/null \
'||' true \
::: "$d"/* \
::: "$d"/*
for g in "$d"/x/*; do
# if there aren't enough leading zeroes
if ! printf '%s' "$i" \
| wc -c \
| xargs test "$il" =; then
for h in "$d"/*
do test "$h" = "$d"/x \
|| printf '%s\n' "$h" \
| sed 's|[^/]*$|0&|' \
| xargs mv "$h"
done
# update index digit length
il="$(printf '1 + %s\n' "$il" | bc)"
fi
parallel \
\<{}/prevs \
sed 's/\\$/ + /' \
\| tr -d '\n' \
\| sed 's/ + \\$//' \
\| bc \
\>{}/sum \
::: "$d"/*
# move file to indexed position
printf '%s\n' "$g" \
| sed 's|^.*\.||' \
| xargs printf '%s/%s%s\n' "$d" "$i". \
| xargs mv "$g"
false
# increment i
i="$(printf '1 + %s\n' "$i" | bc)"
done
done
parallel \
ls {}/../ \; \
parallel -I [] --arg-sep :::: \
test [] -lt {} \
'&&' '<'[]/num xargs \
printf '%s + ' \
:::: {}/../* \
\| sed 's| + $||' \
\| bc \
\>{}/prevs \
::: "$d"/*
rm -r "$d"/x
zip -Z deflate out.cbz "$d"/*
mkdir "$d"/0
false
parallel --dry-run sh -c "\
for dir in "
zip -Z deflate out.cbz "$d"/0/*
rm -r "$d"

View File

@ -27,19 +27,12 @@ CFLAGS = \
LDFLAGS = -L$(X11LIB) -lX11 $(XINERAMALIBS) $(FREETYPELIBS)
dmenubar: config.h dmenubar.o drw.h drw.o util.o
@echo dmenu build options:
@echo "CFLAGS = $(CFLAGS)"
@echo "LDFLAGS = $(LDFLAGS)"
@echo "CC = $(CC)"
dmenubar: dmenubar.o drw.h drw.o util.o
$(CC) -o $@ dmenubar.o drw.o util.o $(LDFLAGS)
.c.o:
$(CC) -c $(CFLAGS) $<
config.h:
cp config.def.h $@
clean:
rm -f dmenubar *.o

View File

@ -1,75 +1,76 @@
/* See LICENSE file for copyright and license details. */
/* This is a hack I did years ago. Fork dmenu and start from there if you can.
* ~ trinity */
#include <locale.h> /* setlocale(3), LC_CTYPE */
#include <stdio.h>
#include <stdlib.h>
#include <string.h> /* strlen(3) */
#include <stdio.h> /* fprintf(3), stderr */
#include <sysexits.h> /* EX_USAGE */
#include <unistd.h> /* getopt(3) */
#include <X11/Xlib.h>
#include <X11/Xlib.h> /* XSupportsLocale(3), Display, Window */
#include <X11/Xutil.h>
#ifdef XINERAMA
# include <X11/extensions/Xinerama.h>
#endif
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define INTERSECT(x,y,w,h,r) (MAX(0, MIN((x)+(w),(r).x_org+(r).width) - MAX((x),(r).x_org)) \
* MAX(0, MIN((y)+(h),(r).y_org+(r).height) - MAX((y),(r).y_org)))
#include <X11/Xft/Xft.h> /* XftColor */
#include "drw.h" /* drw_clr_create(3), drw_create(3), drw_fontset_create(3),
* drw_fontset_getwidth(3), drw_free(3), drw_map(3),
* drw_resize(3), drw_setscheme(3), drw_rect(3), drw_text(3),
* Drw */
/* chars to be allocated for the text displayed in the bar */
#define BUFSIZE 1024
enum { Scheme, SchemeLast }; /* color schemes */
/* enumerated because Suckless has SchemeNorm, SchemeSel, etc.
* should be made into like one char *Scheme[2] */
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define MAX(A, B) ((A) > (B) ? (A) : (B))
static int bh;
static XClassHint ch = {"dmenubar", "dmenubar"};
static Display *dpy;
static Drw *drw;
static char *embed;
static int inputw = 0;
static int lrpad; /* sum of left and right padding */
static int mh;
static int mon = -1;
static int mw;
static Window parentwin;
static Window root;
static Clr *scheme[SchemeLast];
static int screen;
static Window win;
#define BREAK_ON_EOF 0
#define bool char
static struct {
bool topbar; /* -b */
char *bg_hex; /* -B */
bool break_on_eof; /* -e */
char *fg_hex; /* -F */
int mon; /* -m */
char *embed; /* -w */
} args;
#undef bool
/* -f option overrides fonts[0]; default X11 font or font set */
static const char *fonts[] = {
"monospace:size=10"
};
#define topbar_default 1
static char *bg_hex_default = "#005577";
#define break_on_eof_default 0
static char *fg_hex_default = "#EEEEEE";
#define mon_default -1
#define embed_default NULL
static const char *colors[SchemeLast][2] = {
/* fg, bg */
[Scheme] = { "#eeeeee", "#005577" }
/* default X11 font or font set */
static const char *fonts[] = { /* drw_fontset_create(3) wants const char ** */
"monospace:size=10" /* -f overrides this */
};
int
main(int argc, char *argv[]){
int bh;
XftColor bg;
int c;
Display *dpy;
Drw *drw;
unsigned int du;
Window dw;
Window *dws;
XftColor fg;
int i;
int j;
int lrpad; /* sum of left and right padding */
int mh;
int mw;
extern char *optarg;
Window parentwin;
Window root;
int screen;
XSetWindowAttributes swa;
char text[BUFSIZE];
int topbar; /* 0=bottom 1=top */
Window w;
XWindowAttributes wa;
Window win;
int x;
int y;
#ifdef XINERAMA
@ -78,110 +79,147 @@ main(int argc, char *argv[]){
int a, di, n, area = 0;
#endif
topbar = 1;
args.topbar = topbar_default;
args.bg_hex = bg_hex_default;
args.break_on_eof = break_on_eof_default;
args.fg_hex = fg_hex_default;
args.mon = mon_default;
args.embed = embed_default;
while((c = getopt(argc, argv, ":bf:m:B:F:w:")) != -1)
switch(c){
case 'b':
topbar = 0;
args.topbar = !args.topbar;
break;
case 'e':
args.break_on_eof = !args.break_on_eof;
break;
case 'B': if(optarg){
colors[Scheme][ColBg] = optarg;
args.bg_hex = optarg;
break;
}case 'f': if(optarg){
fonts[0] = optarg;
break;
}case 'F': if(optarg){
colors[Scheme][ColFg] = optarg;
args.fg_hex = optarg;
break;
}case 'm': if(optarg){
mon = atoi(optarg);
args.mon = atoi(optarg);
break;
}case 'w': if(optarg){
embed = optarg;
args.embed = optarg;
break;
}default: /* optarg==0 falls through */
fprintf(stderr,
"Usage: %s (-b) (-B [background color])"
"Usage: %s (-be) (-B [background color])"
"(-f [font]) (-F foreground color)\n"
"\t(-m [monitor]) (-w [windowid)\n",
argv[0]);
return EX_USAGE;
}
if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
if(setlocale(LC_CTYPE, "") == NULL || !XSupportsLocale())
fprintf(stderr, "%s: No locale support.\n", argv[0]);
if (!(dpy = XOpenDisplay(NULL)))
die("cannot open display");
if((dpy = XOpenDisplay(NULL)) == NULL){
fprintf(stderr, "%s: Cannot open X display.\n", argv[0]);
return EX_UNAVAILABLE;
}
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
if (!embed || !(parentwin = strtol(embed, NULL, 0)))
if (args.embed == NULL || !(parentwin = strtol(args.embed, NULL, 0)))
parentwin = root;
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx",
parentwin);
if (!XGetWindowAttributes(dpy, parentwin, &wa)){
fprintf(stderr, "%s: Could not get embedding window "
"attributes: 0x%lx", argv[0], parentwin);
return EX_UNAVAILABLE;
}
drw = drw_create(dpy, screen, root, wa.width, wa.height);
if (!drw_fontset_create(drw, fonts, (sizeof fonts) / (sizeof *fonts)))
die("no fonts could be loaded.");
if (!drw_fontset_create(drw, fonts, (sizeof fonts) / (sizeof *fonts))){
fprintf(stderr, "%s: No fonts could be loaded.\n", argv[0]);
return EX_UNAVAILABLE;
}
lrpad = drw->fonts->h;
/* ??? */
#ifdef __OpenBSD__
if (pledge("stdio rpath", NULL) == -1)
die("pledge");
if(pledge("stdio rpath", NULL) == -1){
fprintf(stderr, "%s: Could not pledge(2).\n", argv[0]);
return EX_UNAVAILABLE;
}
#endif
/* init appearance */
for (j = 0; j < SchemeLast; j++)
scheme[j] = drw_scm_create(drw, colors[j], 2);
drw_clr_create(drw, &bg, args.bg_hex);
drw_clr_create(drw, &fg, args.fg_hex);
/* calculate menu geometry */
bh = drw->fonts->h + 2;
mh = bh;
#ifdef XINERAMA
# define INTERSECT(x, y, w, h, r) (\
MAX(0, \
MIN((x) + (w), (r).x_org + (r).width) \
- MAX((x), (r).x_org)) \
* MAX(0, \
MIN((y) + (h), (r).y_org + (r).height) \
- MAX((y), (r).y_org))\
)
i = 0;
if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
if(parentwin == root && (info = XineramaQueryScreens(dpy, &n))){
XGetInputFocus(dpy, &w, &di);
if (mon >= 0 && mon < n)
i = mon;
else if (w != root && w != PointerRoot && w != None) {
/* find top-level window containing current input focus */
do {
if (XQueryTree(dpy, (pw = w), &dw, &w, &dws, &du) && dws)
if(args.mon >= 0 && args.mon < n)
i = args.mon;
else if(w != root && w != PointerRoot && w != None){
/* find top-level window containing current input focus
*/
do{
if( XQueryTree(dpy, (pw = w), &dw,
&w, &dws, &du)
&& dws)
XFree(dws);
} while (w != root && w != pw);
/* find xinerama screen with which the window intersects most */
if (XGetWindowAttributes(dpy, pw, &wa))
for (j = 0; j < n; j++)
if ((a = INTERSECT(wa.x, wa.y, wa.width, wa.height, info[j])) > area) {
}while(w != root && w != pw);
/* find xinerama screen with which the window
* intersects most */
if(XGetWindowAttributes(dpy, pw, &wa))
for(j = 0; j < n; j++)
if( (a = INTERSECT(wa.x,
wa.y, wa.width,
wa.height,
info[j]))
> area){
area = a;
i = j;
}
}
/* no focused window is on screen, so use pointer location instead */
if (mon < 0 && !area && XQueryPointer(dpy, root, &dw, &dw, &x, &y, &di, &di, &du))
for (i = 0; i < n; i++)
if (INTERSECT(x, y, 1, 1, info[i]))
if( args.mon < 0
&& !area
&& XQueryPointer(dpy, root, &dw, &dw, &x, &y,
&di, &di, &du))
for(i = 0; i < n; i++)
if(INTERSECT(x, y, 1, 1, info[i]))
break;
x = info[i].x_org;
y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
y = info[i].y_org + (args.topbar ? 0 : info[i].height - mh);
mw = info[i].width;
XFree(info);
} else
#endif
#endif /* ifdef XINERAMA */
{
if (!XGetWindowAttributes(dpy, parentwin, &wa))
die("could not get embedding window attributes: 0x%lx",
parentwin);
if(!XGetWindowAttributes(dpy, parentwin, &wa)){
fprintf(stderr,
"%s: could not get embedding window"
"attributes: 0x%lx\n",
argv[0], parentwin);
return EX_UNAVAILABLE; /* appropriate sysexit? */
}
x = 0;
y = topbar ? 0 : wa.height - mh;
y = args.topbar ? 0 : wa.height - mh;
mw = wa.width;
}
inputw = MIN(inputw, mw/3);
/* create menu window */
swa.override_redirect = True;
swa.background_pixel = scheme[Scheme][ColBg].pixel;
swa.background_pixel = bg.pixel;
swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
CopyFromParent, CopyFromParent, CopyFromParent,
@ -190,7 +228,7 @@ main(int argc, char *argv[]){
XMapRaised(dpy, win);
if (embed) {
if (args.embed != NULL) {
XSelectInput(dpy, parentwin, FocusChangeMask | SubstructureNotifyMask);
if (XQueryTree(dpy, parentwin, &dw, &w, &dws, &du) && dws) {
for (i = 0; i < du && dws[i] != win; ++i)
@ -199,6 +237,7 @@ main(int argc, char *argv[]){
}
}
drw_resize(drw, mw, mh);
drw_setscheme(drw, fg, bg);
text[0] = '\0';
do{
@ -207,7 +246,6 @@ main(int argc, char *argv[]){
if(text[i] == '\n')
text[i] = '\0';
drw_setscheme(drw, scheme[Scheme]);
drw_rect(drw, 0, 0, mw, mh, 1, 1);
if(*text != '\0')
@ -221,11 +259,9 @@ main(int argc, char *argv[]){
drw_map(drw, win, 0, 0, mw, mh);
}while(
fgets(text, (sizeof text) / (sizeof *text), stdin) != NULL
|| !BREAK_ON_EOF
|| !args.break_on_eof
);
for (i = 0; i < SchemeLast; i++)
free(scheme[i]);
drw_free(drw);
XSync(dpy, False);
XCloseDisplay(dpy);

View File

@ -1,12 +1,16 @@
/* See LICENSE file for copyright and license details. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib.h>
#include <stdarg.h> /* va_start(3), va_end(3), va_list */
#include <stdio.h> /* fputc(3), perror(3) */
#include <stdlib.h> /* calloc(3), exit(3) */
#include <string.h> /* strlen(3) */
#include <X11/Xlib.h> /* Display */
#include <X11/Xft/Xft.h>
#include "drw.h"
#include "util.h"
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
#define UTF_INVALID 0xFFFD
#define UTF_SIZ 4
@ -16,6 +20,34 @@ static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
void
die(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
fputc(' ', stderr);
perror(NULL);
} else {
fputc('\n', stderr);
}
exit(1);
}
void *
ecalloc(size_t nmemb, size_t size)
{
void *p;
if (!(p = calloc(nmemb, size)))
die("calloc:");
return p;
}
static long
utf8decodebyte(const char c, size_t *i)
{
@ -194,7 +226,7 @@ drw_fontset_free(Fnt *font)
}
void
drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
drw_clr_create(Drw *drw, XftColor *dest, const char *clrname)
{
if (!drw || !dest || !clrname)
return;
@ -205,23 +237,6 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
die("error, cannot allocate color '%s'", clrname);
}
/* Wrapper to create color schemes. The caller has to call free(3) on the
* returned color scheme when done using it. */
Clr *
drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
{
size_t i;
Clr *ret;
/* need at least two colors for a scheme */
if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
return NULL;
for (i = 0; i < clrcount; i++)
drw_clr_create(drw, &ret[i], clrnames[i]);
return ret;
}
void
drw_setfontset(Drw *drw, Fnt *set)
{
@ -230,18 +245,20 @@ drw_setfontset(Drw *drw, Fnt *set)
}
void
drw_setscheme(Drw *drw, Clr *scm)
drw_setscheme(Drw *drw, XftColor fg, XftColor bg)
{
if (drw)
drw->scheme = scm;
if (drw) {
drw->bg = bg;
drw->fg = fg;
}
}
void
drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert)
{
if (!drw || !drw->scheme)
if (!drw || !drw->bg || !drw->fg)
return;
XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
XSetForeground(drw->dpy, drw->gc, invert ? drw->bg.pixel : drw->fg.pixel);
if (filled)
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
else
@ -266,13 +283,13 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
XftResult result;
int charexists = 0;
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
if (!drw || (render && (!drw->bg || !drw->fg)) || !text || !drw->fonts)
return 0;
if (!render) {
w = ~w;
} else {
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
XSetForeground(drw->dpy, drw->gc, (invert ? drw->fg : drw->bg).pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
d = XftDrawCreate(drw->dpy, drw->drawable,
DefaultVisual(drw->dpy, drw->screen),
@ -322,7 +339,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
if (render) {
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
XftDrawStringUtf8(d, &(invert ? drw->bg : drw->fg),
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
}
x += ew;

View File

@ -16,14 +16,16 @@ enum { ColFg, ColBg }; /* Clr scheme index */
typedef XftColor Clr;
typedef struct {
unsigned int w, h;
XftColor bg;
Display *dpy;
int screen;
Window root;
Drawable drawable;
GC gc;
Clr *scheme;
XftColor fg;
Fnt *fonts;
GC gc;
unsigned int h;
Window root;
int screen;
unsigned int w;
} Drw;
/* Drawable abstraction */
@ -47,7 +49,7 @@ void drw_cur_free(Drw *drw, Cur *cursor);
/* Drawing context manipulation */
void drw_setfontset(Drw *drw, Fnt *set);
void drw_setscheme(Drw *drw, Clr *scm);
void drw_setscheme(Drw *drw, XftColor fg, XftColor bg);
/* Drawing functions */
void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int invert);

View File

@ -1,11 +1,11 @@
from json import dumps, loads
bookmarks = "bookmarks.json"
bookmarks_filename = "bookmarks.json"
def load():
with open(bookmarks) as f:
with open(bookmarks_filename) as f:
return loads(f.read())
def store(b):
with open(bookmarks + ".new", 'w') as f:
with open(bookmarks_filename + ".new", 'w') as f:
return f.write(dumps(b))

View File

@ -1 +1,3 @@
CFLAGS += -g
libpsargs.o:

View File

@ -1,4 +1,10 @@
all: lowercase-ascii uppercase-ascii
all: lowercase uppercase
lowercase: lowercase-ascii
mv lowercase-ascii lowercase
uppercase: uppercase-ascii
mv uppercase-ascii uppercase
lowercase-ascii: case.c case-ascii.h
$(CC) -DCONV=TOLOWER -include case-ascii.h -o lowercase-ascii case.c

View File

@ -6,24 +6,19 @@ lowercase \(en make text lowercase
.SH SYNOPSIS
lowercase (-f)
lowercase
.SH DESCRIPTION
Lowercase prints text from standard input to standard output as lowercase.
.SH DIAGNOSTICS
Lowercase will print an error message and exit with the appropriate status from sysexits(3) if it attempts
to process a glyph outside the supported encoding range; this is to not inadverdently mangle multi-byte
characters. The -f option exists to override this and process every character anyway.
Lowercase prints text from standard input to standard output as lowercase. It
passes through text it can't convert.
.SH BUGS
Lowercase is not Unicode aware unless it's compiled with the USE_ICU flag, which requires libicu.
This isn't tested to any extent.
Lowercase is not Unicode aware.
.PP
Lowercase is redundant to usages of tr(1) among other POSIX-specified utilities.
Lowercase is redundant to usages of tr(1) among other POSIX-specified
utilities.
.SH HISTORY

View File

@ -70,13 +70,13 @@ get_memory_usage() {
PUBLIC_IP="$(ifpublic)"
printbar() {
printf "%b" "$(get_current_desktop)"
# printf "%b" "$(get_current_desktop)"
printf "%b" $($DATE)
printf "%b" "$DELIMITER"
printf "%b" "BAT: $(battery)"
printf "%b" "$DELIMITER"
printf "%b" "CPU: $(get_cpu_temp)"
printf "%b" "$DELIMITER"
# printf "%b" "CPU: $(get_cpu_temp)"
# printf "%b" "$DELIMITER"
printf "%b" "PuIP: $PUBLIC_IP"
#printf "%b" "$DELIMITER"
#printf "%b" "MEM: $(get_memory_usage)"

139
niceties/openbsd Normal file
View File

@ -0,0 +1,139 @@
#!/bin/sh
set -e
# found this here... may auto install openbsd... may not... who knows
prog(){ while test -n "$!" # ask your doctor about progesterone
do if ! command -v "$1" >/dev/null
then printf '%s: %s command not found. Please install it.\n' \
"$0" "$1" 1>&2
false
fi done }
prog curl
if ! prog signify
then if prog signify-openbsd
then alias signify=signify-openbsd
else false
fi fi
OBSD="$HOME"/OpenBSD
REL=7.5
SREL="$(printf '%s\n' "$REL" | tr -d .)"
test -n "$ARCH" \
|| case "$(uname -m)" in
# aarch64) ARCH=arm64 ;;
amd64) ARCH=amd64 ;;
# arm64) ARCH=arm64 ;;
i386) ARCH=i386 ;;
# *) ARCH=riscv64 ;;
*) ARCH=arm64 ;;
esac
test -n "$MIRROR" \
|| MIRROR=ftp://mirrors.mit.edu/pub/OpenBSD
case "$ARCH" in
amd64) QEMU=x86_64 ;;
i386) QEMU=i386 ;;
*) QEMU=aarch64 ;;
esac
printf '%s: enter a public SSH key for accessing the virtual machine.\n:: ' "$0"
PUBSSH="$(head -n 1)"
printf "\
%s: Setting up a virtualized OpenBSD %s (%s) instance from the mirror %s.
%s: Control+C to cancel. Waiting 10s to continue...
" "$0" "$REL" "$ARCH" "$MIRROR" \
"$0" 1>&2
sleep 10
# <https://www.skreutz.com/posts/autoinstall-openbsd-on-qemu/>
mkdir -p "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"
curl -O --output-dir "$OBSD"/mirror/pub/OpenBSD/"$REL"/ \
https://ftp.openbsd.org/pub/OpenBSD/"$REL"/openbsd-"$SREL"-base.pub
for f in SHA256.sig bsd bsd.mp bsd.rd pxeboot \
base"$SREL".tgz comp"$SREL".tgz man"$SREL".tgz
do curl -O --output-dir "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH" \
"$MIRROR"/"$REL"/"$ARCH"/"$f"
done
signify -C -p "$OBSD"/mirror/pub/OpenBSD/"$REL"/openbsd-"$SREL"-base.pub \
-x "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"/SHA256.sig \
-- bsd* pxeboot *"$SREL".tgz
printf "\
%s: Using the following autoinstall(8) install.conf:
Change the default console to com0 = yes
Which speed should com0 use = 115200
System hostname = openbsd
Password for root = *************
Allow root ssh login = no
Setup a user = puffy
Password for user = *************
Public ssh key for user = %s
What timezone are you in = UTC
Location of sets = http
HTTP Server = 10.33.2.1
Unable to connect using https. Use http instead = yes
URL to autopartitioning template for disklabel = http://10.33.2.1/disklabel
Set name(s) = site%s.tgz
Checksum test for site%s.tgz failed. Continue anyway = yes
Unverified sets: site%s.tgz. Continue without verification = yes
" "$0" "$PUBSSH" "$SREL" "$SREL" "$SREL" \
| tee -a /dev/stderr \
| sed -e 1d -e 's:^\t::g' \
>"$OBSD"/mirror/install.conf
printf "\
%s: Using the following disklabel(8) template:
/ 8G
swap 256M
" "$0" \
| tee -a /dev/stderr \
| sed -e 1d -e 's:^\t::g' \
>"$OBSD"/mirror/disklabel
mkdir -p site
printf "\
#!/bin/sh
printf 'https://cdn.openbsd.org/pub/OpenBSD\n' \
>/etc/installurl
printf 'permit keepenv nopass :wheel\n' \
>>/etc/doas.conf
" >"$OBSD"/site/install.site
chmod +x "$OBSD"/site/install.site
tar -C site czf "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"/site"$SREL".tgz
# probably not necessary
#ls -l "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH" >"$OBSD"/index.txt
mkdir -p tftp/etc
ln "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"/pxeboot "$OBSD"/tftp/auto_install
ln "$OBSD"/mirror/pub/OpenBSD/"$REL"/"$ARCH"/bsd.rd "$OBSD"/tftp/bsd.rd
printf "\
stty com0 115200
set tty com0
boot tftp:/bsd.rd
" >"$OBSD"/tftp/etc/boot.conf
qemu-img create -f qcow2 "$OBSD"/hd0.qcow2 9G
chmod +x
python3 -m http.server --directory "$OBSD"/mirror --bind 127.0.0.1 8080 &
qemu-system-"$QEMU" \
-drive file=\"\$OBSD\"/hd0.qcow2,media=disk,if=virtio \
-device e1000,netdev=n1 \
-m 512M \
-netdev user,id=n1,hostname=openbsd-vm,tftp-server-name=10.0.2.1,tftp=tftp,bootfile=auto_install,hostfwd=tcp::2222-:22,guestfwd=tcp:10.0.2.1:80-cmd:socat STDIO TCP4:127.0.0.1:8080 \
-nographic &
printf "\
%s: ssh into puffy@127.0.0.1:2222 to connect.
%s: press Enter to quit.
" "$0" "$0" 1>&2
head -n 1

View File

@ -4,7 +4,7 @@
# Not a great use of disk...
dd 2>/dev/null \
| sed \
-e 's/l/w/g' \
-e 's/r/w/g' \
-e 's/smaww/smol/g' \
-e 's/wove/wuv/g'
-e s/l/w/g \
-e s/r/w/g \
-e s/smaww/smol/g \
-e s/wove/wuv/g

View File

@ -52,7 +52,7 @@ case "$1" in
-) "$0" r -"$2" ;;
a*)
str isvalue $2 && ! str isvalue $3 && str isdigit "$2" \
test -n $2 && ! str isvalue $3 && str isdigit "$2" \
|| usage
"$0".$VOLUME_SYSTEM "$@"
;;

119
npc.rs Normal file
View File

@ -0,0 +1,119 @@
/*
* Copyright (c) 2023 DTB <trinity@trinity.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*/
use std::{
env::args,
io::{ stdin, stdout, Error, Read, Write },
process::ExitCode
};
extern crate getopt;
use getopt::{ Opt, Parser };
extern crate sysexits;
use sysexits::{ EX_OK, EX_OSERR, EX_USAGE };
fn oserr(s: &str, e: Error) -> ExitCode {
eprintln!("{}: {}", s, e);
ExitCode::from(EX_OSERR as u8)
}
fn usage(s: &str) -> ExitCode {
eprintln!("Usage: {} (-aet)", s);
ExitCode::from(EX_USAGE as u8)
}
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
let input = stdin();
let mut output = stdout().lock();
let mut opts = Parser::new(&argv, "7et");
let mut ascii = false;
let mut showend = false;
let mut showtab = false;
loop {
match opts.next() {
None => break,
Some(o) =>
match o {
Ok(Opt('7', None)) => ascii = true,
Ok(Opt('e', None)) => showend = true,
Ok(Opt('t', None)) => showtab = true,
_ => { return usage(&argv[0]); }
}
}
}
/* cat -v emulation */
if ascii {
let mut c: u8 = 0;
for r in input.bytes() {
match r {
Ok(v) => { c = v; },
Err(e) => { return oserr(&argv[0], e); }
}
/* If a given byte isn't expressable in ASCII, print "M-[char]",
* where char is the chosen representation of the byte with its
* high bit set to 0. */
if c & 0x80 /* 0b 1000 0000 */ != 0 { print!("M-"); }
c ^= 0x80;
/* ASCII DEL is represented as ^? */
if c == 0x7f as u8 {
if let Err(e) = output.write_all(b"^?") {
return oserr(&argv[0], e);
}
break;
}
if c == '\n' as u8 && showend {
if let Err(e) = output.write_all(b"$") {
return oserr(&argv[0], e);
}
}
/* ASCII visual characters are shown literally. */
if c >= ' ' as u8 || c == '\n' as u8
|| (!showtab && c == '\t' as u8) {
if let Err(e) = output.write_all(&[c]) {
return oserr(&argv[0], e);
}
}
/* Otherwise, characters are shown as their control code, with NUL
* being ^@ and successive characters shown as "^" catenated with
* successive visual characters past "@". */
else {
c += '@' as u8;
if let Err(e) = output.write_all(b"^") {
return oserr(&argv[0], e);
}
if let Err(e) = output.write_all(&[c]) {
return oserr(&argv[0], e);
}
}
}
} else {
eprintln!("not implemented");
}
ExitCode::from(EX_OK as u8)
}

View File

@ -1,6 +1,6 @@
#include <fcntl.h> /* open(2), O_RDONLY */
#include <stdio.h> /* fprintf(3), perror(3) */
#if !defined EX_OK || !defined EX_OSERR || !defined EX_USAGE
#if !defined EX_OSERR || !defined EX_USAGE
# include <sysexits.h>
#endif
#include <unistd.h> /* dup(2), dup2(2), fork(2), STDIN_FILENO */

122
walk/walk.rs Normal file
View File

@ -0,0 +1,122 @@
/*
* Copyright (c) 2024 DTB <trinity@trinity.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU Affero General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
* details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see https://www.gnu.org/licenses/.
*
* This file incorporates work covered by the following copyright and permission
* notice:
*
* Copyright 2019 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
use std::{
env::{args, current_dir},
fs::{read_dir, DirEntry},
path::Path,
};
extern crate getopt;
use getopt::{Opt, Parser};
extern crate sysexits;
use sysexits::{EX_SOFTWARE, EX_USAGE};
enum Terminator {
USER,
NUL,
NEWL,
ASV,
}
/* Recursively walks d, yielding all contained files and folders. */
fn walk(d: &Path, l: i8) -> impl Iterator<Item = DirEntry> {
assert!(d.is_dir());
// TODO: read_dir(d)??
for entry in read_dir(d)? {
let e = entry?;
yield e;
if e.is_dir() {
for f in walk(e.path(), l - 1)? {
yield f;
}
}
}
}
fn usage(s: &str) -> ExitCode {
eprintln!("Usage: {} (-0n) (-d [delimiter]) (-l [levels])", s);
ExitCode::from(EX_USAGE as u8)
}
fn main() -> ExitCode {
let argv = args().collect::<Vec<String>>();
let mut opts = Parser::new(&argv, "0d:l:nq");
let mut levels: i8 = -1;
let mut t: (Terminator, Option<String>) = (ASV, None);
loop {
match opts.next() {
None => break,
Some(opt) => match opt {
Ok(Opt('0', None)) => t = (NUL, None),
Ok(Opt('n', None)) => t = (NEWL, None),
Ok(Opt('d', Some(arg))) => t = (USER, arg),
Ok(Opt('l', Some(arg))) => match arg.parse::<u8>() {
Ok(l) => levels = l,
_ => {
return usage(&argv[0]);
}
},
_ => {
return usage(&argv[0]);
}
},
}
}
/* t.2 can only be Some if t.1 is USER */
assert_eq!(t.1 == USER, !t.2.is_none());
// if(*argv == NULL)
// argv = dot;
//
// {
// int retval;
//
// for(retval = 0; *argv != NULL; ++argv)
// if((retval = walk(*argv, levels, verbosity >= 2 ? argv0 : NULL))
// != EX_OK){
// if(verbosity >= 1)
// fprintf(stderr, "%s: %s: %s\n",
// argv0, *argv, strerror(errno));
// return retval;
// }
// }
EX_OK as u8
}