case 0:
VLOG_ABORT("%s: assertion %s failed in %s()",
where, condition, function);
- NOT_REACHED();
+ OVS_NOT_REACHED();
case 1:
fprintf(stderr, "%s: assertion %s failed in %s()",
set_program_name__(const char *argv0, const char *version, const char *date,
const char *time)
{
- const char *slash = strrchr(argv0, '/');
+#ifdef _WIN32
+ char *basename;
+ size_t max_len = strlen(argv0) + 1;
+ if (program_name) {
+ return;
+ }
+ basename = xmalloc(max_len);
+ _splitpath_s(argv0, NULL, 0, NULL, 0, basename, max_len, NULL, 0);
+ assert_single_threaded();
+ program_name = basename;
+#else
+ const char *slash = strrchr(argv0, '/');
assert_single_threaded();
-
program_name = slash ? slash + 1 : argv0;
+#endif
free(program_version);
}
}
-bool
-str_to_uint(const char *s, int base, unsigned int *u)
-{
- return str_to_int(s, base, (int *) u);
-}
-
-bool
-str_to_ulong(const char *s, int base, unsigned long *ul)
-{
- return str_to_long(s, base, (long *) ul);
-}
-
-bool
-str_to_ullong(const char *s, int base, unsigned long long *ull)
-{
- return str_to_llong(s, base, (long long *) ull);
-}
-
/* Converts floating-point string 's' into a double. If successful, stores
* the double in '*d' and returns true; on failure, stores 0 in '*d' and
* returns false.
: " and ");
}
-/* Given a 32 bit word 'n', calculates floor(log_2('n')). This is equivalent
- * to finding the bit position of the most significant one bit in 'n'. It is
- * an error to call this function with 'n' == 0. */
-int
-log_2_floor(uint32_t n)
-{
- ovs_assert(n);
-
-#if !defined(UINT_MAX) || !defined(UINT32_MAX)
-#error "Someone screwed up the #includes."
-#elif __GNUC__ >= 4 && UINT_MAX == UINT32_MAX
- return 31 - __builtin_clz(n);
-#else
- {
- int log = 0;
-
-#define BIN_SEARCH_STEP(BITS) \
- if (n >= (1 << BITS)) { \
- log += BITS; \
- n >>= BITS; \
- }
- BIN_SEARCH_STEP(16);
- BIN_SEARCH_STEP(8);
- BIN_SEARCH_STEP(4);
- BIN_SEARCH_STEP(2);
- BIN_SEARCH_STEP(1);
-#undef BIN_SEARCH_STEP
- return log;
- }
-#endif
-}
-
-/* Given a 32 bit word 'n', calculates ceil(log_2('n')). It is an error to
- * call this function with 'n' == 0. */
-int
-log_2_ceil(uint32_t n)
-{
- return log_2_floor(n) + !is_pow2(n);
-}
-
/* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. */
#if __GNUC__ >= 4
/* Defined inline in util.h. */
#else
+/* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. */
int
raw_ctz(uint64_t n)
{
return count;
}
-#endif
-/* Returns the number of 1-bits in 'x', between 0 and 32 inclusive. */
-static unsigned int
-count_1bits_32(uint32_t x)
+/* Returns the number of leading 0-bits in 'n'. Undefined if 'n' == 0. */
+int
+raw_clz64(uint64_t n)
{
- /* In my testing, this implementation is over twice as fast as any other
- * portable implementation that I tried, including GCC 4.4
- * __builtin_popcount(), although nonportable asm("popcnt") was over 50%
- * faster. */
+ uint64_t k;
+ int count = 63;
+
+#define CLZ_STEP(X) \
+ k = n >> (X); \
+ if (k) { \
+ count -= X; \
+ n = k; \
+ }
+ CLZ_STEP(32);
+ CLZ_STEP(16);
+ CLZ_STEP(8);
+ CLZ_STEP(4);
+ CLZ_STEP(2);
+ CLZ_STEP(1);
+#undef CLZ_STEP
+
+ return count;
+}
+#endif
+
+#if NEED_COUNT_1BITS_8
#define INIT1(X) \
((((X) & (1 << 0)) != 0) + \
(((X) & (1 << 1)) != 0) + \
#define INIT32(X) INIT16(X), INIT16((X) + 16)
#define INIT64(X) INIT32(X), INIT32((X) + 32)
- static const uint8_t count_1bits_8[256] = {
- INIT64(0), INIT64(64), INIT64(128), INIT64(192)
- };
-
- return (count_1bits_8[x & 0xff] +
- count_1bits_8[(x >> 8) & 0xff] +
- count_1bits_8[(x >> 16) & 0xff] +
- count_1bits_8[x >> 24]);
-}
-
-/* Returns the number of 1-bits in 'x', between 0 and 64 inclusive. */
-unsigned int
-count_1bits(uint64_t x)
-{
- return count_1bits_32(x) + count_1bits_32(x >> 32);
-}
+const uint8_t count_1bits_8[256] = {
+ INIT64(0), INIT64(64), INIT64(128), INIT64(192)
+};
+#endif
/* Returns true if the 'n' bytes starting at 'p' are zeros. */
bool
case SCAN_INTMAX_T:
case SCAN_PTRDIFF_T:
case SCAN_SIZE_T:
- NOT_REACHED();
+ OVS_NOT_REACHED();
}
return s;
}
/* This is an implementation of the standard sscanf() function, with the
* following exceptions:
*
- * - It returns true if the entire template was successfully scanned and
+ * - It returns true if the entire format was successfully scanned and
* converted, false if any conversion failed.
*
* - The standard doesn't define sscanf() behavior when an out-of-range value
* - %p is not supported.
*/
bool
-ovs_scan(const char *s, const char *template, ...)
+ovs_scan(const char *s, const char *format, ...)
{
const char *const start = s;
bool ok = false;
const char *p;
va_list args;
- va_start(args, template);
- p = template;
+ va_start(args, format);
+ p = format;
while (*p != '\0') {
struct scan_spec spec;
unsigned char c = *p++;
return ok;
}
+#ifdef _WIN32
+\f
+/* Calls FormatMessage() with GetLastError() as an argument. Returns
+ * pointer to a buffer that receives the null-terminated string that specifies
+ * the formatted message and that has to be freed by the caller with
+ * LocalFree(). */
+char *
+ovs_lasterror_to_string(void)
+{
+ char *buffer;
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0,
+ (char *)&buffer, 0, NULL);
+ return buffer;
+}
+#endif