~ubuntu-branches/ubuntu/saucy/jzip/saucy

« back to all changes in this revision

Viewing changes to .pc/compiler-warnings/input.c

  • Committer: Package Import Robot
  • Author(s): Niko Tyni
  • Date: 2012-03-25 22:42:35 UTC
  • Revision ID: package-import@ubuntu.com-20120325224235-aq5xki4sm298evr3
Tags: 210r20001005d-2
Adapt to zlib gzFile changes. (Closes: #664931)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* $Id: input.c,v 1.3 2000/07/05 15:20:34 jholder Exp $   
 
3
 * --------------------------------------------------------------------
 
4
 * see doc/License.txt for License Information   
 
5
 * --------------------------------------------------------------------
 
6
 * 
 
7
 * File name: $Id: input.c,v 1.3 2000/07/05 15:20:34 jholder Exp $  
 
8
 *   
 
9
 * Description:    
 
10
 *    
 
11
 * Modification history:      
 
12
 * $Log: input.c,v $
 
13
 * Revision 1.3  2000/07/05 15:20:34  jholder
 
14
 * Updated code to remove warnings.
 
15
 *
 
16
 * Revision 1.2  2000/05/25 22:28:56  jholder
 
17
 * changes routine names to reflect zmachine opcode names per spec 1.0
 
18
 *
 
19
 * Revision 1.1.1.1  2000/05/10 14:21:34  jholder
 
20
 *
 
21
 * imported
 
22
 *
 
23
 *
 
24
 * --------------------------------------------------------------------
 
25
 */
 
26
 
 
27
/*
 
28
 * input.c
 
29
 *
 
30
 * Input routines
 
31
 *
 
32
 */
 
33
 
 
34
#include "ztypes.h"
 
35
 
 
36
/* Statically defined word separator list */
 
37
 
 
38
static const char *separators = " \t\n\f.,?";
 
39
static zword_t dictionary_offset = 0;
 
40
static ZINT16 dictionary_size = 0;
 
41
static unsigned int entry_size = 0;
 
42
 
 
43
static void tokenise_line( zword_t, zword_t, zword_t, zword_t );
 
44
static const char *next_token( const char *, const char *, const char **, int *, const char * );
 
45
static zword_t find_word( int, const char *, long );
 
46
 
 
47
/*
 
48
 * z_read_char
 
49
 *
 
50
 * Read one character with optional timeout
 
51
 *
 
52
 *    argv[0] = input device (must be 1)
 
53
 *    argv[1] = timeout value in tenths of a second (optional)
 
54
 *    argv[2] = timeout action routine (optional)
 
55
 *
 
56
 */
 
57
 
 
58
void z_read_char( int argc, zword_t * argv )
 
59
{
 
60
   int c;
 
61
   zword_t arg_list[2];
 
62
 
 
63
   /* Supply default parameters */
 
64
 
 
65
   if ( argc < 3 )
 
66
      argv[2] = 0;
 
67
   if ( argc < 2 )
 
68
      argv[1] = 0;
 
69
 
 
70
   /* Flush any buffered output before read */
 
71
 
 
72
   flush_buffer( FALSE );
 
73
 
 
74
   /* Reset line count */
 
75
 
 
76
   lines_written = 0;
 
77
 
 
78
   /* If more than one characters was asked for then fail the call */
 
79
 
 
80
   if ( argv[0] != 1 )
 
81
 
 
82
      c = 0;
 
83
 
 
84
   else
 
85
   {
 
86
 
 
87
      if ( ( c = playback_key(  ) ) == -1 )
 
88
      {
 
89
 
 
90
         /* Setup the timeout routine argument list */
 
91
 
 
92
         arg_list[0] = argv[2];
 
93
         arg_list[1] = 0;       /* as per spec 1.0 */
 
94
         /* was: arg_list[1] = argv[1]/10; */
 
95
 
 
96
         /* Read a character with a timeout. If the input timed out then
 
97
          * call the timeout action routine. If the return status from the
 
98
          * timeout routine was 0 then try to read a character again */
 
99
 
 
100
         do
 
101
         {
 
102
            flush_buffer( FALSE );
 
103
            c = input_character( ( int ) argv[1] );
 
104
         }
 
105
         while ( c == -1 && z_call( 1, arg_list, ASYNC ) == 0 );
 
106
 
 
107
         /* Fail call if input timed out */
 
108
 
 
109
         if ( c == -1 )
 
110
            c = 0;
 
111
         else
 
112
            record_key( c );
 
113
      }
 
114
   }
 
115
 
 
116
   store_operand( (zword_t)c );
 
117
 
 
118
}                               /* z_read_char */
 
119
 
 
120
/*
 
121
 * z_sread_aread
 
122
 *
 
123
 * Read a line of input with optional timeout.
 
124
 *
 
125
 *    argv[0] = character buffer address
 
126
 *    argv[1] = token buffer address
 
127
 *    argv[2] = timeout value in seconds (optional)
 
128
 *    argv[3] = timeout action routine (optional)
 
129
 *
 
130
 */
 
131
 
 
132
void z_sread_aread( int argc, zword_t * argv )
 
133
{
 
134
   int i, in_size, out_size, terminator;
 
135
   char *cbuf, *buffer;
 
136
 
 
137
   /* Supply default parameters */
 
138
 
 
139
   if ( argc < 4 )
 
140
      argv[3] = 0;
 
141
   if ( argc < 3 )
 
142
      argv[2] = 0;
 
143
   if ( argc < 2 )
 
144
      argv[1] = 0;
 
145
 
 
146
   /* Refresh status line */
 
147
 
 
148
   if ( h_type < V4 )
 
149
      z_show_status(  );
 
150
 
 
151
   /* Flush any buffered output before read */
 
152
 
 
153
   flush_buffer( TRUE );
 
154
 
 
155
   /* Reset line count */
 
156
 
 
157
   lines_written = 0;
 
158
 
 
159
   /* Initialise character pointer and initial read size */
 
160
 
 
161
   cbuf = ( char * ) &datap[argv[0]];
 
162
   in_size = ( h_type > V4 ) ? cbuf[1] : 0;
 
163
 
 
164
   /* Read the line then script and record it */
 
165
 
 
166
   terminator = get_line( cbuf, argv[2], argv[3] );
 
167
   script_line( ( h_type > V4 ) ? &cbuf[2] : &cbuf[1] );
 
168
   record_line( ( h_type > V4 ) ? &cbuf[2] : &cbuf[1] );
 
169
 
 
170
   /* Convert new text in line to lowercase */
 
171
 
 
172
   if ( h_type > V4 )
 
173
   {
 
174
      buffer = &cbuf[2];
 
175
      out_size = cbuf[1];
 
176
   }
 
177
   else
 
178
   {
 
179
      buffer = &cbuf[1];
 
180
      out_size = strlen( buffer );
 
181
   }
 
182
 
 
183
   if ( out_size > in_size )
 
184
      for ( i = in_size; i < out_size; i++ )
 
185
         buffer[i] = ( char ) tolower( buffer[i] );
 
186
 
 
187
   /* Tokenise the line, if a token buffer is present */
 
188
 
 
189
   if ( argv[1] )
 
190
      tokenise_line( argv[0], argv[1], h_words_offset, 0 );
 
191
 
 
192
   /* Return the line terminator */
 
193
 
 
194
   if ( h_type > V4 )
 
195
      store_operand( ( zword_t ) terminator );
 
196
 
 
197
}                               /* z_sread_aread */
 
198
 
 
199
/*
 
200
 * get_line
 
201
 *
 
202
 * Read a line of input and lower case it.
 
203
 *
 
204
 */
 
205
 
 
206
int get_line( char *cbuf, zword_t timeout, zword_t action_routine )
 
207
{
 
208
   char *buffer;
 
209
   int buflen, read_size, status, c;
 
210
   zword_t arg_list[2];
 
211
 
 
212
   /* Set maximum buffer size to width of screen minus any
 
213
    * right margin and 1 character for a terminating NULL */
 
214
 
 
215
   buflen = ( screen_cols > 127 ) ? 127 : screen_cols;
 
216
   buflen -= right_margin + 1;
 
217
   if ( ( int ) cbuf[0] <= buflen )
 
218
      buflen = cbuf[0];
 
219
 
 
220
   /* Set read size and start of read buffer. The buffer may already be
 
221
    * primed with some text in V5 games. The Z-code will have already
 
222
    * displayed the text so we don't have to do that */
 
223
 
 
224
   if ( h_type > V4 )
 
225
   {
 
226
      read_size = cbuf[1];
 
227
      buffer = &cbuf[2];
 
228
   }
 
229
   else
 
230
   {
 
231
      read_size = 0;
 
232
      buffer = &cbuf[1];
 
233
   }
 
234
 
 
235
   /* Try to read input from command file */
 
236
 
 
237
   c = playback_line( buflen, buffer, &read_size );
 
238
 
 
239
   if ( c == -1 )
 
240
   {
 
241
 
 
242
      /* Setup the timeout routine argument list */
 
243
 
 
244
      arg_list[0] = action_routine;
 
245
      arg_list[1] = 0;          /*  as per spec.1.0  */
 
246
      /* arg_list[1] = timeout/10; */
 
247
 
 
248
      /* Read a line with a timeout. If the input timed out then
 
249
       * call the timeout action routine. If the return status from the
 
250
       * timeout routine was 0 then try to read the line again */
 
251
 
 
252
      do
 
253
      {
 
254
         c = input_line( buflen, buffer, timeout, &read_size );
 
255
         status = 0;
 
256
      }
 
257
      while ( c == -1 && ( status = z_call( 1, arg_list, ASYNC ) ) == 0 );
 
258
 
 
259
      /* Throw away any input if timeout returns success */
 
260
 
 
261
      if ( status )
 
262
         read_size = 0;
 
263
 
 
264
 
 
265
   }
 
266
 
 
267
   /* Zero terminate line */
 
268
 
 
269
   if ( h_type > V4 )
 
270
   {
 
271
      cbuf[1] = ( char ) read_size;
 
272
   }
 
273
   else
 
274
   {
 
275
      /* Zero terminate line (V1-4 only) */
 
276
      buffer[read_size] = '\0';
 
277
   }
 
278
 
 
279
   return ( c );
 
280
 
 
281
}                               /* get_line */
 
282
 
 
283
/*
 
284
 * tokenise_line
 
285
 *
 
286
 * Convert a typed input line into tokens. The token buffer needs some
 
287
 * additional explanation. The first byte is the maximum number of tokens
 
288
 * allowed. The second byte is set to the actual number of token read. Each
 
289
 * token is composed of 3 fields. The first (word) field contains the word
 
290
 * offset in the dictionary, the second (byte) field contains the token length,
 
291
 * and the third (byte) field contains the start offset of the token in the
 
292
 * character buffer.
 
293
 *
 
294
 */
 
295
 
 
296
static void tokenise_line( zword_t char_buf, zword_t token_buf, zword_t dictionary, zword_t flag )
 
297
{
 
298
   int i, count, words, token_length;
 
299
   long word_index, chop = 0;
 
300
   int slen;
 
301
   char *str_end;
 
302
   char *cbuf, *tbuf, *tp;
 
303
   const char *cp, *token;
 
304
   char punctuation[16];
 
305
   zword_t word;
 
306
 
 
307
   /* Initialise character and token buffer pointers */
 
308
 
 
309
   cbuf = ( char * ) &datap[char_buf];
 
310
   tbuf = ( char * ) &datap[token_buf];
 
311
 
 
312
   /* Find the string length */
 
313
 
 
314
   if ( h_type > V4 )
 
315
   {
 
316
      slen = ( unsigned char ) ( cbuf[1] );
 
317
      str_end = cbuf + 2 + slen;
 
318
   }
 
319
   else
 
320
   {
 
321
      slen = strlen( cbuf + 1 );
 
322
      str_end = cbuf + 1 + slen;
 
323
   }
 
324
 
 
325
   /* Initialise word count and pointers */
 
326
 
 
327
   words = 0;
 
328
   cp = ( h_type > V4 ) ? cbuf + 2 : cbuf + 1;
 
329
   tp = tbuf + 2;
 
330
 
 
331
   /* Initialise dictionary */
 
332
 
 
333
   count = get_byte( dictionary++ );
 
334
   for ( i = 0; i < count; i++ )
 
335
      punctuation[i] = get_byte( dictionary++ );
 
336
   punctuation[i] = '\0';
 
337
   entry_size = get_byte( dictionary++ );
 
338
   dictionary_size = ( ZINT16 ) get_word( dictionary );
 
339
   dictionary_offset = dictionary + 2;
 
340
 
 
341
   /* Calculate the binary chop start position */
 
342
 
 
343
   if ( dictionary_size > 0 )
 
344
   {
 
345
      word_index = dictionary_size / 2;
 
346
      chop = 1;
 
347
      do
 
348
         chop *= 2;
 
349
      while ( word_index /= 2 );
 
350
   }
 
351
 
 
352
   /* Tokenise the line */
 
353
 
 
354
   do
 
355
   {
 
356
 
 
357
      /* Skip to next token */
 
358
 
 
359
      cp = next_token( cp, str_end, &token, &token_length, punctuation );
 
360
      if ( token_length )
 
361
 
 
362
         /* If still space in token buffer then store word */
 
363
 
 
364
         if ( words <= tbuf[0] )
 
365
         {
 
366
 
 
367
            /* Get the word offset from the dictionary */
 
368
 
 
369
            word = find_word( token_length, token, chop );
 
370
 
 
371
            /* Store the dictionary offset, token length and offset */
 
372
 
 
373
            if ( word || flag == 0 )
 
374
            {
 
375
               tp[0] = ( char ) ( word >> 8 );
 
376
               tp[1] = ( char ) ( word & 0xff );
 
377
            }
 
378
            tp[2] = ( char ) token_length;
 
379
            tp[3] = ( char ) ( token - cbuf );
 
380
 
 
381
            /* Step to next token position and count the word */
 
382
 
 
383
            tp += 4;
 
384
            words++;
 
385
         }
 
386
         else
 
387
         {
 
388
 
 
389
            /* Moan if token buffer space exhausted */
 
390
 
 
391
            output_string( "Too many words typed, discarding: " );
 
392
            output_line( token );
 
393
         }
 
394
   }
 
395
   while ( token_length );
 
396
 
 
397
   /* Store word count */
 
398
 
 
399
   tbuf[1] = ( char ) words;
 
400
 
 
401
}                               /* tokenise_line */
 
402
 
 
403
/*
 
404
 * next_token
 
405
 *
 
406
 * Find next token in a string. The token (word) is delimited by a statically
 
407
 * defined and a game specific set of word separators. The game specific set
 
408
 * of separators look like real word separators, but the parser wants to know
 
409
 * about them. An example would be: 'grue, take the axe. go north'. The
 
410
 * parser wants to know about the comma and the period so that it can correctly
 
411
 * parse the line. The 'interesting' word separators normally appear at the
 
412
 * start of the dictionary, and are also put in a separate list in the game
 
413
 * file.
 
414
 *
 
415
 */
 
416
 
 
417
static const char *next_token( const char *s, const char *str_end, const char **token, int *length,
 
418
                               const char *punctuation )
 
419
{
 
420
   int i;
 
421
 
 
422
   /* Set the token length to zero */
 
423
 
 
424
   *length = 0;
 
425
 
 
426
   /* Step through the string looking for separators */
 
427
 
 
428
   for ( ; s < str_end; s++ )
 
429
   {
 
430
 
 
431
      /* Look for game specific word separators first */
 
432
 
 
433
      for ( i = 0; punctuation[i] && *s != punctuation[i]; i++ )
 
434
         ;
 
435
 
 
436
      /* If a separator is found then return the information */
 
437
 
 
438
      if ( punctuation[i] )
 
439
      {
 
440
 
 
441
         /* If length has been set then just return the word position */
 
442
 
 
443
         if ( *length )
 
444
            return ( s );
 
445
         else
 
446
         {
 
447
 
 
448
            /* End of word, so set length, token pointer and return string */
 
449
 
 
450
            ( *length )++;
 
451
            *token = s;
 
452
            return ( ++s );
 
453
         }
 
454
      }
 
455
 
 
456
      /* Look for statically defined separators last */
 
457
 
 
458
      for ( i = 0; separators[i] && *s != separators[i]; i++ )
 
459
         ;
 
460
 
 
461
      /* If a separator is found then return the information */
 
462
 
 
463
      if ( separators[i] )
 
464
      {
 
465
 
 
466
         /* If length has been set then just return the word position */
 
467
 
 
468
         if ( *length )
 
469
            return ( ++s );
 
470
      }
 
471
      else
 
472
      {
 
473
 
 
474
         /* If first token character then remember its position */
 
475
 
 
476
         if ( *length == 0 )
 
477
            *token = s;
 
478
         ( *length )++;
 
479
      }
 
480
   }
 
481
 
 
482
   return ( s );
 
483
 
 
484
}                               /* next_token */
 
485
 
 
486
/*
 
487
 * find_word
 
488
 *
 
489
 * Search the dictionary for a word. Just encode the word and binary chop the
 
490
 * dictionary looking for it.
 
491
 *
 
492
 */
 
493
 
 
494
static zword_t find_word( int len, const char *cp, long chop )
 
495
{
 
496
   ZINT16 word[3];
 
497
   long word_index, offset, status;
 
498
 
 
499
   /* Don't look up the word if there are no dictionary entries */
 
500
 
 
501
   if ( dictionary_size == 0 )
 
502
      return ( 0 );
 
503
 
 
504
   /* Encode target word */
 
505
 
 
506
   encode_text( len, cp, word );
 
507
 
 
508
   /* Do a binary chop search on the main dictionary, otherwise do
 
509
    * a linear search */
 
510
 
 
511
   word_index = chop - 1;
 
512
 
 
513
   if ( dictionary_size > 0 )
 
514
   {
 
515
 
 
516
      /* Binary chop until the word is found */
 
517
 
 
518
      while ( chop )
 
519
      {
 
520
 
 
521
         chop /= 2;
 
522
 
 
523
         /* Calculate dictionary offset */
 
524
 
 
525
         if ( word_index > ( dictionary_size - 1 ) )
 
526
            word_index = dictionary_size - 1;
 
527
 
 
528
         offset = dictionary_offset + ( word_index * entry_size );
 
529
 
 
530
         /* If word matches then return dictionary offset */
 
531
 
 
532
         if ( ( status = word[0] - ( ZINT16 ) get_word( offset + 0 ) ) == 0                &&
 
533
              ( status = word[1] - ( ZINT16 ) get_word( offset + 2 ) ) == 0                && 
 
534
              ( h_type < V4 || ( status = word[2] - ( ZINT16 ) get_word( offset + 4 ) ) == 0 ) )
 
535
            return ( ( zword_t ) offset );
 
536
 
 
537
         /* Set next position depending on direction of overshoot */
 
538
 
 
539
         if ( status > 0 )
 
540
         {
 
541
            word_index += chop;
 
542
 
 
543
            /* Deal with end of dictionary case */
 
544
 
 
545
            if ( word_index >= ( int ) dictionary_size )
 
546
               word_index = dictionary_size - 1;
 
547
         }
 
548
         else
 
549
         {
 
550
            word_index -= chop;
 
551
 
 
552
            /* Deal with start of dictionary case */
 
553
 
 
554
            if ( word_index < 0 )
 
555
               word_index = 0;
 
556
         }
 
557
      }
 
558
   }
 
559
   else
 
560
   {
 
561
 
 
562
      for ( word_index = 0; word_index < -dictionary_size; word_index++ )
 
563
      {
 
564
 
 
565
         /* Calculate dictionary offset */
 
566
 
 
567
         offset = dictionary_offset + ( word_index * entry_size );
 
568
 
 
569
         /* If word matches then return dictionary offset */
 
570
 
 
571
         if ( ( status = word[0] - ( ZINT16 ) get_word( offset + 0 ) ) == 0                &&
 
572
              ( status = word[1] - ( ZINT16 ) get_word( offset + 2 ) ) == 0                && 
 
573
              ( h_type < V4 || ( status = word[2] - ( ZINT16 ) get_word( offset + 4 ) ) == 0 ) )
 
574
            return ( ( zword_t ) offset );
 
575
      }
 
576
   }
 
577
 
 
578
   return ( 0 );
 
579
 
 
580
}                               /* find_word */
 
581
 
 
582
/*
 
583
 * z_tokenise
 
584
 *
 
585
 *    argv[0] = character buffer address
 
586
 *    argv[1] = token buffer address
 
587
 *    argv[2] = alternate vocabulary table
 
588
 *    argv[3] = ignore unknown words flag
 
589
 *
 
590
 */
 
591
 
 
592
void z_tokenise( int argc, zword_t * argv )
 
593
{
 
594
 
 
595
   /* Supply default parameters */
 
596
 
 
597
   if ( argc < 4 )
 
598
      argv[3] = 0;
 
599
   if ( argc < 3 )
 
600
      argv[2] = h_words_offset;
 
601
 
 
602
   /* Convert the line to tokens */
 
603
 
 
604
   tokenise_line( argv[0], argv[1], argv[2], argv[3] );
 
605
 
 
606
}                               /* z_tokenise */