xref: /plan9-contrib/sys/src/games/music/jukefs/print.c (revision 57ea29230156334add5f192279098aead66e5fca)
1 #include <u.h>
2 #include <libc.h>
3 #include <ctype.h>
4 #include <bio.h>
5 #include <thread.h>
6 #include "object.h"
7 #include "parse.h"
8 #include "catset.h"
9 
10 int	fflag;
11 
12 void
listfiles(Object * o)13 listfiles(Object *o)
14 {
15 	int i;
16 
17 	if(o->type == File){
18 		print("%s\n", o->value);
19 		return;
20 	}
21 	for(i = 0; i < o->nchildren; i++)
22 		if(o->children[i]->parent == o)
23 			listfiles(o->children[i]);
24 }
25 
26 int
indent(char * lp,int ln,int n,char * buf)27 indent(char *lp, int ln, int n, char *buf) {
28 	int sln;
29 	char *p, c;
30 
31 	sln = ln;
32 	if (ln <= 0)
33 		return 0;
34 	if (n < 0)
35 		n = -n;
36 	else {
37 		if (ln < 4*n)
38 			goto out;
39 		memset(lp, ' ', 4*n);
40 		lp += 4*n;
41 		ln -= 4*n;
42 	}
43 	if(p = buf) while (ln > 1) {
44 		c = *p++;
45 		if(c == '\0')
46 			break;
47 		if(c == '~')
48 			continue;
49 		*lp++ = c;
50 		ln--;
51 		if (c == '\n' && p[1]) {
52 			if (ln < 4*n)
53 				break;
54 			memset(lp, ' ', 4*n);
55 			lp += 4*n;
56 			ln -= 4*n;
57 		}
58 	}
59 	*lp = '\0';
60 out:
61 	return sln - ln;
62 }
63 
64 long
printchildren(char * lp,int ln,Object * o)65 printchildren(char *lp, int ln, Object *o) {
66 	int i, r;
67 	char *sp;
68 
69 	sp = lp;
70 	if (o->flags & Sort) {
71 		childsort(o);
72 		o->flags &= ~Sort;
73 	}
74 	for(i = 0; i < o->nchildren && ln > 0; i++){
75 		r = snprint(lp, ln, "%d\n", o->children[i]->tabno);
76 		lp += r;
77 		ln -= r;
78 	}
79 	return lp - sp;
80 }
81 
82 long
printminiparentage(char * lp,int ln,Object * o)83 printminiparentage(char *lp, int ln, Object *o) {
84 	char *p, c;
85 	int r, sln;
86 
87 	if (ln <= 0) return 0;
88 	*lp = '\0';
89 	if (o == 0 || o->type == Root)
90 		return 0;
91 	sln = ln;
92 	if(o->orig) o = o->orig;
93 	r = printminiparentage(lp, ln, o->parent);
94 	lp += r;
95 	ln -= r;
96 	if (ln <= 0) return 0;
97 	if(o->value && o->type != File){
98 		if(r && o->value && ln > 1){
99 			*lp++ = '/';
100 			ln--;
101 		}
102 		p = o->value;
103 		while(ln > 0){
104 			c = *p++;
105 	    		if(c == '\n' || c == '\0')
106 	    			break;
107 			if(c == '~')
108 				continue;
109 			*lp++ = c;
110 			ln--;
111 		}
112 	}
113 	if(ln > 0)
114 		*lp = '\0';
115 	return sln - ln;
116 }
117 
118 long
printparentage(char * lp,int ln,Object * o)119 printparentage(char *lp, int ln, Object *o) {
120 	int i;
121 	int r, k, sln;
122 
123 	if(ln <= 0)
124 		return 0;
125 	*lp = '\0';
126 	if(o == 0 || o->type == Root)
127 		return 0;
128 	if(0)fprint(2, "parentage 0x%p %d type %d value 0x%p parent 0x%p %d\n", o, o->tabno, o->type, o->value, o->parent, o->parent->tabno);
129 	if(o->orig){
130 		if(0)fprint(2, "parentage 0x%p %d type %d orig %d type %d parent 0x%p %d\n", o, o->tabno, o->type, o->orig->tabno, o->orig->type, o->orig->parent, o->orig->parent->tabno);
131 		o = o->orig;
132 	}
133 	sln = ln;
134 	r = printparentage(lp, ln, o->parent);
135 	lp += r; ln -= r;
136 	if(o->type == File && fflag == 0){
137 		if(ln > 0)
138 			*lp = '\0';
139 		return sln - ln;
140 	}
141 	if(o->value && *o->value && ln > 0){
142 		if(o->type == Category){
143 			if(o->parent == root){
144 				r = snprint(lp, ln, "category: ");
145 				lp += r; ln -= r;
146 			}else{
147 				for(k = Ntoken; k < ntoken; k++)
148 					if(catseteq(&o->categories,&tokenlist[k].categories)){
149 						r = snprint(lp, ln, "%s: ", tokenlist[k].name);
150 						lp += r; ln -= r;
151 						break;
152 					}
153 			}
154 		}else{
155 			r = snprint(lp, ln, "%s: ", tokenlist[o->type].name);
156 			lp += r; ln -= r;
157 		}
158 		if(ln <= 0)
159 			return sln - ln;
160 		if(o->num){
161 			r = snprint(lp, ln, "%2d. ", o->num);
162 			lp += r; ln -= r;
163 		}
164 		if(ln <= 0)
165 			return sln - ln;
166 		r = indent(lp, ln, -1, o->value);
167 		lp += r; ln -= r;
168 		if(ln > 1){
169 			*lp++ = '\n';
170 			ln--;
171 		}
172 	}else{
173 		if(0)fprint(2, "parentage 0x%p %d type %d no value\n", o, o->tabno, o->type);
174 	}
175 	for(i = 0; i < o->nchildren && ln > 0; i++)
176 		switch(o->children[i]->type){
177 		case Performance:
178 		case Soloists:
179 		case Lyrics:
180 			r = snprint(lp, ln, "%s: ", tokenlist[o->children[i]->type].name);
181 			lp += r; ln -= r;
182 			if(ln <= 0)
183 				break;
184 			r = indent(lp, ln, -1, o->children[i]->value);
185 			lp += r; ln -= r;
186 			if(ln > 1){
187 				*lp++ = '\n';
188 				ln--;
189 			}
190 			break;
191 		case Time:
192 			r = snprint(lp, ln, "%s: %s\n", "duration", o->children[i]->value);
193 			lp += r; ln -= r;
194 			break;
195 		case File:
196 			if(fflag){
197 				r = snprint(lp, ln, "%s: %s\n", "file", o->children[i]->value);
198 				lp += r; ln -= r;
199 			}
200 			break;
201 		default:
202 			break;
203 		}
204 	if(ln > 0)
205 		*lp = '\0';
206 	return sln - ln;
207 }
208 
209 long
printparent(char * lp,int ln,Object * o)210 printparent(char *lp, int ln, Object *o) {
211 	return snprint(lp, ln, "%d", o->parent->tabno);
212 }
213 
214 long
printkey(char * lp,int ln,Object * o)215 printkey(char *lp, int ln, Object *o) {
216 	return snprint(lp, ln, "%s", o->key?o->key:o->value);
217 }
218 
219 long
printtype(char * lp,int ln,Object * o)220 printtype(char *lp, int ln, Object *o) {
221 	return snprint(lp, ln, "%s", tokenlist[o->type].name);
222 }
223 
224 long
printtext(char * lp,int ln,Object * o)225 printtext(char *lp, int ln, Object *o) {
226 	return snprint(lp, ln, "%s", o->value?o->value:o->key);
227 }
228 
229 long
printfulltext(char * lp,int ln,Object * o)230 printfulltext(char *lp, int ln, Object *o) {
231 	char *sp, *p, *q;
232 	int i, j, k, c, depth;
233 	Object *oo;
234 
235 	depth = 0;
236 	sp = lp;
237 	switch(o->type){
238 	case Category:
239 		if(o->parent == root){
240 			j = snprint(lp, ln, "category:");
241 			lp += j; ln -= j;
242 		}else{
243 			for(k = Ntoken; k < ntoken; k++)
244 				if(catseteq(&o->categories, &tokenlist[k].categories)){
245 					j = snprint(lp, ln, "%s:", tokenlist[k].name);
246 					lp += j; ln -= j;
247 					break;
248 				}
249 		}
250 		if(ln <= 0)
251 			return lp - sp;
252 		p = o->value;
253 		if(p == nil)
254 			p = o->key;
255 		if((q = strchr(p, '\n')) && q[1] != '\0'){
256 			// multiple lines
257 			*lp++ = '\n'; ln--;
258 			if(ln <= 0)
259 				break;
260 			j = indent(lp, ln, depth+1, p);
261 			lp += j; ln -= j;
262 		}else{
263 			*lp++ = ' '; ln--;
264 			while((c=*p++) && ln > 0){
265 				if(c == '~')
266 					continue;
267 				*lp++ = c;
268 				ln--;
269 				if(c == '\n')
270 					break;
271 			}
272 		}
273 		break;
274 	case Track:
275 	case Part:
276 	case Recording:
277 	case Root:
278 	case Search:
279 	case Work:
280 		j = snprint(lp, ln, "%s:", tokenlist[o->type].name);
281 		lp += j; ln -= j;
282 		if(ln <= 0)
283 			break;
284 		if(o->num){
285 			j = snprint(lp, ln, " %2d.", o->num);
286 			lp += j; ln -= j;
287 		}
288 		if(ln <= 0)
289 			break;
290 		p = o->value;
291 		if(p == nil)
292 			p = o->key;
293 		if((q = strchr(p, '\n')) && q[1] != '\0'){
294 			// multiple lines
295 			*lp++ = '\n'; ln--;
296 			if(ln <= 0)
297 				break;
298 			j = indent(lp, ln, depth+1, p);
299 			lp += j; ln -= j;
300 		}else{
301 			*lp++ = ' '; ln--;
302 			while((c =*p++) && ln > 0){
303 				if(c == '~')
304 					continue;
305 				*lp++ = c;
306 				ln--;
307 				if(c == '\n')
308 					break;
309 			}
310 		}
311 	default:
312 		break;
313 	}
314 	depth++;
315 	for(i = 0; i < o->nchildren && ln > 0; i++){
316 		oo = o->children[i];
317 		switch(oo->type){
318 		case Lyrics:
319 		case Performance:
320 		case Soloists:
321 		case Time:
322 			if (ln <= 4*depth + 1)
323 				break;
324 			*lp++ = '\n'; ln--;
325 			memset(lp, ' ', 4*depth);
326 			lp += 4*depth;
327 			ln -= 4*depth;
328 			if(ln <= 0)
329 				break;
330 			j = snprint(lp, ln, "%s:", tokenlist[oo->type].name);
331 			lp += j; ln -= j;
332 			if(ln <= 0)
333 				break;
334 			p = oo->value;
335 			if(ln <= 1)
336 				break;
337 			if((q = strchr(p, '\n')) && q[1] != '\0'){
338 				// multiple lines
339 				*lp++ = '\n'; ln--;
340 				j = indent(lp, ln, depth+1, p);
341 				lp += j; ln -= j;
342 			}else{
343 				*lp++ = ' '; ln--;
344 				while((c =*p++) && ln > 0){
345 					if(c == '~')
346 						continue;
347 					*lp++ = c;
348 					ln--;
349 					if(c == '\n')
350 						break;
351 				}
352 			}
353 		}
354 	}
355 	*lp = '\0';
356 	return lp - sp;
357 }
358 
359 long
printfiles(char * lp,int ln,Object * o)360 printfiles(char *lp, int ln, Object *o) {
361 	int i, r;
362 	char *sp;
363 
364 	sp = lp;
365 	if (o->type == File)
366 		lp += snprint(lp, ln, "%d	%s\n", o->tabno, o->value);
367 	else {
368 		for (i = 0; i < o->nchildren && ln > 0; i++){
369 			r = printfiles(lp, ln, o->children[i]);
370 			lp += r;
371 			ln -= r;
372 		}
373 	}
374 	return lp - sp;
375 }
376 
377 long
printdigest(char * lp,int ln,Object * o)378 printdigest(char *lp, int ln, Object *o) {
379 	char *p;
380 	int j, c, k;
381 	char *sp;
382 
383 	sp = lp;
384 	switch(o->type){
385 	case Category:
386 		if (o->parent == root) {
387 			j = snprint(lp, ln, "category: ");
388 			lp += j; ln -= j;
389 		} else {
390 			for (k = Ntoken; k < ntoken; k++)
391 				if (catseteq(&o->categories,& tokenlist[k].categories)) {
392 					j = snprint(lp, ln, "%s: ", tokenlist[k].name);
393 					lp += j; ln -= j;
394 //					break;
395 				}
396 		}
397 		p = o->value;
398 		if (p == 0) p = o->key;
399 		while ((c=*p++) && c != '\n' && ln > 0) {
400 			if(c == '~')
401 				continue;
402 			*lp++ = c;
403 			ln--;
404 		}
405 		break;
406 	case Track:
407 	case Part:
408 	case Recording:
409 	case Root:
410 	case Search:
411 	case Work:
412 		j = snprint(lp, ln, "%s: ", tokenlist[o->type].name);
413 		lp += j; ln -= j;
414 		if (o->num) {
415 			j = snprint(lp, ln, "%2d. ", o->num);
416 			lp += j; ln -= j;
417 		}
418 		p = o->value;
419 		if (p == 0) p = o->key;
420 		while ((c = *p++) && c != '\n' && ln > 0) {
421 			if(c == '~')
422 				continue;
423 			*lp++ =  c;
424 			ln--;
425 		}
426 	default:
427 		break;
428 	}
429 	if(ln)
430 		*lp = '\0';
431 	return lp - sp;
432 }
433 
434 #ifdef UNDEF
435 
436 void
printtree(Object * o,int ind)437 printtree(Object *o, int ind) {
438 	char *p;
439 	char buf[2048];
440 	int i;
441 
442 	sprintf(buf, "%s {\n", tokenlist[o->type].name);
443 	indent(ind, buf);
444 	ind++;
445 	if ((p = o->value)) {
446 		sprintf(buf, "%s\n", p);
447 		indent(ind, buf);
448 	}
449 	for (i = 0; i < o->nchildren; i++)
450 		printtree(o->children[i], ind);
451 	indent(--ind, "}\n");
452 }
453 
454 void
mapdump(Object * o,int depth,char * inheritance)455 mapdump(Object *o, int depth, char *inheritance) {
456 	Object *oo;
457 	char *data;
458 	int n, l;
459 
460 	if (o == root) {
461 	    depth = 0;
462 	    inheritance = "";
463 	    data = NULL;
464 	} else {
465 	    if (o->value) {
466 		l = nlines(o->value);
467 	        n = strlen(inheritance) +
468 		    l * (strlen(tokenlist[o->type].name) + 2) +
469 		    strlen(o->value) + 2;
470 		data = mymalloc(NULL, n);
471 		strcpy(data, inheritance);
472 		p = data + strlen(inheritance);
473 		q = o->value;
474 		while (*q) {
475 		    p += sprintf(p, "%s:\t", tokenlist[o->type].name);
476 		    do {
477 			*p++ = *q;
478 		    while (*q++ != '\n');
479 		}
480 		if (p[-1] != '\n') *p++ = '\n';
481 		*p = 0;
482 		inheritance = data;
483 	    }
484 	    indent(depth, inheritance);
485 	}
486 	c = 0;
487 }
488 
489 #endif
490