blob: dc89d15b6063ebf77e9f63afb9727a4ffcda5c64 [file] [log] [blame]
The Android Open Source Projectcbb10112009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2005 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//
18// Miscellaneous utility functions.
19//
20#include <utils/misc.h>
21
22#include <sys/stat.h>
23#include <string.h>
24#include <errno.h>
25#include <assert.h>
26#include <stdio.h>
27
28using namespace android;
29
30namespace android {
31
32/*
33 * Like strdup(), but uses C++ "new" operator instead of malloc.
34 */
35char* strdupNew(const char* str)
36{
37 char* newStr;
38 int len;
39
40 if (str == NULL)
41 return NULL;
42
43 len = strlen(str);
44 newStr = new char[len+1];
45 memcpy(newStr, str, len+1);
46
47 return newStr;
48}
49
50/*
51 * Concatenate an argument vector.
52 */
53char* concatArgv(int argc, const char* const argv[])
54{
55 char* newStr = NULL;
56 int len, totalLen, posn, idx;
57
58 /*
59 * First, figure out the total length.
60 */
61 totalLen = idx = 0;
62 while (1) {
63 if (idx == argc || argv[idx] == NULL)
64 break;
65 if (idx)
66 totalLen++; // leave a space between args
67 totalLen += strlen(argv[idx]);
68 idx++;
69 }
70
71 /*
72 * Alloc the string.
73 */
74 newStr = new char[totalLen +1];
75 if (newStr == NULL)
76 return NULL;
77
78 /*
79 * Finally, allocate the string and copy data over.
80 */
81 idx = posn = 0;
82 while (1) {
83 if (idx == argc || argv[idx] == NULL)
84 break;
85 if (idx)
86 newStr[posn++] = ' ';
87
88 len = strlen(argv[idx]);
89 memcpy(&newStr[posn], argv[idx], len);
90 posn += len;
91
92 idx++;
93 }
94
95 assert(posn == totalLen);
96 newStr[posn] = '\0';
97
98 return newStr;
99}
100
101/*
102 * Count the #of args in an argument vector. Don't count the final NULL.
103 */
104int countArgv(const char* const argv[])
105{
106 int count = 0;
107
108 while (argv[count] != NULL)
109 count++;
110
111 return count;
112}
113
114
115#include <stdio.h>
116/*
117 * Get a file's type.
118 */
119FileType getFileType(const char* fileName)
120{
121 struct stat sb;
122
123 if (stat(fileName, &sb) < 0) {
124 if (errno == ENOENT || errno == ENOTDIR)
125 return kFileTypeNonexistent;
126 else {
127 fprintf(stderr, "getFileType got errno=%d on '%s'\n",
128 errno, fileName);
129 return kFileTypeUnknown;
130 }
131 } else {
132 if (S_ISREG(sb.st_mode))
133 return kFileTypeRegular;
134 else if (S_ISDIR(sb.st_mode))
135 return kFileTypeDirectory;
136 else if (S_ISCHR(sb.st_mode))
137 return kFileTypeCharDev;
138 else if (S_ISBLK(sb.st_mode))
139 return kFileTypeBlockDev;
140 else if (S_ISFIFO(sb.st_mode))
141 return kFileTypeFifo;
142#ifdef HAVE_SYMLINKS
143 else if (S_ISLNK(sb.st_mode))
144 return kFileTypeSymlink;
145 else if (S_ISSOCK(sb.st_mode))
146 return kFileTypeSocket;
147#endif
148 else
149 return kFileTypeUnknown;
150 }
151}
152
153/*
154 * Get a file's modification date.
155 */
156time_t getFileModDate(const char* fileName)
157{
158 struct stat sb;
159
160 if (stat(fileName, &sb) < 0)
161 return (time_t) -1;
162
163 return sb.st_mtime;
164}
165
166/*
167 * Round up to the next highest power of 2.
168 *
169 * Found on http://graphics.stanford.edu/~seander/bithacks.html.
170 */
171unsigned int roundUpPower2(unsigned int val)
172{
173 val--;
174 val |= val >> 1;
175 val |= val >> 2;
176 val |= val >> 4;
177 val |= val >> 8;
178 val |= val >> 16;
179 val++;
180
181 return val;
182}
183
184}; // namespace android
185