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.
Files changed (91) hide show
  1. data/.document +5 -0
  2. data/Gemfile +14 -0
  3. data/Gemfile.lock +22 -0
  4. data/LICENSE.txt +20 -0
  5. data/README.rdoc +42 -0
  6. data/Rakefile +54 -0
  7. data/VERSION +1 -0
  8. data/all-up-in-your-elo.gemspec +148 -0
  9. data/ext/bayeselo/.gitignore +4 -0
  10. data/ext/bayeselo/CBradleyTerry.cpp +670 -0
  11. data/ext/bayeselo/CBradleyTerry.h +137 -0
  12. data/ext/bayeselo/CCDistribution.cpp +135 -0
  13. data/ext/bayeselo/CCDistribution.h +44 -0
  14. data/ext/bayeselo/CCDistributionCUI.cpp +104 -0
  15. data/ext/bayeselo/CCDistributionCUI.h +38 -0
  16. data/ext/bayeselo/CCondensedResults.cpp +253 -0
  17. data/ext/bayeselo/CCondensedResults.h +64 -0
  18. data/ext/bayeselo/CDiscretization.h +40 -0
  19. data/ext/bayeselo/CDistribution.cpp +123 -0
  20. data/ext/bayeselo/CDistribution.h +58 -0
  21. data/ext/bayeselo/CDistributionCollection.cpp +34 -0
  22. data/ext/bayeselo/CDistributionCollection.h +29 -0
  23. data/ext/bayeselo/CEloRatingCUI.cpp +1046 -0
  24. data/ext/bayeselo/CEloRatingCUI.h +67 -0
  25. data/ext/bayeselo/CIndirectCompare.h +28 -0
  26. data/ext/bayeselo/CJointBayesian.cpp +111 -0
  27. data/ext/bayeselo/CJointBayesian.h +38 -0
  28. data/ext/bayeselo/CLUDecomposition.cpp +154 -0
  29. data/ext/bayeselo/CLUDecomposition.h +36 -0
  30. data/ext/bayeselo/CMatrix.cpp +48 -0
  31. data/ext/bayeselo/CMatrix.h +35 -0
  32. data/ext/bayeselo/CMatrixIO.cpp +27 -0
  33. data/ext/bayeselo/CMatrixIO.h +17 -0
  34. data/ext/bayeselo/CPredictionCUI.cpp +393 -0
  35. data/ext/bayeselo/CPredictionCUI.h +50 -0
  36. data/ext/bayeselo/CResultSet.cpp +245 -0
  37. data/ext/bayeselo/CResultSet.h +50 -0
  38. data/ext/bayeselo/CResultSetCUI.cpp +355 -0
  39. data/ext/bayeselo/CResultSetCUI.h +44 -0
  40. data/ext/bayeselo/CTimeIO.cpp +58 -0
  41. data/ext/bayeselo/CTimeIO.h +19 -0
  42. data/ext/bayeselo/CVector.cpp +110 -0
  43. data/ext/bayeselo/CVector.h +42 -0
  44. data/ext/bayeselo/EloDataFromFile.cpp +120 -0
  45. data/ext/bayeselo/EloDataFromFile.h +21 -0
  46. data/ext/bayeselo/README +8 -0
  47. data/ext/bayeselo/ReadLineToString.cpp +32 -0
  48. data/ext/bayeselo/ReadLineToString.h +18 -0
  49. data/ext/bayeselo/chtime.cpp +56 -0
  50. data/ext/bayeselo/chtime.h +61 -0
  51. data/ext/bayeselo/chtimer.h +27 -0
  52. data/ext/bayeselo/clktimer.cpp +178 -0
  53. data/ext/bayeselo/clktimer.h +29 -0
  54. data/ext/bayeselo/consolui.cpp +538 -0
  55. data/ext/bayeselo/consolui.h +154 -0
  56. data/ext/bayeselo/const.cpp +79 -0
  57. data/ext/bayeselo/const.h +42 -0
  58. data/ext/bayeselo/date.cpp +96 -0
  59. data/ext/bayeselo/date.h +44 -0
  60. data/ext/bayeselo/debug.h +58 -0
  61. data/ext/bayeselo/elomain.cpp +26 -0
  62. data/ext/bayeselo/eloratings.cpp +76 -0
  63. data/ext/bayeselo/extconf.rb +6 -0
  64. data/ext/bayeselo/list.h +367 -0
  65. data/ext/bayeselo/listi.h +125 -0
  66. data/ext/bayeselo/move.cpp +249 -0
  67. data/ext/bayeselo/move.h +139 -0
  68. data/ext/bayeselo/pgn.h +62 -0
  69. data/ext/bayeselo/pgnlex.cpp +432 -0
  70. data/ext/bayeselo/pgnlex.h +105 -0
  71. data/ext/bayeselo/pgnstr.cpp +126 -0
  72. data/ext/bayeselo/piece.h +44 -0
  73. data/ext/bayeselo/player.h +31 -0
  74. data/ext/bayeselo/position.h +89 -0
  75. data/ext/bayeselo/random.cpp +114 -0
  76. data/ext/bayeselo/random.h +63 -0
  77. data/ext/bayeselo/readstr.cpp +51 -0
  78. data/ext/bayeselo/readstr.h +19 -0
  79. data/ext/bayeselo/square.h +61 -0
  80. data/ext/bayeselo/str.cpp +81 -0
  81. data/ext/bayeselo/str.h +71 -0
  82. data/ext/bayeselo/version.cpp +30 -0
  83. data/ext/bayeselo/version.h +28 -0
  84. data/ext/bayeselo/version_number.h +1 -0
  85. data/lib/elo_ratings.rb +9 -0
  86. data/lib/elo_ratings/c_bayeselo.rb +5 -0
  87. data/lib/elo_ratings/results.rb +41 -0
  88. data/test/elo_ratings/test_c_bayeselo.rb +84 -0
  89. data/test/elo_ratings/test_results.rb +41 -0
  90. data/test/helper.rb +19 -0
  91. 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 = &in;
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
+ }