Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
3cdc6d68
Commit
3cdc6d68
authored
Sep 29, 2021
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winedump: Use the shared tools functions.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
9e3959bd
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
47 additions
and
139 deletions
+47
-139
debug.c
tools/winedump/debug.c
+3
-2
dump.c
tools/winedump/dump.c
+2
-1
main.c
tools/winedump/main.c
+8
-28
misc.c
tools/winedump/misc.c
+4
-70
msc.c
tools/winedump/msc.c
+6
-5
msmangle.c
tools/winedump/msmangle.c
+0
-0
nls.c
tools/winedump/nls.c
+3
-4
pdb.c
tools/winedump/pdb.c
+3
-2
pe.c
tools/winedump/pe.c
+5
-5
search.c
tools/winedump/search.c
+9
-14
symbol.c
tools/winedump/symbol.c
+2
-1
tlb.c
tools/winedump/tlb.c
+2
-3
winedump.h
tools/winedump/winedump.h
+0
-4
No files found.
tools/winedump/debug.c
View file @
3cdc6d68
...
...
@@ -41,6 +41,7 @@
#endif
#include <fcntl.h>
#include "../tools.h"
#include "windef.h"
#include "winbase.h"
#include "winedump.h"
...
...
@@ -683,7 +684,7 @@ void dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr,
* where the stab is continued over multiple lines.
*/
stabbufflen
=
65536
;
stabbuff
=
malloc
(
stabbufflen
);
stabbuff
=
x
malloc
(
stabbufflen
);
stabbuff
[
0
]
=
'\0'
;
...
...
@@ -707,7 +708,7 @@ void dump_stabs(const void* pv_stabs, unsigned szstabs, const char* stabstr,
if
(
strlen
(
stabbuff
)
+
len
>
stabbufflen
)
{
stabbufflen
+=
65536
;
stabbuff
=
realloc
(
stabbuff
,
stabbufflen
);
stabbuff
=
x
realloc
(
stabbuff
,
stabbufflen
);
}
strcat
(
stabbuff
,
ptr
);
continue
;
...
...
tools/winedump/dump.c
View file @
3cdc6d68
...
...
@@ -36,6 +36,7 @@
#endif
#include <fcntl.h>
#include "../tools.h"
#include "windef.h"
#include "winbase.h"
#include "winedump.h"
...
...
@@ -287,7 +288,7 @@ BOOL dump_analysis(const char *name, file_dumper fn, enum FileSig wanted_sig)
if
(
fstat
(
fd
,
&
s
)
<
0
)
fatal
(
"Can't get size"
);
dump_total_len
=
s
.
st_size
;
if
(
!
(
dump_base
=
malloc
(
dump_total_len
)))
fatal
(
"Out of memory"
);
dump_base
=
xmalloc
(
dump_total_len
);
if
((
unsigned
long
)
read
(
fd
,
dump_base
,
dump_total_len
)
!=
dump_total_len
)
fatal
(
"Cannot read file"
);
printf
(
"Contents of %s: %ld bytes
\n\n
"
,
name
,
dump_total_len
);
...
...
tools/winedump/main.c
View file @
3cdc6d68
...
...
@@ -21,6 +21,7 @@
#include "config.h"
#include "wine/port.h"
#include "../tools.h"
#include "winedump.h"
_globals
globals
;
/* All global variables */
...
...
@@ -28,15 +29,10 @@ _globals globals; /* All global variables */
static
void
do_include
(
const
char
*
arg
)
{
char
*
newIncludes
;
if
(
!
globals
.
directory
)
globals
.
directory
=
strdup
(
arg
);
else
{
newIncludes
=
str_create
(
3
,
globals
.
directory
,
" "
,
arg
);
free
(
globals
.
directory
);
globals
.
directory
=
newIncludes
;
}
globals
.
directory
=
xstrdup
(
arg
);
else
globals
.
directory
=
strmake
(
"%s %s"
,
globals
.
directory
,
arg
);
globals
.
do_code
=
TRUE
;
}
...
...
@@ -47,7 +43,7 @@ static inline const char* strip_ext (const char *str)
if
(
len
>
4
&&
strcmp
(
str
+
len
-
4
,
".dll"
)
==
0
)
return
str_substring
(
str
,
str
+
len
-
4
);
else
return
strdup
(
str
);
return
x
strdup
(
str
);
}
...
...
@@ -145,8 +141,7 @@ static void do_symfile (const char *arg)
while
(
1
==
fscanf
(
f
,
"%255s"
,
symstring
))
/* keep count with [<width>] above */
{
symstring
[
sizeof
(
symstring
)
-
1
]
=
'\0'
;
if
(
!
(
symbolp
=
malloc
(
sizeof
(
*
symbolp
)
+
strlen
(
symstring
))))
fatal
(
"Out of memory"
);
symbolp
=
xmalloc
(
sizeof
(
*
symbolp
)
+
strlen
(
symstring
));
strcpy
(
symbolp
->
symbolname
,
symstring
);
symbolp
->
found
=
FALSE
;
symbolp
->
next
=
NULL
;
...
...
@@ -322,26 +317,11 @@ static void parse_options (char *argv[])
static
void
set_module_name
(
BOOL
setUC
)
{
const
char
*
ptr
;
char
*
buf
;
int
len
;
/* FIXME: we shouldn't assume all module extensions are .dll in winedump
* in some cases, we could have some .drv for example
*/
/* get module name from name */
if
((
ptr
=
strrchr
(
globals
.
input_name
,
'/'
)))
ptr
++
;
else
ptr
=
globals
.
input_name
;
len
=
strlen
(
ptr
);
if
(
len
>
4
&&
strcmp
(
ptr
+
len
-
4
,
".dll"
)
==
0
)
len
-=
4
;
buf
=
malloc
(
len
+
1
);
memcpy
(
buf
,
(
const
void
*
)
ptr
,
len
);
buf
[
len
]
=
0
;
globals
.
input_module
=
buf
;
OUTPUT_UC_DLL_NAME
=
(
setUC
)
?
str_toupper
(
strdup
(
OUTPUT_DLL_NAME
))
:
""
;
globals
.
input_module
=
replace_extension
(
get_basename
(
globals
.
input_name
),
".dll"
,
""
);
OUTPUT_UC_DLL_NAME
=
(
setUC
)
?
str_toupper
(
xstrdup
(
OUTPUT_DLL_NAME
))
:
""
;
}
/* Marks the symbol as 'found'! */
...
...
tools/winedump/misc.c
View file @
3cdc6d68
...
...
@@ -21,73 +21,11 @@
#include "config.h"
#include "wine/port.h"
#include "../tools.h"
#include "winedump.h"
/*******************************************************************
* str_create
*
* Create a single string from many substrings
*/
char
*
str_create
(
size_t
num_str
,
...)
{
va_list
args
;
size_t
len
=
1
,
i
=
0
;
char
*
tmp
,
*
t
;
va_start
(
args
,
num_str
);
for
(
i
=
0
;
i
<
num_str
;
i
++
)
if
((
t
=
va_arg
(
args
,
char
*
)))
len
+=
strlen
(
t
);
va_end
(
args
);
if
(
!
(
tmp
=
malloc
(
len
)))
fatal
(
"Out of memory"
);
tmp
[
0
]
=
'\0'
;
va_start
(
args
,
num_str
);
for
(
i
=
0
;
i
<
num_str
;
i
++
)
if
((
t
=
va_arg
(
args
,
char
*
)))
strcat
(
tmp
,
t
);
va_end
(
args
);
return
tmp
;
}
/*******************************************************************
* str_create_num
*
* Create a single string from many substrings, terminating in a number
*/
char
*
str_create_num
(
size_t
num_str
,
int
num
,
...)
{
va_list
args
;
size_t
len
=
8
,
i
=
0
;
char
*
tmp
,
*
t
;
va_start
(
args
,
num
);
for
(
i
=
0
;
i
<
num_str
;
i
++
)
if
((
t
=
va_arg
(
args
,
char
*
)))
len
+=
strlen
(
t
);
va_end
(
args
);
if
(
!
(
tmp
=
malloc
(
len
)))
fatal
(
"Out of memory"
);
tmp
[
0
]
=
'\0'
;
va_start
(
args
,
num
);
for
(
i
=
0
;
i
<
num_str
;
i
++
)
if
((
t
=
va_arg
(
args
,
char
*
)))
strcat
(
tmp
,
t
);
va_end
(
args
);
sprintf
(
tmp
+
len
-
8
,
"%d"
,
num
);
return
tmp
;
}
/*******************************************************************
* str_substring
*
* Create a new substring from a string
...
...
@@ -98,9 +36,7 @@ char *str_substring(const char *start, const char *end)
assert
(
start
&&
end
&&
end
>
start
);
if
(
!
(
newstr
=
malloc
(
end
-
start
+
1
)))
fatal
(
"Out of memory"
);
newstr
=
xmalloc
(
end
-
start
+
1
);
memcpy
(
newstr
,
start
,
end
-
start
);
newstr
[
end
-
start
]
=
'\0'
;
...
...
@@ -196,12 +132,10 @@ char *str_toupper (char *str)
*/
FILE
*
open_file
(
const
char
*
name
,
const
char
*
ext
,
const
char
*
mode
)
{
char
fname
[
128
]
;
char
*
fname
;
FILE
*
fp
;
if
(((
unsigned
)
snprintf
(
fname
,
sizeof
(
fname
),
"%s%s%s"
,
*
mode
==
'w'
?
"./"
:
""
,
name
,
ext
)
>
sizeof
(
fname
)))
fatal
(
"File name too long"
);
fname
=
strmake
(
"%s%s%s"
,
*
mode
==
'w'
?
"./"
:
""
,
name
,
ext
);
if
(
VERBOSE
)
printf
(
"Open file %s
\n
"
,
fname
);
...
...
tools/winedump/msc.c
View file @
3cdc6d68
...
...
@@ -39,6 +39,7 @@
#endif
#include <fcntl.h>
#include "../tools.h"
#include "windef.h"
#include "winbase.h"
#include "winedump.h"
...
...
@@ -1364,7 +1365,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
p_string
(
&
sym
->
thunk_v1
.
p_name
),
sym
->
thunk_v1
.
segment
,
sym
->
thunk_v1
.
offset
,
sym
->
thunk_v1
.
thunk_len
,
sym
->
thunk_v1
.
thtype
);
curr_func
=
strdup
(
p_string
(
&
sym
->
thunk_v1
.
p_name
));
curr_func
=
x
strdup
(
p_string
(
&
sym
->
thunk_v1
.
p_name
));
break
;
case
S_THUNK32
:
...
...
@@ -1372,7 +1373,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
sym
->
thunk_v3
.
name
,
sym
->
thunk_v3
.
segment
,
sym
->
thunk_v3
.
offset
,
sym
->
thunk_v3
.
thunk_len
,
sym
->
thunk_v3
.
thtype
);
curr_func
=
strdup
(
sym
->
thunk_v3
.
name
);
curr_func
=
x
strdup
(
sym
->
thunk_v3
.
name
);
break
;
/* Global and static functions */
...
...
@@ -1391,7 +1392,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
printf
(
">>> prev func '%s' still has nest_block %u count
\n
"
,
curr_func
,
nest_block
);
nest_block
=
0
;
}
curr_func
=
strdup
(
p_string
(
&
sym
->
proc_v1
.
p_name
));
curr_func
=
x
strdup
(
p_string
(
&
sym
->
proc_v1
.
p_name
));
/* EPP unsigned int pparent; */
/* EPP unsigned int pend; */
/* EPP unsigned int next; */
...
...
@@ -1412,7 +1413,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
printf
(
">>> prev func '%s' still has nest_block %u count
\n
"
,
curr_func
,
nest_block
);
nest_block
=
0
;
}
curr_func
=
strdup
(
p_string
(
&
sym
->
proc_v2
.
p_name
));
curr_func
=
x
strdup
(
p_string
(
&
sym
->
proc_v2
.
p_name
));
/* EPP unsigned int pparent; */
/* EPP unsigned int pend; */
/* EPP unsigned int next; */
...
...
@@ -1433,7 +1434,7 @@ BOOL codeview_dump_symbols(const void* root, unsigned long size)
printf
(
">>> prev func '%s' still has nest_block %u count
\n
"
,
curr_func
,
nest_block
);
nest_block
=
0
;
}
curr_func
=
strdup
(
sym
->
proc_v3
.
name
);
curr_func
=
x
strdup
(
sym
->
proc_v3
.
name
);
/* EPP unsigned int pparent; */
/* EPP unsigned int pend; */
/* EPP unsigned int next; */
...
...
tools/winedump/msmangle.c
View file @
3cdc6d68
This diff is collapsed.
Click to expand it.
tools/winedump/nls.c
View file @
3cdc6d68
...
...
@@ -25,6 +25,7 @@
#include <string.h>
#include <assert.h>
#include "../tools.h"
#include "windef.h"
#include "winedump.h"
...
...
@@ -368,7 +369,7 @@ static void dump_norm(void)
{
unsigned
int
pos
,
len
=
(
dump_total_len
-
info
->
comp_seq
*
offset_scale
)
/
sizeof
(
WCHAR
);
const
WCHAR
*
seq
=
GET_TABLE
(
info
,
comp_seq
);
unsigned
int
*
map
=
malloc
(
len
*
sizeof
(
*
map
)
);
unsigned
int
*
map
=
x
malloc
(
len
*
sizeof
(
*
map
)
);
printf
(
"
\n
Compositions:
\n\n
"
);
...
...
@@ -710,9 +711,7 @@ static void dump_sort( int old_version )
void
nls_dump
(
void
)
{
const
char
*
name
=
strrchr
(
globals
.
input_name
,
'/'
);
if
(
name
)
name
++
;
else
name
=
globals
.
input_name
;
const
char
*
name
=
get_basename
(
globals
.
input_name
);
if
(
!
strcasecmp
(
name
,
"l_intl.nls"
))
return
dump_casemap
();
if
(
!
strncasecmp
(
name
,
"c_"
,
2
))
return
dump_codepage
();
if
(
!
strncasecmp
(
name
,
"norm"
,
4
))
return
dump_norm
();
...
...
tools/winedump/pdb.c
View file @
3cdc6d68
...
...
@@ -41,6 +41,7 @@
#define NONAMELESSUNION
#include "../tools.h"
#include "windef.h"
#include "winbase.h"
#include "winedump.h"
...
...
@@ -75,7 +76,7 @@ static void* pdb_jg_read(const struct PDB_JG_HEADER* pdb, const WORD* block_list
if
(
!
size
)
return
NULL
;
nBlocks
=
(
size
+
pdb
->
block_size
-
1
)
/
pdb
->
block_size
;
buffer
=
malloc
(
nBlocks
*
pdb
->
block_size
);
buffer
=
x
malloc
(
nBlocks
*
pdb
->
block_size
);
for
(
i
=
0
;
i
<
nBlocks
;
i
++
)
memcpy
(
buffer
+
i
*
pdb
->
block_size
,
...
...
@@ -861,7 +862,7 @@ static void* pdb_ds_read(const struct PDB_DS_HEADER* header, const DWORD* block_
if
(
!
size
)
return
NULL
;
nBlocks
=
(
size
+
header
->
block_size
-
1
)
/
header
->
block_size
;
buffer
=
malloc
(
nBlocks
*
header
->
block_size
);
buffer
=
x
malloc
(
nBlocks
*
header
->
block_size
);
for
(
i
=
0
;
i
<
nBlocks
;
i
++
)
memcpy
(
buffer
+
i
*
header
->
block_size
,
...
...
tools/winedump/pe.c
View file @
3cdc6d68
...
...
@@ -41,6 +41,7 @@
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "../tools.h"
#include "windef.h"
#include "winbase.h"
#include "winedump.h"
...
...
@@ -2419,8 +2420,7 @@ static void do_grab_sym( void )
/* dll_close(); */
if
(
!
(
dll_symbols
=
malloc
((
exportDir
->
NumberOfFunctions
+
1
)
*
sizeof
(
dll_symbol
))))
fatal
(
"Out of memory"
);
dll_symbols
=
xmalloc
((
exportDir
->
NumberOfFunctions
+
1
)
*
sizeof
(
dll_symbol
));
/* bit map of used funcs */
map
=
calloc
(((
exportDir
->
NumberOfFunctions
+
31
)
&
~
31
)
/
32
,
sizeof
(
DWORD
));
...
...
@@ -2431,7 +2431,7 @@ static void do_grab_sym( void )
map
[
*
pOrdl
/
32
]
|=
1
<<
(
*
pOrdl
%
32
);
ptr
=
RVA
(
*
pName
++
,
sizeof
(
DWORD
));
if
(
!
ptr
)
ptr
=
"cant_get_function"
;
dll_symbols
[
j
].
symbol
=
strdup
(
ptr
);
dll_symbols
[
j
].
symbol
=
x
strdup
(
ptr
);
dll_symbols
[
j
].
ordinal
=
exportDir
->
Base
+
*
pOrdl
;
assert
(
dll_symbols
[
j
].
symbol
);
}
...
...
@@ -2446,7 +2446,7 @@ static void do_grab_sym( void )
globals
.
forward_dll
?
globals
.
forward_dll
:
OUTPUT_UC_DLL_NAME
,
exportDir
->
Base
+
i
);
str_toupper
(
ordinal_text
);
dll_symbols
[
j
].
symbol
=
strdup
(
ordinal_text
);
dll_symbols
[
j
].
symbol
=
x
strdup
(
ordinal_text
);
assert
(
dll_symbols
[
j
].
symbol
);
dll_symbols
[
j
].
ordinal
=
exportDir
->
Base
+
i
;
j
++
;
...
...
@@ -2486,7 +2486,7 @@ BOOL dll_next_symbol (parsed_symbol * sym)
if
(
!
dll_current_symbol
||
!
dll_current_symbol
->
symbol
)
return
FALSE
;
assert
(
dll_symbols
);
sym
->
symbol
=
strdup
(
dll_current_symbol
->
symbol
);
sym
->
symbol
=
x
strdup
(
dll_current_symbol
->
symbol
);
sym
->
ordinal
=
dll_current_symbol
->
ordinal
;
dll_current_symbol
++
;
return
TRUE
;
...
...
tools/winedump/search.c
View file @
3cdc6d68
...
...
@@ -21,6 +21,7 @@
#include "config.h"
#include "wine/port.h"
#include "../tools.h"
#include "winedump.h"
static
char
*
grep_buff
=
NULL
;
...
...
@@ -50,13 +51,10 @@ BOOL symbol_search (parsed_symbol *sym)
return
FALSE
;
if
(
!
grep_buff
)
grep_buff
=
malloc
(
MAX_RESULT_LEN
);
grep_buff
=
x
malloc
(
MAX_RESULT_LEN
);
if
(
!
fgrep_buff
)
fgrep_buff
=
malloc
(
MAX_RESULT_LEN
);
if
(
!
grep_buff
||
!
fgrep_buff
)
fatal
(
"Out of Memory"
);
fgrep_buff
=
xmalloc
(
MAX_RESULT_LEN
);
/* Use 'grep' to tell us which possible files the function is in,
* then use 'function_grep.pl' to get the prototype. If this fails the
...
...
@@ -66,8 +64,8 @@ BOOL symbol_search (parsed_symbol *sym)
while
(
attempt
<
2
)
{
FILE
*
f_grep
;
char
*
cmd
=
str
_create
(
4
,
"grep -d recurse -l
\"
"
,
sym
->
symbol
,
!
attempt
?
"[:blank:]*(
\"
"
:
"
\"
"
,
globals
.
directory
);
char
*
cmd
=
str
make
(
"grep -d recurse -l
\"
%s%s
\"
%s
"
,
sym
->
symbol
,
!
attempt
?
"[:blank:]*("
:
"
"
,
globals
.
directory
);
if
(
VERBOSE
)
puts
(
cmd
);
...
...
@@ -98,8 +96,7 @@ BOOL symbol_search (parsed_symbol *sym)
if
(
VERBOSE
)
puts
(
grep_buff
);
cmd
=
str_create
(
5
,
"function_grep.pl "
,
sym
->
symbol
,
"
\"
"
,
grep_buff
,
"
\"
"
);
cmd
=
strmake
(
"function_grep.pl %s
\"
%s
\"
"
,
sym
->
symbol
,
grep_buff
);
if
(
VERBOSE
)
puts
(
cmd
);
...
...
@@ -199,7 +196,7 @@ static BOOL symbol_from_prototype (parsed_symbol *sym, const char *proto)
else
sym
->
flags
=
CALLING_CONVENTION
;
sym
->
function_name
=
strdup
(
sym
->
symbol
);
sym
->
function_name
=
x
strdup
(
sym
->
symbol
);
proto
=
iter
;
/* Now should be the arguments */
...
...
@@ -301,9 +298,7 @@ static const char *get_type (parsed_symbol *sym, const char *proto, int arg)
if
(
iter
==
base_type
||
catch_unsigned
)
{
/* 'unsigned' with no type */
char
*
tmp
=
str_create
(
2
,
type_str
,
" int"
);
free
(
type_str
);
type_str
=
tmp
;
type_str
=
strmake
(
"%s int"
,
type_str
);
}
symbol_clean_string
(
type_str
);
...
...
@@ -320,7 +315,7 @@ static const char *get_type (parsed_symbol *sym, const char *proto, int arg)
sym
->
arg_flag
[
arg
]
=
is_const
?
CT_CONST
:
is_volatile
?
CT_VOLATILE
:
0
;
if
(
*
proto_str
==
','
||
*
proto_str
==
')'
)
sym
->
arg_name
[
arg
]
=
str
_create_num
(
1
,
arg
,
"arg"
);
sym
->
arg_name
[
arg
]
=
str
make
(
"arg%u"
,
arg
);
else
{
iter
=
str_find_set
(
proto_str
,
" ,)"
);
...
...
tools/winedump/symbol.c
View file @
3cdc6d68
...
...
@@ -21,6 +21,7 @@
#include "config.h"
#include "wine/port.h"
#include "../tools.h"
#include "winedump.h"
...
...
@@ -92,7 +93,7 @@ static const char * const known_longs[] =
void
symbol_init
(
parsed_symbol
*
sym
,
const
char
*
name
)
{
memset
(
sym
,
0
,
sizeof
(
parsed_symbol
));
sym
->
symbol
=
strdup
(
name
);
sym
->
symbol
=
x
strdup
(
name
);
}
/*******************************************************************
...
...
tools/winedump/tlb.c
View file @
3cdc6d68
...
...
@@ -26,8 +26,7 @@
#include <string.h>
#include <assert.h>
#include "windef.h"
#include "../tools.h"
#include "winedump.h"
#define MSFT_MAGIC 0x5446534d
...
...
@@ -1190,7 +1189,7 @@ static const char *decode_string(const BYTE *table, const char *stream, DWORD st
table_size
=
*
(
const
DWORD
*
)
table
;
table
+=
sizeof
(
DWORD
);
buf
=
malloc
(
buf_size
);
buf
=
x
malloc
(
buf_size
);
buf
[
0
]
=
0
;
while
((
p
=
lookup_code
(
table
,
table_size
,
&
bits
)))
...
...
tools/winedump/winedump.h
View file @
3cdc6d68
...
...
@@ -198,10 +198,6 @@ void output_prototype (FILE *file, const parsed_symbol *sym);
void
output_makefile
(
void
);
/* Misc functions */
char
*
str_create
(
size_t
num_str
,
...);
char
*
str_create_num
(
size_t
num_str
,
int
num
,
...);
char
*
str_substring
(
const
char
*
start
,
const
char
*
end
);
char
*
str_replace
(
char
*
str
,
const
char
*
oldstr
,
const
char
*
newstr
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment