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