1 : /*
2 : * Copyright 2009 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can
4 : * be found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * Some useful routines to handle command line arguments.
9 : */
10 :
11 : #include <stdlib.h>
12 : #include <string.h>
13 :
14 : #include "native_client/src/shared/utils/flags.h"
15 :
16 : /*
17 : * Given a pointer to a flag name to be
18 : * checked against the pointer to the corresponding
19 : * argument, return true iff the argument begins with
20 : * the flag name. During the match, advance both pointers
21 : * to the maximal matched prefix.
22 : */
23 114268 : static Bool MatchFlagPrefix(const char** name,
24 114268 : const char** arg) {
25 462390 : while (*(*name)) {
26 340620 : if (*(*name) != *(*arg)) {
27 106766 : return FALSE;
28 : }
29 233854 : ++(*name);
30 233854 : ++(*arg);
31 233854 : }
32 7502 : return TRUE;
33 114268 : }
34 :
35 : /*
36 : * Given a pointer to a flag name to be checked
37 : * against the pointer to the corresponding argument, return true
38 : * iff the argument begins with the flag name, followed by
39 : * and equals sign. During the match, advance both pointers
40 : * to the maximal matched prefix.
41 : */
42 110517 : static Bool MatchFlagPrefixEquals(const char** name,
43 110517 : const char** arg) {
44 110517 : const char* equals = "=";
45 110517 : return MatchFlagPrefix(name, arg) &&
46 3751 : MatchFlagPrefix(&equals, arg);
47 110517 : }
48 :
49 98918 : Bool GrokBoolFlag(const char* name,
50 98918 : const char* arg,
51 98918 : Bool* flag) {
52 98918 : if (strcmp(name, arg) == 0) {
53 1210 : *flag = TRUE;
54 1210 : return TRUE;
55 97708 : } else if (MatchFlagPrefixEquals(&name, &arg)) {
56 1000 : if (strcmp(arg, "true") == 0) {
57 0 : *flag = TRUE;
58 0 : return TRUE;
59 1000 : } else if (strcmp(arg, "false") == 0) {
60 1000 : *flag = FALSE;
61 1000 : return TRUE;
62 : }
63 0 : }
64 96708 : return FALSE;
65 98918 : }
66 :
67 0 : static Bool IsZero(const char* arg) {
68 0 : while (*arg) {
69 0 : if ('0' != *arg) {
70 0 : return FALSE;
71 : }
72 0 : ++arg;
73 0 : }
74 0 : return TRUE;
75 0 : }
76 :
77 3970 : Bool GrokIntFlag(const char* name,
78 3970 : const char* arg,
79 3970 : int* flag) {
80 3970 : if (MatchFlagPrefixEquals(&name, &arg)) {
81 568 : int value = atoi(arg);
82 : /* verify that arg is all zeros. Otherwise,
83 : * assume that 0 was returned due to an error.
84 : */
85 568 : if (0 == value && !IsZero(arg)) return FALSE;
86 568 : *flag = value;
87 568 : return TRUE;
88 : }
89 3402 : return FALSE;
90 3970 : }
91 :
92 1990 : Bool GrokUint32HexFlag(const char* name,
93 1990 : const char* arg,
94 1990 : uint32_t* flag) {
95 1990 : if (MatchFlagPrefixEquals(&name, &arg)) {
96 24 : unsigned long value = strtoul(arg, NULL, 16);
97 : /* Verify that arg is all zeros. Otherwise,
98 : * assume that 0 was returned due to an error.
99 : */
100 24 : if (0L == value && !IsZero(arg)) return FALSE;
101 24 : *flag = (uint32_t) value;
102 24 : return TRUE;
103 : }
104 1966 : return FALSE;
105 1990 : }
106 :
107 :
108 6849 : Bool GrokCstringFlag(const char* name,
109 6849 : const char* arg,
110 6849 : char** flag) {
111 6849 : if (MatchFlagPrefixEquals(&name, &arg)) {
112 2159 : *flag = (char*) arg;
113 2159 : return TRUE;
114 : }
115 4690 : return FALSE;
116 6849 : }
|