File: while.cc

package info (click to toggle)
gri 2.4.2-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 4,540 kB
  • ctags: 1,966
  • sloc: cpp: 32,542; lisp: 3,243; perl: 806; makefile: 548; sh: 253
file content (119 lines) | stat: -rw-r--r-- 2,857 bytes parent folder | download
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
// #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 char *s);


bool
whileCmd(void)
{
    int             loop_level = 1;
    int             lines = 0;
    string test(6 + strstr(_cmdLine, "while"));
    if (re_compare(test.c_str(), " *")) {
	err("`while .test.|{rpn ...}' missing the test part");
	return false;
    }
    test_is_true(test.c_str()); // to catch syntax errors on this line
    // Store lines until end while into the buffer
    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 = new char [1 + strlen(_cmdLine)];
	    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\\s*")) {
		loop_level--;
		if (loop_level < 1) {
		    break;
		}
	    }
	    delete [] copy;
	}
	buffer.append(_cmdLine);
	buffer.append("\n");
    }
    perform_while_block(buffer.c_str(), test.c_str(), lines);
    return true;
}

const int NOTIFY = 1000;
bool
perform_while_block(const char *buffer, const char *test, int lines)
{
    string          filename;
    int             fileline;
    int             passes = 0;
    while (test_is_true(test)) {
	// 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 char *s)
{
    char            res[100];
    double          value;
    substitute_rpn_expressions(s, res);
    if (is_var(res)) {
	getdnum(res, &value);
    } else {
	sscanf(res, "%lf", &value);
    }
    return ((value != 0.0) ? true : false);
}