File: Util2.cpp

package info (click to toggle)
pymol 3.1.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 74,084 kB
  • sloc: cpp: 482,660; python: 89,328; ansic: 29,512; javascript: 6,792; sh: 84; makefile: 25
file content (131 lines) | stat: -rw-r--r-- 2,628 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Utility functions
 *
 * (c) 2015 Schrodinger, Inc.
 */

#include <cstdio>
#include <cctype>
#include <cmath>
#include <sstream>
#include <string>
#include <vector>

#include "Util2.h"
#include "pymol/algorithm.h"

/**
 * strsplit: split string `s` by character `delim`
 *
 * If `delim` is null, then do whitespace split.
 */
std::vector<std::string> strsplit(const std::string &s, char delim) {
  std::vector<std::string> elems;
  std::istringstream iss(s);
  std::string item;

  if (delim) {
    // token split
    while (std::getline(iss, item, delim))
      elems.push_back(item);
  } else {
    // whitespace split
    while (iss >> item)
      elems.push_back(item);
  }

  return elems;
}

/**
 * Natural string compare: F1 < F2 < F10
 *
 * Return true if a < b
 */
bool cstrlessnat(const char * a, const char * b) {
  if (!b[0])
    return false;
  if (!a[0])
    return true;

  bool a_digit = isdigit(a[0]);
  bool b_digit = isdigit(b[0]);

  if (a_digit && !b_digit)
    return true;
  if (!a_digit && b_digit)
    return false;

  if (!a_digit && !b_digit) {
    if (a[0] != b[0])
      return (a[0] < b[0]);

    return cstrlessnat(a + 1, b + 1);
  }

  int ia, ib, na, nb;
  sscanf(a, "%d%n", &ia, &na);
  sscanf(b, "%d%n", &ib, &nb);

  if (ia != ib)
    return ia < ib;

  return cstrlessnat(a + na, b + nb);
}

/**
 * Natural string compare: F1 < F2 < F10
 */
bool strlessnat(const std::string& a, const std::string& b) {
  return cstrlessnat(a.c_str(), b.c_str());
}

/**
 * Return true if s starts with the specified prefix, false otherwise.
 */
bool p_strstartswith(const char * s, const char * prefix) {
  while (*prefix)
    if (*s++ != *prefix++)
      return false;
  return true;
}

/**
 * case-insensitive version of p_strstartswith
 */
bool p_strcasestartswith(const char * s, const char * prefix) {
  for (; *prefix; ++s, ++prefix)
    if (*s != *prefix && tolower(*s) != tolower(*prefix))
      return false;
  return true;
}

namespace pymol
{

/**
 * Convert float to double, rounded to decimal precision.
 */
double pretty_f2d(float f)
{
  if (f == 0.0f) {
    // don't call log10(0.0)
    return 0.0;
  }

  int digits = std::ceil(std::log10(std::fabs(f)));
  auto factor = std::pow(10.0L, 7 - digits);
  return std::round(f * factor) / factor;
}

bool string_equal_case(
    pymol::zstring_view str1, pymol::zstring_view str2, bool case_insensitive)
{
  return pymol::ranges::equal(str1, str2,
      [case_insensitive](char c1, char c2) {
        return case_insensitive ? std::tolower(c1) == std::tolower(c2)
                                : c1 == c2;
      });
}

} // namespace pymol