169 lines · 3.1 KB · C
RawDownload
#include <u.h>#include <libc.h>#include "xml.h"#include "xmpp.h" Target **targets;int curr, numtargets; inttargmatches(Target *t, char *s, int n){	return	(t->name != nil && strncmp(t->name, s, n) == 0) ||			(t->jid  != nil && strncmp(t->jid,  s, n) == 0);} static intcmptarg(void *a, void *b){	Target *ta, *tb;	int r; 	ta = *(void**)a;	tb = *(void**)b;	if(ta->name != nil && tb->name != nil)		r = strcmp(ta->name, tb->name);	else		r = strcmp(ta->jid, tb->jid);	if(r == 0 && ta->type == Erost && tb->type == Erost)		return (ta->rost.flags & Fonline) ? -1 : 1;	return r;} static voidsorttargets(void){	Target *t; 	t = (curr >= 0) ? targets[curr] : nil;	qsort(targets, numtargets, sizeof(t), cmptarg);	if(t != nil){		for(curr = 0; curr < numtargets; curr++)			if(targets[curr] == t)				break;	}} Target*addtarget(int type, char *name){	Target *t; 	numtargets++;	if(numtargets == 1 || (numtargets & (numtargets-1)) == 0)		targets = realloc(targets, sizeof(t)*numtargets*2);	if(targets == nil)		sysfatal("%r");	t = targets[numtargets-1] = mallocz(sizeof(*t), 1);	if(t == nil)		sysfatal("%r");	t->type = type;	t->name = strdup(name);	sorttargets();	return t;} voidrmtarget(Target *t){	int i; 	if(curr >= 0 && targets[curr] == t){		setlabel("", nil);		curr = -1;	}	free(t->name);	free(t->jid); 	if(t->type == Erost)		free(t->rost.show);	else if(t->type == Emucent){		free(t->mucent.jid);		free(t->mucent.show);	}else if(t->type == Emuc)		free(t->muc.subj); 	free(t);	for(i = 0; i < numtargets; i++){		if(targets[i] == t){			numtargets--;			memcpy(&targets[i], &targets[i+1], sizeof(t)*(numtargets-i));			if(curr > i)				curr--;			t = nil;			break;		}	}	if(t != nil)		sysfatal("rmtarget: not found");} intcmdtarget(int, int argc, char **argv){	Target *t;	char *a, *b;	int i, cycle, alen, blen; 	if(argc < 2){		curr = -1;		setlabel("", nil);		return 0;	} 	a = argv[1];	b = strchr(a, '/');	if(b == nil){		blen = 0;		alen = strlen(a);	}else{		b++;		blen = strlen(b);		alen = b-1 - a;	} 	for(cycle = 0, i = curr+1; cycle < 2; cycle++){		for(; i < numtargets; i++){			char *s;			t = targets[i];			if(b == nil && t->type == Emuc && targmatches(t, a, alen)){				setlabel(t->jid, nil);				curr = i;				return 0;			}			if(t->type == Erost && targmatches(t, a, alen) && (b == nil || strncmp(t->jid, b, blen) == 0)){				s = smprint("%t", t);				setlabel(s, (t->rost.flags & Fonline) ? t->rost.show : "offline");				free(s);				curr = i;				return 0;			}			if(t->type == Emucent && b != nil && targmatches(t->mucent.room, a, alen) && strncmp(t->name, b, blen) == 0){				s = smprint("%t", t);				setlabel(s, nil);				free(s);				curr = i;				return 0;			}		}		i = 0;	} 	print("no such target: %q\n", a);	return 0;} inttargetfmt(Fmt *f){	Target *t; 	t = va_arg(f->args, Target*);	if(t->type == Erost && curr >= 0 && targets[curr] == t)		return fmtprint(f, "%s", t->name);	if(t->type == Emucent)		return fmtprint(f, "%s/%s", t->mucent.room->name, t->name);	if(t->jid == nil)		return fmtprint(f, "%s", t->name);	return fmtprint(f, "%s/%s", t->name, t->jid);}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t