elo-ratings 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +22 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +23 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/elo-ratings.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/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/rb_bayeselo.cpp +76 -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/bayeselo.rb +6 -0
- data/lib/bayeselo/bayeselo.rb +11 -0
- data/lib/bayeselo/c_bayeselo.rb +7 -0
- data/test/bayeselo/test_bayeselo.rb +33 -0
- data/test/bayeselo/test_c_bayeselo.rb +84 -0
- data/test/helper.rb +18 -0
- metadata +226 -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
|
+
}
|