mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-09 22:26:06 +00:00
win: get tools/crashpad_database_util mostly working
- Add public domain getopt implementation to third_party. - Add timegm to compat/win. - Add stub of strptime to compat/win. Requires https://codereview.chromium.org/1119173003/ and https://codereview.chromium.org/1117013006/. Rather than working in wchar_t everywhere on Windows, convert UTF16 command line arguments in wmain to UTF8, work primarily in UTF8, and convert back when necessary to UTF16 for base::FilePath. This avoids the need to genericize over all the standard C string functions, getopt, etc. while still handling non-ASCII properly. R=mark@chromium.org BUG=crashpad:1 Review URL: https://codereview.chromium.org/1119783005
This commit is contained in:
parent
720882cc14
commit
17b770ece4
2
DEPS
2
DEPS
@ -28,7 +28,7 @@ deps = {
|
||||
'32ca1cd8e010d013a606a752fb49a603a3598071', # svn r2015
|
||||
'crashpad/third_party/mini_chromium/mini_chromium':
|
||||
Var('chromium_git') + '/chromium/mini_chromium@' +
|
||||
'91ea4908ffd74d9c886bd2f8ccbfae6d31c499af',
|
||||
'bf64e609259be3faf24e32aa899491f22fa1fb90',
|
||||
}
|
||||
|
||||
hooks = [
|
||||
|
@ -563,6 +563,9 @@ bool CrashReportDatabaseWin::Initialize() {
|
||||
// TODO(scottmg): When are completed reports pruned from disk? Delete here or
|
||||
// maybe on AcquireMetadata().
|
||||
|
||||
if (!settings_.Initialize())
|
||||
return false;
|
||||
|
||||
INITIALIZATION_STATE_SET_VALID(initialized_);
|
||||
return true;
|
||||
}
|
||||
|
@ -35,7 +35,10 @@
|
||||
'non_win/verrsrc.h',
|
||||
'non_win/windows.h',
|
||||
'non_win/winnt.h',
|
||||
'win/getopt.h',
|
||||
'win/sys/types.h',
|
||||
'win/time.cc',
|
||||
'win/time.h',
|
||||
'win/winnt.h',
|
||||
],
|
||||
'conditions': [
|
||||
@ -61,6 +64,9 @@
|
||||
'win',
|
||||
],
|
||||
},
|
||||
'dependencies': [
|
||||
'../third_party/getopt/getopt.gyp:getopt',
|
||||
],
|
||||
}, {
|
||||
'include_dirs': [
|
||||
'non_win',
|
||||
|
20
compat/win/getopt.h
Normal file
20
compat/win/getopt.h
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_COMPAT_WIN_GETOPT_H_
|
||||
#define CRASHPAD_COMPAT_WIN_GETOPT_H_
|
||||
|
||||
#include "third_party/getopt/getopt.h"
|
||||
|
||||
#endif // CRASHPAD_COMPAT_WIN_GETOPT_H_
|
40
compat/win/time.cc
Normal file
40
compat/win/time.cc
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <time.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
struct tm* gmtime_r(const time_t* timep, struct tm* result) {
|
||||
if (gmtime_s(result, timep) != 0)
|
||||
return nullptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
struct tm* localtime_r(const time_t* timep, struct tm* result) {
|
||||
if (localtime_s(result, timep) != 0)
|
||||
return nullptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
const char* strptime(const char* buf, const char* format, struct tm* tm) {
|
||||
// TODO(scottmg): strptime implementation.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
time_t timegm(struct tm* tm) {
|
||||
return _mkgmtime(tm);
|
||||
}
|
||||
|
||||
} // extern "C"
|
36
compat/win/time.h
Normal file
36
compat/win/time.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef CRASHPAD_COMPAT_WIN_TIME_H_
|
||||
#define CRASHPAD_COMPAT_WIN_TIME_H_
|
||||
|
||||
#include <../include/time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct tm* gmtime_r(const time_t* timep, struct tm* result);
|
||||
|
||||
struct tm* localtime_r(const time_t* timep, struct tm* result);
|
||||
|
||||
const char* strptime(const char* buf, const char* format, struct tm* tm);
|
||||
|
||||
time_t timegm(struct tm* tm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // CRASHPAD_COMPAT_WIN_TIME_H_
|
5
third_party/getopt/LICENSE
vendored
Normal file
5
third_party/getopt/LICENSE
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
Copyright (C) 1997 Gregory Pietsch
|
||||
|
||||
[These files] are hereby placed in the public domain without restrictions. Just
|
||||
give the author credit, don't claim you wrote it or prevent anyone else from
|
||||
using it.
|
12
third_party/getopt/README.crashpad
vendored
Normal file
12
third_party/getopt/README.crashpad
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
Name: Gregory Pietsch getopt
|
||||
Short Name: getop
|
||||
URL: https://sourceware.org/ml/newlib/2005/msg00758.html
|
||||
License: Public domain
|
||||
License File: LICENSE
|
||||
Security Critical: no
|
||||
|
||||
Description:
|
||||
A public domain implementation of getopt.
|
||||
|
||||
Local Modifications:
|
||||
Minor compilation fixes applied for Windows.
|
410
third_party/getopt/getopt.c
vendored
Normal file
410
third_party/getopt/getopt.c
vendored
Normal file
@ -0,0 +1,410 @@
|
||||
/****************************************************************************
|
||||
|
||||
getopt.c - Read command line options
|
||||
|
||||
AUTHOR: Gregory Pietsch
|
||||
CREATED Fri Jan 10 21:13:05 1997
|
||||
|
||||
DESCRIPTION:
|
||||
|
||||
The getopt() function parses the command line arguments. Its arguments argc
|
||||
and argv are the argument count and array as passed to the main() function
|
||||
on program invocation. The argument optstring is a list of available option
|
||||
characters. If such a character is followed by a colon (`:'), the option
|
||||
takes an argument, which is placed in optarg. If such a character is
|
||||
followed by two colons, the option takes an optional argument, which is
|
||||
placed in optarg. If the option does not take an argument, optarg is NULL.
|
||||
|
||||
The external variable optind is the index of the next array element of argv
|
||||
to be processed; it communicates from one call to the next which element to
|
||||
process.
|
||||
|
||||
The getopt_long() function works like getopt() except that it also accepts
|
||||
long options started by two dashes `--'. If these take values, it is either
|
||||
in the form
|
||||
|
||||
--arg=value
|
||||
|
||||
or
|
||||
|
||||
--arg value
|
||||
|
||||
It takes the additional arguments longopts which is a pointer to the first
|
||||
element of an array of type GETOPT_LONG_OPTION_T. The last element of the
|
||||
array has to be filled with NULL for the name field.
|
||||
|
||||
The longind pointer points to the index of the current long option relative
|
||||
to longopts if it is non-NULL.
|
||||
|
||||
The getopt() function returns the option character if the option was found
|
||||
successfully, `:' if there was a missing parameter for one of the options,
|
||||
`?' for an unknown option character, and EOF for the end of the option list.
|
||||
|
||||
The getopt_long() function's return value is described in the header file.
|
||||
|
||||
The function getopt_long_only() is identical to getopt_long(), except that a
|
||||
plus sign `+' can introduce long options as well as `--'.
|
||||
|
||||
The following describes how to deal with options that follow non-option
|
||||
argv-elements.
|
||||
|
||||
If the caller did not specify anything, the default is REQUIRE_ORDER if the
|
||||
environment variable POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||
|
||||
REQUIRE_ORDER means don't recognize them as options; stop option processing
|
||||
when the first non-option is seen. This is what Unix does. This mode of
|
||||
operation is selected by either setting the environment variable
|
||||
POSIXLY_CORRECT, or using `+' as the first character of the optstring
|
||||
parameter.
|
||||
|
||||
PERMUTE is the default. We permute the contents of ARGV as we scan, so that
|
||||
eventually all the non-options are at the end. This allows options to be
|
||||
given in any order, even with programs that were not written to expect this.
|
||||
|
||||
RETURN_IN_ORDER is an option available to programs that were written to
|
||||
expect options and other argv-elements in any order and that care about the
|
||||
ordering of the two. We describe each non-option argv-element as if it were
|
||||
the argument of an option with character code 1. Using `-' as the first
|
||||
character of the optstring parameter selects this mode of operation.
|
||||
|
||||
The special argument `--' forces an end of option-scanning regardless of the
|
||||
value of ordering. In the case of RETURN_IN_ORDER, only `--' can cause
|
||||
getopt() and friends to return EOF with optind != argc.
|
||||
|
||||
COPYRIGHT NOTICE AND DISCLAIMER:
|
||||
|
||||
Copyright (C) 1997 Gregory Pietsch
|
||||
|
||||
This file and the accompanying getopt.h header file are hereby placed in the
|
||||
public domain without restrictions. Just give the author credit, don't
|
||||
claim you wrote it or prevent anyone else from using it.
|
||||
|
||||
Gregory Pietsch's current e-mail address:
|
||||
gpietsch@comcast.net
|
||||
****************************************************************************/
|
||||
|
||||
/* include files */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef GETOPT_H
|
||||
#include "getopt.h"
|
||||
#endif
|
||||
|
||||
/* macros */
|
||||
|
||||
/* types */
|
||||
typedef enum GETOPT_ORDERING_T
|
||||
{
|
||||
PERMUTE,
|
||||
RETURN_IN_ORDER,
|
||||
REQUIRE_ORDER
|
||||
} GETOPT_ORDERING_T;
|
||||
|
||||
/* globally-defined variables */
|
||||
char *optarg = NULL;
|
||||
int optind = 0;
|
||||
int opterr = 1;
|
||||
int optopt = '?';
|
||||
|
||||
/* functions */
|
||||
|
||||
/* reverse_argv_elements: reverses num elements starting at argv */
|
||||
static void
|
||||
reverse_argv_elements (char **argv, int num)
|
||||
{
|
||||
int i;
|
||||
char *tmp;
|
||||
|
||||
for (i = 0; i < (num >> 1); i++)
|
||||
{
|
||||
tmp = argv[i];
|
||||
argv[i] = argv[num - i - 1];
|
||||
argv[num - i - 1] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* permute: swap two blocks of argv-elements given their lengths */
|
||||
static void
|
||||
permute (char **argv, int len1, int len2)
|
||||
{
|
||||
reverse_argv_elements (argv, len1);
|
||||
reverse_argv_elements (argv, len1 + len2);
|
||||
reverse_argv_elements (argv, len2);
|
||||
}
|
||||
|
||||
/* is_option: is this argv-element an option or the end of the option list? */
|
||||
static int
|
||||
is_option (char *argv_element, int only)
|
||||
{
|
||||
return ((argv_element == NULL)
|
||||
|| (argv_element[0] == '-') || (only && argv_element[0] == '+'));
|
||||
}
|
||||
|
||||
/* getopt_internal: the function that does all the dirty work */
|
||||
static int
|
||||
getopt_internal (int argc, char **argv, char *shortopts,
|
||||
GETOPT_LONG_OPTION_T * longopts, int *longind, int only)
|
||||
{
|
||||
GETOPT_ORDERING_T ordering = PERMUTE;
|
||||
static size_t optwhere = 0;
|
||||
size_t permute_from = 0;
|
||||
int num_nonopts = 0;
|
||||
int optindex = 0;
|
||||
size_t match_chars = 0;
|
||||
char *possible_arg = NULL;
|
||||
int longopt_match = -1;
|
||||
int has_arg = -1;
|
||||
char *cp = NULL;
|
||||
int arg_next = 0;
|
||||
|
||||
/* first, deal with silly parameters and easy stuff */
|
||||
if (argc == 0 || argv == NULL || (shortopts == NULL && longopts == NULL))
|
||||
return (optopt = '?');
|
||||
if (optind >= argc || argv[optind] == NULL)
|
||||
return EOF;
|
||||
if (strcmp (argv[optind], "--") == 0)
|
||||
{
|
||||
optind++;
|
||||
return EOF;
|
||||
}
|
||||
/* if this is our first time through */
|
||||
if (optind == 0) {
|
||||
optind = 1;
|
||||
optwhere = 1;
|
||||
}
|
||||
|
||||
/* define ordering */
|
||||
if (shortopts != NULL && (*shortopts == '-' || *shortopts == '+'))
|
||||
{
|
||||
ordering = (*shortopts == '-') ? RETURN_IN_ORDER : REQUIRE_ORDER;
|
||||
shortopts++;
|
||||
}
|
||||
else
|
||||
ordering = (getenv ("POSIXLY_CORRECT") != NULL) ? REQUIRE_ORDER : PERMUTE;
|
||||
|
||||
/*
|
||||
* based on ordering, find our next option, if we're at the beginning of
|
||||
* one
|
||||
*/
|
||||
if (optwhere == 1)
|
||||
{
|
||||
switch (ordering)
|
||||
{
|
||||
case PERMUTE:
|
||||
permute_from = optind;
|
||||
num_nonopts = 0;
|
||||
while (!is_option (argv[optind], only))
|
||||
{
|
||||
optind++;
|
||||
num_nonopts++;
|
||||
}
|
||||
if (argv[optind] == NULL)
|
||||
{
|
||||
/* no more options */
|
||||
optind = (int)permute_from;
|
||||
return EOF;
|
||||
}
|
||||
else if (strcmp (argv[optind], "--") == 0)
|
||||
{
|
||||
/* no more options, but have to get `--' out of the way */
|
||||
permute (argv + permute_from, num_nonopts, 1);
|
||||
optind = (int)(permute_from + 1);
|
||||
return EOF;
|
||||
}
|
||||
break;
|
||||
case RETURN_IN_ORDER:
|
||||
if (!is_option (argv[optind], only))
|
||||
{
|
||||
optarg = argv[optind++];
|
||||
return (optopt = 1);
|
||||
}
|
||||
break;
|
||||
case REQUIRE_ORDER:
|
||||
if (!is_option (argv[optind], only))
|
||||
return EOF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* we've got an option, so parse it */
|
||||
|
||||
/* first, is it a long option? */
|
||||
if (longopts != NULL
|
||||
&& (memcmp (argv[optind], "--", 2) == 0
|
||||
|| (only && argv[optind][0] == '+')) && optwhere == 1)
|
||||
{
|
||||
/* handle long options */
|
||||
if (memcmp (argv[optind], "--", 2) == 0)
|
||||
optwhere = 2;
|
||||
longopt_match = -1;
|
||||
possible_arg = strchr (argv[optind] + optwhere, '=');
|
||||
if (possible_arg == NULL)
|
||||
{
|
||||
/* no =, so next argv might be arg */
|
||||
match_chars = strlen (argv[optind]);
|
||||
possible_arg = argv[optind] + match_chars;
|
||||
match_chars = match_chars - optwhere;
|
||||
}
|
||||
else
|
||||
match_chars = (possible_arg - argv[optind]) - optwhere;
|
||||
for (optindex = 0; longopts[optindex].name != NULL; optindex++)
|
||||
{
|
||||
if (memcmp (argv[optind] + optwhere,
|
||||
longopts[optindex].name, match_chars) == 0)
|
||||
{
|
||||
/* do we have an exact match? */
|
||||
if (match_chars == strlen (longopts[optindex].name))
|
||||
{
|
||||
longopt_match = optindex;
|
||||
break;
|
||||
}
|
||||
/* do any characters match? */
|
||||
else
|
||||
{
|
||||
if (longopt_match < 0)
|
||||
longopt_match = optindex;
|
||||
else
|
||||
{
|
||||
/* we have ambiguous options */
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous "
|
||||
"(could be `--%s' or `--%s')\n",
|
||||
argv[0],
|
||||
argv[optind],
|
||||
longopts[longopt_match].name,
|
||||
longopts[optindex].name);
|
||||
return (optopt = '?');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (longopt_match >= 0)
|
||||
has_arg = longopts[longopt_match].has_arg;
|
||||
}
|
||||
/* if we didn't find a long option, is it a short option? */
|
||||
if (longopt_match < 0 && shortopts != NULL)
|
||||
{
|
||||
cp = strchr (shortopts, argv[optind][optwhere]);
|
||||
if (cp == NULL)
|
||||
{
|
||||
/* couldn't find option in shortopts */
|
||||
if (opterr)
|
||||
fprintf (stderr,
|
||||
"%s: invalid option -- `-%c'\n",
|
||||
argv[0], argv[optind][optwhere]);
|
||||
optwhere++;
|
||||
if (argv[optind][optwhere] == '\0')
|
||||
{
|
||||
optind++;
|
||||
optwhere = 1;
|
||||
}
|
||||
return (optopt = '?');
|
||||
}
|
||||
has_arg = ((cp[1] == ':')
|
||||
? ((cp[2] == ':') ? OPTIONAL_ARG : required_argument) : no_argument);
|
||||
possible_arg = argv[optind] + optwhere + 1;
|
||||
optopt = *cp;
|
||||
}
|
||||
/* get argument and reset optwhere */
|
||||
arg_next = 0;
|
||||
switch (has_arg)
|
||||
{
|
||||
case OPTIONAL_ARG:
|
||||
if (*possible_arg == '=')
|
||||
possible_arg++;
|
||||
if (*possible_arg != '\0')
|
||||
{
|
||||
optarg = possible_arg;
|
||||
optwhere = 1;
|
||||
}
|
||||
else
|
||||
optarg = NULL;
|
||||
break;
|
||||
case required_argument:
|
||||
if (*possible_arg == '=')
|
||||
possible_arg++;
|
||||
if (*possible_arg != '\0')
|
||||
{
|
||||
optarg = possible_arg;
|
||||
optwhere = 1;
|
||||
}
|
||||
else if (optind + 1 >= argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
fprintf (stderr, "%s: argument required for option `", argv[0]);
|
||||
if (longopt_match >= 0)
|
||||
fprintf (stderr, "--%s'\n", longopts[longopt_match].name);
|
||||
else
|
||||
fprintf (stderr, "-%c'\n", *cp);
|
||||
}
|
||||
optind++;
|
||||
return (optopt = ':');
|
||||
}
|
||||
else
|
||||
{
|
||||
optarg = argv[optind + 1];
|
||||
arg_next = 1;
|
||||
optwhere = 1;
|
||||
}
|
||||
break;
|
||||
case no_argument:
|
||||
if (longopt_match < 0)
|
||||
{
|
||||
optwhere++;
|
||||
if (argv[optind][optwhere] == '\0')
|
||||
optwhere = 1;
|
||||
}
|
||||
else
|
||||
optwhere = 1;
|
||||
optarg = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* do we have to permute or otherwise modify optind? */
|
||||
if (ordering == PERMUTE && optwhere == 1 && num_nonopts != 0)
|
||||
{
|
||||
permute (argv + permute_from, num_nonopts, 1 + arg_next);
|
||||
optind = (int)(permute_from + 1 + arg_next);
|
||||
}
|
||||
else if (optwhere == 1)
|
||||
optind = optind + 1 + arg_next;
|
||||
|
||||
/* finally return */
|
||||
if (longopt_match >= 0)
|
||||
{
|
||||
if (longind != NULL)
|
||||
*longind = longopt_match;
|
||||
if (longopts[longopt_match].flag != NULL)
|
||||
{
|
||||
*(longopts[longopt_match].flag) = longopts[longopt_match].val;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return longopts[longopt_match].val;
|
||||
}
|
||||
else
|
||||
return optopt;
|
||||
}
|
||||
|
||||
int
|
||||
getopt (int argc, char **argv, char *optstring)
|
||||
{
|
||||
return getopt_internal (argc, argv, optstring, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
int
|
||||
getopt_long (int argc, char **argv, const char *shortopts,
|
||||
const GETOPT_LONG_OPTION_T * longopts, int *longind)
|
||||
{
|
||||
return getopt_internal (argc, argv, (char*)shortopts, (GETOPT_LONG_OPTION_T*)longopts, longind, 0);
|
||||
}
|
||||
|
||||
int
|
||||
getopt_long_only (int argc, char **argv, const char *shortopts,
|
||||
const GETOPT_LONG_OPTION_T * longopts, int *longind)
|
||||
{
|
||||
return getopt_internal (argc, argv, (char*)shortopts, (GETOPT_LONG_OPTION_T*)longopts, longind, 1);
|
||||
}
|
||||
|
||||
/* end of file GETOPT.C */
|
35
third_party/getopt/getopt.gyp
vendored
Normal file
35
third_party/getopt/getopt.gyp
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright 2015 The Crashpad Authors. All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
{
|
||||
'includes': [
|
||||
'../../build/crashpad.gypi',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="win"', {
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'getopt',
|
||||
'type': 'static_library',
|
||||
'sources': [
|
||||
'getopt.c',
|
||||
'getopt.h',
|
||||
],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
'targets': []
|
||||
}]
|
||||
],
|
||||
}
|
55
third_party/getopt/getopt.h
vendored
Normal file
55
third_party/getopt/getopt.h
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
#ifndef GETOPT_H
|
||||
#define GETOPT_H
|
||||
|
||||
/* include files needed by this include file */
|
||||
|
||||
/* macros defined by this include file */
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define OPTIONAL_ARG 2
|
||||
|
||||
/* types defined by this include file */
|
||||
|
||||
/* GETOPT_LONG_OPTION_T: The type of long option */
|
||||
typedef struct GETOPT_LONG_OPTION_T
|
||||
{
|
||||
const char *name; /* the name of the long option */
|
||||
int has_arg; /* one of the above macros */
|
||||
int *flag; /* determines if getopt_long() returns a
|
||||
* value for a long option; if it is
|
||||
* non-NULL, 0 is returned as a function
|
||||
* value and the value of val is stored in
|
||||
* the area pointed to by flag. Otherwise,
|
||||
* val is returned. */
|
||||
int val; /* determines the value to return if flag is
|
||||
* NULL. */
|
||||
} GETOPT_LONG_OPTION_T;
|
||||
|
||||
typedef GETOPT_LONG_OPTION_T option;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* externally-defined variables */
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
extern int optopt;
|
||||
|
||||
/* function prototypes */
|
||||
int getopt (int argc, char **argv, char *optstring);
|
||||
int getopt_long (int argc, char **argv, const char *shortopts,
|
||||
const GETOPT_LONG_OPTION_T * longopts, int *longind);
|
||||
int getopt_long_only (int argc, char **argv, const char *shortopts,
|
||||
const GETOPT_LONG_OPTION_T * longopts, int *longind);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* GETOPT_H */
|
||||
|
||||
/* END OF FILE getopt.h */
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -25,10 +24,13 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "base/numerics/safe_conversions.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "build/build_config.h"
|
||||
#include "client/crash_report_database.h"
|
||||
#include "client/settings.h"
|
||||
#include "tools/tool_support.h"
|
||||
@ -36,12 +38,22 @@
|
||||
#include "util/file/file_reader.h"
|
||||
#include "util/misc/uuid.h"
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
base::FilePath::StringType UTF8ToFilePathStringType(const char* path) {
|
||||
return path;
|
||||
}
|
||||
#elif defined(OS_WIN)
|
||||
base::FilePath::StringType UTF8ToFilePathStringType(const char* path) {
|
||||
return base::UTF8ToUTF16(path);
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace crashpad {
|
||||
namespace {
|
||||
|
||||
void Usage(const std::string& me) {
|
||||
void Usage(const base::FilePath& me) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s [OPTION]... PID\n"
|
||||
"Usage: %" PRFilePath " [OPTION]... PID\n"
|
||||
"Operate on Crashpad crash report databases.\n"
|
||||
"\n"
|
||||
" -d, --database=PATH operate on the crash report database at PATH\n"
|
||||
@ -60,7 +72,7 @@ void Usage(const std::string& me) {
|
||||
" --utc show and set UTC times instead of local\n"
|
||||
" --help display this help and exit\n"
|
||||
" --version output version information and exit\n",
|
||||
me.c_str());
|
||||
me.value().c_str());
|
||||
ToolSupport::UsageTail(me);
|
||||
}
|
||||
|
||||
@ -104,14 +116,14 @@ bool StringToBool(const char* string, bool* boolean) {
|
||||
};
|
||||
|
||||
for (size_t index = 0; index < arraysize(kFalseWords); ++index) {
|
||||
if (strcasecmp(string, kFalseWords[index]) == 0) {
|
||||
if (base::strcasecmp(string, kFalseWords[index]) == 0) {
|
||||
*boolean = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t index = 0; index < arraysize(kTrueWords); ++index) {
|
||||
if (strcasecmp(string, kTrueWords[index]) == 0) {
|
||||
if (base::strcasecmp(string, kTrueWords[index]) == 0) {
|
||||
*boolean = true;
|
||||
return true;
|
||||
}
|
||||
@ -133,7 +145,7 @@ std::string BoolToString(bool boolean) {
|
||||
// when true, causes |string| to be interpreted as a UTC time rather than a
|
||||
// local time when the time zone is ambiguous.
|
||||
bool StringToTime(const char* string, time_t* time, bool utc) {
|
||||
if (strcasecmp(string, "never") == 0) {
|
||||
if (base::strcasecmp(string, "never") == 0) {
|
||||
*time = 0;
|
||||
return true;
|
||||
}
|
||||
@ -153,7 +165,7 @@ bool StringToTime(const char* string, time_t* time, bool utc) {
|
||||
if (utc) {
|
||||
*time = timegm(&time_tm);
|
||||
} else {
|
||||
*time = timelocal(&time_tm);
|
||||
*time = mktime(&time_tm);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -172,7 +184,7 @@ bool StringToTime(const char* string, time_t* time, bool utc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Converst |time_tt| to a string, and returns it. |utc| determines whether the
|
||||
// Converts |time_tt| to a string, and returns it. |utc| determines whether the
|
||||
// converted time will reference local time or UTC. If |time_tt| is 0, the
|
||||
// string "never" will be returned as a special case.
|
||||
std::string TimeToString(time_t time_tt, bool utc) {
|
||||
@ -203,7 +215,9 @@ void ShowReport(const CrashReportDatabase::Report& report,
|
||||
bool utc) {
|
||||
std::string spaces(space_count, ' ');
|
||||
|
||||
printf("%sPath: %s\n", spaces.c_str(), report.file_path.value().c_str());
|
||||
printf("%sPath: %" PRFilePath "\n",
|
||||
spaces.c_str(),
|
||||
report.file_path.value().c_str());
|
||||
if (!report.id.empty()) {
|
||||
printf("%sRemote ID: %s\n", spaces.c_str(), report.id.c_str());
|
||||
}
|
||||
@ -239,7 +253,8 @@ void ShowReports(const std::vector<CrashReportDatabase::Report>& reports,
|
||||
}
|
||||
|
||||
int DatabaseUtilMain(int argc, char* argv[]) {
|
||||
const std::string me(basename(argv[0]));
|
||||
const base::FilePath me(
|
||||
base::FilePath(UTF8ToFilePathStringType(argv[0])).BaseName());
|
||||
|
||||
enum OptionFlags {
|
||||
// “Short” (single-character) options.
|
||||
@ -349,7 +364,8 @@ int DatabaseUtilMain(int argc, char* argv[]) {
|
||||
break;
|
||||
}
|
||||
case kOptionNewReport: {
|
||||
options.new_report_paths.push_back(base::FilePath(optarg));
|
||||
options.new_report_paths.push_back(
|
||||
base::FilePath(UTF8ToFilePathStringType(optarg)));
|
||||
break;
|
||||
}
|
||||
case kOptionUTC: {
|
||||
@ -408,8 +424,8 @@ int DatabaseUtilMain(int argc, char* argv[]) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
scoped_ptr<CrashReportDatabase> database(
|
||||
CrashReportDatabase::Initialize(base::FilePath(options.database)));
|
||||
scoped_ptr<CrashReportDatabase> database(CrashReportDatabase::Initialize(
|
||||
base::FilePath(UTF8ToFilePathStringType(options.database))));
|
||||
if (!database) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@ -453,7 +469,7 @@ int DatabaseUtilMain(int argc, char* argv[]) {
|
||||
printf("%s%s (%ld)\n",
|
||||
prefix,
|
||||
TimeToString(last_upload_attempt_time, options.utc).c_str(),
|
||||
implicit_cast<long>(last_upload_attempt_time));
|
||||
static_cast<long>(last_upload_attempt_time));
|
||||
}
|
||||
|
||||
if (options.show_pending_reports) {
|
||||
@ -497,7 +513,8 @@ int DatabaseUtilMain(int argc, char* argv[]) {
|
||||
// If only asked to do one thing, a failure to find the single requested
|
||||
// report should result in a failure exit status.
|
||||
if (show_operations + set_operations == 1) {
|
||||
fprintf(stderr, "%s: Report not found\n", me.c_str());
|
||||
fprintf(
|
||||
stderr, "%" PRFilePath ": Report not found\n", me.value().c_str());
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("Report %s not found\n", uuid.ToString().c_str());
|
||||
@ -562,6 +579,19 @@ int DatabaseUtilMain(int argc, char* argv[]) {
|
||||
} // namespace
|
||||
} // namespace crashpad
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
int main(int argc, char* argv[]) {
|
||||
return crashpad::DatabaseUtilMain(argc, argv);
|
||||
}
|
||||
#elif defined(OS_WIN)
|
||||
int wmain(int argc, wchar_t* argv[]) {
|
||||
scoped_ptr<char*[]> argv_as_utf8(new char*[argc]);
|
||||
std::vector<std::string> storage;
|
||||
storage.reserve(argc);
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
storage.push_back(base::UTF16ToUTF8(argv[i]));
|
||||
argv_as_utf8[i] = &storage[i][0];
|
||||
}
|
||||
return crashpad::DatabaseUtilMain(argc, argv_as_utf8.get());
|
||||
}
|
||||
#endif // OS_POSIX
|
||||
|
@ -21,31 +21,50 @@
|
||||
namespace crashpad {
|
||||
|
||||
// static
|
||||
void ToolSupport::Version(const std::string& me) {
|
||||
void ToolSupport::Version(const base::FilePath& me) {
|
||||
fprintf(stderr,
|
||||
"%s (%s) %s\n%s\n",
|
||||
me.c_str(),
|
||||
"%s" PRFilePath " (%s) %s\n%s\n",
|
||||
me.value().c_str(),
|
||||
PACKAGE_NAME,
|
||||
PACKAGE_VERSION,
|
||||
PACKAGE_COPYRIGHT);
|
||||
}
|
||||
|
||||
// static
|
||||
void ToolSupport::UsageTail(const std::string& me) {
|
||||
void ToolSupport::UsageTail(const base::FilePath& me) {
|
||||
fprintf(stderr,
|
||||
"\nReport %s bugs to\n%s\n%s home page: <%s>\n",
|
||||
me.c_str(),
|
||||
"\nReport %" PRFilePath " bugs to\n%s\n%s home page: <%s>\n",
|
||||
me.value().c_str(),
|
||||
PACKAGE_BUGREPORT,
|
||||
PACKAGE_NAME,
|
||||
PACKAGE_URL);
|
||||
}
|
||||
|
||||
// static
|
||||
void ToolSupport::UsageHint(const std::string& me, const char* hint) {
|
||||
void ToolSupport::UsageHint(const base::FilePath& me, const char* hint) {
|
||||
if (hint) {
|
||||
fprintf(stderr, "%s: %s\n", me.c_str(), hint);
|
||||
fprintf(stderr, "%" PRFilePath ": %s\n", me.value().c_str(), hint);
|
||||
}
|
||||
fprintf(stderr, "Try '%s --help' for more information.\n", me.c_str());
|
||||
fprintf(stderr,
|
||||
"Try '%" PRFilePath " --help' for more information.\n",
|
||||
me.value().c_str());
|
||||
}
|
||||
|
||||
#if defined(OS_POSIX)
|
||||
// static
|
||||
void ToolSupport::Version(const std::string& me) {
|
||||
Version(base::FilePath(me));
|
||||
}
|
||||
|
||||
// static
|
||||
void ToolSupport::UsageTail(const std::string& me) {
|
||||
UsageTail(base::FilePath(me));
|
||||
}
|
||||
|
||||
// static
|
||||
void ToolSupport::UsageHint(const std::string& me, const char* hint) {
|
||||
UsageHint(base::FilePath(me), hint);
|
||||
}
|
||||
#endif // OS_POSIX
|
||||
|
||||
} // namespace crashpad
|
||||
|
@ -18,6 +18,8 @@
|
||||
#include <string>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/files/file_path.h"
|
||||
#include "build/build_config.h"
|
||||
|
||||
namespace crashpad {
|
||||
|
||||
@ -27,18 +29,29 @@ class ToolSupport {
|
||||
//! \brief Handles `--version`.
|
||||
//!
|
||||
//! \param[in] me The tool’s name, the basename of `argv[0]`.
|
||||
static void Version(const std::string& me);
|
||||
static void Version(const base::FilePath& me);
|
||||
|
||||
//! \brief Prints the footer for `--help`.
|
||||
//!
|
||||
//! \param[in] me The tool’s name, the basename of `argv[0]`.
|
||||
static void UsageTail(const std::string& me);
|
||||
static void UsageTail(const base::FilePath& me);
|
||||
|
||||
//! \brief Suggests using `--help` when a command line tool can’t make sense
|
||||
//! of its arguments.
|
||||
//!
|
||||
//! \param[in] me The tool’s name, the basename of `argv[0]`.
|
||||
static void UsageHint(const base::FilePath& me, const char* hint);
|
||||
|
||||
#if defined(OS_POSIX) || DOXYGEN
|
||||
//! \copydoc Version
|
||||
static void Version(const std::string& me);
|
||||
|
||||
//! \copydoc UsageTail
|
||||
static void UsageTail(const std::string& me);
|
||||
|
||||
//! \copydoc UsageHint
|
||||
static void UsageHint(const std::string& me, const char* hint);
|
||||
#endif // OS_POSIX
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(ToolSupport);
|
||||
|
@ -16,34 +16,6 @@
|
||||
'includes': [
|
||||
'../build/crashpad.gypi',
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'variables': {
|
||||
# Programs that use task_for_pid() can indicate to taskgated(8) in their
|
||||
# Info.plist that they are allowed to call that function. In order for
|
||||
# this to work, the programs in question must be signed by an authority
|
||||
# trusted by the system. Signing is beyond the scope of the build, but
|
||||
# the key to make this work is placed in Info.plist to enable the
|
||||
# desired behavior once the tools that require this access are signed.
|
||||
#
|
||||
# The tools built here are flat-file executables, and are not bundled.
|
||||
# To have an Info.plist, they must have a special __TEXT,__info_plist
|
||||
# section. This section is created at link time.
|
||||
#
|
||||
# The Info.plist for this purpose is mac/sectaskaccess_info.plist and is
|
||||
# referenced by OTHER_LDFLAGS. ninja runs the link step from the output
|
||||
# directory such as out/Release, and requires a relative path from that
|
||||
# directory. Xcode runs the link step from the directory of the
|
||||
# .xcodeproj, which is the directory of the .gyp file.
|
||||
'conditions': [
|
||||
['GENERATOR=="ninja"', {
|
||||
'sectaskaccess_info_plist': '<!(pwd)/mac/sectaskaccess_info.plist',
|
||||
}, { # else: GENERATOR!="ninja"
|
||||
'sectaskaccess_info_plist': 'mac/sectaskaccess_info.plist',
|
||||
}],
|
||||
],
|
||||
},
|
||||
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'crashpad_tool_support',
|
||||
@ -76,6 +48,36 @@
|
||||
'crashpad_database_util.cc',
|
||||
],
|
||||
},
|
||||
],
|
||||
'conditions': [
|
||||
['OS=="mac"', {
|
||||
'variables': {
|
||||
# Programs that use task_for_pid() can indicate to taskgated(8) in their
|
||||
# Info.plist that they are allowed to call that function. In order for
|
||||
# this to work, the programs in question must be signed by an authority
|
||||
# trusted by the system. Signing is beyond the scope of the build, but
|
||||
# the key to make this work is placed in Info.plist to enable the
|
||||
# desired behavior once the tools that require this access are signed.
|
||||
#
|
||||
# The tools built here are flat-file executables, and are not bundled.
|
||||
# To have an Info.plist, they must have a special __TEXT,__info_plist
|
||||
# section. This section is created at link time.
|
||||
#
|
||||
# The Info.plist for this purpose is mac/sectaskaccess_info.plist and is
|
||||
# referenced by OTHER_LDFLAGS. ninja runs the link step from the output
|
||||
# directory such as out/Release, and requires a relative path from that
|
||||
# directory. Xcode runs the link step from the directory of the
|
||||
# .xcodeproj, which is the directory of the .gyp file.
|
||||
'conditions': [
|
||||
['GENERATOR=="ninja"', {
|
||||
'sectaskaccess_info_plist': '<!(pwd)/mac/sectaskaccess_info.plist',
|
||||
}, { # else: GENERATOR!="ninja"
|
||||
'sectaskaccess_info_plist': 'mac/sectaskaccess_info.plist',
|
||||
}],
|
||||
],
|
||||
},
|
||||
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'catch_exception_tool',
|
||||
'type': 'executable',
|
||||
@ -182,8 +184,6 @@
|
||||
],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
'targets': [],
|
||||
}],
|
||||
],
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user