1
- /* FUNCTION: getopt */
2
-
3
- extern char * optarg ;
4
- extern int optind ;
1
+ /* FUNCTION: _getopt */
5
2
6
3
#ifndef __CPROVER_STRING_H_INCLUDED
7
4
#include <string.h>
8
5
#define __CPROVER_STRING_H_INCLUDED
9
6
#endif
10
7
8
+ char * optarg = NULL ;
9
+ int optind = 1 ;
10
+
11
11
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool (void );
12
12
size_t __VERIFIER_nondet_size_t (void );
13
13
14
- int getopt (int argc , char * const argv [], const char * optstring )
14
+ int _getopt (int argc , char * const argv [], const char * optstring )
15
15
{
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 ;
21
20
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' ))
23
26
return -1 ;
24
27
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 ();
26
43
__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 ),
30
48
"getopt zero-termination of 3rd argument" );
31
- #endif
49
+ #endif
32
50
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 ] != ':' )
35
53
{
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 ];
40
56
}
41
57
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 )
43
65
{
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 ];
52
69
}
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 );
53
80
54
- return result ;
81
+ int getopt (int argc , char * const argv [], const char * optstring )
82
+ {
83
+ __CPROVER_HIDE :;
84
+ return _getopt (argc , argv , optstring );
55
85
}
56
86
57
87
/* FUNCTION: getopt_long */
58
88
89
+ #ifndef _WIN32
90
+ // MSVC doesn't provide getopt.h, which we need for struct option
91
+
59
92
#ifndef __CPROVER_GETOPT_H_INCLUDED
60
93
#include <getopt.h>
61
94
#define __CPROVER_GETOPT_H_INCLUDED
@@ -77,3 +110,5 @@ int getopt_long(
77
110
78
111
return getopt (argc , argv , optstring );
79
112
}
113
+
114
+ #endif
0 commit comments