Personal tools
You are here: Home Projects C++ Cfront releases Release 3.0.3 source lib task_SPARC TESTS filter.C
Document Actions

filter.C

by Michael L Powell last modified 2007-01-26 03:22

Click here to get the file

Size 4.4 kB - File type text/plain

File contents

#include <stdio.h>
#include <task.h>
#include <string.h>
#include <stdlib.h>

/*
 * filter.C
 * Builds on example in "More About Queues:  Cutting and Splicing"
 * section of Stroustrup/Shopiro coroutine memo, Release Notes pp 13-13 - 13-14.
 * Demonstrates "fairly static" use of filters, creating 3 tasks:
 * Producer produces lines, Consumer consumes words, and Line_to_Word
 * converts lines to words.  Requires filter.in file to provide lines
 * for Producer.
 */

const int MAXLEN = 512;

class Word : public object
{
	char	word[MAXLEN];
public:
		Word(char *);
	void	print(int =0, int =0);
};

Word::Word(char *w) {
	(void) strcpy(word, w);
//	printf("Word::Word:\n");
//	this->print();
}
void
Word::print(int i, int j)
{
//	printf("\tWord %x: %s\n", this, word);
	printf("%s\n", word);
}

class Line : public object
{
	char	line[MAXLEN];
	char	*begin;
public:
		Line(char *l);
	Word	*next_word();
	void	print(int =0, int =0);
};

Line::Line(char *l)
{
	(void) strcpy(line, l);
	begin = line;
//	printf("Line::Line():");
//	this->print();
}

/* Modifies this Line by moving the begin pointer
 * to point at next non-whitespace character.
 */
Word *
Line::next_word()
{
	char	tmpword[MAXLEN];
	char	*wp = tmpword;
	Word	*w;
	if (begin == NULL) {	// no more words in line
		return 0;
	}
//	printf("Line::next_word:");
//	this->print();
	for (;;) {
		*wp = *begin;
		switch(*wp) {
		case ' ':
		case '\t':
			*wp = '\0';
			// leave begin pointing at next non-whitespace char
			// SAK: ws at end of line will be a problem
			while( (*begin == ' ') || (*begin == '\t') ) {
				begin++;
			}
			w = new Word(tmpword);
//			printf("Line::next_word:\tabout to return Word %x\n", w);
//			w->print();
			return w;
		case '\n':	/* fgets doesn't discard \n; gets does */
		case '\0':	/* end of Line */
			*wp = '\0';
			begin = NULL;
			w = new Word(tmpword);
//			printf("Line::next_word:\tabout to return Word %x\n", w);
//			w->print();
			return w;
			break;
		default:
			begin++;
			wp++;
			break;
		}
	}
}

void
Line::print(int i, int j)
{
	printf("\tLine %x:\t%s\n", this, line);
	printf("\t\t\tbegin: %s\n", begin);
}

class Producer : public task	// produce lines
{
public:
		Producer(qtail *, char *);
};

Producer::Producer(qtail *qt, char *n) : task(n)
{
	FILE	*fp;
	Line	*l;
	char	tmpline[MAXLEN];
	char	*cp;
//	printf("Producer::Producer():	type in lines of characters,\n");
//	printf("			end with a ^D on a line by itself\n");
	if ((fp = fopen("filter.in", "r")) == NULL) {
		printf("filter:  Cannot open file filter.in.\n");
		exit(0);
	}
	while ((cp = fgets(tmpline, MAXLEN, fp)) != NULL) {
		l = new Line(tmpline);
//		printf("Producer::Producer():  about to put line %x on qtail %x\n", l, qt);
		qt->put( (object *) l);
	}
	//SAK:  cycle6.1, thistask expanded to this_task() but NOT inlined!
	thistask->resultis(0);
}

class Consumer : public task	// consume words
{
public:
		Consumer(qhead *, char *); };

Consumer::Consumer(qhead *qh, char *n) : task(n)
{
	Word	*w;
	for(;;)	{
		w = (Word *) qh->get();
//		printf("Consumer::Consumer():\n");
//SAK:  default args not picked up for some reason.
//SAK:		w->print();
		w->print(0,0);
	}
	//SAK:  cycle6.1, thistask expanded to this_task() but NOT inlined!
	thistask->resultis(0);
}

class Line_to_Word : private task
{
public:
		Line_to_Word(qhead *, qtail *, char *);
//	Word	*next_word(Line *);
};

Line_to_Word::Line_to_Word(qhead *in_q, qtail *out_q, char *n) : task(n)
{
	Line	*l;
	Word	*w;
	for(;;) {
		l = (Line *) in_q->get();
//		printf("%s:\tgot line %x from qhead %x\n", n, l, in_q);
		while (w = l->next_word()) {
//			printf("%s:\tabout to put word %x on qtail %x\n", n, w, out_q);
//			w->print();
			out_q->put((object *) w);
		}
	}
	//SAK:  cycle6.1, thistask expanded to this_task() but NOT inlined!
	thistask->resultis(0);
}

main()
{
//printf("main:\n");
	qhead		*line_q = new qhead(WMODE, 5);
	qtail		*line_qt = line_q->tail();
//printf("\tqhead line_q is %x, line_qt is %x\n", line_q, line_qt);
	qtail		*word_q = new qtail(WMODE, 15);
	qhead		*word_qh = word_q->head();
//printf("\tqtail word_q is %x, word_qh is %x\n", word_q, word_qh);
	//Producer	*prod = new Producer(line_q->tail(), "prod");
	Producer	*prod = new Producer(line_qt, "prod");
	//Consumer	*cons = new Consumer(word_q->head(), "cons");
	Consumer	*cons = new Consumer(word_qh, "cons");
	Line_to_Word	*filt = new Line_to_Word(line_q, word_q, "filt");
//printf("main: done\n");
	//SAK:  this task expanded to this_task() and properly inlined
	thistask->resultis(0);
}
« April 2024 »
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: