#include <u.h>
#include <libc.h>
#include <ctype.h>
#include <bio.h>
#include <thread.h>
#include "object.h"
#include "parse.h"
#include "catset.h"
int fflag;
void
listfiles(Object *o)
{
int i;
if(o->type == File){
print("%s\n", o->value);
return;
}
for(i = 0; i < o->nchildren; i++)
if(o->children[i]->parent == o)
listfiles(o->children[i]);
}
int
indent(char *lp, int ln, int n, char *buf) {
int sln;
char *p, c;
sln = ln;
if (ln <= 0)
return 0;
if (n < 0)
n = -n;
else {
if (ln < 4*n)
goto out;
memset(lp, ' ', 4*n);
lp += 4*n;
ln -= 4*n;
}
if(p = buf) while (ln > 1) {
c = *p++;
if(c == '\0')
break;
if(c == '~')
continue;
*lp++ = c;
ln--;
if (c == '\n' && p[1]) {
if (ln < 4*n)
break;
memset(lp, ' ', 4*n);
lp += 4*n;
ln -= 4*n;
}
}
*lp = '\0';
out:
return sln - ln;
}
long
printchildren(char *lp, int ln, Object *o) {
int i, r;
char *sp;
sp = lp;
if (o->flags & Sort) {
childsort(o);
o->flags &= ~Sort;
}
for(i = 0; i < o->nchildren && ln > 0; i++){
r = snprint(lp, ln, "%d\n", o->children[i]->tabno);
lp += r;
ln -= r;
}
return lp - sp;
}
long
printminiparentage(char *lp, int ln, Object *o) {
char *p, c;
int r, sln;
if (ln <= 0) return 0;
*lp = '\0';
if (o == 0 || o->type == Root)
return 0;
sln = ln;
if(o->orig) o = o->orig;
r = printminiparentage(lp, ln, o->parent);
lp += r;
ln -= r;
if (ln <= 0) return 0;
if(o->value && o->type != File){
if(r && o->value && ln > 1){
*lp++ = '/';
ln--;
}
p = o->value;
while(ln > 0){
c = *p++;
if(c == '\n' || c == '\0')
break;
if(c == '~')
continue;
*lp++ = c;
ln--;
}
}
if(ln > 0)
*lp = '\0';
return sln - ln;
}
long
printparentage(char *lp, int ln, Object *o) {
int i;
int r, k, sln;
if(ln <= 0)
return 0;
*lp = '\0';
if(o == 0 || o->type == Root)
return 0;
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);
if(o->orig){
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);
o = o->orig;
}
sln = ln;
r = printparentage(lp, ln, o->parent);
lp += r; ln -= r;
if(o->type == File && fflag == 0){
if(ln > 0)
*lp = '\0';
return sln - ln;
}
if(o->value && *o->value && ln > 0){
if(o->type == Category){
if(o->parent == root){
r = snprint(lp, ln, "category: ");
lp += r; ln -= r;
}else{
for(k = Ntoken; k < ntoken; k++)
if(catseteq(&o->categories,&tokenlist[k].categories)){
r = snprint(lp, ln, "%s: ", tokenlist[k].name);
lp += r; ln -= r;
break;
}
}
}else{
r = snprint(lp, ln, "%s: ", tokenlist[o->type].name);
lp += r; ln -= r;
}
if(ln <= 0)
return sln - ln;
if(o->num){
r = snprint(lp, ln, "%2d. ", o->num);
lp += r; ln -= r;
}
if(ln <= 0)
return sln - ln;
r = indent(lp, ln, -1, o->value);
lp += r; ln -= r;
if(ln > 1){
*lp++ = '\n';
ln--;
}
}else{
if(0)fprint(2, "parentage 0x%p %d type %d no value\n", o, o->tabno, o->type);
}
for(i = 0; i < o->nchildren && ln > 0; i++)
switch(o->children[i]->type){
case Performance:
case Soloists:
case Lyrics:
r = snprint(lp, ln, "%s: ", tokenlist[o->children[i]->type].name);
lp += r; ln -= r;
if(ln <= 0)
break;
r = indent(lp, ln, -1, o->children[i]->value);
lp += r; ln -= r;
if(ln > 1){
*lp++ = '\n';
ln--;
}
break;
case Time:
r = snprint(lp, ln, "%s: %s\n", "duration", o->children[i]->value);
lp += r; ln -= r;
break;
case File:
if(fflag){
r = snprint(lp, ln, "%s: %s\n", "file", o->children[i]->value);
lp += r; ln -= r;
}
break;
default:
break;
}
if(ln > 0)
*lp = '\0';
return sln - ln;
}
long
printparent(char *lp, int ln, Object *o) {
return snprint(lp, ln, "%d", o->parent->tabno);
}
long
printkey(char *lp, int ln, Object *o) {
return snprint(lp, ln, "%s", o->key?o->key:o->value);
}
long
printtype(char *lp, int ln, Object *o) {
return snprint(lp, ln, "%s", tokenlist[o->type].name);
}
long
printtext(char *lp, int ln, Object *o) {
return snprint(lp, ln, "%s", o->value?o->value:o->key);
}
long
printfulltext(char *lp, int ln, Object *o) {
char *sp, *p, *q;
int i, j, k, c, depth;
Object *oo;
depth = 0;
sp = lp;
switch(o->type){
case Category:
if(o->parent == root){
j = snprint(lp, ln, "category:");
lp += j; ln -= j;
}else{
for(k = Ntoken; k < ntoken; k++)
if(catseteq(&o->categories, &tokenlist[k].categories)){
j = snprint(lp, ln, "%s:", tokenlist[k].name);
lp += j; ln -= j;
break;
}
}
if(ln <= 0)
return lp - sp;
p = o->value;
if(p == nil)
p = o->key;
if((q = strchr(p, '\n')) && q[1] != '\0'){
// multiple lines
*lp++ = '\n'; ln--;
if(ln <= 0)
break;
j = indent(lp, ln, depth+1, p);
lp += j; ln -= j;
}else{
*lp++ = ' '; ln--;
while((c=*p++) && ln > 0){
if(c == '~')
continue;
*lp++ = c;
ln--;
if(c == '\n')
break;
}
}
break;
case Track:
case Part:
case Recording:
case Root:
case Search:
case Work:
j = snprint(lp, ln, "%s:", tokenlist[o->type].name);
lp += j; ln -= j;
if(ln <= 0)
break;
if(o->num){
j = snprint(lp, ln, " %2d.", o->num);
lp += j; ln -= j;
}
if(ln <= 0)
break;
p = o->value;
if(p == nil)
p = o->key;
if((q = strchr(p, '\n')) && q[1] != '\0'){
// multiple lines
*lp++ = '\n'; ln--;
if(ln <= 0)
break;
j = indent(lp, ln, depth+1, p);
lp += j; ln -= j;
}else{
*lp++ = ' '; ln--;
while((c =*p++) && ln > 0){
if(c == '~')
continue;
*lp++ = c;
ln--;
if(c == '\n')
break;
}
}
default:
break;
}
depth++;
for(i = 0; i < o->nchildren && ln > 0; i++){
oo = o->children[i];
switch(oo->type){
case Lyrics:
case Performance:
case Soloists:
case Time:
if (ln <= 4*depth + 1)
break;
*lp++ = '\n'; ln--;
memset(lp, ' ', 4*depth);
lp += 4*depth;
ln -= 4*depth;
if(ln <= 0)
break;
j = snprint(lp, ln, "%s:", tokenlist[oo->type].name);
lp += j; ln -= j;
if(ln <= 0)
break;
p = oo->value;
if(ln <= 1)
break;
if((q = strchr(p, '\n')) && q[1] != '\0'){
// multiple lines
*lp++ = '\n'; ln--;
j = indent(lp, ln, depth+1, p);
lp += j; ln -= j;
}else{
*lp++ = ' '; ln--;
while((c =*p++) && ln > 0){
if(c == '~')
continue;
*lp++ = c;
ln--;
if(c == '\n')
break;
}
}
}
}
*lp = '\0';
return lp - sp;
}
long
printfiles(char *lp, int ln, Object *o) {
int i, r;
char *sp;
sp = lp;
if (o->type == File)
lp += snprint(lp, ln, "%d %s\n", o->tabno, o->value);
else {
for (i = 0; i < o->nchildren && ln > 0; i++){
r = printfiles(lp, ln, o->children[i]);
lp += r;
ln -= r;
}
}
return lp - sp;
}
long
printdigest(char *lp, int ln, Object *o) {
char *p;
int j, c, k;
char *sp;
sp = lp;
switch(o->type){
case Category:
if (o->parent == root) {
j = snprint(lp, ln, "category: ");
lp += j; ln -= j;
} else {
for (k = Ntoken; k < ntoken; k++)
if (catseteq(&o->categories,& tokenlist[k].categories)) {
j = snprint(lp, ln, "%s: ", tokenlist[k].name);
lp += j; ln -= j;
// break;
}
}
p = o->value;
if (p == 0) p = o->key;
while ((c=*p++) && c != '\n' && ln > 0) {
if(c == '~')
continue;
*lp++ = c;
ln--;
}
break;
case Track:
case Part:
case Recording:
case Root:
case Search:
case Work:
j = snprint(lp, ln, "%s: ", tokenlist[o->type].name);
lp += j; ln -= j;
if (o->num) {
j = snprint(lp, ln, "%2d. ", o->num);
lp += j; ln -= j;
}
p = o->value;
if (p == 0) p = o->key;
while ((c = *p++) && c != '\n' && ln > 0) {
if(c == '~')
continue;
*lp++ = c;
ln--;
}
default:
break;
}
if(ln)
*lp = '\0';
return lp - sp;
}
#ifdef UNDEF
void
printtree(Object *o, int ind) {
char *p;
char buf[2048];
int i;
sprintf(buf, "%s {\n", tokenlist[o->type].name);
indent(ind, buf);
ind++;
if ((p = o->value)) {
sprintf(buf, "%s\n", p);
indent(ind, buf);
}
for (i = 0; i < o->nchildren; i++)
printtree(o->children[i], ind);
indent(--ind, "}\n");
}
void
mapdump(Object *o, int depth, char *inheritance) {
Object *oo;
char *data;
int n, l;
if (o == root) {
depth = 0;
inheritance = "";
data = NULL;
} else {
if (o->value) {
l = nlines(o->value);
n = strlen(inheritance) +
l * (strlen(tokenlist[o->type].name) + 2) +
strlen(o->value) + 2;
data = mymalloc(NULL, n);
strcpy(data, inheritance);
p = data + strlen(inheritance);
q = o->value;
while (*q) {
p += sprintf(p, "%s:\t", tokenlist[o->type].name);
do {
*p++ = *q;
while (*q++ != '\n');
}
if (p[-1] != '\n') *p++ = '\n';
*p = 0;
inheritance = data;
}
indent(depth, inheritance);
}
c = 0;
}
#endif
|