File: while.cc

package info (click to toggle)
gri 2.8.7-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 4,472 kB
  • ctags: 2,092
  • sloc: cpp: 33,255; lisp: 3,980; perl: 1,037; makefile: 668; sh: 301
file content (139 lines) | stat: -rw-r--r-- 3,354 bytes parent folder | download | duplicates (4)
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// #define DEBUG_WHILE
#include	<string>
#include	<math.h>
#include	<stdio.h>
#include	"private.hh"
#include	"extern.hh"
#include	"gr.hh"
bool            whileCmd(void);
static bool     test_is_true(const std::string& t);


bool
whileCmd(void)
{
	std::string test(6 + strstr(_cmdLine, "while"));
	if (re_compare(test.c_str(), " *")) {
		err("`while .test.|{rpn ...}' missing the test part");
		return false;
	}
	int loop_level = 1;
	int lines = 0;
	//printf("=============== in while cmd.  '%s'       test '%s'\n",_cmdLine,test.c_str());
	test_is_true(test); // to catch syntax errors on this line
	// Store lines until end while into the buffer
	std::string buffer;
	while (1) {
		if (!get_command_line()) {
			err("Missing `end while'");
			return false;
		}
		lines++;
		// Search for matching end while
		if (re_compare(_cmdLine, "\\s*while.*")) {
			loop_level++;
		} else {
			// Search for `end while', but first make a copy
			// without the source_indicator
			char *copy = (char*)malloc((1 + strlen(_cmdLine)) * sizeof(char));
			if (!copy) OUT_OF_MEMORY;
			strcpy(copy, _cmdLine);
			int len = strlen(copy);
			for (int i = 0; i < len; i++) {
				if (copy[i] == PASTE_CHAR) {
					copy[i] = '\0';
					break;
				}
			}
			if (re_compare(copy, "\\s*end\\s+while.*")) {
				loop_level--;
				if (loop_level < 1) {
					break;
				}
			}
			free(copy);
		}
		buffer.append(_cmdLine);
		buffer.append("\n");
	}
	perform_while_block(buffer.c_str(), test.c_str(), lines);
	return true;
}

#define DEBUG 1
const int NOTIFY = 1000;
bool
perform_while_block(const char *buffer, const char *test, int lines)
{
	//printf("^^^^^^^^^^^^ perform_while_block(...,%s,...)\n",test);
	std::string     filename;
	int             fileline;
	int             passes = 0;
	std::string t(test);
	while (test_is_true(t)) {
		// Check to see if test is now false
		if (block_level() > 0) {
			filename.assign(block_source_file());
			fileline = block_source_line() + 2;
#ifdef DEBUG_WHILE
			printf("Register while AT BLOCKLEVEL = %d at %s:%d lines=%d\n",
			       block_level(),
			       block_source_file(),
			       block_source_line() + 2,
			       block_line());
#endif
		} else {
			filename.assign(what_file());
			fileline = what_line() - lines + 1;
#ifdef DEBUG_WHILE
			printf("Register OUT OF BLOCK while at %s:%d\n",
			       what_file(),
			       what_line() - lines + 1);
#endif
		}
		
		if (!perform_block(buffer, filename.c_str(), fileline)) {
			// got break
			break;
		}

		passes++;
		if (_chatty > 0 && !(passes % NOTIFY)) {
			char msg[100];
			sprintf(msg, "`while' performed %d passes\n", passes);
			gr_textput(msg);
		}
	}
#ifdef DEBUG_WHILE
	printf("\nFINISHED WITH LOOP\n");
#endif
	return true;
}

static bool
test_is_true(const std::string& t)
{
	std::string tt;
	substitute_synonyms(t.c_str(), tt, true);
	clean_blanks_quotes(tt);
	// Catch "! SOMETHING" form
	bool negate = false;
	if (tt[0] == '!') {
		negate = true;
		tt.STRINGERASE(0, 1);
		clean_blanks_quotes(tt);
	}
	char res[100]; // BUG: fixed size
	substitute_rpn_expressions(tt.c_str(), res);
	//printf(" + '%s'        ->     '%s'\n", t.c_str(),tt.c_str());
	double value;
	if (is_var(res)) {
		getdnum(res, &value);
	} else {
		sscanf(res, "%lf", &value);
	}
	if (negate)
		return ((value != 0.0) ? false : true);
	else
		return ((value != 0.0) ? true : false);
}