Skip to content

Commit

Permalink
use ssb
Browse files Browse the repository at this point in the history
consolidates certain string-related functions into a library.
  • Loading branch information
r-c-f committed Apr 5, 2023
1 parent dde9b5b commit 2c15551
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 64 deletions.
224 changes: 224 additions & 0 deletions include/ssb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
/* simple string builder
*
* Version 1.3
*
* Copyright 2023 Ryan Farley <[email protected]>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef SSB_H_INC
#define SSB_H_INC

#if defined(__GNUC__)
#define SHL_UNUSED __attribute__((unused))
#else
#define SHL_UNUSED
#endif

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdbool.h>
#include <errno.h>

/* defines the length used for ssb_readfile, if SSB_GROW_EXACT is used */
#if !defined SSB_READ_LEN
#define SSB_READ_LEN 4096
#endif


enum ssb_grow {
/* grow by a factor of 1.5 */
SSB_GROW_1_5 = 0,
/* grow by a factor of 2.0 */
SSB_GROW_2_0,
/* grow by exactly the amount needed each time */
SSB_GROW_EXACT
};

struct ssb {
enum ssb_grow grow;
char *buf;
size_t size;
size_t pos;
};

SHL_UNUSED static bool ssb_truncate(struct ssb *s, size_t newsize)
{
char *realloc_buf;

if (!(realloc_buf = realloc(s->buf, newsize + 1))) {
return false;
}
s->buf = realloc_buf;
if (s->pos >= newsize) {
s->buf[newsize] = '\0';
}

s->size = newsize + 1;

return true;
}

SHL_UNUSED static bool ssb_grow_min(struct ssb *s, size_t min)
{
size_t newsize;

newsize = min += s->size;

switch (s->grow) {
case SSB_GROW_1_5:
newsize = s->size + (s->size / 2);
break;
case SSB_GROW_2_0:
newsize = s->size * 2;
break;
default:
break;
}

return ssb_truncate(s, (newsize >= min ? newsize : min));
}

SHL_UNUSED static int ssb_vprintf(struct ssb *s, const char *fmt, va_list ap)
{
va_list sizeap;
int size;

if (!s) {
errno = EINVAL;
return -1;
}

va_copy(sizeap, ap);
if ((size = vsnprintf(s->buf + s->pos, s->size - s->pos, fmt, sizeap)) >= s->size - s->pos) {
if (!ssb_grow_min(s, size)) {
return -1;
}
vsnprintf(s->buf + s->pos, s->size - s->pos, fmt, ap);
}
va_end(sizeap);
s->pos += size;

return 0;
}

SHL_UNUSED static int ssb_printf(struct ssb *s, const char *fmt, ...)
{
int ret;
va_list ap;
va_start(ap, fmt);
ret = ssb_vprintf(s, fmt, ap);
va_end(ap);
return ret;
}

SHL_UNUSED static void ssb_rewind(struct ssb *s)
{
s->pos = 0;
if (s->buf) {
*(s->buf) = '\0';
}
}

SHL_UNUSED static void ssb_free(struct ssb *s)
{
s->pos = 0;
if (s->buf) {
free(s->buf);
}
s->size = 0;
s->buf = NULL;
}

/* add a single character to the buffer */
SHL_UNUSED static bool ssb_addc(struct ssb *s, unsigned char c)
{
if (s->size - s->pos < 2) {
if (!ssb_grow_min(s, 1)) {
return false;
}
}
s->buf[s->pos++] = c;
s->buf[s->pos] = '\0';
return true;
}

/* analogous to getdelim -- returns true if anything is successfully read */
SHL_UNUSED static bool ssb_getdelim(struct ssb *s, int delim, FILE *f)
{
int c;
size_t old_pos = s->pos;

while ((c = getc(f)) != EOF) {
if (!ssb_addc(s, c)) {
return false;
}

if (c == delim) {
return true;
}
}

return s->pos - old_pos;
}

/* a bit like getline -- return true if anything is successfully read */
SHL_UNUSED static bool ssb_getline(struct ssb *s, FILE *f)
{
return ssb_getdelim(s, '\n', f);
}

/* read an entire file into a buffer */
SHL_UNUSED static bool ssb_readfile(struct ssb *s, FILE *f)
{
size_t read_count = 0;

do {
s->pos += read_count;
if (s->size - s->pos <= 2) {
if (!ssb_grow_min(s, SSB_READ_LEN)) {
return false;
}
}
} while ((read_count = fread(s->buf + s->pos, 1, s->size - s->pos - 1, f)));

/* ideally the result would be NUL terminated, but we cannot be sure */
s->buf[s->pos] = '\0';

return feof(f);
}

/* x variants -- can never fail! */
SHL_UNUSED static void ssb_xvprintf(struct ssb *s, const char *fmt, va_list ap)
{
if (ssb_vprintf(s, fmt, ap))
abort();
}
SHL_UNUSED static void ssb_xprintf(struct ssb *s, const char *fmt, ...)
{
va_list ap;

va_start(ap, fmt);
ssb_xvprintf(s, fmt, ap);
va_end(ap);
}
SHL_UNUSED static void ssb_xtruncate(struct ssb *s, size_t newsize)
{
if (!ssb_truncate(s, newsize))
abort();
}
#undef SHL_UNUSED
#endif

25 changes: 6 additions & 19 deletions src/clip-update.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,20 @@
#include <stdbool.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "ssb.h"
#include "xmem.h"
#include "fdio_full.h"

/* read file into a buffer, resizing as needed */
static bool buf_append_file(char **buf, size_t *len, size_t *pos, FILE *f)
{
size_t read_count;
while ((read_count = fread(*buf + *pos, 1, *len - *pos - 1, f))) {
*pos += read_count;
if (*len - *pos <= 2) {
*buf = xrealloc(*buf, *len *= 2);
}
}
return true;
}
int main(int argc, char **argv)
{
char *path = argv[2];
char cid = argv[1][0];
char *buf;
size_t len = 4000;
size_t pos = 0;
struct ssb s = {0};
struct sockaddr_un sa = {0};
int sock;
buf = xmalloc(len);
if (!buf_append_file(&buf, &len, &pos, stdin))
if (!ssb_readfile(&s, stdin)) {
return EXIT_FAILURE;
}
/* write out the clipboard sequence -- char for ID, size_t for size, then data */
strncpy(sa.sun_path, path, sizeof(sa.sun_path) - 1);
sa.sun_family = AF_UNIX;
Expand All @@ -43,10 +30,10 @@ int main(int argc, char **argv)
if (!write_full(sock, &cid, 1, 0)) {
return EXIT_FAILURE;
}
if (!write_full(sock, &pos, sizeof(pos), 0)) {
if (!write_full(sock, &(s.pos), sizeof(s.pos), 0)) {
return EXIT_FAILURE;
}
if (!write_full(sock, buf, pos, 0)) {
if (!write_full(sock, s.buf, s.pos, 0)) {
return EXIT_FAILURE;
}
shutdown(sock, SHUT_RDWR);
Expand Down
32 changes: 8 additions & 24 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "xmem.h"
#include "fdio_full.h"
#include "log.h"
#include "ssb.h"
#include <stdbool.h>
#include <dirent.h>
#include <sys/stat.h>
Expand All @@ -13,40 +14,23 @@
#include "ini.h"
static ini_t *config_ini = NULL;

/* read file into a buffer, resizing as needed */
static bool buf_append_file(char **buf, size_t *len, size_t *pos, char *path)
static char *read_file_dumb(char *path)
{
FILE *f;
size_t read_count;
struct ssb s = {0};

if (!path)
return false;
if (!(f = fopen(path, "r"))) {
return false;
}
while ((read_count = fread(*buf + *pos, 1, *len - *pos - 1, f))) {
*pos += read_count;
if (*len - *pos <= 2) {
*buf = xrealloc(*buf, *len *= 2);
}
if (!(ssb_readfile(&s, f) && ssb_truncate(&s, s.pos))) {
ssb_free(&s);
}
fclose(f);
return true;
}
static char *read_file_dumb(char *path)
{
size_t len, pos;
char *buf;

len = 4096;
buf = xmalloc(len);
pos = 0;
if (!buf_append_file(&buf, &len, &pos, path)) {
free(buf);
return NULL;
}
buf[pos] = 0;
return xrealloc(buf, pos + 1);
return s.buf;
}

static char *try_read_ini(char *name)
{
char *section_buf = NULL;
Expand Down
17 changes: 4 additions & 13 deletions src/mapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "xdg-shell-client-protocol.h"
#include "keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h"
#include "sopt.h"

#include "ssb.h"

static struct sopt optspec[] = {
SOPT_INITL('h', "help", "Help text"),
Expand Down Expand Up @@ -53,33 +53,24 @@ static int started;

static char *get_syms_str(void)
{
char *buf = NULL;
char sym_name[64];
size_t buf_size = 0;
FILE *f;
struct ssb s = {0};
const xkb_keysym_t *syms_out;
int syms_count, i, levels, level, layouts, layout;

if (!(f = open_memstream(&buf, &buf_size))) {
perror("open_memstream");
exit(1);
}
layouts = xkb_keymap_num_layouts_for_key(xkb_keymap, raw_keymap_pos);
for (layout = 0; layout < layouts; ++layout) {
levels = xkb_keymap_num_levels_for_key(xkb_keymap, raw_keymap_pos, layout);
for (level = 0; level < levels; ++level) {
if ((syms_count = xkb_keymap_key_get_syms_by_level(xkb_keymap, raw_keymap_pos, layout, level, &syms_out))) {
for (i = 0; i < syms_count; ++i) {
xkb_keysym_get_name(syms_out[i], sym_name, sizeof(sym_name));
fprintf(f, "%s ", sym_name);
ssb_xprintf(&s, "%s ", sym_name);
}
}
}
}
fseek(f, -1, SEEK_END);
fputc(0, f);
fclose(f);
return buf;
return s.buf;
}

static void raw_keymap_print(void)
Expand Down
Loading

0 comments on commit 2c15551

Please sign in to comment.