Plan 9 from Bell Labs’s /usr/web/sources/contrib/quanstro/src/9term-nocolor/label.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


#include <u.h>
#include <libc.h>
#include <draw.h>
#include <keyboard.h>
#include <cursor.h>
#include <mouse.h>
#include <frame.h>
#include <thread.h>
#include "dat.h"
#include "fns.h"

extern Window *w;

typedef enum { 
	eZero=0, 
	eTitle, 
	eColor, 
	eInfinite,
} eType;

enum {
	ESC = 0x1b,
};

static void
esctitle(const Rune* start, const Rune* end)
{
	char* p;

//	fprint(2, "esctitle(%.*S)\n", end-start, start);

	p = smprint("%.*S", end-start-3, start+3);
	if(p){
		drawsetlabel(p);
		free(w->dir);
		w->dir = p;

		/* remove trailing /-sysname if present */
		p = strrchr(p, '/');
		if(p && *(p+1) == '-'){
			if(p == w->dir)
				p++;
			*p = 0;
		}
	}
}

static void 
esctitleonly(const Rune* start, const Rune* end)
{
	esctitle(start+1, end);
}

static void
esccolor(const Rune* start, const Rune* end)
{
//	fprint(2, "_ecolor(%#.*S)\n", end-start, start);
}

static void
escnop(const Rune* start, const Rune* end)
{
}

/* this parsing method isn't sufficient for every case.
   for example erase n characters is ESC [ <n> K
   so the color-wacking could eat too much if we get 
	"ESC [Kwhatever, man" → "an" oops

   also, if we match the start, we don't backtrack if 
   runstrnchar fails.
*/
struct {
	Rune start[5];
	char  end;
	eType esc;
	void (*fn)(const Rune*, const Rune*);
} esc_tab[] = {
	{{0}, 		0,	0,	escnop},
	{{']', ';', 0},	'\007',	eTitle, 	esctitle},
	{{']', '1', ';', 0},	'\007',	eTitle, 	escnop},		// set "icon" title only
	{{']', '2', ';', 0},	'\007',	eTitle,	esctitleonly},
	{{'[', 0},		'm',	eColor,	esccolor},
	0
};

static Rune* 
runestrnchr(const Rune* r, char c, unsigned long len){
	for(; len--; r++){
		if (c == *r){
//			fprint(2, "→ %.*S, %uld\n", len, r, len);
			return (Rune*)r;
		}
	}
	return 0;
}

eType
matchEsc(const Rune* r, const Rune* er, Rune** start, Rune** end)
{
	eType i;
	int j;
	int runesleft;

	if (er<r){
		return eZero;
	}
	runesleft = er-r;
	for(i=1; esc_tab[i].esc; i++){
		for(j=0; j<=runesleft && r[j] == esc_tab[i].start[j]; j++){
			if (0 == esc_tab[i].start[j+1])
				goto match;
		}
	}
//	fprint(2, "loosing on %uld runesleft %.*S\n", runesleft, runesleft, *start);
	return eZero;
match:
	*start = (Rune*)r;
	r += j+1;
	*end = runestrnchr(r, esc_tab[i].end, er-r);
	if (!*end)
		return eZero;
	return esc_tab[i].esc;
}

int
labelcooked(Rune *sr, int n)
{
	Rune *sl, *el, *er, *r;
	eType esctype;

	er = sr+n;
	esctype = eZero;

	for(r=sr; r<=er; ){
		if (*r == ESC){
			esctype = matchEsc(r+1, er, &sl, &el);
			if (!esctype){
				r++;
				continue;
			}
			esc_tab[esctype].fn(r, el);
			el++;
			runemove(r, el, er-el);
			n -= el-r;
			er = sr+n;
		} else
			r++;
	}

	return n;
}

int
labelnone(Rune *s, int n)
{
	return n;
}


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.