all-up-in-your-elo 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +22 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +42 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/all-up-in-your-elo.gemspec +148 -0
- data/ext/bayeselo/.gitignore +4 -0
- data/ext/bayeselo/CBradleyTerry.cpp +670 -0
- data/ext/bayeselo/CBradleyTerry.h +137 -0
- data/ext/bayeselo/CCDistribution.cpp +135 -0
- data/ext/bayeselo/CCDistribution.h +44 -0
- data/ext/bayeselo/CCDistributionCUI.cpp +104 -0
- data/ext/bayeselo/CCDistributionCUI.h +38 -0
- data/ext/bayeselo/CCondensedResults.cpp +253 -0
- data/ext/bayeselo/CCondensedResults.h +64 -0
- data/ext/bayeselo/CDiscretization.h +40 -0
- data/ext/bayeselo/CDistribution.cpp +123 -0
- data/ext/bayeselo/CDistribution.h +58 -0
- data/ext/bayeselo/CDistributionCollection.cpp +34 -0
- data/ext/bayeselo/CDistributionCollection.h +29 -0
- data/ext/bayeselo/CEloRatingCUI.cpp +1046 -0
- data/ext/bayeselo/CEloRatingCUI.h +67 -0
- data/ext/bayeselo/CIndirectCompare.h +28 -0
- data/ext/bayeselo/CJointBayesian.cpp +111 -0
- data/ext/bayeselo/CJointBayesian.h +38 -0
- data/ext/bayeselo/CLUDecomposition.cpp +154 -0
- data/ext/bayeselo/CLUDecomposition.h +36 -0
- data/ext/bayeselo/CMatrix.cpp +48 -0
- data/ext/bayeselo/CMatrix.h +35 -0
- data/ext/bayeselo/CMatrixIO.cpp +27 -0
- data/ext/bayeselo/CMatrixIO.h +17 -0
- data/ext/bayeselo/CPredictionCUI.cpp +393 -0
- data/ext/bayeselo/CPredictionCUI.h +50 -0
- data/ext/bayeselo/CResultSet.cpp +245 -0
- data/ext/bayeselo/CResultSet.h +50 -0
- data/ext/bayeselo/CResultSetCUI.cpp +355 -0
- data/ext/bayeselo/CResultSetCUI.h +44 -0
- data/ext/bayeselo/CTimeIO.cpp +58 -0
- data/ext/bayeselo/CTimeIO.h +19 -0
- data/ext/bayeselo/CVector.cpp +110 -0
- data/ext/bayeselo/CVector.h +42 -0
- data/ext/bayeselo/EloDataFromFile.cpp +120 -0
- data/ext/bayeselo/EloDataFromFile.h +21 -0
- data/ext/bayeselo/README +8 -0
- data/ext/bayeselo/ReadLineToString.cpp +32 -0
- data/ext/bayeselo/ReadLineToString.h +18 -0
- data/ext/bayeselo/chtime.cpp +56 -0
- data/ext/bayeselo/chtime.h +61 -0
- data/ext/bayeselo/chtimer.h +27 -0
- data/ext/bayeselo/clktimer.cpp +178 -0
- data/ext/bayeselo/clktimer.h +29 -0
- data/ext/bayeselo/consolui.cpp +538 -0
- data/ext/bayeselo/consolui.h +154 -0
- data/ext/bayeselo/const.cpp +79 -0
- data/ext/bayeselo/const.h +42 -0
- data/ext/bayeselo/date.cpp +96 -0
- data/ext/bayeselo/date.h +44 -0
- data/ext/bayeselo/debug.h +58 -0
- data/ext/bayeselo/elomain.cpp +26 -0
- data/ext/bayeselo/eloratings.cpp +76 -0
- data/ext/bayeselo/extconf.rb +6 -0
- data/ext/bayeselo/list.h +367 -0
- data/ext/bayeselo/listi.h +125 -0
- data/ext/bayeselo/move.cpp +249 -0
- data/ext/bayeselo/move.h +139 -0
- data/ext/bayeselo/pgn.h +62 -0
- data/ext/bayeselo/pgnlex.cpp +432 -0
- data/ext/bayeselo/pgnlex.h +105 -0
- data/ext/bayeselo/pgnstr.cpp +126 -0
- data/ext/bayeselo/piece.h +44 -0
- data/ext/bayeselo/player.h +31 -0
- data/ext/bayeselo/position.h +89 -0
- data/ext/bayeselo/random.cpp +114 -0
- data/ext/bayeselo/random.h +63 -0
- data/ext/bayeselo/readstr.cpp +51 -0
- data/ext/bayeselo/readstr.h +19 -0
- data/ext/bayeselo/square.h +61 -0
- data/ext/bayeselo/str.cpp +81 -0
- data/ext/bayeselo/str.h +71 -0
- data/ext/bayeselo/version.cpp +30 -0
- data/ext/bayeselo/version.h +28 -0
- data/ext/bayeselo/version_number.h +1 -0
- data/lib/elo_ratings.rb +9 -0
- data/lib/elo_ratings/c_bayeselo.rb +5 -0
- data/lib/elo_ratings/results.rb +41 -0
- data/test/elo_ratings/test_c_bayeselo.rb +84 -0
- data/test/elo_ratings/test_results.rb +41 -0
- data/test/helper.rb +19 -0
- metadata +233 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
/////////////////////////////////////////////////////////////////////////////
|
2
|
+
//
|
3
|
+
// ReadLineToString.h
|
4
|
+
//
|
5
|
+
// R�mi Coulom
|
6
|
+
//
|
7
|
+
// April, 2006
|
8
|
+
//
|
9
|
+
/////////////////////////////////////////////////////////////////////////////
|
10
|
+
#ifndef ReadLineToString_Declared
|
11
|
+
#define ReadLineToString_Declared
|
12
|
+
|
13
|
+
#include <iosfwd>
|
14
|
+
#include <string>
|
15
|
+
|
16
|
+
void ReadLineToString(std::string &s, std::istream &in);
|
17
|
+
|
18
|
+
#endif
|
@@ -0,0 +1,56 @@
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////
|
2
|
+
//
|
3
|
+
// chtime.cpp
|
4
|
+
//
|
5
|
+
// CTime class
|
6
|
+
//
|
7
|
+
// Remi Coulom
|
8
|
+
//
|
9
|
+
// August 1996
|
10
|
+
//
|
11
|
+
////////////////////////////////////////////////////////////////////////////
|
12
|
+
#include "chtime.h"
|
13
|
+
#include <sstream>
|
14
|
+
|
15
|
+
////////////////////////////////////////////////////////////////////////////
|
16
|
+
// Conversion from a string
|
17
|
+
// Format : HH:MM:SS,HH (filled with zeroes)
|
18
|
+
////////////////////////////////////////////////////////////////////////////
|
19
|
+
void CTime::Set(const char *psz)
|
20
|
+
{
|
21
|
+
unsigned long ulHours = 0;
|
22
|
+
unsigned long ulMinutes = 0;
|
23
|
+
unsigned long ulSeconds = 0;
|
24
|
+
unsigned long ulHundredths = 0;
|
25
|
+
|
26
|
+
char szBuffer[3];
|
27
|
+
szBuffer[2] = 0;
|
28
|
+
|
29
|
+
szBuffer[0] = psz[0];
|
30
|
+
if (szBuffer[0])
|
31
|
+
szBuffer[1] = psz[1];
|
32
|
+
std::istringstream(szBuffer) >> std::dec >> ulHours;
|
33
|
+
if (psz[0] && psz[1] && psz[2])
|
34
|
+
{
|
35
|
+
szBuffer[0] = psz[3];
|
36
|
+
if (szBuffer[0])
|
37
|
+
szBuffer[1] = psz[4];
|
38
|
+
std::istringstream(szBuffer) >> std::dec >> ulMinutes;
|
39
|
+
if (psz[3] && psz[4] && psz[5])
|
40
|
+
{
|
41
|
+
szBuffer[0] = psz[6];
|
42
|
+
if (szBuffer[0])
|
43
|
+
szBuffer[1] = psz[7];
|
44
|
+
std::istringstream(szBuffer) >> std::dec >> ulSeconds;
|
45
|
+
if (psz[6] && psz[7] && psz[8])
|
46
|
+
{
|
47
|
+
szBuffer[0] = psz[9];
|
48
|
+
if (szBuffer[0])
|
49
|
+
szBuffer[1] = psz[10];
|
50
|
+
std::istringstream(szBuffer) >> std::dec >> ulHundredths;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
Set(ulHours, ulMinutes, ulSeconds, ulHundredths);
|
56
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////
|
2
|
+
//
|
3
|
+
// chtime.h
|
4
|
+
//
|
5
|
+
// CTime class declaration
|
6
|
+
//
|
7
|
+
// Remi Coulom
|
8
|
+
//
|
9
|
+
// August 1996
|
10
|
+
//
|
11
|
+
////////////////////////////////////////////////////////////////////////////
|
12
|
+
#ifndef CTime_Declared
|
13
|
+
#define CTime_Declared
|
14
|
+
|
15
|
+
class CTime //time
|
16
|
+
{
|
17
|
+
private: //////////////////////////////////////////////////////////////////
|
18
|
+
long lTime; // time in hundredths of a second
|
19
|
+
|
20
|
+
public: ///////////////////////////////////////////////////////////////////
|
21
|
+
//
|
22
|
+
// Compatibility with the long type
|
23
|
+
//
|
24
|
+
operator long () const {return lTime;}
|
25
|
+
CTime(long l) {lTime = l;}
|
26
|
+
CTime operator += (long l) {return lTime += l;}
|
27
|
+
CTime operator -= (long l) {return lTime -= l;}
|
28
|
+
CTime operator *= (long l) {return lTime *= l;}
|
29
|
+
CTime operator /= (long l) {return lTime /= l;}
|
30
|
+
|
31
|
+
//
|
32
|
+
// Default constructor
|
33
|
+
//
|
34
|
+
CTime() {lTime = 0;}
|
35
|
+
|
36
|
+
//
|
37
|
+
// Gets for HH:MM:SS,HH
|
38
|
+
//
|
39
|
+
long GetHours() const {return (lTime / 360000L);}
|
40
|
+
long GetMinutes() const {return (lTime / 6000) % 60;}
|
41
|
+
long GetSeconds() const {return (lTime / 100) % 60;}
|
42
|
+
long GetHundredths() const {return lTime % 100;}
|
43
|
+
|
44
|
+
//
|
45
|
+
// Sets
|
46
|
+
//
|
47
|
+
void Reset() {lTime = 0;}
|
48
|
+
void Set(long lHours,
|
49
|
+
long lMinutes,
|
50
|
+
long lSeconds,
|
51
|
+
long lHundredths)
|
52
|
+
{
|
53
|
+
lTime = lHundredths +
|
54
|
+
lSeconds * 100 +
|
55
|
+
lMinutes * 6000 +
|
56
|
+
lHours * 360000L;
|
57
|
+
}
|
58
|
+
void Set(const char *psz);
|
59
|
+
};
|
60
|
+
|
61
|
+
#endif
|
@@ -0,0 +1,27 @@
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////
|
2
|
+
//
|
3
|
+
// chtimer.h
|
4
|
+
//
|
5
|
+
// CChessTimer class declaration
|
6
|
+
//
|
7
|
+
// Remi Coulom
|
8
|
+
//
|
9
|
+
// September, 1996
|
10
|
+
//
|
11
|
+
////////////////////////////////////////////////////////////////////////////
|
12
|
+
#ifndef CHTIMER_H
|
13
|
+
#define CHTIMER_H
|
14
|
+
|
15
|
+
#include "chtime.h" // CTime
|
16
|
+
|
17
|
+
class CChessTimer // timer
|
18
|
+
{
|
19
|
+
private: //////////////////////////////////////////////////////////////////
|
20
|
+
|
21
|
+
public: ///////////////////////////////////////////////////////////////////
|
22
|
+
virtual void Wait(long lMilliSeconds = 0) = 0;
|
23
|
+
virtual CTime GetInterval(void) = 0;
|
24
|
+
virtual ~CChessTimer() {}
|
25
|
+
};
|
26
|
+
|
27
|
+
#endif
|
@@ -0,0 +1,178 @@
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////
|
2
|
+
//
|
3
|
+
// clktimer.cpp
|
4
|
+
//
|
5
|
+
// CClockTimer
|
6
|
+
//
|
7
|
+
// Remi Coulom
|
8
|
+
//
|
9
|
+
// October, 1996
|
10
|
+
//
|
11
|
+
////////////////////////////////////////////////////////////////////////////
|
12
|
+
#include "clktimer.h"
|
13
|
+
|
14
|
+
#ifdef CLOCK_FTIME /////////////////////////////////////////////////////////
|
15
|
+
#define MILLISECONDS
|
16
|
+
|
17
|
+
#include <time.h>
|
18
|
+
#include <sys/timeb.h>
|
19
|
+
|
20
|
+
static long lTime0;
|
21
|
+
|
22
|
+
static struct CGetTheProgramStartingTime
|
23
|
+
{
|
24
|
+
CGetTheProgramStartingTime()
|
25
|
+
{
|
26
|
+
struct timeb tb;
|
27
|
+
ftime(&tb);
|
28
|
+
lTime0 = tb.time;
|
29
|
+
}
|
30
|
+
} ObjectThatGetsTheProgramStartingTime;
|
31
|
+
|
32
|
+
static long MilliSeconds()
|
33
|
+
{
|
34
|
+
struct timeb tb;
|
35
|
+
ftime(&tb);
|
36
|
+
return (tb.time - lTime0) * 1000 + tb.millitm;
|
37
|
+
}
|
38
|
+
|
39
|
+
#elif defined(CLOCK_GETTIMEOFDAY) //////////////////////////////////////////
|
40
|
+
#define MILLISECONDS
|
41
|
+
|
42
|
+
#include <sys/time.h>
|
43
|
+
|
44
|
+
static long lTime0;
|
45
|
+
|
46
|
+
static struct CGetTheProgramStartingTime
|
47
|
+
{
|
48
|
+
CGetTheProgramStartingTime()
|
49
|
+
{
|
50
|
+
struct timeval tv;
|
51
|
+
gettimeofday(&tv, 0);
|
52
|
+
lTime0 = tv.tv_sec;
|
53
|
+
}
|
54
|
+
} ObjectThatGetsTheProgramStartingTime;
|
55
|
+
|
56
|
+
static long MilliSeconds()
|
57
|
+
{
|
58
|
+
struct timeval tv;
|
59
|
+
gettimeofday(&tv, 0);
|
60
|
+
return (tv.tv_sec - lTime0) * 1000 + tv.tv_usec / 1000;
|
61
|
+
}
|
62
|
+
|
63
|
+
#elif defined(CLOCK_PERFCOUNTER) ///////////////////////////////////////////
|
64
|
+
#define MILLISECONDS
|
65
|
+
|
66
|
+
#include <windows.h>
|
67
|
+
#include "debug.h"
|
68
|
+
|
69
|
+
static LARGE_INTEGER StartingTime;
|
70
|
+
static LARGE_INTEGER Frequency;
|
71
|
+
|
72
|
+
static struct CGetTheProgramStartingTime
|
73
|
+
{
|
74
|
+
CGetTheProgramStartingTime()
|
75
|
+
{
|
76
|
+
FATAL(!QueryPerformanceFrequency(&Frequency));
|
77
|
+
QueryPerformanceCounter(&StartingTime);
|
78
|
+
}
|
79
|
+
} ObjectThatGetsTheProgramStartingTime;
|
80
|
+
|
81
|
+
static long MilliSeconds()
|
82
|
+
{
|
83
|
+
LARGE_INTEGER Counter;
|
84
|
+
QueryPerformanceCounter(&Counter);
|
85
|
+
return (long)(((Counter.QuadPart - StartingTime.QuadPart) * 1000) / Frequency.QuadPart);
|
86
|
+
}
|
87
|
+
|
88
|
+
#endif
|
89
|
+
|
90
|
+
#ifdef MILLISECONDS //######################################################
|
91
|
+
|
92
|
+
////////////////////////////////////////////////////////////////////////////
|
93
|
+
// Default constructor
|
94
|
+
////////////////////////////////////////////////////////////////////////////
|
95
|
+
CClockTimer::CClockTimer()
|
96
|
+
{
|
97
|
+
lPrevious = MilliSeconds();
|
98
|
+
}
|
99
|
+
|
100
|
+
////////////////////////////////////////////////////////////////////////////
|
101
|
+
// Function to wait for a clock tick
|
102
|
+
// (needed for accurate timing)
|
103
|
+
////////////////////////////////////////////////////////////////////////////
|
104
|
+
void CClockTimer::Wait(long lMilliSeconds)
|
105
|
+
{
|
106
|
+
long t = MilliSeconds();
|
107
|
+
while (MilliSeconds() <= t + lMilliSeconds) {}
|
108
|
+
GetInterval();
|
109
|
+
}
|
110
|
+
|
111
|
+
////////////////////////////////////////////////////////////////////////////
|
112
|
+
// WaitInterval
|
113
|
+
////////////////////////////////////////////////////////////////////////////
|
114
|
+
void CClockTimer::WaitInterval(long lMilliSeconds)
|
115
|
+
{
|
116
|
+
while (MilliSeconds() <= lPrevious + lMilliSeconds) {}
|
117
|
+
lPrevious += lMilliSeconds;
|
118
|
+
}
|
119
|
+
|
120
|
+
////////////////////////////////////////////////////////////////////////////
|
121
|
+
// Returns time elapsed since construction or last call
|
122
|
+
////////////////////////////////////////////////////////////////////////////
|
123
|
+
CTime CClockTimer::GetInterval()
|
124
|
+
{
|
125
|
+
const long lTime = MilliSeconds();
|
126
|
+
const long lResult = (lTime - lPrevious) / 10;
|
127
|
+
lPrevious = lTime - (lTime - lPrevious) % 10;
|
128
|
+
|
129
|
+
return lResult;
|
130
|
+
}
|
131
|
+
|
132
|
+
#else // ###################################################################
|
133
|
+
|
134
|
+
#include <time.h>
|
135
|
+
|
136
|
+
////////////////////////////////////////////////////////////////////////////
|
137
|
+
// Default constructor
|
138
|
+
////////////////////////////////////////////////////////////////////////////
|
139
|
+
CClockTimer::CClockTimer()
|
140
|
+
{
|
141
|
+
time_t Previous;
|
142
|
+
time(&Previous);
|
143
|
+
lPrevious = Previous;
|
144
|
+
}
|
145
|
+
|
146
|
+
////////////////////////////////////////////////////////////////////////////
|
147
|
+
// Function to wait for the beginning of a second
|
148
|
+
// (needed for accurate timing)
|
149
|
+
////////////////////////////////////////////////////////////////////////////
|
150
|
+
void CClockTimer::Wait(long lMilliSeconds)
|
151
|
+
{
|
152
|
+
time_t t, Bidon;
|
153
|
+
|
154
|
+
time (&t);
|
155
|
+
while ((long)(time(&Bidon)) <= (long)(t + lMilliSeconds / 1000));
|
156
|
+
GetInterval();
|
157
|
+
}
|
158
|
+
|
159
|
+
////////////////////////////////////////////////////////////////////////////
|
160
|
+
// WaitInterval
|
161
|
+
////////////////////////////////////////////////////////////////////////////
|
162
|
+
void CClockTimer::WaitInterval(long lMilliSeconds) {
|
163
|
+
Wait(lMilliSeconds); // ???
|
164
|
+
}
|
165
|
+
|
166
|
+
////////////////////////////////////////////////////////////////////////////
|
167
|
+
// Returns number of seconds since construction or last call
|
168
|
+
////////////////////////////////////////////////////////////////////////////
|
169
|
+
CTime CClockTimer::GetInterval()
|
170
|
+
{
|
171
|
+
time_t Time = (time_t)lPrevious;
|
172
|
+
time_t Previous;
|
173
|
+
time(&Previous);
|
174
|
+
lPrevious = Previous;
|
175
|
+
return (lPrevious - Time) * 100;
|
176
|
+
}
|
177
|
+
|
178
|
+
#endif // ##################################################################
|
@@ -0,0 +1,29 @@
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////
|
2
|
+
//
|
3
|
+
// clktimer.h
|
4
|
+
//
|
5
|
+
// CClockTimer
|
6
|
+
//
|
7
|
+
// Remi Coulom
|
8
|
+
//
|
9
|
+
// October, 1996
|
10
|
+
//
|
11
|
+
////////////////////////////////////////////////////////////////////////////
|
12
|
+
#ifndef CLKTIMER_H
|
13
|
+
#define CLKTIMER_H
|
14
|
+
|
15
|
+
#include "chtimer.h" // CChessTimer
|
16
|
+
|
17
|
+
class CClockTimer : public CChessTimer // clkt
|
18
|
+
{
|
19
|
+
private: //////////////////////////////////////////////////////////////////
|
20
|
+
long lPrevious;
|
21
|
+
|
22
|
+
public: ///////////////////////////////////////////////////////////////////
|
23
|
+
CClockTimer();
|
24
|
+
virtual void Wait(long lMilliSeconds = 0);
|
25
|
+
virtual void WaitInterval(long lMilliSeconds = 0);
|
26
|
+
virtual CTime GetInterval();
|
27
|
+
};
|
28
|
+
|
29
|
+
#endif
|
@@ -0,0 +1,538 @@
|
|
1
|
+
////////////////////////////////////////////////////////////////////////////
|
2
|
+
//
|
3
|
+
// consolui.cpp
|
4
|
+
//
|
5
|
+
// CConsoleUI class
|
6
|
+
//
|
7
|
+
// Remi Coulom
|
8
|
+
//
|
9
|
+
// june 1996
|
10
|
+
//
|
11
|
+
////////////////////////////////////////////////////////////////////////////
|
12
|
+
#include "consolui.h"
|
13
|
+
#include "listi.h" // CListIterator<T>
|
14
|
+
#include "readstr.h" // ReadString
|
15
|
+
|
16
|
+
#include <iostream>
|
17
|
+
#include <fstream>
|
18
|
+
#include <cstdlib>
|
19
|
+
#include <cstring>
|
20
|
+
#include <sstream>
|
21
|
+
|
22
|
+
//
|
23
|
+
// Size of buffer for command input
|
24
|
+
//
|
25
|
+
const int CConsoleUI::BufferSize = 1024;
|
26
|
+
|
27
|
+
//
|
28
|
+
// Array of command strings
|
29
|
+
//
|
30
|
+
const char * const CConsoleUI::tszCommands[] =
|
31
|
+
{
|
32
|
+
"?",
|
33
|
+
"x",
|
34
|
+
"p",
|
35
|
+
"child",
|
36
|
+
"children",
|
37
|
+
"echo",
|
38
|
+
"!",
|
39
|
+
"prompt",
|
40
|
+
"myself",
|
41
|
+
0
|
42
|
+
};
|
43
|
+
|
44
|
+
////////////////////////////////////////////////////////////////////////////
|
45
|
+
// Constructor
|
46
|
+
////////////////////////////////////////////////////////////////////////////
|
47
|
+
CConsoleUI::CConsoleUI(CConsoleUI *pcui, int openmodeInit):
|
48
|
+
openmode(openmodeInit)
|
49
|
+
{
|
50
|
+
SetParent(pcui);
|
51
|
+
}
|
52
|
+
|
53
|
+
////////////////////////////////////////////////////////////////////////////
|
54
|
+
// Set parent
|
55
|
+
////////////////////////////////////////////////////////////////////////////
|
56
|
+
void CConsoleUI::SetParent(CConsoleUI *pcui)
|
57
|
+
{
|
58
|
+
pcuiParent = pcui;
|
59
|
+
if (pcui)
|
60
|
+
SetFPrompt(pcui->GetFPrompt());
|
61
|
+
else
|
62
|
+
fPrompt = 1;
|
63
|
+
}
|
64
|
+
|
65
|
+
////////////////////////////////////////////////////////////////////////////
|
66
|
+
// Function to look up a string in a nul-terminated array of strings
|
67
|
+
// return value: -1 if not found, index if found
|
68
|
+
////////////////////////////////////////////////////////////////////////////
|
69
|
+
int CConsoleUI::ArrayLookup(const char * const psz,
|
70
|
+
const char * const * const ppsz)
|
71
|
+
{
|
72
|
+
int Result = -1;
|
73
|
+
|
74
|
+
for (int i = 0; ppsz[i]; i++)
|
75
|
+
if (!strcmp(psz, ppsz[i]))
|
76
|
+
{
|
77
|
+
Result = i;
|
78
|
+
break;
|
79
|
+
}
|
80
|
+
|
81
|
+
return Result;
|
82
|
+
}
|
83
|
+
|
84
|
+
////////////////////////////////////////////////////////////////////////////
|
85
|
+
// Function to set a flag
|
86
|
+
////////////////////////////////////////////////////////////////////////////
|
87
|
+
const char *CConsoleUI::SetFlag(int &f, const char *psz)
|
88
|
+
{
|
89
|
+
if (!strcmp(psz, "on"))
|
90
|
+
f = 1;
|
91
|
+
else if (!strcmp(psz, "off"))
|
92
|
+
f = 0;
|
93
|
+
|
94
|
+
return f ? "on\n" : "off\n";
|
95
|
+
}
|
96
|
+
|
97
|
+
////////////////////////////////////////////////////////////////////////////
|
98
|
+
// Opening of a child
|
99
|
+
////////////////////////////////////////////////////////////////////////////
|
100
|
+
void CConsoleUI::OpenChild(int Parameter,
|
101
|
+
std::istream &in,
|
102
|
+
std::ostream &out)
|
103
|
+
{
|
104
|
+
CListIterator<CConsoleUI *> listi(lpcuiChildren);
|
105
|
+
int Child = 1;
|
106
|
+
|
107
|
+
while (!listi.IsAtTheEnd() && Child != Parameter)
|
108
|
+
{
|
109
|
+
listi.Increment();
|
110
|
+
Child++;
|
111
|
+
}
|
112
|
+
|
113
|
+
if (listi.IsAtTheEnd())
|
114
|
+
out << "Error: no child having number " << Parameter << ".\n";
|
115
|
+
else
|
116
|
+
if (listi.Value()->MainLoop(in, out) == PC_Close)
|
117
|
+
{
|
118
|
+
delete listi.Value();
|
119
|
+
listi.Remove();
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
////////////////////////////////////////////////////////////////////////////
|
124
|
+
// Function to print an error message
|
125
|
+
////////////////////////////////////////////////////////////////////////////
|
126
|
+
void CConsoleUI::PrintErrorMessage(std::ostream &out, const char *pszCommand)
|
127
|
+
{
|
128
|
+
out << "Unknown command: " << pszCommand << '\n';
|
129
|
+
out << "type '?' for help\n";
|
130
|
+
}
|
131
|
+
|
132
|
+
////////////////////////////////////////////////////////////////////////////
|
133
|
+
// Function to process commands
|
134
|
+
////////////////////////////////////////////////////////////////////////////
|
135
|
+
int CConsoleUI::ProcessCommand(const char *pszCommand,
|
136
|
+
const char *pszParameters,
|
137
|
+
std::istream &in,
|
138
|
+
std::ostream &out)
|
139
|
+
{
|
140
|
+
enum
|
141
|
+
{
|
142
|
+
IDC_Help,
|
143
|
+
IDC_Close,
|
144
|
+
IDC_Parent,
|
145
|
+
IDC_Child,
|
146
|
+
IDC_Children,
|
147
|
+
IDC_Echo,
|
148
|
+
IDC_System,
|
149
|
+
IDC_Prompt,
|
150
|
+
IDC_Myself
|
151
|
+
};
|
152
|
+
|
153
|
+
int RetVal = PC_Continue;
|
154
|
+
|
155
|
+
switch (ArrayLookup(pszCommand, tszCommands))
|
156
|
+
{
|
157
|
+
case IDC_Help: ///////////////////////////////////////////////////////////
|
158
|
+
out << '\n';
|
159
|
+
out << "Syntax for command lines\n";
|
160
|
+
out << "~~~~~~~~~~~~~~~~~~~~~~~~\n";
|
161
|
+
out << "_command_ _parameters_ [< _input_] [>[>] _output_] [;_comment_]\n";
|
162
|
+
out << '\n';
|
163
|
+
out << "Universal commands\n";
|
164
|
+
out << "~~~~~~~~~~~~~~~~~~\n";
|
165
|
+
out << "x ............... close this console interface\n";
|
166
|
+
out << "p ............... go to the parent interface\n";
|
167
|
+
out << "children ........ list children interfaces\n";
|
168
|
+
out << "child <n> ....... select a child interface\n";
|
169
|
+
out << '\n';
|
170
|
+
out << "echo <params> ... repeat <params> to the output stream\n";
|
171
|
+
out << "! [<command>] ... make a system call\n";
|
172
|
+
out << "prompt [on|off] . show|hide the command prompt\n";
|
173
|
+
out << "myself <n> ...... call recursively this interface <n> times\n";
|
174
|
+
out << '\n';
|
175
|
+
break;
|
176
|
+
|
177
|
+
case IDC_Close: //////////////////////////////////////////////////////////
|
178
|
+
if (openmode != OpenPermanent)
|
179
|
+
RetVal = PC_Close;
|
180
|
+
else
|
181
|
+
out << "Error: impossible to close a permanent interface\n";
|
182
|
+
break;
|
183
|
+
|
184
|
+
case IDC_Parent: /////////////////////////////////////////////////////////
|
185
|
+
if (openmode != OpenModal)
|
186
|
+
RetVal = PC_Parent;
|
187
|
+
else
|
188
|
+
out << "Error: parent not accessible to modal interfaces\n";
|
189
|
+
break;
|
190
|
+
|
191
|
+
case IDC_Child: //////////////////////////////////////////////////////////
|
192
|
+
{
|
193
|
+
int Parameter = 0;
|
194
|
+
std::istringstream(pszParameters) >> Parameter;
|
195
|
+
OpenChild(Parameter, in, out);
|
196
|
+
}
|
197
|
+
break;
|
198
|
+
|
199
|
+
case IDC_Children: ///////////////////////////////////////////////////////
|
200
|
+
{
|
201
|
+
CListIterator<CConsoleUI *> listi(lpcuiChildren);
|
202
|
+
int n = 0;
|
203
|
+
|
204
|
+
while (!listi.IsAtTheEnd())
|
205
|
+
{
|
206
|
+
out << ' ' << ++n << ": ";
|
207
|
+
listi.Value()->PrintLocalPrompt(out);
|
208
|
+
out << '\n';
|
209
|
+
listi.Increment();
|
210
|
+
}
|
211
|
+
}
|
212
|
+
break;
|
213
|
+
|
214
|
+
case IDC_Echo: ///////////////////////////////////////////////////////////
|
215
|
+
out << pszParameters << '\n';
|
216
|
+
break;
|
217
|
+
|
218
|
+
case IDC_System: /////////////////////////////////////////////////////////
|
219
|
+
#ifndef NOSYSTEM
|
220
|
+
{
|
221
|
+
int r = system(pszParameters);
|
222
|
+
if (r)
|
223
|
+
out << "Exit status = " << r << '\n';
|
224
|
+
}
|
225
|
+
#else
|
226
|
+
out << "Not available.\n";
|
227
|
+
#endif
|
228
|
+
break;
|
229
|
+
|
230
|
+
case IDC_Prompt: /////////////////////////////////////////////////////////
|
231
|
+
out << SetFlag(fPrompt, pszParameters);
|
232
|
+
break;
|
233
|
+
|
234
|
+
case IDC_Myself: /////////////////////////////////////////////////////////
|
235
|
+
{
|
236
|
+
int Parameter = 1;
|
237
|
+
std::istringstream(pszParameters) >> Parameter;
|
238
|
+
int OldPrompt = GetFPrompt();
|
239
|
+
SetFPrompt(0);
|
240
|
+
for (int i = Parameter; --i >= 0;)
|
241
|
+
{
|
242
|
+
MainLoop(in, out);
|
243
|
+
if (i > 0)
|
244
|
+
in.seekg(0); // ???: may cause infinite looping if input not set
|
245
|
+
}
|
246
|
+
SetFPrompt(OldPrompt);
|
247
|
+
}
|
248
|
+
break;
|
249
|
+
|
250
|
+
default: /////////////////////////////////////////////////////////////////
|
251
|
+
PrintErrorMessage(out, pszCommand);
|
252
|
+
break;
|
253
|
+
}
|
254
|
+
|
255
|
+
return RetVal;
|
256
|
+
}
|
257
|
+
|
258
|
+
////////////////////////////////////////////////////////////////////////////
|
259
|
+
// Function to set the parent CUI for this CUI
|
260
|
+
////////////////////////////////////////////////////////////////////////////
|
261
|
+
void CConsoleUI::AddChild(CConsoleUI *pcui,
|
262
|
+
std::istream &in,
|
263
|
+
std::ostream &out)
|
264
|
+
{
|
265
|
+
if (pcui)
|
266
|
+
{
|
267
|
+
lpcuiChildren.Add();
|
268
|
+
lpcuiChildren.Head() = pcui;
|
269
|
+
OpenChild(1, in, out);
|
270
|
+
}
|
271
|
+
else
|
272
|
+
out << "Error: could not create child\n";
|
273
|
+
}
|
274
|
+
|
275
|
+
////////////////////////////////////////////////////////////////////////////
|
276
|
+
// Function: parses a command string
|
277
|
+
// The syntax is:
|
278
|
+
//
|
279
|
+
// 'command' 'parameters' [<'input'] [>[>]'output'] ;'comment'
|
280
|
+
//
|
281
|
+
// '\0's are inserted in the string between fields
|
282
|
+
////////////////////////////////////////////////////////////////////////////
|
283
|
+
void CConsoleUI::Parse(char *pszCommand,
|
284
|
+
const char *&pszCommand2,
|
285
|
+
const char *&pszParameters,
|
286
|
+
const char *&pszInput,
|
287
|
+
const char *&pszOutput) const
|
288
|
+
{
|
289
|
+
//
|
290
|
+
// Tabulation and white spaces at the beginning are ignored
|
291
|
+
//
|
292
|
+
while(*pszCommand == ' ' || *pszCommand == '\t')
|
293
|
+
pszCommand++;
|
294
|
+
pszCommand2 = pszCommand;
|
295
|
+
|
296
|
+
//
|
297
|
+
// Comments are removed
|
298
|
+
//
|
299
|
+
{
|
300
|
+
char *psz = strchr(pszCommand, ';');
|
301
|
+
if (psz && (psz[1] || psz == pszCommand))
|
302
|
+
*psz = 0;
|
303
|
+
}
|
304
|
+
|
305
|
+
//
|
306
|
+
// Name of file for output
|
307
|
+
//
|
308
|
+
pszOutput = 0;
|
309
|
+
{
|
310
|
+
char *psz = strchr(pszCommand, '>');
|
311
|
+
if (psz)
|
312
|
+
{
|
313
|
+
pszOutput = psz + 1;
|
314
|
+
*psz = 0;
|
315
|
+
}
|
316
|
+
}
|
317
|
+
|
318
|
+
//
|
319
|
+
// Name of file for input
|
320
|
+
//
|
321
|
+
pszInput = 0;
|
322
|
+
{
|
323
|
+
char *psz = strchr(pszCommand, '<');
|
324
|
+
if (psz)
|
325
|
+
{
|
326
|
+
pszInput = psz + 1;
|
327
|
+
*psz = 0;
|
328
|
+
}
|
329
|
+
}
|
330
|
+
|
331
|
+
//
|
332
|
+
// Separation between command string and parameters
|
333
|
+
//
|
334
|
+
char *psz = pszCommand;
|
335
|
+
|
336
|
+
while(*psz && *psz != ' ')
|
337
|
+
psz++;
|
338
|
+
|
339
|
+
while(*psz == ' ')
|
340
|
+
{
|
341
|
+
*psz = 0;
|
342
|
+
psz++;
|
343
|
+
}
|
344
|
+
|
345
|
+
pszParameters = psz;
|
346
|
+
}
|
347
|
+
|
348
|
+
////////////////////////////////////////////////////////////////////////////
|
349
|
+
// Function to print a prompt
|
350
|
+
////////////////////////////////////////////////////////////////////////////
|
351
|
+
void CConsoleUI::PrintPrompt(std::ostream &out)
|
352
|
+
{
|
353
|
+
if (pcuiParent)
|
354
|
+
{
|
355
|
+
pcuiParent->PrintPrompt(out);
|
356
|
+
switch(openmode)
|
357
|
+
{
|
358
|
+
case OpenModal: out << '-'; break;
|
359
|
+
case OpenModeless: out << '/'; break;
|
360
|
+
case OpenPermanent: out << '|'; break;
|
361
|
+
}
|
362
|
+
}
|
363
|
+
PrintLocalPrompt(out);
|
364
|
+
}
|
365
|
+
|
366
|
+
////////////////////////////////////////////////////////////////////////////
|
367
|
+
// Function to process a command
|
368
|
+
////////////////////////////////////////////////////////////////////////////
|
369
|
+
int CConsoleUI::EnterParseAndProcess(std::istream &in,
|
370
|
+
std::ostream &out,
|
371
|
+
std::ostream *pofsLog)
|
372
|
+
{
|
373
|
+
int Result = PC_Continue;
|
374
|
+
|
375
|
+
//
|
376
|
+
// The user may be prompted
|
377
|
+
//
|
378
|
+
if (fPrompt)
|
379
|
+
{
|
380
|
+
PrintPrompt(out);
|
381
|
+
out << '>';
|
382
|
+
}
|
383
|
+
|
384
|
+
//
|
385
|
+
// The output stream is flushed before the command is entered
|
386
|
+
//
|
387
|
+
out.flush();
|
388
|
+
|
389
|
+
//
|
390
|
+
// The command string is entered
|
391
|
+
//
|
392
|
+
char szCommand[BufferSize];
|
393
|
+
if (ReadString(in, szCommand, sizeof(szCommand)) < 0)
|
394
|
+
return PC_Close;
|
395
|
+
else
|
396
|
+
{
|
397
|
+
//
|
398
|
+
// The string is parsed
|
399
|
+
//
|
400
|
+
const char *pszCommand;
|
401
|
+
const char *pszParameters;
|
402
|
+
const char *pszInput;
|
403
|
+
const char *pszOutput;
|
404
|
+
|
405
|
+
Parse(szCommand, pszCommand, pszParameters, pszInput, pszOutput);
|
406
|
+
|
407
|
+
//
|
408
|
+
// The command is processed only if it is not empty
|
409
|
+
//
|
410
|
+
if (*pszCommand)
|
411
|
+
{
|
412
|
+
int fStreamsOK = 1;
|
413
|
+
|
414
|
+
//
|
415
|
+
// New input stream
|
416
|
+
//
|
417
|
+
std::istream *pinNew = ∈
|
418
|
+
std::ifstream *pifs = 0;
|
419
|
+
if (pszInput)
|
420
|
+
{
|
421
|
+
if (!*pszInput)
|
422
|
+
pinNew = &std::cin;
|
423
|
+
else
|
424
|
+
{
|
425
|
+
pifs = new std::ifstream(pszInput, std::ios::in);
|
426
|
+
if (pifs->good())
|
427
|
+
pinNew = pifs;
|
428
|
+
else
|
429
|
+
{
|
430
|
+
out << "Error: could not open input stream: " << pszInput << '\n';
|
431
|
+
out.flush();
|
432
|
+
fStreamsOK = 0;
|
433
|
+
}
|
434
|
+
}
|
435
|
+
}
|
436
|
+
|
437
|
+
//
|
438
|
+
// New output stream
|
439
|
+
//
|
440
|
+
std::ostream *poutNew = &out;
|
441
|
+
std::ofstream *pofs = 0;
|
442
|
+
if (pszOutput)
|
443
|
+
{
|
444
|
+
if (!*pszOutput)
|
445
|
+
poutNew = &std::cout;
|
446
|
+
else
|
447
|
+
{
|
448
|
+
pofs = new std::ofstream;
|
449
|
+
if (*pszOutput == '>')
|
450
|
+
pofs->open(pszOutput + 1, std::ios::out | std::ios::app);
|
451
|
+
else
|
452
|
+
pofs->open(pszOutput, std::ios::out);
|
453
|
+
|
454
|
+
if (pofs->good())
|
455
|
+
poutNew = pofs;
|
456
|
+
else
|
457
|
+
{
|
458
|
+
out << "Error: could not open output stream: " << pszOutput << '\n';
|
459
|
+
out.flush();
|
460
|
+
fStreamsOK = 0;
|
461
|
+
}
|
462
|
+
}
|
463
|
+
}
|
464
|
+
|
465
|
+
//
|
466
|
+
// The command is processed with these new streams
|
467
|
+
//
|
468
|
+
if (fStreamsOK)
|
469
|
+
{
|
470
|
+
if (pofsLog)
|
471
|
+
{
|
472
|
+
*pofsLog << "Command: " << pszCommand << ' ' << pszParameters << '\n';
|
473
|
+
pofsLog->flush();
|
474
|
+
}
|
475
|
+
Result = ProcessCommand(pszCommand, pszParameters, *pinNew, *poutNew);
|
476
|
+
poutNew->flush();
|
477
|
+
}
|
478
|
+
|
479
|
+
//
|
480
|
+
// If new file streams have been created, we must delete them
|
481
|
+
//
|
482
|
+
if (pifs)
|
483
|
+
delete pifs;
|
484
|
+
if (pofs)
|
485
|
+
delete pofs;
|
486
|
+
}
|
487
|
+
}
|
488
|
+
|
489
|
+
return Result;
|
490
|
+
}
|
491
|
+
|
492
|
+
////////////////////////////////////////////////////////////////////////////
|
493
|
+
// Function: Main loop of the user interface
|
494
|
+
////////////////////////////////////////////////////////////////////////////
|
495
|
+
int CConsoleUI::MainLoop(std::istream &in, std::ostream &out)
|
496
|
+
{
|
497
|
+
while(1)
|
498
|
+
{
|
499
|
+
int Result;
|
500
|
+
|
501
|
+
Result = EnterParseAndProcess(in, out);
|
502
|
+
if (Result != PC_Continue)
|
503
|
+
return Result;
|
504
|
+
}
|
505
|
+
}
|
506
|
+
|
507
|
+
////////////////////////////////////////////////////////////////////////////
|
508
|
+
// Get[Set] utility function
|
509
|
+
////////////////////////////////////////////////////////////////////////////
|
510
|
+
template<class T>
|
511
|
+
void CConsoleUI::GetSet(T &x, const char *pszParameters, std::ostream &out)
|
512
|
+
{
|
513
|
+
if (*pszParameters)
|
514
|
+
{
|
515
|
+
std::istringstream is(pszParameters);
|
516
|
+
is >> x;
|
517
|
+
}
|
518
|
+
out << x << '\n';
|
519
|
+
}
|
520
|
+
|
521
|
+
template void CConsoleUI::GetSet<int>(int&, const char*, std::ostream&);
|
522
|
+
template void CConsoleUI::GetSet<float>(float&, const char*, std::ostream&);
|
523
|
+
template void CConsoleUI::GetSet<double>(double&, const char*, std::ostream&);
|
524
|
+
template void CConsoleUI::GetSet<std::string>(std::string&, const char*, std::ostream&);
|
525
|
+
|
526
|
+
////////////////////////////////////////////////////////////////////////////
|
527
|
+
// Destructor
|
528
|
+
////////////////////////////////////////////////////////////////////////////
|
529
|
+
CConsoleUI::~CConsoleUI()
|
530
|
+
{
|
531
|
+
CListIterator<CConsoleUI *> listi(lpcuiChildren);
|
532
|
+
|
533
|
+
while (!listi.IsAtTheEnd())
|
534
|
+
{
|
535
|
+
delete listi.Value();
|
536
|
+
listi.Remove();
|
537
|
+
}
|
538
|
+
}
|