1- /* FUNCTION: getopt */
2-
3- extern char * optarg ;
4- extern int optind ;
1+ /* FUNCTION: _getopt */
52
63#ifndef __CPROVER_STRING_H_INCLUDED
74#include <string.h>
85#define __CPROVER_STRING_H_INCLUDED
96#endif
107
8+ char * optarg = NULL ;
9+ int optind = 1 ;
10+
1111__CPROVER_bool __VERIFIER_nondet___CPROVER_bool (void );
1212size_t __VERIFIER_nondet_size_t (void );
1313
14- int getopt (int argc , char * const argv [], const char * optstring )
14+ int _getopt (int argc , char * const argv [], const char * optstring )
1515{
16- __CPROVER_HIDE :;
17- int result = -1 ;
18-
19- if (optind == 0 )
20- optind = 1 ;
16+ __CPROVER_HIDE :;
17+ // re-init requested by environment, we just reset optind
18+ if (optind == 0 )
19+ optind = 1 ;
2120
22- if (optind >=argc || argv [optind ][0 ]!= '-' )
21+ // test whether all arguments have been processed
22+ if (optind >= argc )
23+ return -1 ;
24+ char * const arg = argv [optind ];
25+ if (arg [0 ] != '-' || arg [1 ] == '\0' || (arg [1 ] == '-' && arg [2 ] == '\0' ))
2326 return -1 ;
2427
25- size_t result_index = __VERIFIER_nondet_size_t ();
28+ // test whether the option is in optstring at all
29+ size_t optstring_len = strlen (optstring );
30+ // gcc doesn't know __CPROVER_forall
31+ #ifndef LIBRARY_CHECK
32+ __CPROVER_bool not_found = __CPROVER_forall
33+ {
34+ size_t i ;
35+ i < optstring_len == > optstring [i ] != arg [1 ]
36+ };
37+ if (not_found )
38+ return '?' ;
39+ #endif
40+
41+ // option is in optstring, find the exact index
42+ size_t result_index = __VERIFIER_nondet_size_t ();
2643 __CPROVER_assume (
27- result_index < strlen (optstring ) && optstring [result_index ]!= ':' );
28- #ifdef __CPROVER_STRING_ABSTRACTION
29- __CPROVER_assert (__CPROVER_is_zero_string (optstring ),
44+ result_index < optstring_len && optstring [result_index ] == arg [1 ]);
45+ #ifdef __CPROVER_STRING_ABSTRACTION
46+ __CPROVER_assert (
47+ __CPROVER_is_zero_string (optstring ),
3048 "getopt zero-termination of 3rd argument" );
31- #endif
49+ #endif
3250
33- __CPROVER_bool found = __VERIFIER_nondet___CPROVER_bool ();
34- if (found )
51+ // is an argument required?
52+ if (result_index + 1 == optstring_len || optstring [ result_index + 1 ] != ':' )
3553 {
36- result = optstring [result_index ];
37- __CPROVER_bool skipped = __VERIFIER_nondet___CPROVER_bool ();
38- if (skipped )
39- ++ optind ;
54+ optarg = NULL ;
55+ return arg [1 ];
4056 }
4157
42- if (result != -1 && optind < argc && optstring [result_index + 1 ]== ':' )
58+ // test whether a required argument can be found
59+ if (arg [2 ] != '\0' )
60+ {
61+ optarg = & arg [2 ];
62+ return arg [1 ];
63+ }
64+ else if (optind + 1 < argc )
4365 {
44- __CPROVER_bool has_no_arg = __VERIFIER_nondet___CPROVER_bool ();
45- if (has_no_arg )
46- {
47- optarg = argv [optind ];
48- ++ optind ;
49- }
50- else
51- optarg = NULL ;
66+ optarg = argv [optind + 1 ];
67+ ++ optind ;
68+ return arg [1 ];
5269 }
70+ else
71+ {
72+ optarg = NULL ;
73+ return optstring [0 ] == ':' ? ':' : '?' ;
74+ }
75+ }
76+
77+ /* FUNCTION: getopt */
78+
79+ int _getopt (int argc , char * const argv [], const char * optstring );
5380
54- return result ;
81+ int getopt (int argc , char * const argv [], const char * optstring )
82+ {
83+ __CPROVER_HIDE :;
84+ return _getopt (argc , argv , optstring );
5585}
5686
5787/* FUNCTION: getopt_long */
5888
89+ #ifndef _WIN32
90+ // MSVC doesn't provide getopt.h, which we need for struct option
91+
5992#ifndef __CPROVER_GETOPT_H_INCLUDED
6093#include <getopt.h>
6194#define __CPROVER_GETOPT_H_INCLUDED
@@ -77,3 +110,5 @@ int getopt_long(
77110
78111 return getopt (argc , argv , optstring );
79112}
113+
114+ #endif
0 commit comments