delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2003/02/10/00:52:33

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
Date: Mon, 10 Feb 2003 00:52:00 -0500
From: Brian Minton <bminton AT efn DOT org>
Subject: ncurses softkeys (slk) don't display correctly
To: cygwin AT cygwin DOT com
Message-id: <3E473E00.10103@efn.org>
MIME-version: 1.0
X-Accept-Language: en-us, en
User-Agent: Mozilla/5.0 (Windows; U; Win95; en-US; rv:1.2) Gecko/20021126

--Boundary_(ID_NJGwEhVsqstBB0D7f2EbSA)
Content-type: text/plain; charset=us-ascii; format=flowed
Content-transfer-encoding: 7BIT

I am using CYGWIN_95-4.0 mintons 1.3.19(0.71/3/2) 2003-01-23 21:31 i586 
unknown unknown Cygwin, with ncurses default version, and I tried to run 
a program that I compiled with ncurses.  I didn't have any build 
problems, but the program uses the ncurses soft keys feature (slk_init, 
slk_reset, etc.) and it does not display properly.  I am using 
slk_init(3) which makes soft keys with an extra line of explanation for 
what key does what.  If you are interested, I have attached a screen 
shot and the code in question.

thanks,
Brian

--Boundary_(ID_NJGwEhVsqstBB0D7f2EbSA)
Content-type: image/png; name=ncurses.png
Content-transfer-encoding: base64
Content-disposition: inline; filename=ncurses.png

iVBORw0KGgoAAAANSUhEUgAAAowAAAHLCAIAAADN5F7IAAAACXBIWXMAAA7NAAAOwwH9ZckU
AAAUdUlEQVR42u3dr3bj5qLG4W+6BmzYS9hwYGDY7mFzCYaBgYFlJ7AwMIcF+txB2OlmgYED
ewmFm/UAz6iK/lmSJeuN8zyrKyt1ZOWz7PHPn2Q5n/aPDwUACLO7vftcSrm6vt56JADA354e
Hkopnw//8/rysvV4AIA3ftp6AABAt8/1/3nav249HgD40G52V9X3ZtIAEOrzwM+ef3/qvPzr
LzdbDxsA5nt4uB2/8Jer62+vE9659eXq+hDKqb+lndfeSPcVuvEjwQbgPRr5julqsanLn3Kt
SnekBwq9lMPri7u7x7V/EQAsZXd71/ejNT535POM6/TNnid1V54B+DgOda+HvH1J2/FI26EN
AJXOrA7MsKtr7W7vdrd3h6uPKXQZOZN+/tdTuS/l9+//ff10M7Dww8Pt3d1jfVZdfV8dQq8v
0DiuXs2w+y4HgPeo6nT1v0evMuoUrK//vim/l/JLOaT6+f+env/76flfT89/PbUXPlrTvgXq
Ra8Srs0AXIwqzCMPYKecJy3GAFy8ahp9dPf4wejd3b907e7+tPXNBYB3on4cun58esCoSH/9
9035rx//MzHMk07lBoAza09q1ziZqvFOscb7yPocj3T7nOm+93sf3gV2eONY9f28G3Pi1QFg
JSP3VDe0YzzmpcCc86QHPnGsfmi5fZi586d9V+l7mzcALGjSvHmNSfaA7kh//eXmDB86NsD5
VwCsauQHds5e/pRrVXpn0gOdPsPHm6gyAOv5cnW96vKnXKtuaHe3zxoD4CKdJ3Cn/5aU86QB
gIY3M+mb3dXW4wEAvnsT6ROPbwMAJ7q6/vtI9tuZ9N3d1mMDgA+tPmE2kwaAUN44BgCh5nzi
2EdWP1Qwz5er62+vp+6xWGolfR+ds8jNXHXlJ66hlPLt9aVv19GqNx9gPLu7O9zc3Q1silO2
UnXdnJWsejNXXfmvN7vZKzma4VVvPsBIzZn0b0/7rYe0MROgd+Twcurq+nrG163HDnBcx+7u
0/ejZhrzvDzvb5tcsN3tn+MX3j/+fObhKTRw2T7WMenhnZxPDw+T1tb4891Hv+/UDsaJB0Tr
rzMW2Svw7fVr45L91fWu9Uruy9Xz6b+r9Pxh18NrhfaLgEZ9f4zhyNdvr19nd3rMH2kHWMrH
inRZ+nhh/c93ty8sP/6s9/BK6qenPz08HHozaRiNX/HXX6WU8unT8sEupeyvrktPp0/XmcDd
7V0p953Lz5sfn1LootPAGa14CtYib8FNNvKZesxiry8vh//Ksbette1u7+7vy683u/v7Ukr5
66/y6VP59Ol7qg+X/3qzW2RP/r52n+6Xvn8P8eucSfddpTGTLqV8e/26f/x54GtZ4s3bAOex
5Ux6kfOINjRyRjVmsUOVD/E47HWvd/poVP7zx66Ucn9f9o8P//s/Zf9YSimHb3a3d7/e7P7x
z2XeD3iYPS81jW70+FDo6uuYNbRn0o1Lvt3+WR47ljl95CbTwBmsFelDgN97hs/m6vq6KvHr
y8vUHeD/+Of+0Om+6fJ//tiVclKn+8J8YrAPD4/DWcX1QtcrOLC7uzWTfq6+3189716/fivP
1feNZaYOtW+iD7Ce882k68Guvq9/c/jReaLensOdbTt0qvZ11y+pvr+5u3t6eBjo9H/+2P3j
n/vDjPnw/duv5cSZdGPPdqPKJ3a6KvThVV2909/X/+ONY53brW8mvXv9emhzvdBLzaSLyTRw
FqtEukrv0cl0I9XlXPvAGw2YvZKlFqvPpOu7uxs7wPs63ajy/eHodGl8vZ95M38U+vBN1ePW
8emZ6y+lHApdfjxgGs0u/Sd3fe/x7Z8/3rldat8/l1Lur/7+un+cP5OukmwyDZzTh3t3d2XS
sc9Oyx6TbmSjnu0q1X11acyeS+u8qS9Xz7Mjunt9aeS5urzUyn0/9xSsxmuySUdJqj3YYxZe
diZdTKaB9a14THrrm3ZczjNs50y6/vGfY45JV187e/zt9euXq+d5nzdSdfr7dnu7f3vxc7HG
70qpurt//Hn400t2t3+efkx62ZsJcNTykW5PgxqXvIt+n1P77dzlbbYPBrrSnkmX1mH+wwd9
7G7/nN3pSZePdxjnYQJdv3xMqtvvF+v7WspztSd89r7u+iV9PwJY0Pl2d1fPwo1vvr2+1J+g
39G7wRc5Jt2OcXsmXY6dhdU5k65vyWrv94mfC9Z3fPoU1Thn3PV9Z151fg5oY7Z90nZwZBo4
i+Uj3X6qbT8LD3zzjix1TLozGAvOpCunb+T6fu+l9nKfbSY9o9CdM+ZGno9+8ivAbB/rjWNT
P537qOq5e/izu+eNc2RLarO6/Y+v92W11z2HTi94HPpsM+kZnyHamV49Bs7mA0V68f2TA5/X
3fn9SO059KSRlFJ2t38u9ecuSvce8vvZ7+VurfykNyisPZMG2FYz0vvHh0t9CntHE6CTj5j+
vNRIVv3rk6ffI1Vxx/z9K3+tEnh33kS6/mmUkO/7J4A+vhydSSs08B69ibQnrzEW2Uo5K3m/
Kz8cFKh/Psn4r9vefICRPtAx6UUscpJ3zkre78pXPR3AqfxAiE/7xwc7AAEgyuvLy29P+5+2
HgYA0M0xaQBIcXN3V29x85j0b08n/eFhAGCe9ompdnfDRdnv9/v9/JfaJ14dWJZIw0XZ7Xal
lHmhPVzrsAYggVOw4NLsdrvDhLie23a2GzFWaAgk0nCB2p0erq9CQyaRhsvU6PTATFqhIZZI
w8Wqd7qvwQoNybxxDC7ZmPoqNMQSabhwww1WaEg2FOmpZ0xa3vKWt7zlLW/505evmEkDQCiR
BoBQb/5U5eEPY209JAD4iNpFdkza8pa3vOUtb/ms5St2dwNAKJEGgFCOSQNAhHaRuz8WtL7r
vP1ZB/u3f13n+G+duPykNQ+M851qH7dY46btt/gwSI8rgEk6dndXT9+dn8s/9dD3vEPl49fc
N873q/5ni9a7aQMf5rwSjyuAqXr/wMa+60P5qyesxjysb+Yxdfkya4b3QZ5Gqy3T3kSd27O+
WN/277t/p66nc219t8LjCmCkjpl0fQ7R9yzceJ7d/VB6nijryy87U7ngZ9Jq+x82VLW5Gttt
xvbsbNXU9dSXHzMv97gCmKp3Jl3N2MYc+ZvxjNZ3lRn7YKuhXpjwaV/1ZxAnjdbjCmC8jkjX
ZyQDT1KNKd3R6UvjSXmpv277Md/X077VnZfMiOi8YRx+0fCv8LgCmKr7FKyj78ItPccIB46Y
Hj2G2rfwgIt8F+7RA7Fl3LHk+o9GLn/08vr9O++A9MDyHlfAB9cusvOkASDCMudJLzCONffB
AsBlmHye9CK0GQCO+jzws5F57jt/d+D82jG/se9YYzl2YBIALkPvH9gYP4HuO393qr4Z/NTz
cQHgMgzNpDc5T7Tzk6sHTiXSbAAu1dCHmcxY3enJ7FzDwPm4dncDcKm6Pxa0tD6TckBjv3Tn
ejr3YJeug9D7H+rrr1+oxwB8EN0z6UkhHFi476Og+q4yPI0+fagA8I78dPoqAIA1iDQAhBJp
AAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCIN
AKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQB
IJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQA
hBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaA
UCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQ
SqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBC
iTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0Ao
kQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl
0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFE
GgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRI
A0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJp
AAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCIN
AKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQB
IJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQA
hBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaA
UCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQ
SqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBC
iTQAhBJpAAgl0gAQSqQBIJRIA0AokQaAUCINAKFEGgBCiTQAhBJpAAgl0gAQSqQBIJRIA0Ao
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
nfh/YKnAJRyHCsYAAAAASUVORK5CYII=

--Boundary_(ID_NJGwEhVsqstBB0D7f2EbSA)
Content-type: text/plain; name=turing.c
Content-transfer-encoding: 7BIT
Content-disposition: inline; filename=turing.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <curses.h>
#include <unistd.h>

#include "turing.h"

/* displays a menu to the user */
void display_menu()
{
	clear(); 
	slk_restore();
	slk_set(1,"AddRule",0);
	slk_set(2,"DelRule",0);
	slk_set(3,"Load",0);
	slk_set(4,"SetState",0);
	slk_set(5,"ClrTape",0);
	slk_set(6,"Step",0);
	slk_set(7,"Run",0);
	slk_set(8,"Quit",0);
	slk_set(9,"",0);  /* get rid of the Break label if it exists */
	slk_refresh();
}

/* prints the tape, including several spaces on either side of the r/w head */
void print_tape(tape_t t)
{
	int n;
	int first;
	int last;
	for (n=0; n<(COLS/2); n++)
		printw(" ");
	printw("\\=/\n");
    first=t.pos - (COLS/4);
    last=t.pos + (COLS/4);
	for (n=first; n<last; n++)
		printw("|%c",t.data[n]);
}

/* displays the state */
void print_state(int s,int o)
{
	char str[30]="";
	sprintf(str,"State: %d\tPrevious State: %d\n",s,o);
	printw(str);
}

/* input a new state from the user */
int get_new_state()
{
	int result;
	char str[1000]={0}; /* FIXME vulnerable to buffer overflows */
	clear();
	printw("Enter new state: ");
	echo();
	getstr(str);
	noecho();
	sscanf(str,"%d",&result);
	return result;
}

/* notify user that the tape is halted */
void do_halt()
{
	char str[1000]={0}; /* FIXME vulnerable to buffer overflows */
	clear();
	printw("No rule corresponding to current state; machine halted\n");
	printw("press Enter:\n");
	getstr(str);
	ungetch(KEY_F(9));  /* so the machine will halt if it is runningt */
}

/* initial setup */
void init_tm(turing_machine_t *tm)
{
    /* set up the tape */
	tm->tape.size=100;
	tm->tape.data=malloc(tm->tape.size * sizeof (char));
	memset(tm->tape.data,' ',tm->tape.size);
	tm->tape.pos=50; /* start in the middle */

    /* set up the rules */
	tm->ruleset.num_rules=0;
	tm->ruleset.rules=calloc(1 ,sizeof (rule_t));

	/* set up the state */
	tm->state=0;
	tm->old_state=0;
}

/* make the tape larger by adding blank spaces at the begging */
void grow_tape_left (tape_t *t)
{
	int grow_size = 5000;   /* as good a number as any */
	t->data=realloc(t->data,t->size + grow_size);
    memmove(t->data+grow_size, t->data,t->size);
	memset(t->data,' ',grow_size);  /* fill new area with spaces */
	t->size += grow_size;
	t->pos += grow_size;  /* since we added to beginning of tape, before pos */
}

/* grow the tape to the right. */
void grow_tape_right(tape_t *t)
{
	int grow_size = 5000;   /* as good a number as any */
	t->data=realloc(t->data,t->size + grow_size);
	memset(t->data+t->size,' ',grow_size);  /* fill the new area with spaces */
	t->size += grow_size;
}

/* move the head one space to the left, growing as needed */
void move_left(tape_t *t)
{
	if (t->pos <= COLS) /* print_tape needs to be able to peek ahead */
		grow_tape_left(t);
	t->pos --;
}

/* move one space to the right, growing as needed */
void move_right(tape_t *t)
{
	if ((t->size - t->pos) <= COLS) { /* COLS / 2 would really be enough */
		grow_tape_right(t);
	}
	t->pos ++;
}

/* write a character to the tape in the current position */
void tape_write(tape_t *t, char c)
{
	if (isprint(c))
		t->data[t->pos]=c;
}

/* read a character from the tape at the current position */
void tape_read(tape_t t, char *c)
{
	*c = t.data[t.pos];
}

/* gets a rule from the user */
rule_t input_rule ()
{
	rule_t r;
    char str[1000]; /* FIXME vulnerable to buffer overflows */
	char dir;
	clear();
    printw("Use the following syntax for rules:\n");
    printw("S0 R S1 W M\n");
    printw("where:\n");
	printw("S0 = current state\n");
    printw("R = symbol to read\n");
    printw("S1 = new state\n");
    printw("W = symbol to write\n");
    printw("M = movement, one of L, R, or S (Left, Right, Stay)\n");
	printw("use _ to represent a blank space.\n");
	printw("Enter rule: ");
    echo();
    getstr(str);
    noecho();
    sscanf(str,"%d %c %d %c %c",
			&(r.cur_state), &(r.read), &(r.new_state), &(r.write), &dir);
	if ((toupper(dir)=='L') || (dir=='<'))
		r.direction=LEFT;
	else if ((toupper(dir)=='R') || (dir=='>'))
		r.direction=RIGHT;
	else
		r.direction=STAY;
	if (r.read=='_')
		r.read=' ';
	if (r.write=='_')
		r.write=' ';
	return r;
}

/* display (a subset of) the rules */
void display_rules(ruleset_t r, int hilite)
{
	int n;
	int start_rule_num=0,end_rule_num=r.num_rules;
	int num_rows = LINES - 4;   /* save room for menu, tape display etc. */

	if (r.num_rules > num_rows) {
		if (hilite <=(num_rows / 2))
			start_rule_num=0;
		else if ((r.num_rules - hilite) <= (num_rows / 2))
			start_rule_num=r.num_rules - num_rows;
		else
			start_rule_num = hilite - num_rows / 2;
		end_rule_num=start_rule_num + num_rows;
	}

		
	printw("%d %s:\n",r.num_rules, (r.num_rules != 1) ? "rules" : "rule");
	for (n=start_rule_num; n<end_rule_num; n++) {
		printw("%d %c %d %c %s",
				r.rules[n].cur_state,
				(r.rules[n].read==' ') ? '_' : r.rules[n].read,
				r.rules[n].new_state,
				(r.rules[n].write==' ') ? '_' : r.rules[n].write,
				(r.rules[n].direction==LEFT) ? "LEFT" : 
				(r.rules[n].direction==RIGHT) ? "RIGHT" :
				"STAY");
		if (n == hilite)
			printw(" <--\n");
		else
			printw("\n");
	}
}

/* adds a rule to the rule set */
int insert_rule(ruleset_t *rs, rule_t r)
{
	int n;
    int valid_rule = 1;
	
	for (n=0;n<rs->num_rules;n++)
		if((rs->rules[n].read==r.read) && (rs->rules[n].cur_state == r.cur_state))
			valid_rule = 0;
	if (!valid_rule) {
		printw("Error, conflict with an existing rule: %d %c %d %c %s\n",
			r.cur_state,
			r.read,
			r.new_state,
			r.write,
			(r.direction==LEFT) ? "LEFT" :
			(r.direction==RIGHT) ? "RIGHT" :
			"STAY");
		return 0;
	} else {
		rs->num_rules++;
		rs->rules=realloc(rs->rules,rs->num_rules * sizeof r);
		rs->rules[rs->num_rules-1]=r;  /* because we start at 0 */
		return 1;
	}
}

void bulk_insert_rules(ruleset_t *rs)
{
	char str[1000];  /* FIXME vulnerable to buffer overflows */
	
	clear();
	printw("Enter name of rule file: ");
	echo();
	getstr(str);
	noecho();

	while (! load_rules_from_file(str,rs)) {
		printw("Unable to open file \"%s\", please try again.\n",str);
		printw("Enter name of rule file: ");
		echo();
		getstr(str);
		noecho();
	}
}

int load_rules_from_file(const char *flnm, ruleset_t *rs)
{
    rule_t r;
	char dir;
	FILE *f;

    f=fopen(flnm,"ro");
	if (f == NULL)		
		return 0;
	while (! feof(f)) {
		fscanf(f,"%d %c %d %c %c",
				&(r.cur_state), &(r.read), &(r.new_state), &(r.write), &dir);
		if ((toupper(dir)=='L') || (dir=='<'))
			r.direction=LEFT;
		else if ((toupper(dir)=='R') || (dir='>'))
			r.direction=RIGHT;
		else
			r.direction=STAY;
		if (r.read=='_')
			r.read=' ';
		if (r.write=='_')
			r.write=' ';
		insert_rule(rs,r);
	}
	return 1;
}

/* delete a rule from the rule set */
void delete_rule (ruleset_t *rs, int rule_num) 
{
	/* don't delete if there are no rules */
	if (rs->num_rules >= 1) {
		/* shift all the elements in the array down one */
		memmove(rs->rules + rule_num,rs->rules + rule_num + 1,(rs->num_rules - rule_num) * sizeof (rule_t));
		rs->num_rules --;
		rs->rules=realloc(rs->rules,rs->num_rules * sizeof (rule_t));
	}
}

/* check to see if the current conditions match any rule in the set */
int match_rule(tape_t t, ruleset_t r, int st)
{
    char current;
	int n;
	tape_read(t,&current);
	for (n=0;n<r.num_rules;n++)
		if ((r.rules[n].read == current) && (r.rules[n].cur_state == st))
			return n;
	return -1;  /* no rule matched */
}

/* set the tape to all blanks. */
void clear_tape(tape_t *t)
{
	memset(t->data,' ',t->size);
}	

/* perform action specified by rule */
int execute_rule(tape_t *t, rule_t r)
{
	tape_write(t,r.write);
	if (r.direction==LEFT)
		move_left(t);
	if (r.direction==RIGHT)
		move_right(t);
	return r.new_state;
}

/* run the machine one step */
int single_step(turing_machine_t *tm)
{
	int result=0;
	result=match_rule(tm->tape,tm->ruleset, tm->state);
	if (result != -1) {
		tm->old_state = tm->state;
		tm->state=execute_rule(&(tm->tape),tm->ruleset.rules[result]);
	} else
		do_halt();
	return result;
}

/* run the machine until halted, or forever if it doesn't halt */
int auto_run(turing_machine_t *tm)
{
	int current_rule=0;
	int n=0;
	while (1) {
	/*	usleep(1); */
		current_rule=single_step(tm);
		clear();
		for (n=1;n<=8;n++)
			slk_set(n,"",0);  /* clear the function keys */
		slk_set(9,"Break",0);
		slk_refresh();
		print_tape(tm->tape);
		print_state(tm->state, tm->old_state);
		display_rules(tm->ruleset,current_rule);
		printw("\nRunning, press F9 to stop");
		refresh();
		nodelay(stdscr,TRUE);  /* make the getch non-blocking */
		if (getch()==KEY_F(9)) {
			nodelay(stdscr,FALSE);
			nocbreak();  /* get out of half-delay mode */
			cbreak();
			printw("Stopped\n");
			refresh();
			return current_rule;
		}
	}
	nocbreak();  /* get out of half-delay mode */
	cbreak();
}





/* curses setup */
void do_ncurses_setup()
{
	slk_init(3);  /* enhanced PC-style function key line */
    initscr();
	cbreak(); 
	noecho();
	nonl();
	intrflush(stdscr, FALSE);
	keypad(stdscr, TRUE);
	curs_set(0);  /* hide the cursor */
}


int main(int argc,char* argv[])
{
	turing_machine_t my_tm;
	int choice=0;
	int highlight=0;
	int old_highlight=0;

	init_tm(&my_tm);
	do_ncurses_setup();

	if (argc == 2)
		if (! load_rules_from_file(argv[1], &(my_tm.ruleset))) {
			fprintf(stderr,"Error loading file: %s\n",argv[1]);
			return EXIT_FAILURE;
		}
	
    while (choice != KEY_F(8)) {
		display_menu();
		print_tape(my_tm.tape);
		print_state(my_tm.state,my_tm.old_state);
		display_rules(my_tm.ruleset, highlight);
		choice=getch();
		switch (choice) {
			case KEY_LEFT: 
				move_left(&(my_tm.tape));
				break;
			case KEY_RIGHT:
				move_right(&(my_tm.tape));
				break;
			case KEY_UP:
				if (my_tm.ruleset.num_rules >= 1)
					highlight = (highlight + my_tm.ruleset.num_rules - 1) % my_tm.ruleset.num_rules;
				break;
			case KEY_DOWN:
				if (my_tm.ruleset.num_rules >= 1)
					highlight = (highlight + 1) % my_tm.ruleset.num_rules;
				break;
			case KEY_F(1):
			case KEY_IC:
				while (! insert_rule(&(my_tm.ruleset),input_rule()))
					; /* do nothing until a valid rule is input */
				break;
			case KEY_F(2):
			case KEY_DC:
				delete_rule(&(my_tm.ruleset),highlight);
				if (my_tm.ruleset.num_rules >= 1)
					highlight = highlight % my_tm.ruleset.num_rules;
				else
					highlight = 0;
				break;
			case KEY_F(3):
				bulk_insert_rules(&(my_tm.ruleset));
				break;
			case KEY_F(4):
				my_tm.state=get_new_state();
				break;
			case KEY_F(5):
				clear_tape(&(my_tm.tape));
				break;
			case KEY_F(6):
				old_highlight=highlight;
				highlight=single_step(&my_tm);
				if (highlight==-1)
					highlight=old_highlight;
				break;
			case KEY_F(7):
				old_highlight=highlight;
				highlight=auto_run(&my_tm);
				if (highlight==-1)
					highlight=old_highlight;
				break;
			case KEY_F(8):
			case KEY_F(9):
			case KEY_F(10):
			case KEY_F(11):
			case KEY_F(12):
				break;
			default: /* if no special key entered, it must be a regular char, so put it on the tape and keep going */
				tape_write(&(my_tm.tape),choice);
				move_right(&(my_tm.tape));
		}
	}
	
    free(my_tm.tape.data);
	free(my_tm.ruleset.rules);
	endwin(); /* free all the curses stuff */ 
	return EXIT_SUCCESS;
}	

--Boundary_(ID_NJGwEhVsqstBB0D7f2EbSA)
Content-type: text/plain; name=turing.h
Content-transfer-encoding: 7BIT
Content-disposition: inline; filename=turing.h

#ifndef TURING_H
#define TURING_H

struct tape_struct {
	char *data;
	size_t size;
	int pos;
}
typedef tape_t;

struct rule_struct {
	int cur_state;
	char read;
	int new_state;
	char write;
	enum {LEFT,RIGHT, STAY} direction;
}
typedef rule_t;

struct ruleset_struct {
	int num_rules;
	rule_t *rules;
}
typedef ruleset_t;

/* the formal definition of a turing machine also includes an alphabet. */
struct turing_machine_struct {
	tape_t tape;
	ruleset_t ruleset;
	int state;
	int old_state;  /* not strictly required, but makes life easier */
}
typedef turing_machine_t;



void do_ncurses_setup();
void display_menu();
void print_tape(tape_t t);
void print_state(int s, int o);
int get_new_state();
void display_rules(ruleset_t, int hilite);
void do_halt();
void init_tm(turing_machine_t *tm);
void grow_tape_left (tape_t *t);
void grow_tape_right(tape_t *t);
void move_left(tape_t *t);
void move_right(tape_t *t);
void tape_write(tape_t *t, char c);
void tape_read(tape_t t, char *c);
int insert_rule(ruleset_t *rs, rule_t r);
int load_rules_from_file(const char *flnm, ruleset_t *rs);
void bulk_insert_rules(ruleset_t *rs);
void delete_rule (ruleset_t *rs, int rule_num);
int match_rule(tape_t t, ruleset_t r, int st);
void clear_tape(tape_t *t);
int execute_rule(tape_t *t, rule_t r);
int single_step(turing_machine_t *tm);
int auto_run(turing_machine_t *tm);

#endif


--Boundary_(ID_NJGwEhVsqstBB0D7f2EbSA)
Content-Type: text/plain; charset=us-ascii

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/
--Boundary_(ID_NJGwEhVsqstBB0D7f2EbSA)--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019