domfs

Document Object Model as a filesystem for plan9 os
git clone git://nsmpr.xyz/domfs.git
Log | Files | Refs | README

tree.c (2954B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <String.h>
      4 #include <thread.h>
      5 
      6 #include "html5dom.h"
      7 
      8 Treeconstrctl *tctl;
      9 String *tstr;
     10 char *tnode;
     11 
     12 void
     13 nwrite(char *strnode, char *strfile, char *data, long n)
     14 {
     15 	int fd;
     16 	char *path;
     17 	path = smprint("%s/%s/%s", tctl->treeroot, strnode, strfile);
     18 	fd = create(path, OWRITE, 0);
     19 	if (fd < 0) sysfatal("failed to create %s, %r", path);
     20 	free(path);
     21 	write(fd, data, n);
     22 	write(fd, "\n", 1);
     23 	close(fd);
     24 }
     25 
     26 char*
     27 newnode(void)
     28 {
     29 	int fd;
     30 	long n;
     31 	char *strnew, *strnode;
     32 	strnode = mallocz(64, 1);
     33 	strnew = smprint("%s/new", tctl->treeroot);
     34 	fd = open(strnew, OREAD);
     35 	if (fd < 0) sysfatal("failed to open %s, %r", strnew);
     36 	free(strnew);
     37 	n = read(fd, strnode, 64);
     38 	close(fd);
     39 	if (strnode[n-1] == '\n') strnode[n-1] = '\0';
     40 	return strnode;
     41 }
     42 
     43 char*
     44 getparent(char *node)
     45 {
     46 	int fd;
     47 	long n;
     48 	char *path;
     49 	char buf[1024];
     50 	char *args[8];
     51 	char *start, *end;
     52 	if (strcmp(node, "0") == 0) return strdup("0");
     53 	path = smprint("%s/%s/ctl", tctl->treeroot, node);
     54 	fd = open(path, OREAD);
     55 	if (fd < 0) sysfatal("failed to open %s, %r", path);
     56 	free(path);
     57 	n = readn(fd, buf, 1024);
     58 	close(fd);
     59 	buf[n] = '\0';
     60 	start = buf;
     61 	while (start < buf + n) {
     62 		for (end = start; *end != '\n'; end++)
     63 			if (*end == '\0') return 0;
     64 		*end = '\0';
     65 		tokenize(start, args, 8);
     66 		if (strcmp(args[0], "parent") == 0)
     67 			return strdup(args[1]);
     68 	}
     69 	return 0;
     70 }
     71 
     72 void
     73 adopt(char *parent, char *child)
     74 {
     75 	char buf[1024];
     76 	long n;
     77 	if (strcmp(parent, "0") != 0){
     78 		n = snprint(buf, 1024, "adopt %s", child);
     79 		nwrite(parent, "ctl", buf, n);
     80 	}
     81 }
     82 
     83 void
     84 pushchar(Rune c)
     85 {
     86 	if (tnode == nil) {
     87 		tnode = newnode();
     88 		nwrite(tnode, "type", "text", 4);
     89 		tstr = s_new();
     90 	}
     91 	s_putc(tstr, c);	
     92 }
     93 
     94 void
     95 pushtext(void)
     96 {
     97 	s_terminate(tstr);
     98 	nwrite(tnode, "text", s_to_c(tstr), strlen(s_to_c(tstr)));
     99 	s_free(tstr);
    100 	tstr = nil;
    101 	free(tnode);
    102 	tnode = nil;
    103 }
    104 
    105 void
    106 threadtreeconstr(void *v)
    107 {
    108 	char *tp;
    109 	char *strnode;
    110 	char *pnode;
    111 	int teof;
    112 	Token *tok;
    113 	teof = 0;
    114 	tctl = v;
    115 	tok = nil;
    116 	pnode = strdup("0");
    117 	threadsetname("treeconstr");
    118 	while(teof == 0){
    119 		recv(tctl->in, &tok);
    120 		switch(tok->type){
    121 		case TDOCT:
    122 			strnode = newnode();
    123 			nwrite(strnode, "type", "doctype", 7);
    124 			nwrite(strnode, "name", s_to_c(tok->name),
    125 				strlen(s_to_c(tok->name)));
    126 			free(strnode);
    127 			break;
    128 		case TSTART:
    129 			if (tnode != nil) {
    130 				adopt(pnode, tnode);
    131 				pushtext();
    132 			}
    133 			strnode = newnode();
    134 			nwrite(strnode, "type", "element", 7);
    135 			nwrite(strnode, "name", s_to_c(tok->name),
    136 				strlen(s_to_c(tok->name)));
    137 			adopt(pnode, strnode);
    138 			if ((tok->flags & TF_SELF_CLOSING) == 0) {
    139 				tp = pnode;
    140 				pnode = strdup(strnode);
    141 				free(tp);
    142 				free(strnode);
    143 			}
    144 			break;
    145 		case TEND:
    146 			if (tnode != nil) {
    147 				adopt(pnode, tnode);
    148 				pushtext();
    149 			}
    150 			tp = pnode;
    151 			pnode = getparent(pnode);
    152 			free(tp);
    153 			break;
    154 		case TCHAR:
    155 			pushchar(tok->c);
    156 			break;
    157 		case TEOF:
    158 			teof = 1;
    159 		}
    160 		t_free(tok);
    161 	}
    162 }