util  Check-in [ff13f110ee]

Overview
Comment:add rosshil, misc updates
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ff13f110ee82490355f77be435ec383ab2eb4e0d4bce5e368a85fa9ef31ea419
User & Date: lexi on 2019-07-13 07:07:36
Other Links: manifest | tags
Context
2019-07-13
08:22
add another hundred lines or so two rosshil. im done this time i swear check-in: 384965fe63 user: lexi tags: trunk
07:07
add rosshil, misc updates check-in: ff13f110ee user: lexi tags: trunk
2019-05-06
23:35
add hue api check-in: 967c6eaf26 user: lexi tags: trunk
Changes

Added clib/compose.c version [e0c5b0d583].

            1  +/* [ʞ] compose.c
            2  + *  ~ lexi hale <lexi@hale.su>
            3  + *  © affero general public license v3
            4  + *  $ cc -c compose.c
            5  + *  # include <string.h>
            6  + *
            7  + * compose.c contains some useful string utilities
            8  + * that libc lacks.
            9  +
           10  +   TODO add macro to use homebrew strlen instead of
           11  +        dragging in <string.h> */
           12  +
           13  +#ifdef k_header // only emit the declarations
           14  +#	define fn(x)
           15  +#else
           16  +#	define fn(x) x
           17  +#endif
           18  +
           19  +#include <string.h>
           20  +
           21  +typedef struct pstr { size_t len; union {
           22  +	const char* ptr;
           23  +	char* mutptr;
           24  +}; } pstr;
           25  +#define _p(str) { sizeof str - 1, str }
           26  +
           27  +typedef struct safestr {
           28  +	union {
           29  +		const char* ptr;
           30  +		char* mutptr;
           31  +	}; // im sorry okay
           32  +	bool heap;
           33  +	size_t len;
           34  +} safestr;
           35  +
           36  +void delstr(safestr s) fn ({
           37  +	if (s.heap) { free(s.mutptr); }
           38  +});
           39  +
           40  +void clrstr(safestr* s) fn ({
           41  +	delstr(*s);
           42  +	s->heap = false;
           43  +	s->ptr = NULL;
           44  +	s->len = 0;
           45  +})
           46  +
           47  +char* compose(pstr* lst,size_t ct, size_t* strsz) fn({
           48  +	size_t len = 0;
           49  +	for (size_t i = 0; i < ct; ++i) {
           50  +		if (lst[i].len == 0) {
           51  +			if (lst[i].ptr == NULL) continue;
           52  +			lst[i].len = strlen(lst[i].ptr);
           53  +		}
           54  +		len += lst[i].len;
           55  +	}
           56  +	if (strsz != NULL) *strsz = len;
           57  +	if (len == 0) return NULL;
           58  +	
           59  +	char* str = malloc(len + 1);
           60  +	char* ptr = str;
           61  +	for (size_t i = 0; i < ct; ++i) {
           62  +		if (lst[i].len == 0) continue;
           63  +		strncpy(ptr,lst[i].ptr,lst[i].len);
           64  +		ptr += lst[i].len;
           65  +	}
           66  +	*ptr = 0;
           67  +	return str;
           68  +});
           69  +

Added clib/dbg.h version [b957fa3405].

            1  +// a simple C debug mechanism
            2  +#define _itoa(x) _str(x)
            3  +#define _str(x) #x
            4  +#define _ul(n,s,l,r) "\e[3"#n"m"l"\e[9"#n";4m" s "\e[;3"#n"m"r"\e[m"
            5  +#define _hl(n,s,l,r) "\e[3"#n"m"l"\e[9"#n"m" s "\e[;3"#n"m"r"\e[m"
            6  +#define _hlstr _ul(5,"%s","“","”")
            7  +#define _hlpath _ul(4,"%s","“","”")
            8  +#define _hlvar(v) _hl(2,v,"$","")
            9  +
           10  +#if defined(_debug) || defined(_live_debug)
           11  +#	include <stdio.h>
           12  +#	define _var_pos "\e[34mat \e[94;4m" __FILE__ "#" _itoa(__LINE__) "\e[;34m:\e[m " 
           13  +#	ifdef _live_debug
           14  +#		define say(fmt,...) (debug ? fprintf(stderr, \
           15  +			_var_pos fmt "\n", __VA_ARGS__) : 0)
           16  +#	else
           17  +#		define say(fmt,...) fprintf(stderr, \
           18  +			_var_pos fmt "\n", __VA_ARGS__)
           19  +#	endif
           20  +#	define _var_expr(name,code,prefix,suffix) _var_pos "\e[1m" name "\e[m \e[35m= \e[35m" \
           21  +		prefix "\e[95;4m" "%" #code "\e[24;35m" suffix "\e[m\n"
           22  +#	define var(v) fprintf(stderr, _Generic ((v),      \
           23  +			char*         : _var_expr(#v,s,"“","”"),     \
           24  +			const char*   : _var_expr(#v,s,"",""),     \
           25  +			char          : _var_expr(#v,c,"‘","’"),      \
           26  +			signed   char : _var_expr(#v,hhi,"","i"),     \
           27  +			unsigned char : _var_expr(#v,hhu,"","u"),     \
           28  +			signed   short: _var_expr(#v,hi,"","I"),      \
           29  +			unsigned short: _var_expr(#v,hu,"","U"),      \
           30  +			signed   int  : _var_expr(#v,i,"","I"),       \
           31  +			unsigned int  : _var_expr(#v,u,"","U"),       \
           32  +			signed   long : _var_expr(#v,li,"","L"),      \
           33  +			unsigned long : _var_expr(#v,lu,"","UL"),      \
           34  +			signed   long long : _var_expr(#v,lli,"","LL"),\
           35  +			unsigned long long : _var_expr(#v,llu,"","ULL"),\
           36  +			default       : _var_expr(#v,p,"[","]")), v)
           37  +#else
           38  +#	define say(...) 
           39  +#	define var(v)
           40  +#endif

Added clib/findconf.c version [1d68483540].

            1  +/* [ʞ] findconf.c
            2  + *  ~ lexi hale <lexi@hale.su>
            3  + *  $ cc -c findconf.c
            4  + *	© GNU AGPL v3
            5  + *	# include <stdlib.h>
            6  + *	  include "compose.c"
            7  + */
            8  +
            9  +#include <stdlib.h>
           10  +#define sz(x) (sizeof x / sizeof x[0])
           11  +
           12  +#define _k_conf(name,s) findconf((name ".cf"), ("ʞ_" name "_conf"), (s))
           13  +bool findconf(char* filename,char* env,safestr* s) {
           14  +	say("attempting to locate config file",0);
           15  +	var(filename);
           16  +
           17  +	if (filename != NULL) {
           18  +		char* conf = getenv(env);
           19  +		if (conf != NULL) {
           20  +			say("config file specified by " _hlvar("%s") ": " _hlpath, env, conf);
           21  +			s->heap=false; s->ptr = conf;
           22  +			s->len=strlen(conf); return true;
           23  +		} else {
           24  +			say("no config file specified by " _hlvar("%s") ", constructing XDG path",env);
           25  +		}
           26  +	}
           27  +
           28  +	char* xdg, *home, *path = NULL;
           29  +	size_t len;
           30  +	if (xdg  = getenv("XDG_CONFIG_HOME")) {
           31  +		say("config dir " _hlpath " specified by " _hlvar("XDG_CONFIG_HOME"), xdg);
           32  +		pstr xdg_path[] = { {0, xdg}, _p("/"), {0, filename} } ;
           33  +		path = compose(xdg_path, sz(xdg_path), &(s->len));
           34  +	} else if (home = getenv("HOME")) {
           35  +		say(_hlvar("XDG_CONFIG_HOME") " undefined, constructing default from " _hlvar("HOME"),home);
           36  +		var(home);
           37  +		pstr home_path[] = { {0, home}, _p("/.config/"), {0, filename} };
           38  +		path = compose(home_path, sz(home_path), &(s->len));
           39  +	} else {
           40  +		say("no " _hlvar("HOME") " variable, assuming /home/$USER",0);
           41  +		char* user = getenv("USER");
           42  +		if (user == NULL) { /* uh oh */ user = getlogin();
           43  +			say("no " _hlvar("USER") " variable, but " _hl(3, "getlogin","","()") " reports %s",user); }
           44  +		if (user != NULL) {
           45  +			pstr user_path[] = { _p("/home/"), {0, user}, _p("/.config/"), {0, filename} };
           46  +			path = compose(user_path, sz(user_path), &(s->len));
           47  +		} else {
           48  +			// UH OH
           49  +			say("no " _hlvar("USER") " and " _hl(3, "getlogin","","()") " did not return a sane value - bailing the fuck out",0);
           50  +			return false;
           51  +		}
           52  +	}
           53  +
           54  +	var(path);
           55  +	if (path) {
           56  +		s->ptr = path;
           57  +		s->heap = true;
           58  +		return true;
           59  +	} else return false;
           60  +}
           61  +#undef sz

Added rosshil.ml version [1155e40476].

            1  +(* [ʞ] rosshil.ml - tasshila semes sirvos
            2  + *  ~ lexi hale <lexi@hale.su>
            3  + *  $ ocamlopt.opt rosshil.ml -o rosshil
            4  + *  © AGPL
            5  + *)
            6  +
            7  +(* basic units *)
            8  +type timespan  = int (* earth seconds are current tick unit *)
            9  +type timepoint = int
           10  +type quantity = int
           11  +type proportion = float
           12  +
           13  +type runopt = NoOpt | NoANSI | ASCII
           14  +let optstrs = [
           15  +	NoANSI, "noansi";
           16  +	ASCII, "ascii";
           17  +]
           18  +let is_opt str = List.exists (fun (_,s) -> ("-"^s) = str) optstrs
           19  +let opt_of_str str = let (opt,_) = List.find
           20  +	(fun (_,s) -> ("-"^s) = str) optstrs in opt;
           21  +
           22  +type name             = { short: string; long: string; }
           23  +let nmpair short long = { short = short; long = long   };
           24  +
           25  +type timeunit = {
           26  +	name   : string;
           27  +	expr   : timespan -> string;
           28  +	span   : timespan;
           29  +}
           30  +
           31  +let span (start: timepoint) (stop: timepoint) : timespan = stop - start
           32  +	(* because im a dyscalculic idiot *)
           33  +
           34  +type epoch = {
           35  +	(* an epoch delineates discrete eras in a calendar system,
           36  +	 * such as which empress is reigning *)
           37  +	title : name;
           38  +	start : timepoint;
           39  +}
           40  +let inepoch (e: epoch) (date: timepoint) = date > e.start
           41  +
           42  +type era = {
           43  +	(* an era is a period of time that may be attached to
           44  +	 * galactic history or to a single calendar *)
           45  +	title : name;
           46  +	start : timepoint;
           47  +	stop  : timepoint;
           48  +}
           49  +let eraspan (e: era) : timespan = span e.start e.stop
           50  +
           51  +let history : era list = [] (* in DESCENDING order!! *)
           52  +let galacticzero : timepoint = 0
           53  +
           54  +type date = { years : quantity; days : quantity }
           55  +
           56  +let strify = string_of_int
           57  +
           58  +exception Bad_dimension
           59  +let bad_dim _ = raise Bad_dimension
           60  +
           61  +module Gregorian = struct
           62  +	module Span = struct
           63  +		let sec  : timespan =   1
           64  +		let min  : timespan =  60 * sec
           65  +		let hour : timespan =  60 * min
           66  +		let day  : timespan =  24 * hour
           67  +		let days : quantity = 365
           68  +		let year : timespan = days * day
           69  +
           70  +		let equiv (d: date): timespan =
           71  +			(year * d.years) + (day * d.days)
           72  +
           73  +		let day_equiv calendar_days earth_equiv = int_of_float
           74  +			(float day *. (float earth_equiv /. float calendar_days))
           75  +
           76  +		let calc (span: timespan) : date =
           77  +			let ctdays = span / day in
           78  +			let ctyears = ctdays / days in
           79  +			let rem = ctdays mod days in
           80  +				{ years = ctyears; days = rem; }
           81  +
           82  +		let fmt (d: date) : string = (
           83  +			(strify d.years) ^ " Gregorian years and " ^
           84  +			(strify d.days) ^ " days"
           85  +		)
           86  +	end
           87  +end
           88  +
           89  +module Society = struct
           90  +	module Span = struct
           91  +		let days = 256
           92  +		let earth_days_in_year = 414
           93  +		let day = Gregorian.Span.day_equiv days earth_days_in_year
           94  +		let rantis = day / 64
           95  +		let year = day * days
           96  +
           97  +		let equiv (d: date): timespan =
           98  +			(year * d.years) + (day * d.days)
           99  +
          100  +		let calc (span: timespan) : date =
          101  +			let ctdays = span / day in
          102  +			let ctyears = ctdays / days in
          103  +			let rem = ctdays mod days in
          104  +				{years = ctyears; days = rem}
          105  +
          106  +		let fmt (d : date) : string =
          107  +			("Sh." ^ (strify d.years) ^ "/" ^ (strify d.days))
          108  +	end
          109  +
          110  +	module Cal = struct
          111  +		let zero = galacticzero + (0 * Span.year)
          112  +
          113  +		let equiv (d: date): timepoint =
          114  +			zero + (Span.year * d.years) + (Span.day * d.days)
          115  +
          116  +		let calc (pt: timepoint) : date =
          117  +			let adj = pt - zero in
          118  +			let span = Span.calc adj in
          119  +				{years = span.years; days = span.days; }
          120  +
          121  +		let fmt (d: date) : string =
          122  +			("R" ^ (strify d.years) ^ "/" ^ (strify d.days))
          123  +	end
          124  +end
          125  +
          126  +module Empire = struct
          127  +	module Span = struct
          128  +		let days = 376
          129  +		let earth_days_in_year = 394
          130  +		let day = Gregorian.Span.day_equiv days earth_days_in_year
          131  +		let year = day * days
          132  +
          133  +		let equiv (d: date): timespan =
          134  +			(year * d.years) + (day * d.days)
          135  +
          136  +		let calc (span: timespan) : date =
          137  +			let ctdays = span / day in
          138  +			let ctyears = ctdays / days in
          139  +			let rem = ctdays mod days in
          140  +				{years = ctyears; days = rem}
          141  +
          142  +		let fmt (d : date) : string =
          143  +			((strify d.years)^" Old Carnelian orbital years, "^(strify d.days)^" days")
          144  +	end
          145  +
          146  +	module Cal = struct
          147  +		let zero = Society.Cal.zero + (524 * Span.year)
          148  +
          149  +		let equiv (d: date): timepoint =
          150  +			zero + (Span.year * d.years) + (Span.day * d.days)
          151  +
          152  +		let calc (pt: timepoint) : date =
          153  +			let adj = pt - zero in
          154  +			let span = Span.calc adj in
          155  +				{years = span.years; days = span.days; }
          156  +
          157  +		let fmt (d: date) : string =
          158  +			((strify d.years)^"ᵉ and "^(strify d.days)^" days")
          159  +	end
          160  +end
          161  +
          162  +module League = struct
          163  +	module Span = struct
          164  +		let days = 300
          165  +		let earth_days_in_year = 388
          166  +		let day = Gregorian.Span.day_equiv days earth_days_in_year
          167  +		let year = day * days
          168  +
          169  +		let equiv (d: date): timespan =
          170  +			(year * d.years) + (day * d.days)
          171  +
          172  +		let calc (span: timespan) : date =
          173  +			let ctdays = span / day in
          174  +			let ctyears = ctdays / days in
          175  +			let rem = ctdays mod days in
          176  +				{years = ctyears; days = rem}
          177  +
          178  +		let fmt (d : date) : string =
          179  +			((strify d.years)^" Topaz orbital years, "^(strify d.days)^" days")
          180  +	end
          181  +
          182  +	module Cal = struct
          183  +		let zero = Society.Cal.zero + (928 * Society.Span.year)
          184  +
          185  +		let equiv (d: date): timepoint =
          186  +			zero + (Span.year * d.years) + (Span.day * d.days)
          187  +
          188  +		let calc (pt: timepoint) : date =
          189  +			let adj = pt - zero in
          190  +			let span = Span.calc adj in
          191  +				{years = span.years; days = span.days; }
          192  +
          193  +		let fmt (d: date) : string =
          194  +			("L."^(strify d.years)^"."^(strify d.days))
          195  +	end
          196  +end
          197  +
          198  +(*
          199  +let test () = let time : timepoint = Empire.Cal.equiv {years=953; days=38} in
          200  +	let span : timespan = time - galacticzero in
          201  +	List.iter print_string [
          202  +		"\x1b[1m"^ Gregorian.Span.(fmt(calc time)) ^" from Creation\x1b[0m\n";
          203  +		Society.Span.(fmt(calc span)) ^" from Creation →\n\t";
          204  +		Society.Cal.(fmt(calc time)) ^"\n";
          205  +		Empire.Span.(fmt(calc span)) ^" from Creation →\n\t";
          206  +		Empire.Cal.(fmt(calc time)) ^"\n";
          207  +		League.Span.(fmt(calc span)) ^" from Creation →\n\t";
          208  +		League.Cal.(fmt(calc time)) ^"\n";
          209  +	]
          210  +*)
          211  +
          212  +let usage arrow ansi hl bin = 
          213  +	let heading = "usage: " in
          214  +	let syntax = [
          215  +		"<faction> [year <year>] [day <day>] to <faction>",
          216  +			"convert a calendar date";
          217  +		"<number> <faction> (days | years [<days> days]) to <faction>",
          218  +			"convert a span of time";
          219  +	] in
          220  +	let spacing = String.make (String.length heading) ' ' in
          221  +	let mkrow (s,d) = bin ^ " " ^ (ansi "96" s) ^"\n" ^
          222  +		spacing ^ ((ansi "3;95" ("  "^arrow^" " ^ d))^"\n") in
          223  +	let space s = spacing ^ (mkrow s) in
          224  +	let fst = (hl heading) ^ (mkrow (List.hd syntax)) in
          225  +	let rst = List.map space (List.tl syntax) in
          226  +		List.fold_left (^) fst rst;;
          227  +
          228  +type funcset = {
          229  +	calc : int -> date;
          230  +	fmt : date -> string;
          231  +	equiv : date -> int;
          232  +}
          233  +
          234  +type funcrow = {
          235  +	names : string list;
          236  +	fmt : string;
          237  +	span : funcset;
          238  +	cal : funcset;
          239  +}
          240  +
          241  +
          242  +let funcs : funcrow list = [
          243  +	(* Society *) {
          244  +		names=["society"; "shil"; "ranshil"; "rs"];
          245  +		fmt="92";
          246  +		span = {
          247  +			calc=Society.Span.calc;
          248  +			fmt=Society.Span.fmt;
          249  +			equiv=Society.Span.equiv;
          250  +		};
          251  +		cal = {
          252  +			calc=Society.Cal.calc;
          253  +			fmt=Society.Cal.fmt;
          254  +			equiv=Society.Cal.equiv;
          255  +		};
          256  +	};
          257  +	(* Empire *) {
          258  +		names=["empire"; "ziapha"; "zp"; "imperial"];
          259  +		fmt="91";
          260  +		span = {
          261  +			calc =Empire.Span.calc;
          262  +			fmt  =Empire.Span.fmt;
          263  +			equiv=Empire.Span.equiv;
          264  +		};
          265  +		cal = {
          266  +			calc   =Empire.Cal.calc;
          267  +			fmt    =Empire.Cal.fmt;
          268  +			equiv  =Empire.Cal.equiv;
          269  +		};
          270  +	};
          271  +	(* League *) {
          272  +		names=["league"; "ly"];
          273  +		fmt="96";
          274  +		span = {
          275  +			calc =League.Span.calc;
          276  +			fmt  =League.Span.fmt;
          277  +			equiv=League.Span.equiv;
          278  +		};
          279  +		cal = {
          280  +			calc   =League.Cal.calc;
          281  +			fmt    =League.Cal.fmt;
          282  +			equiv  =League.Cal.equiv;
          283  +		};
          284  +	};
          285  +	(* Gregorian *) {
          286  +		names=["gregorian"; "terrestrial"; "earth"; "gy"];
          287  +		fmt="95";
          288  +		span = {
          289  +			calc  = Gregorian.Span.calc;
          290  +			fmt   = Gregorian.Span.fmt;
          291  +			equiv = Gregorian.Span.equiv;
          292  +		};
          293  +		cal = {
          294  +			(* gregorian dates do not reference the same
          295  +			 * spacetime continuum that Spirals dates do,
          296  +			 * so any attempt to convert between calendars
          297  +			 * needs to raise an exception *)
          298  +			calc  = bad_dim;
          299  +			fmt   = bad_dim;
          300  +			equiv = bad_dim;
          301  +		};
          302  +	};
          303  +]
          304  +
          305  +let contains ar v : bool = List.exists (fun a -> a = v) ar
          306  +
          307  +let getfuncs (tag: string) : funcrow = List.find
          308  +	(* pred *) (fun (a:funcrow) -> contains a.names tag)
          309  +	(* from array *) funcs
          310  +
          311  +type convkind = Calendar | Timespan
          312  +
          313  +let conv (kind: convkind) tagfrom tagto years days =
          314  +	let choosefuncs system = match kind with
          315  +		| Calendar -> system.cal
          316  +		| Timespan -> system.span in
          317  +	let from_funcs = getfuncs tagfrom in
          318  +	let to_funcs = getfuncs tagto in
          319  +	let from_sys = choosefuncs from_funcs in
          320  +	let to_sys = choosefuncs to_funcs in
          321  +	let indate = {years = years; days = days} in
          322  +	let time = from_sys.equiv indate in
          323  +	let outdate = to_sys.calc time in
          324  +	let instr = from_sys.fmt indate in
          325  +	let outstr = to_sys.fmt outdate in
          326  +		(from_funcs.fmt, instr, to_funcs.fmt, outstr)
          327  +
          328  +
          329  +let rec parse (opts: runopt list) (args: string list) (bin: string) = let
          330  +	has_opt o = List.exists (fun a -> a = o) opts in
          331  +	let switch o a b = if has_opt o then a else b in
          332  +
          333  +	let ansi (fmt: string) (str: string) = switch NoANSI str
          334  +		("\x1b["^fmt^"m"^str^"\x1b[m") in
          335  +	let hl txt = switch NoANSI txt
          336  +		("\x1b[1m" ^ txt ^ "\x1b[21m") in
          337  +
          338  +	let res_fmt (inf,ind,outf,outd) =
          339  +		(ansi inf ind) ^ (switch ASCII " -> " " → ") ^ (ansi outf (hl outd)) in
          340  +
          341  +	match args with
          342  +	| opt :: rst when is_opt opt -> let o = opt_of_str opt in
          343  +		(* (print_string ("running conv with flag "^opt^"!\n")); *)
          344  +		parse (o :: opts) rst bin
          345  +	| [fromcal; "to"; calendar] ->
          346  +		(res_fmt (conv Timespan fromcal calendar 1 0))^"\n" ^
          347  +		(res_fmt (conv Timespan fromcal calendar 0 1))^"\n"
          348  +	| [fromcal; "date"; date; "to"; calendar]
          349  +	| [fromcal; "year"; date; "to"; calendar] ->
          350  +		(res_fmt (conv Calendar fromcal calendar (int_of_string date) 0))^"\n"
          351  +	| [fromcal; "year"; years; "day"; days; "to"; calendar] ->
          352  +		(res_fmt (conv Calendar fromcal calendar
          353  +			(int_of_string years)
          354  +			(int_of_string days)))^"\n"
          355  +	| [count; from; "years"; "to"; system] ->
          356  +		(res_fmt (conv Timespan from system (int_of_string count) 0))^"\n"
          357  +	| [count; from; "days"; "to"; system] ->
          358  +		(res_fmt (conv Timespan from system 0 (int_of_string count)))^"\n"
          359  +	| [years; from; "years"; days; "days"; "to"; system] ->
          360  +		(res_fmt (conv Timespan from system
          361  +			(int_of_string years)
          362  +			(int_of_string days)))^"\n"
          363  +	| _ -> (usage (switch ASCII "->" "→") ansi hl bin);;
          364  +
          365  +let () = print_string (match (Array.to_list Sys.argv) with
          366  +	| bin :: rst -> parse [] rst bin
          367  +	| _ -> "buddy ya fucked up BAD");;

Modified xpriv.c from [c9d2d3baea] to [bebef73805].

   331    331   
   332    332   	size_t nsz;
   333    333   	const char* basename = argv[0], *p;
   334    334   	for (p = argv[0]; *p!=0; ++p) {
   335    335   		if(*p == '/') basename = p + 1;
   336    336   	}
   337    337   	nsz = p - basename;
   338         -	char shid[nsz + sizeof shmem_prefix + 0];
          338  +	char shid[nsz + sizeof shmem_prefix];
   339    339   	strncpy(shid,shmem_prefix,sizeof shmem_prefix);
   340    340   	strncpy(shid + sizeof shmem_prefix - 1, basename, nsz);
          341  +	shid[nsz + sizeof shmem_prefix - 1] = 0;
   341    342   
   342    343   	if (op == mode_go) {
   343    344   		int fd;
   344    345   		if ((fd = shm_open(shid, O_RDWR, 0600)) == -1) {
   345    346   			const char* args[] = {
   346    347   				"urxvtc", "-bg", "[90]#4b0024",
   347    348   				          "-e",  argv[0],