4
* Copyright © 2003 Keith Packard
6
* Permission to use, copy, modify, distribute, and sell this software and its
7
* documentation for any purpose is hereby granted without fee, provided that
8
* the above copyright notice appear in all copies and that both that
9
* copyright notice and this permission notice appear in supporting
10
* documentation, and that the name of Keith Packard not be used in
11
* advertising or publicity pertaining to distribution of the software without
12
* specific, written prior permission. Keith Packard makes no
13
* representations about the suitability of this software for any purpose. It
14
* is provided "as is" without express or implied warranty.
16
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22
* PERFORMANCE OF THIS SOFTWARE.
28
public namespace Send {
29
bool needsquote (string s) {
30
int len = String::length (s);
33
for (int i = 0; i < len; i++)
34
if (Ctype::isblank (s[i]) || s[i] == '"' || s[i] == '\\')
39
public exception too_few_arguments (string format, poly[] args);
41
public exception too_many_arguments (string format, poly[] args);
43
public void send (file f, string format, poly args...)
45
void put_string (string s) {
46
void quote (string s) {
49
for (i = 0; i < String::length (s); i++)
51
if (s[i] == '"' || s[i] == '\\')
60
File::fprintf (f, "%s", s);
63
void put_color (Color c) {
65
case Color.Red: File::fprintf (f, "red"); break;
66
case Color.Yellow: File::fprintf (f, "yellow"); break;
67
case Color.Green: File::fprintf (f, "green"); break;
68
case Color.Blue: File::fprintf (f, "blue"); break;
69
case Color.Whirl: File::fprintf (f, "whirl"); break;
73
void put_shape (Shape c) {
75
case Shape.Triangle: File::fprintf (f, "triangle"); break;
76
case Shape.Square: File::fprintf (f, "square"); break;
77
case Shape.Octagon: File::fprintf (f, "octagon"); break;
78
case Shape.Circle: File::fprintf (f, "circle"); break;
79
case Shape.Whirl: File::fprintf (f, "whirl"); break;
83
void put_direction (Direction d) {
85
case Direction.North: File::fprintf (f, "north"); break;
86
case Direction.East: File::fprintf (f, "east"); break;
87
case Direction.South: File::fprintf (f, "south"); break;
88
case Direction.West: File::fprintf (f, "west"); break;
92
void put_gamestate (GameState s) {
94
case GameState.NEW: File::fprintf (f, "NEW"); break;
95
case GameState.BID: File::fprintf (f, "BID"); break;
96
case GameState.SHOW: File::fprintf (f, "SHOW"); break;
97
case GameState.DONE: File::fprintf (f, "DONE"); break;
101
void put_error (Error e) {
103
case Error.NOGAME: File::fprintf (f, "NOGAME"); break;
104
case Error.NOUSER: File::fprintf (f, "NOUSER"); break;
105
case Error.NOTINGAME: File::fprintf (f, "NOTINGAME"); break;
106
case Error.NOTPLAYING: File::fprintf (f, "NOTPLAYING"); break;
107
case Error.NOTBIDDING: File::fprintf (f, "NOTBIDDING"); break;
108
case Error.NOTLOWER: File::fprintf (f, "NOTLOWER"); break;
109
case Error.NOBID: File::fprintf (f, "NOBID"); break;
110
case Error.NOTACTIVE: File::fprintf (f, "NOTACTIVE"); break;
111
case Error.NOTDONE: File::fprintf (f, "NOTDONE"); break;
112
case Error.NOTNUMBER: File::fprintf (f, "NOTNUMBER"); break;
113
case Error.BLOCKED: File::fprintf (f, "BLOCKED"); break;
114
case Error.COMMAND: File::fprintf (f, "COMMAND"); break;
115
case Error.SYNTAX: File::fprintf (f, "SYNTAX"); break;
116
case Error.NOTCOLOR: File::fprintf (f, "NOTCOLOR"); break;
117
case Error.NOTSHAPE: File::fprintf (f, "NOTSHAPE"); break;
118
case Error.NOTDIRECTION:File::fprintf (f, "NOTDIRECTION"); break;
119
case Error.TOOMANYMOVES:File::fprintf (f, "TOOMANYMOVES"); break;
120
case Error.NONAMESET: File::fprintf (f, "NONAMESET"); break;
121
case Error.INVALIDNAME: File::fprintf (f, "INVALIDNAME"); break;
125
void put_number (int n) {
126
File::fprintf (f, "%d", n);
129
void put_bool (bool b) {
130
File::fprintf (f, "%s", b ? "true" : "false");
134
* A private namespace to walk the format string
138
int len = String::length(format);
141
* Return whether the end of the string has been reached
143
public bool done () {
148
* Return current character, raising an exception if
149
* the end of the string has been reached
153
raise invalid_argument ("invalid format", 1, format);
158
* Step to next character
160
public void step () {
165
* Return true and step if current character matches 'm'
167
public bool match(int m) {
177
* Return a number from the format string
179
public int number () {
181
while ('0' <= c() && c() <= '9')
183
n = n * 10 + c() - '0';
193
public poly next () {
195
raise too_few_arguments (format, args);
199
public void done () {
201
raise too_many_arguments (format, args);
205
while (!fmt::done () && !File::error (f)) {
206
if (fmt::match ('%') && fmt::c() != '%')
208
poly a = arg::next ();
210
case 's': put_string (a); break;
211
case 'd': put_number (a); break;
212
case 'b': put_bool (a); break;
213
case 'C': put_color (a); break;
214
case 'D': put_direction (a); break;
215
case 'S': put_shape (a); break;
216
case 'G': put_gamestate (a); break;
217
case 'E': put_error (a); break;
221
File::putc (fmt::c(), f);