4
4
*
5
5
* Based on Eric Roberts' genlib.c and simpio.c.
6
6
*
7
- * Copyright (c) 2017.
8
- * All rights reserved.
7
+ * Copyright (c) 2019
8
+ * All rights reserved
9
9
*
10
10
* BSD 3-Clause License
11
11
* http://www.opensource.org/licenses/BSD-3-Clause
56
56
#pragma GCC diagnostic push
57
57
#pragma GCC diagnostic ignored "-Wformat-security"
58
58
59
- // Temporarily here for backward compatibility
60
- #undef get_char
61
- #undef get_double
62
- #undef get_float
63
- #undef get_int
64
- #undef get_long
65
- #undef get_long_long
66
- #undef get_string
67
-
68
- /**
69
- * Prints an error message, formatted like printf, to standard error, prefixing it with
70
- * file name and line number from which function was called (which a macro provides).
71
- *
72
- * This function is not intended to be called directly. Instead, call the macro of the same name,
73
- * which expects fewer arguments.
74
- *
75
- * Inspired by http://www.gnu.org/software/libc/manual/html_node/Variable-Arguments-Output.html,
76
- * http://www.gnu.org/software/libc/manual/html_node/Error-Messages.html#Error-Messages, and
77
- * https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html.
78
- */
79
- #undef eprintf
80
- void eprintf (const string file , int line , const string format , ...)
81
- {
82
- // Print caller's file name and line number
83
- fprintf (stderr , "%s:%i: " , file , line );
84
-
85
- // Variable argument list
86
- va_list ap ;
87
-
88
- // Last parameter before variable argument list is format
89
- va_start (ap , format );
90
-
91
- // Print error message, formatted like printf
92
- vfprintf (stderr , format , ap );
93
-
94
- // Invalidate variable argument list
95
- va_end (ap );
96
- }
97
-
98
-
99
59
/**
100
60
* Number of strings allocated by get_string.
101
61
*/
@@ -114,6 +74,7 @@ static string *strings = NULL;
114
74
* upon error or no input whatsoever (i.e., just EOF). Stores string
115
75
* on heap, but library's destructor frees memory on program's exit.
116
76
*/
77
+ #undef get_string
117
78
string get_string (va_list * args , const string format , ...)
118
79
{
119
80
// Check whether we have room for another string
@@ -171,18 +132,10 @@ string get_string(va_list *args, const string format, ...)
171
132
// Grow buffer if necessary
172
133
if (size + 1 > capacity )
173
134
{
174
- // Initialize capacity to 16 (as reasonable for most inputs) and double thereafter
175
- if (capacity == 0 )
176
- {
177
- capacity = 16 ;
178
- }
179
- else if (capacity <= (SIZE_MAX / 2 ))
180
- {
181
- capacity *= 2 ;
182
- }
183
- else if (capacity < SIZE_MAX )
135
+ // Increment buffer's capacity if possible
136
+ if (capacity < SIZE_MAX )
184
137
{
185
- capacity = SIZE_MAX ;
138
+ capacity ++ ;
186
139
}
187
140
else
188
141
{
@@ -255,98 +208,6 @@ string get_string(va_list *args, const string format, ...)
255
208
// Return string
256
209
return s ;
257
210
}
258
- string GetString (void )
259
- {
260
- // Growable buffer for characters
261
- string buffer = NULL ;
262
-
263
- // Capacity of buffer
264
- size_t capacity = 0 ;
265
-
266
- // Number of characters actually in buffer
267
- size_t size = 0 ;
268
-
269
- // Character read or EOF
270
- int c ;
271
-
272
- // Iteratively get characters from standard input, checking for CR (Mac OS), LF (Linux), and CRLF (Windows)
273
- while ((c = fgetc (stdin )) != '\r' && c != '\n' && c != EOF )
274
- {
275
- // Grow buffer if necessary
276
- if (size + 1 > capacity )
277
- {
278
- // Initialize capacity to 16 (as reasonable for most inputs) and double thereafter
279
- if (capacity == 0 )
280
- {
281
- capacity = 16 ;
282
- }
283
- else if (capacity <= (SIZE_MAX / 2 ))
284
- {
285
- capacity *= 2 ;
286
- }
287
- else if (capacity < SIZE_MAX )
288
- {
289
- capacity = SIZE_MAX ;
290
- }
291
- else
292
- {
293
- free (buffer );
294
- return NULL ;
295
- }
296
-
297
- // Extend buffer's capacity
298
- string temp = realloc (buffer , capacity );
299
- if (temp == NULL )
300
- {
301
- free (buffer );
302
- return NULL ;
303
- }
304
- buffer = temp ;
305
- }
306
-
307
- // Append current character to buffer
308
- buffer [size ++ ] = c ;
309
- }
310
-
311
- // Check whether user provided no input
312
- if (size == 0 && c == EOF )
313
- {
314
- return NULL ;
315
- }
316
-
317
- // Check whether user provided too much input (leaving no room for trailing NUL)
318
- if (size == SIZE_MAX )
319
- {
320
- free (buffer );
321
- return NULL ;
322
- }
323
-
324
- // If last character read was CR, try to read LF as well
325
- if (c == '\r' && (c = fgetc (stdin )) != '\n' )
326
- {
327
- // Return NULL if character can't be pushed back onto standard input
328
- if (c != EOF && ungetc (c , stdin ) == EOF )
329
- {
330
- free (buffer );
331
- return NULL ;
332
- }
333
- }
334
-
335
- // Minimize buffer
336
- string s = realloc (buffer , size + 1 );
337
- if (s == NULL )
338
- {
339
- free (buffer );
340
- return NULL ;
341
- }
342
-
343
- // Terminate string
344
- s [size ] = '\0' ;
345
-
346
- // Return string
347
- return s ;
348
- }
349
-
350
211
351
212
/**
352
213
* Prompts user for a line of text from standard input and returns the
@@ -376,18 +237,8 @@ char get_char(const string format, ...)
376
237
va_end (ap );
377
238
return c ;
378
239
}
379
-
380
- // Temporarily here for backward compatibility
381
- if (format == NULL )
382
- {
383
- printf ("Retry: " );
384
- }
385
240
}
386
241
}
387
- char GetChar (void )
388
- {
389
- return get_char (NULL );
390
- }
391
242
392
243
/**
393
244
* Prompts user for a line of text from standard input and returns the
@@ -427,18 +278,8 @@ double get_double(const string format, ...)
427
278
}
428
279
}
429
280
}
430
-
431
- // Temporarily here for backward compatibility
432
- if (format == NULL )
433
- {
434
- printf ("Retry: " );
435
- }
436
281
}
437
282
}
438
- double GetDouble (void )
439
- {
440
- return get_double (NULL );
441
- }
442
283
443
284
/**
444
285
* Prompts user for a line of text from standard input and returns the
@@ -479,18 +320,8 @@ float get_float(const string format, ...)
479
320
}
480
321
}
481
322
}
482
-
483
- // Temporarily here for backward compatibility
484
- if (format == NULL )
485
- {
486
- printf ("Retry: " );
487
- }
488
323
}
489
324
}
490
- float GetFloat (void )
491
- {
492
- return get_float (NULL );
493
- }
494
325
495
326
/**
496
327
* Prompts user for a line of text from standard input and returns the
@@ -526,76 +357,14 @@ int get_int(const string format, ...)
526
357
return n ;
527
358
}
528
359
}
529
-
530
- // Temporarily here for backward compatibility
531
- if (format == NULL )
532
- {
533
- printf ("Retry: " );
534
- }
535
- }
536
- }
537
- int GetInt (void )
538
- {
539
- return get_int (NULL );
540
- }
541
-
542
- /**
543
- * Prompts user for a line of text from standard input and returns the
544
- * equivalent long long; if text does not represent a long long in
545
- * [-2^63, 2^63 - 1) or would cause underflow or overflow, user is
546
- * prompted to retry. If line can't be read, returns LLONG_MAX.
547
- *
548
- * Will be deprecated in favor of get_long.
549
- */
550
- long long get_long_long (const string format , ...)
551
- {
552
- va_list ap ;
553
- va_start (ap , format );
554
-
555
- // Try to get a long long from user
556
- while (true)
557
- {
558
- // Get line of text, returning LLONG_MAX on failure
559
- string line = get_string (& ap , format );
560
- if (line == NULL )
561
- {
562
- va_end (ap );
563
- return LLONG_MAX ;
564
- }
565
-
566
- // Return a long long if only a long long (in range) was provided
567
- if (strlen (line ) > 0 && !isspace ((unsigned char ) line [0 ]))
568
- {
569
- char * tail ;
570
- errno = 0 ;
571
- long long n = strtoll (line , & tail , 10 );
572
- if (errno == 0 && * tail == '\0' && n < LLONG_MAX )
573
- {
574
- va_end (ap );
575
- return n ;
576
- }
577
- }
578
-
579
- // Temporarily here for backward compatibility
580
- if (format == NULL )
581
- {
582
- printf ("Retry: " );
583
- }
584
360
}
585
361
}
586
- long long GetLongLong (void )
587
- {
588
- return get_long_long (NULL );
589
- }
590
-
591
362
592
363
/**
593
364
* Prompts user for a line of text from standard input and returns the
594
365
* equivalent long; if text does not represent a long in
595
366
* [-2^63, 2^63 - 1) or would cause underflow or overflow, user is
596
367
* prompted to retry. If line can't be read, returns LONG_MAX.
597
- *
598
- * This will replace get_long_long in the future
599
368
*/
600
369
long get_long (const string format , ...)
601
370
{
@@ -625,12 +394,6 @@ long get_long(const string format, ...)
625
394
return n ;
626
395
}
627
396
}
628
-
629
- // Temporarily here for backward compatibility
630
- if (format == NULL )
631
- {
632
- printf ("Retry: " );
633
- }
634
397
}
635
398
}
636
399
@@ -673,7 +436,7 @@ static void teardown(void)
673
436
#else
674
437
#error The CS50 library requires some compiler-specific features, \
675
438
but we do not recognize this compiler/version. Please file an issue at \
676
- github.com/cs50/libcs50
439
+ https:// github.com/cs50/libcs50
677
440
#endif
678
441
679
442
/**
@@ -686,4 +449,5 @@ INITIALIZER(setup)
686
449
atexit (teardown );
687
450
}
688
451
452
+ // Re-enable warnings
689
453
#pragma GCC diagnostic pop
0 commit comments