Skip to content

Commit f691135

Browse files
committed
Import getopt{,_long} and vasprintf models from SV-COMP/busybox
Licensing: I had contributed these myself to the SV-COMP benchmarks.
1 parent 6eef691 commit f691135

File tree

2 files changed

+94
-9
lines changed

2 files changed

+94
-9
lines changed

src/ansi-c/library/getopt.c

+54-9
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,67 @@
33
extern char *optarg;
44
extern int optind;
55

6+
#ifndef __CPROVER_STRING_H_INCLUDED
7+
#include <string.h>
8+
#define __CPROVER_STRING_H_INCLUDED
9+
#endif
10+
611
inline int getopt(int argc, char * const argv[],
712
const char *optstring)
813
{
914
__CPROVER_HIDE:;
10-
int result_index;
11-
__CPROVER_assume(result_index>=0);
12-
(void)*optstring;
13-
if(optind>=argc)
15+
int result=-1;
16+
17+
if(optind==0)
18+
optind=1;
19+
20+
if(optind>=argc || argv[optind][0]!='-')
1421
return -1;
15-
__CPROVER_assume(result_index<argc && result_index>=optind);
22+
23+
size_t result_index;
24+
__CPROVER_assume(
25+
result_index<strlen(optstring) && optstring[result_index]!=':');
1626
#ifdef __CPROVER_STRING_ABSTRACTION
1727
__CPROVER_assert(__CPROVER_is_zero_string(optstring),
1828
"getopt zero-termination of 3rd argument");
1929
#endif
20-
optarg = argv[result_index];
21-
optind = result_index+1;
22-
int retval;
23-
return retval;
30+
31+
_Bool found;
32+
if(found)
33+
{
34+
result=optstring[result_index];
35+
if(skipped)
36+
++optind;
37+
}
38+
39+
if(result!=-1 && optind<argc && optstring[result_index+1]==':')
40+
{
41+
_Bool has_no_arg;
42+
if(has_no_arg)
43+
{
44+
optarg=argv[optind];
45+
++optind;
46+
}
47+
else
48+
optarg=NULL;
49+
}
50+
51+
return result;
52+
}
53+
54+
/* FUNCTION: getopt_long */
55+
56+
int getopt(int argc, char * const argv[], const char *optstring);
57+
58+
inline int getopt_long(int argc, char * const argv[], const char *optstring,
59+
const struct option *longopts, int *longindex)
60+
{
61+
// trigger valid-pointer checks (if enabled), even though we don't
62+
// use the parameter in this model
63+
(void)*longopts;
64+
// avoid unused-parameter warnings when compiling using GCC (for
65+
// internal library syntax checks)
66+
(void)longindex;
67+
68+
return getopt(argc, argv, optstring);
2469
}

src/ansi-c/library/stdio.c

+40
Original file line numberDiff line numberDiff line change
@@ -794,3 +794,43 @@ inline int vfprintf(FILE *stream, const char *restrict format, va_list arg)
794794

795795
return result;
796796
}
797+
798+
/* FUNCTION: vasprintf */
799+
800+
#ifndef __CPROVER_STDIO_H_INCLUDED
801+
#include <stdio.h>
802+
#define __CPROVER_STDIO_H_INCLUDED
803+
#endif
804+
805+
#ifndef __CPROVER_STDARG_H_INCLUDED
806+
#include <stdarg.h>
807+
#define __CPROVER_STDARG_H_INCLUDED
808+
#endif
809+
810+
#ifndef __CPROVER_STDLIB_H_INCLUDED
811+
#include <stdlib.h>
812+
#define __CPROVER_STDLIB_H_INCLUDED
813+
#endif
814+
815+
inline int vasprintf(char **ptr, const char *fmt, va_list ap)
816+
{
817+
(void)*fmt;
818+
(void)ap;
819+
820+
int result_buffer_size;
821+
if(result_buffer_size<=0)
822+
return -1;
823+
824+
*ptr=malloc(result_buffer_size);
825+
for(int i=0; i<result_buffer_size; ++i)
826+
{
827+
char c;
828+
(*ptr)[i]=c;
829+
if(c=='\0')
830+
break;
831+
}
832+
833+
__CPROVER_assume(i<result_buffer_size);
834+
835+
return i;
836+
}

0 commit comments

Comments
 (0)