Esempio n. 1
0
static char *
rbody(Biobuf *in)
{
    Bufblock *buf;
    int r, lastr;
    char *p;

    lastr = '\n';
    buf = newbuf();
    for(;;) {
        r = Bgetrune(in);
        if (r < 0)
            break;
        if (lastr == '\n') {
            if (r == '#')
                rinsert(buf, r);
            else if (r != ' ' && r != '\t') {
                Bungetrune(in);
                break;
            }
        } else
            rinsert(buf, r);
        lastr = r;
        if (r == '\n')
            mkinline++;
    }
    insert(buf, 0);
    p = strdup(buf->start);
    freebuf(buf);
    return p;
}
Esempio n. 2
0
static void accept_connection(int fd, short what, void *arg) {
  struct sockaddr_in addr;
  socklen_t addrlen = sizeof(addr);
  int newfd = accept(fd, (struct sockaddr *) &addr, &addrlen);
  Connection *conn;

  if (newfd < 0)
    return;

  conn = calloc(sizeof(Connection), 1);

  conn->txfer_buf = newbuf(4096);
  conn->collecting_from = -1;
  conn->last_read_time = 0;

  conn->name[0] = malloc(1024);
  conn->fd[0] = newfd;
  get_addr_name(conn->name[0], (unsigned char *) &addr.sin_addr.s_addr);
  event_set(&conn->read_event[0], conn->fd[0], EV_READ | EV_PERSIST,
	    (event_handler_t) handle_data0, conn);

  conn->name[1] = cfg.otherhostname;
  conn->fd[1] = open_otherhost();
  event_set(&conn->read_event[1], conn->fd[1], EV_READ | EV_PERSIST,
	    (event_handler_t) handle_data1, conn);

  log_fmt("connection accepted on I fd %d from %s to O fd %d\n",
	  newfd, conn->name[0], conn->fd[1]);

  event_add(&conn->read_event[0], &cfg.timeout);
  event_add(&conn->read_event[1], &cfg.timeout);
}
Esempio n. 3
0
/*
 *	extract a variable name
 */
static Bufblock*
varname(char **s)
{
	Bufblock *b;
	char *cp;
	Rune r;
	int n;

	b = newbuf();
	cp = *s;
	for(;;){
		n = chartorune(&r, cp);
		if (!WORDCHR(r))
			break;
		rinsert(b, r);
		cp += n;
	}
	if (b->current == b->start){
		SYNERR(-1);
		fprint(2, "missing variable name <%s>\n", *s);
		freebuf(b);
		return 0;
	}
	*s = cp;
	insert(b, 0);
	return b;
}
Esempio n. 4
0
/*
 * Wrapper to enable Harvey's channel read function to be used like FreeBSD's
 * block read function.
 * Use when reading relative to a vnode.
 */
int32_t
bread(vnode *vn, daddr_t lblkno, size_t size, Buf **buf)
{
	daddr_t pblkno;
	int rcode = ufs_bmaparray(vn, lblkno, &pblkno, nil, nil, nil);
	if (rcode) {
		print("bread failed to transform logical block to physical\n");
		return 1;
	}

	Buf *b = newbuf(size);
	b->vnode = vn;

	MountPoint *mp = vn->mount;
	Chan *c = mp->chan;
	int64_t offset = dbtob(pblkno);

	int32_t bytesRead = c->dev->read(c, b->data, size, offset);

	if (bytesRead != size) {
		releasebuf(b);
		print("bread returned wrong size\n");
		return 1;
	}

	b->resid = size - bytesRead;
	*buf = b;
	return 0;
}
Esempio n. 5
0
void TestBoundedBuffer::TestReadBuffer()
{
    BoundedBuffer buf (NULL, 10);
	buf.WriteStringAt(0, _T("abc"), 3);
	BoundedBuffer newbuf(buf.ReadBufferAt(0, 3));
	assertMessage(newbuf.m_iMaxSize == 3, _T("Failed to read the buffer"));
	assertMessage(newbuf.ReadStringAt(0, 3) == _T("abc"), _T("Failed to read the buffer"));
}
Esempio n. 6
0
int test_printwchartobuf_backslash_question(void)
{
    Buf *buf = newbuf();

    printwchartobuf(L'\\', ESCAPE_QUESTION, buf);
    assert(strcmp(bufstring(buf), "\\") == 0);
    return 0;
}
Esempio n. 7
0
int test_printwchartobuf_newline_cescape(void)
{
    Buf *buf = newbuf();

    printwchartobuf(L'\n', ESCAPE_C, buf);
    assert(strcmp(bufstring(buf), "\\\n") == 0);
    return 0;
}
Esempio n. 8
0
int test_newbuf(void)
{
    Buf *buf = newbuf();

    /* newbuf sets shiftstate to initial shift state */
    assert(mbsinit(&buf->shiftstate));
    return 0;
}
Esempio n. 9
0
int test_printwchartobuf_newline_question(void)
{
    Buf *buf = newbuf();

    printwchartobuf(L'\n', ESCAPE_QUESTION, buf);
    assert(strcmp(bufstring(buf), "?") == 0);
    return 0;
}
Esempio n. 10
0
int test_printtobuf_arabic(void)
{
    Buf *buf = newbuf();

    printtobuf("دليل", ESCAPE_NONE, buf);
    assert(bufscreenpos(buf) == 4);
    return 0;
}
Esempio n. 11
0
int test_printwchartobuf_backslash_cescape(void)
{
    Buf *buf = newbuf();

    printwchartobuf(L'\\', ESCAPE_C, buf);
    assert(strcmp(bufstring(buf), "\\\\") == 0);
    return 0;
}
Esempio n. 12
0
void CL_PNGProvider::save(CL_PixelBuffer buffer, CL_IODevice &iodev)
{
	if (buffer.get_format() != cl_abgr8)
	{
		CL_PixelBuffer newbuf(
			buffer.get_width(),
			buffer.get_height(), 
			cl_abgr8);
		buffer.convert(newbuf);
		buffer = newbuf;
	}

	png_structp png_ptr;
	png_infop info_ptr;

	png_ptr  = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	info_ptr = png_create_info_struct(png_ptr);

	png_set_read_fn(png_ptr, &iodev, &CustomIOFunctions::read);
	png_set_write_fn(png_ptr, &iodev, &CustomIOFunctions::write, CustomIOFunctions::flush);

	#ifndef PNG_COLOR_TYPE_RGBA
	#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
	#endif

	png_set_IHDR(
		png_ptr, info_ptr, 
		buffer.get_width(), buffer.get_height(), 8 /* bitdepth */,
		PNG_COLOR_TYPE_RGBA,
		PNG_INTERLACE_NONE, 
		PNG_COMPRESSION_TYPE_BASE, 
		PNG_FILTER_TYPE_BASE);

	png_write_info(png_ptr, info_ptr);

	png_uint_32 height = buffer.get_height();
	png_uint_32 row_bytes = buffer.get_width()*4;

	png_byte* image = new png_byte[height * row_bytes];
	png_bytep* row_pointers = new png_bytep[height];

	// fill the image with data
	for (int i = 0; i < buffer.get_width()*buffer.get_height()*4; ++i)
		image[i] = static_cast<unsigned char*>(buffer.get_data())[i];

	// generate row pointers
	for (unsigned int k = 0; k < height; k++)
		row_pointers[k] = image + (k * row_bytes);

	png_write_image(png_ptr, row_pointers);

	png_write_end(png_ptr, info_ptr);

	png_destroy_write_struct( &png_ptr, &info_ptr );

	delete[] image;
	delete[] row_pointers;
}
Esempio n. 13
0
int test_printtobuf_japanese(void)
{
    Buf *buf = newbuf();

    printtobuf("ディレクトリ", ESCAPE_NONE, buf);
    /* 6 double width characters == 12 characters */
    assert(bufscreenpos(buf) == 12);
    return 0;
}
Esempio n. 14
0
File: wc.c Progetto: HNGNU/hutils
int
readtobuf(char **buf, int f) {
	ssize_t w, i;
	*buf=sizeset(newbuf(),2);
	for(i=0; (w=read(f,*buf+i,1)) && w!=-1; i++) {
		*buf=sizeset(*buf,i+2);
	}
	return i;
}
Esempio n. 15
0
int test_printwchartobuf_unicode(void)
{
    Buf *buf = newbuf();

    printwchartobuf(L'‽', ESCAPE_NONE, buf);
    /* don't care what bufpos is */
    /* ensure a single Unicode character has screen width 1 */
    assert(bufscreenpos(buf) == 1);
    return 0;
}
Esempio n. 16
0
int test_append_string(void)
{
    Buf *buf = newbuf();

    bufappend(buf, "abc", 3, 3);
    assert(strcmp(bufstring(buf), "abc") == 0);
    assert(bufpos(buf) == 3);
    assert(bufscreenpos(buf) == 3);
    return 0;
}
Esempio n. 17
0
int test_printwchartobuf_ascii(void)
{
    Buf *buf = newbuf();

    printwchartobuf(L'a', ESCAPE_NONE, buf);
    assert(strcmp(bufstring(buf), "a") == 0);
    assert(bufpos(buf) == 1);
    assert(bufscreenpos(buf) == 1);
    return 0;
}
Esempio n. 18
0
PRIVATE ObjectStoreItem *read_item(FILE *f) {
  ObjectStoreItem *item = safe_malloc(sizeof(ObjectStoreItem));
  BUFFER varname;
  char str[1024];	/* %%% Yuck, a fixed-size buffer. */
  int key;

  if (fscanf(f, "%s %d [", str, &key) < 2) {
    free(item);
    return NULL;
  }

  item->tag = safe_string_dup(str);
  item->key = key;
  item->object = NULL;
  item->db = NULL;
  item->fields = g_hash_table_new(g_str_hash, g_str_equal);

  varname = newbuf(128);

  while (!feof(f)) {
    int ch;

    /* Strip leading whitespace (there _should_ always be some). */
    do { ch = fgetc(f); } while (isspace(ch) && (ch != ']') && (ch != EOF));

    if (ch == ']' || ch == EOF) {
      /* That's it. We're done with this item. */
      /* Empty line signals no more fields. */
      break;
    }

    /* Read the field name */
    do {
      buf_append(varname, ch);
      ch = fgetc(f);
    } while (!isspace(ch));

    /* Skip the whitespace and equals-sign */
    do { ch = fgetc(f); } while (isspace(ch) || ch == '=');
    ungetc(ch, f);

    /* Now we have the complete variable name in varname, and we are about to read the
       first character of the variable value. */
    buf_append(varname, '\0');
    objectstore_item_set(item, varname->buf, read_item_field_value(f));
    varname->pos = 0;	/* reset varname for next round */

    /* Trailing whitespace, if any, is dealt with at the top of the loop. */
  }

  killbuf(varname);
  return item;
}
Esempio n. 19
0
File: run.c Progetto: 8l/cmm
static void
sched(void)
{
	char *flags;
	Job *j;
	Bufblock *buf;
	int slot;
	Node *n;
	Envy *e;

	if(jobs == 0){
		usage();
		return;
	}
	j = jobs;
	jobs = j->next;
	if(DEBUG(D_EXEC))
		printf("firing up job for target %s\n", wtos(j->t, ' '));
	slot = nextslot();
	events[slot].job = j;
	buf = newbuf();
	e = buildenv(j, slot);
	shprint(j->r->recipe, e, buf);
	if(!tflag && (nflag || !(j->r->attr&QUIET)))
		Bwrite(&bout, buf->start, (long)strlen(buf->start));
	freebuf(buf);
	if(nflag||tflag){
		for(n = j->n; n; n = n->next){
			if(tflag){
				if(!(n->flags&VIRTUAL))
					touch(n->name);
				else if(explain)
					Bprint(&bout, "no touch of virtual '%s'\n", n->name);
			}
			n->time = time((long *)0);
			MADESET(n, MADE);
		}
	} else {
		if(DEBUG(D_EXEC))
			printf("recipe='%s'", j->r->recipe);/**/
		Bflush(&bout);
		if(j->r->attr&NOMINUSE)
			flags = 0;
		else
			flags = "-e";
		events[slot].pid = execsh(flags, j->r->recipe, 0, e);
		usage();
		nrunning++;
		if(DEBUG(D_EXEC))
			printf("pid for target %s = %d\n", wtos(j->t, ' '), events[slot].pid);
	}
}
Esempio n. 20
0
File: sh.c Progetto: HNGNU/hutils
char*
readline(int f) {
	char *buf;
	size_t i;
	for(buf=newbuf(), i=0;; i++) {
		buf=sizeset(buf,i+1);
		if(read(f,buf+i,1)==0)
			return 0;
		if(buf[i]=='\n')
			break;
	}
	buf[i]=0;
	return buf;
}
Esempio n. 21
0
/*
 * Wrapper to enable Harvey's channel read function to be used like FreeBSD's
 * block read function.
 * Use when reading Fs or anything else not relative to a vnode.
 */
int32_t
breadmp(MountPoint *mp, daddr_t blkno, size_t size, Buf **buf)
{
	Buf *b = newbuf(size);

	Chan *c = mp->chan;
	int64_t offset = dbtob(blkno);
	int32_t bytesRead = c->dev->read(c, b->data, size, offset);
	if (bytesRead != size) {
		releasebuf(b);
		print("bread returned wrong size\n");
		return 1;
	}

	b->resid = size - bytesRead;
	*buf = b;
	return 0;
}
Esempio n. 22
0
std::unique_ptr<BYTE[]> CreateNewBuffer(unsigned long& padding, BYTE* pmatrix, const int& width, const int& height){
    
    int scanlinebytes, total_scanlinebytes;
    
    long newsize, bufpos = 0, newpos = 0;
    
    padding = (4 - ((width * 3)%4))%4;
    
    scanlinebytes = width * 3;
    total_scanlinebytes = scanlinebytes + padding;
    
    newsize = height * total_scanlinebytes;
    
    std::unique_ptr<BYTE[]> newbuf(new BYTE[newsize]);
    
    //fill new array with original buffer, pad remaining with zeros
    
    std::fill(&newbuf[0], &newbuf[newsize], 0);
    
    std::cout << "[i] new buffer of size " << newsize << " created." << std::endl;
    
    for(int y = 0; y < height; y++){
        
        for(int x = 0; x < 3 * width; x+=3){
            
            //Determine positions in original and padded buffers
            
            bufpos = y * 3 * width + (3 * width - x);
            newpos = (height - y - 1) * total_scanlinebytes + x;
            
            //swap R&B, G remains, swap B&R
            
            newbuf[newpos] = pmatrix[bufpos + 2];
            newbuf[newpos + 1] = pmatrix[bufpos + 1];
            newbuf[newpos + 2] = pmatrix[bufpos];
            
        }
        
    }
    
    return newbuf;
    
}
Esempio n. 23
0
		void checkSpace(uint64_t const outlen)
		{
			// buffer overflow?
			if ( freeSpace() < outlen )
			{
				flush();
				assert ( opc == opa );
			
				if ( outlen > outbuf.size() )
				{
					::libmaus::autoarray::AutoArray<uint8_t> newbuf(outlen);	
					std::copy( outbuf.begin(), outbuf.end(), newbuf.begin() );
					
					outbuf = newbuf;
					opa = outbuf.begin();
					opc = opa;
					ope = outbuf.end();
				}
			}
			
			assert ( freeSpace() >= outlen );		
		}
Esempio n. 24
0
File: run.c Progetto: 8l/cmm
int
waitup(int echildok, int *retstatus)
{
	Envy *e;
	int pid;
	int slot;
	Symtab *s;
	Word *w;
	Job *j;
	char buf[ERRLEN];
	Bufblock *bp;
	int uarg = 0;
	int done;
	Node *n;
	Process *p;
	extern int runerrs;

	/* first check against the proces slist */
	if(retstatus)
		for(p = phead; p; p = p->f)
			if(p->pid == *retstatus){
				*retstatus = p->status;
				pdelete(p);
				return(-1);
			}
again:		/* rogue processes */
	pid = waitfor(buf);
	if(pid == -1){
		if(echildok > 0)
			return(1);
		else {
			fprintf(stderr, "mk: (waitup %d) ", echildok);
			perror("mk wait");
			Exit();
		}
	}
	if(DEBUG(D_EXEC))
		printf("waitup got pid=%d, status='%s'\n", pid, buf);
	if(retstatus && pid == *retstatus){
		*retstatus = buf[0]? 1:0;
		return(-1);
	}
	slot = pidslot(pid);
	if(slot < 0){
		if(DEBUG(D_EXEC))
			fprintf(stderr, "mk: wait returned unexpected process %d\n", pid);
		pnew(pid, buf[0]? 1:0);
		goto again;
	}
	j = events[slot].job;
	usage();
	nrunning--;
	events[slot].pid = -1;
	if(buf[0]){
		e = buildenv(j, slot);
		bp = newbuf();
		shprint(j->r->recipe, e, bp);
		front(bp->start);
		fprintf(stderr, "mk: %s: exit status=%s", bp->start, buf);
		freebuf(bp);
		for(n = j->n, done = 0; n; n = n->next)
			if(n->flags&DELETE){
				if(done++ == 0)
					fprintf(stderr, ", deleting");
				fprintf(stderr, " '%s'", n->name);
				delete(n->name);
			}
		fprintf(stderr, "\n");
		if(kflag){
			runerrs++;
			uarg = 1;
		} else {
			jobs = 0;
			Exit();
		}
	}
	for(w = j->t; w; w = w->next){
		if((s = symlook(w->s, S_NODE, 0)) == 0)
			continue;	/* not interested in this node */
		update(uarg, (Node *)s->value);
	}
	if(nrunning < nproclimit)
		sched();
	return(0);
}
Esempio n. 25
0
static Word*
subsub(Word *v, char *s, char *end)
{
	int nmid;
	Word *head, *tail, *w, *h;
	Word *a, *b, *c, *d;
	Bufblock *buf;
	char *cp, *enda;

	a = extractpat(s, &cp, "=%&", end);
	b = c = d = 0;
	if(PERCENT(*cp))
		b = extractpat(cp+1, &cp, "=", end);
	if(*cp == '=')
		c = extractpat(cp+1, &cp, "&%", end);
	if(PERCENT(*cp))
		d = stow(cp+1);
	else if(*cp)
		d = stow(cp);

	head = tail = 0;
	buf = newbuf();
	for(; v; v = v->next){
		h = w = 0;
		if(submatch(v->s, a, b, &nmid, &enda)){
			/* enda points to end of A match in source;
			 * nmid = number of chars between end of A and start of B
			 */
			if(c){
				h = w = wdup(c);
				while(w->next)
					w = w->next;
			}
			if(PERCENT(*cp) && nmid > 0){	
				if(w){
					bufcpy(buf, w->s, strlen(w->s));
					bufcpy(buf, enda, nmid);
					insert(buf, 0);
					free(w->s);
					w->s = strdup(buf->start);
				} else {
					bufcpy(buf, enda, nmid);
					insert(buf, 0);
					h = w = newword(buf->start);
				}
				buf->current = buf->start;
			}
			if(d && *d->s){
				if(w){

					bufcpy(buf, w->s, strlen(w->s));
					bufcpy(buf, d->s, strlen(d->s));
					insert(buf, 0);
					free(w->s);
					w->s = strdup(buf->start);
					w->next = wdup(d->next);
					while(w->next)
						w = w->next;
					buf->current = buf->start;
				} else
					h = w = wdup(d);
			}
		}
		if(w == 0)
			h = w = newword(v->s);
	
		if(head == 0)
			head = h;
		else
			tail->next = h;
		tail = w;
	}
	freebuf(buf);
	delword(a);
	delword(b);
	delword(c);
	delword(d);
	return head;
}
Esempio n. 26
0
void
main(int argc, char **argv)
{
	Word *w;
	char *s, *temp;
	char *files[256], **f = files, **ff;
	int sflag = 0;
	int i;
	int tfd = -1;
	Biobuf tb;
	Bufblock *buf;
	Bufblock *whatif;

	/*
	 *  start with a copy of the current environment variables
	 *  instead of sharing them
	 */

	Binit(&bout, 1, OWRITE);
	buf = newbuf();
	whatif = 0;
	USED(argc);
	for(argv++; *argv && (**argv == '-'); argv++)
	{
		bufcpy(buf, argv[0], strlen(argv[0]));
		insert(buf, ' ');
		switch(argv[0][1])
		{
		case 'a':
			aflag = 1;
			break;
		case 'd':
			if(*(s = &argv[0][2]))
				while(*s) switch(*s++)
				{
				case 'p':	debug |= D_PARSE; break;
				case 'g':	debug |= D_GRAPH; break;
				case 'e':	debug |= D_EXEC; break;
				}
			else
				debug = 0xFFFF;
			break;
		case 'e':
			explain = &argv[0][2];
			break;
		case 'f':
			if(*++argv == 0)
				badusage();
			*f++ = *argv;
			bufcpy(buf, argv[0], strlen(argv[0]));
			insert(buf, ' ');
			break;
		case 'i':
			iflag = 1;
			break;
		case 'k':
			kflag = 1;
			break;
		case 'n':
			nflag = 1;
			break;
		case 's':
			sflag = 1;
			break;
		case 't':
			tflag = 1;
			break;
		case 'u':
			uflag = 1;
			break;
		case 'w':
			if(whatif == 0)
				whatif = newbuf();
			else
				insert(whatif, ' ');
			if(argv[0][2])
				bufcpy(whatif, &argv[0][2], strlen(&argv[0][2]));
			else {
				if(*++argv == 0)
					badusage();
				bufcpy(whatif, &argv[0][0], strlen(&argv[0][0]));
			}
			break;
		default:
			badusage();
		}
	}
#ifdef	PROF
	{
		extern etext();
		monitor(main, etext, buf, sizeof buf, 300);
	}
#endif

	if(aflag)
		iflag = 1;
	usage();
	syminit();
	initenv();
	usage();

	/*
		assignment args become null strings
	*/
	temp = 0;
	for(i = 0; argv[i]; i++) if(utfrune(argv[i], '=')){
		bufcpy(buf, argv[i], strlen(argv[i]));
		insert(buf, ' ');
		if(tfd < 0){
			temp = maketmp();
			if(temp == 0) {
				perror("temp file");
				Exit();
			}
			close(create(temp, OWRITE, 0600));
			if((tfd = open(temp, 2)) < 0){
				perror(temp);
				Exit();
			}
			Binit(&tb, tfd, OWRITE);
		}
		Bprint(&tb, "%s\n", argv[i]);
		*argv[i] = 0;
	}
	if(tfd >= 0){
		Bflush(&tb);
		LSEEK(tfd, 0L, 0);
		parse("command line args", tfd, 1);
		remove(temp);
	}

	if (buf->current != buf->start) {
		buf->current--;
		insert(buf, 0);
	}
	symlook("MKFLAGS", S_VAR, (void *) stow(buf->start));
	buf->current = buf->start;
	for(i = 0; argv[i]; i++){
		if(*argv[i] == 0) continue;
		if(i)
			insert(buf, ' ');
		bufcpy(buf, argv[i], strlen(argv[i]));
	}
	insert(buf, 0);
	symlook("MKARGS", S_VAR, (void *) stow(buf->start));
	freebuf(buf);

	if(f == files){
		if(access(MKFILE, 4) == 0)
			parse(MKFILE, open(MKFILE, 0), 0);
	} else
		for(ff = files; ff < f; ff++)
			parse(*ff, open(*ff, 0), 0);
	if(DEBUG(D_PARSE)){
		dumpw("default targets", target1);
		dumpr("rules", rules);
		dumpr("metarules", metarules);
		dumpv("variables");
	}
	if(whatif){
		insert(whatif, 0);
		timeinit(whatif->start);
		freebuf(whatif);
	}
	execinit();
	/* skip assignment args */
	while(*argv && (**argv == 0))
		argv++;

	catchnotes();
	if(*argv == 0){
		if(target1)
			for(w = target1; w; w = w->next)
				mk(w->s);
		else {
			fprint(2, "mk: nothing to mk\n");
			Exit();
		}
	} else {
		if(sflag){
			for(; *argv; argv++)
				if(**argv)
					mk(*argv);
		} else {
			Word *head, *tail, *t;

			/* fake a new rule with all the args as prereqs */
			tail = 0;
			t = 0;
			for(; *argv; argv++)
				if(**argv){
					if(tail == 0)
						tail = t = newword(*argv);
					else {
						t->next = newword(*argv);
						t = t->next;
					}
				}
			if(tail->next == 0)
				mk(tail->s);
			else {
				head = newword("command line arguments");
				addrules(head, tail, strdup(""), VIR, mkinline, 0);
				mk(head->s);
			}
		}
	}
	if(uflag)
		prusage();
	exits(0);
}
Esempio n. 27
0
void
parse(char *f, int fd, int varoverride)
{
    int hline;
    char *body;
    Word *head, *tail;
    int attr, set, pid;
    char *prog, *p;
    int newfd;
    Biobuf in;
    Bufblock *buf;

    if(fd < 0) {
        perror(f);
        Exit();
    }
    ipush();
    infile = strdup(f);
    mkinline = 1;
    Binit(&in, fd, OREAD);
    buf = newbuf();
    while(assline(&in, buf)) {
        hline = mkinline;
        switch(rhead(buf->start, &head, &tail, &attr, &prog))
        {
        case '<':
            p = wtos(tail, ' ');
            if(*p == 0) {
                SYNERR(-1);
                fprint(2, "missing include file name\n");
                Exit();
            }
            newfd = open(p, OREAD);
            if(newfd < 0) {
                fprint(2, "warning: skipping missing include file: ");
                perror(p);
            } else
                parse(p, newfd, 0);
            break;
        case '|':
            p = wtos(tail, ' ');
            if(*p == 0) {
                SYNERR(-1);
                fprint(2, "missing include program name\n");
                Exit();
            }
            execinit();
            pid=pipecmd(p, envy, &newfd);
            if(newfd < 0) {
                fprint(2, "warning: skipping missing program file: ");
                perror(p);
            } else
                parse(p, newfd, 0);
            while(waitup(-3, &pid) >= 0)
                ;
            if(pid != 0) {
                fprint(2, "bad include program status\n");
                Exit();
            }
            break;
        case ':':
            body = rbody(&in);
            addrules(head, tail, body, attr, hline, prog);
            break;
        case '=':
            if(head->next) {
                SYNERR(-1);
                fprint(2, "multiple vars on left side of assignment\n");
                Exit();
            }
            if(symlook(head->s, S_OVERRIDE, 0)) {
                set = varoverride;
            } else {
                set = 1;
                if(varoverride)
                    symlook(head->s, S_OVERRIDE, (void *)"");
            }
            if(set) {
                /*
                char *cp;
                dumpw("tail", tail);
                cp = wtos(tail, ' '); print("assign %s to %s\n", head->s, cp); free(cp);
                */
                setvar(head->s, (void *) tail);
                symlook(head->s, S_WESET, (void *)"");
            }
            if(attr)
                symlook(head->s, S_NOEXPORT, (void *)"");
            break;
        default:
            SYNERR(hline);
            fprint(2, "expected one of :<=\n");
            Exit();
            break;
        }
    }
    close(fd);
    freebuf(buf);
    ipop();
}