File: Util2.cpp

package info (click to toggle)
pymol 2.4.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 43,312 kB
  • sloc: cpp: 480,106; python: 79,860; ansic: 28,343; javascript: 6,792; sh: 47; makefile: 30; csh: 8
file content (120 lines) | stat: -rw-r--r-- 2,274 bytes parent folder | download
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
/*
 * Utility functions
 *
 * (c) 2015 Schrodinger, Inc.
 */

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

#include "Util2.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;
}

} // namespace pymol