mirror of
https://github.com/google/cpu_features.git
synced 2025-04-28 07:23:37 +02:00

Visual C++ reported a number of warnings: ..\src\filesystem.c(27): warning C4996: '_open': This function or variable may be unsafe. Consider using _sopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. ..\src\filesystem.c(34): warning C4267: 'function': conversion from 'size_t' to 'unsigned int', possible loss of data ..\src\string_view.c(25): warning C4244: 'return': conversion from '__int64' to 'int', possible loss of data ..\src\string_view.c(41): warning C4244: 'return': conversion from '__int64' to 'int', possible loss of data ..\src\utils\list_cpu_features.c(151): warning C4090: 'function': different 'const' qualifiers ..\src\cpuinfo_x86.c(67): warning C4244: 'return': conversion from 'unsigned __int64' to 'uint32_t', possible loss of data ..\test\filesystem_for_testing.cc(48): warning C4267: 'return': conversion from 'size_t' to 'int', possible loss of data ..\test\filesystem_for_testing.cc(57): warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data ..\test\bit_utils_test.cc(26): warning C4267: 'argument': conversion from 'size_t' to 'uint32_t', possible loss of data ..\test\bit_utils_test.cc(32): warning C4267: 'argument': conversion from 'size_t' to 'uint32_t', possible loss of data ..\test\bit_utils_test.cc(37): warning C4267: 'argument': conversion from 'size_t' to 'uint32_t', possible loss of data Most of them, with the exception of _open() -> _sopen_s() are about questionable implicit casts. Fixing the types and adding explicit casts to explicitly mark the intention (and silence the warnings in the process)
183 lines
6.1 KiB
C
183 lines
6.1 KiB
C
// Copyright 2017 Google Inc.
|
|
//
|
|
// 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 "internal/string_view.h"
|
|
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
|
|
int CpuFeatures_StringView_IndexOfChar(const StringView view, char c) {
|
|
if (view.ptr && view.size) {
|
|
const char* const found = (const char*)memchr(view.ptr, c, view.size);
|
|
if (found) {
|
|
return (int)(found - view.ptr);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int CpuFeatures_StringView_IndexOf(const StringView view,
|
|
const StringView sub_view) {
|
|
if (sub_view.size) {
|
|
StringView remainder = view;
|
|
while (remainder.size >= sub_view.size) {
|
|
const int found_index =
|
|
CpuFeatures_StringView_IndexOfChar(remainder, sub_view.ptr[0]);
|
|
if (found_index < 0) break;
|
|
remainder = CpuFeatures_StringView_PopFront(remainder, found_index);
|
|
if (CpuFeatures_StringView_StartsWith(remainder, sub_view)) {
|
|
return (int)(remainder.ptr - view.ptr);
|
|
}
|
|
remainder = CpuFeatures_StringView_PopFront(remainder, 1);
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
bool CpuFeatures_StringView_IsEquals(const StringView a, const StringView b) {
|
|
if (a.size == b.size) {
|
|
return a.ptr == b.ptr || memcmp(a.ptr, b.ptr, b.size) == 0;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CpuFeatures_StringView_StartsWith(const StringView a, const StringView b) {
|
|
return a.ptr && b.ptr && b.size && a.size >= b.size
|
|
? memcmp(a.ptr, b.ptr, b.size) == 0
|
|
: false;
|
|
}
|
|
|
|
StringView CpuFeatures_StringView_PopFront(const StringView str_view,
|
|
size_t count) {
|
|
if (count > str_view.size) {
|
|
return kEmptyStringView;
|
|
}
|
|
return view(str_view.ptr + count, str_view.size - count);
|
|
}
|
|
|
|
StringView CpuFeatures_StringView_PopBack(const StringView str_view,
|
|
size_t count) {
|
|
if (count > str_view.size) {
|
|
return kEmptyStringView;
|
|
}
|
|
return view(str_view.ptr, str_view.size - count);
|
|
}
|
|
|
|
StringView CpuFeatures_StringView_KeepFront(const StringView str_view,
|
|
size_t count) {
|
|
return count <= str_view.size ? view(str_view.ptr, count) : str_view;
|
|
}
|
|
|
|
char CpuFeatures_StringView_Front(const StringView view) {
|
|
assert(view.size);
|
|
assert(view.ptr);
|
|
return view.ptr[0];
|
|
}
|
|
|
|
char CpuFeatures_StringView_Back(const StringView view) {
|
|
assert(view.size);
|
|
return view.ptr[view.size - 1];
|
|
}
|
|
|
|
StringView CpuFeatures_StringView_TrimWhitespace(StringView view) {
|
|
while (view.size && isspace(CpuFeatures_StringView_Front(view)))
|
|
view = CpuFeatures_StringView_PopFront(view, 1);
|
|
while (view.size && isspace(CpuFeatures_StringView_Back(view)))
|
|
view = CpuFeatures_StringView_PopBack(view, 1);
|
|
return view;
|
|
}
|
|
|
|
static int HexValue(const char c) {
|
|
if (c >= '0' && c <= '9') return c - '0';
|
|
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
|
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
|
return -1;
|
|
}
|
|
|
|
// Returns -1 if view contains non digits.
|
|
static int ParsePositiveNumberWithBase(const StringView view, int base) {
|
|
int result = 0;
|
|
StringView remainder = view;
|
|
for (; remainder.size;
|
|
remainder = CpuFeatures_StringView_PopFront(remainder, 1)) {
|
|
const int value = HexValue(CpuFeatures_StringView_Front(remainder));
|
|
if (value < 0 || value >= base) return -1;
|
|
result = (result * base) + value;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int CpuFeatures_StringView_ParsePositiveNumber(const StringView view) {
|
|
if (view.size) {
|
|
const StringView hex_prefix = str("0x");
|
|
if (CpuFeatures_StringView_StartsWith(view, hex_prefix)) {
|
|
const StringView span_no_prefix =
|
|
CpuFeatures_StringView_PopFront(view, hex_prefix.size);
|
|
return ParsePositiveNumberWithBase(span_no_prefix, 16);
|
|
}
|
|
return ParsePositiveNumberWithBase(view, 10);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void CpuFeatures_StringView_CopyString(const StringView src, char* dst,
|
|
size_t dst_size) {
|
|
if (dst_size > 0) {
|
|
const size_t max_copy_size = dst_size - 1;
|
|
const size_t copy_size =
|
|
src.size > max_copy_size ? max_copy_size : src.size;
|
|
memcpy(dst, src.ptr, copy_size);
|
|
dst[copy_size] = '\0';
|
|
}
|
|
}
|
|
|
|
bool CpuFeatures_StringView_HasWord(const StringView line,
|
|
const char* const word_str) {
|
|
const StringView word = str(word_str);
|
|
StringView remainder = line;
|
|
for (;;) {
|
|
const int index_of_word = CpuFeatures_StringView_IndexOf(remainder, word);
|
|
if (index_of_word < 0) {
|
|
return false;
|
|
} else {
|
|
const StringView before =
|
|
CpuFeatures_StringView_KeepFront(line, index_of_word);
|
|
const StringView after =
|
|
CpuFeatures_StringView_PopFront(line, index_of_word + word.size);
|
|
const bool valid_before =
|
|
before.size == 0 || CpuFeatures_StringView_Back(before) == ' ';
|
|
const bool valid_after =
|
|
after.size == 0 || CpuFeatures_StringView_Front(after) == ' ';
|
|
if (valid_before && valid_after) return true;
|
|
remainder =
|
|
CpuFeatures_StringView_PopFront(remainder, index_of_word + word.size);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CpuFeatures_StringView_GetAttributeKeyValue(const StringView line,
|
|
StringView* key,
|
|
StringView* value) {
|
|
const StringView sep = str(": ");
|
|
const int index_of_separator = CpuFeatures_StringView_IndexOf(line, sep);
|
|
if (index_of_separator < 0) return false;
|
|
*value = CpuFeatures_StringView_TrimWhitespace(
|
|
CpuFeatures_StringView_PopFront(line, index_of_separator + sep.size));
|
|
*key = CpuFeatures_StringView_TrimWhitespace(
|
|
CpuFeatures_StringView_KeepFront(line, index_of_separator));
|
|
return true;
|
|
}
|