This file is indexed.

/usr/include/GeographicLib/DMS.hpp is in libgeographic-dev 1.45-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
/**
 * \file DMS.hpp
 * \brief Header for GeographicLib::DMS class
 *
 * Copyright (c) Charles Karney (2008-2015) <charles@karney.com> and licensed
 * under the MIT/X11 License.  For more information, see
 * http://geographiclib.sourceforge.net/
 **********************************************************************/

#if !defined(GEOGRAPHICLIB_DMS_HPP)
#define GEOGRAPHICLIB_DMS_HPP 1

#include <GeographicLib/Constants.hpp>
#include <GeographicLib/Utility.hpp>

#if defined(_MSC_VER)
// Squelch warnings about dll vs vector and constant conditional expressions
#  pragma warning (push)
#  pragma warning (disable: 4251 4127)
#endif

namespace GeographicLib {

  /**
   * \brief Convert between degrees and the %DMS representation
   *
   * Parse a string representing degree, minutes, and seconds and return the
   * angle in degrees and format an angle in degrees as degree, minutes, and
   * seconds.  In addition, handle NANs and infinities on input and output.
   *
   * Example of use:
   * \include example-DMS.cpp
   **********************************************************************/
  class GEOGRAPHICLIB_EXPORT DMS {
  public:

    /**
     * Indicator for presence of hemisphere indicator (N/S/E/W) on latitudes
     * and longitudes.
     **********************************************************************/
    enum flag {
      /**
       * No indicator present.
       * @hideinitializer
       **********************************************************************/
      NONE = 0,
      /**
       * Latitude indicator (N/S) present.
       * @hideinitializer
       **********************************************************************/
      LATITUDE = 1,
      /**
       * Longitude indicator (E/W) present.
       * @hideinitializer
       **********************************************************************/
      LONGITUDE = 2,
      /**
       * Used in Encode to indicate output of an azimuth in [000, 360) with no
       * letter indicator.
       * @hideinitializer
       **********************************************************************/
      AZIMUTH = 3,
      /**
       * Used in Encode to indicate output of a plain number.
       * @hideinitializer
       **********************************************************************/
      NUMBER = 4,
    };

    /**
     * Indicator for trailing units on an angle.
     **********************************************************************/
    enum component {
      /**
       * Trailing unit is degrees.
       * @hideinitializer
       **********************************************************************/
      DEGREE = 0,
      /**
       * Trailing unit is arc minutes.
       * @hideinitializer
       **********************************************************************/
      MINUTE = 1,
      /**
       * Trailing unit is arc seconds.
       * @hideinitializer
       **********************************************************************/
      SECOND = 2,
    };

  private:
    typedef Math::real real;
    // Replace all occurrences of pat by c
    static void replace(std::string& s, const std::string& pat, char c) {
      std::string::size_type p = 0;
      while (true) {
        p = s.find(pat, p);
        if (p == std::string::npos)
          break;
        s.replace(p, pat.length(), 1, c);
      }
    }
    static const std::string hemispheres_;
    static const std::string signs_;
    static const std::string digits_;
    static const std::string dmsindicators_;
    static const std::string components_[3];
    static Math::real NumMatch(const std::string& s);
    static Math::real InternalDecode(const std::string& dmsa, flag& ind);
    DMS();                      // Disable constructor

  public:

    /**
     * Convert a string in DMS to an angle.
     *
     * @param[in] dms string input.
     * @param[out] ind a DMS::flag value signaling the presence of a
     *   hemisphere indicator.
     * @exception GeographicErr if \e dms is malformed (see below).
     * @return angle (degrees).
     *
     * Degrees, minutes, and seconds are indicated by the characters d, '
     * (single quote), &quot; (double quote), and these components may only be
     * given in this order.  Any (but not all) components may be omitted and
     * other symbols (e.g., the &deg; symbol for degrees and the unicode prime
     * and double prime symbols for minutes and seconds) may be substituted;
     * two single quotes can be used instead of &quot;.  The last component
     * indicator may be omitted and is assumed to be the next smallest unit
     * (thus 33d10 is interpreted as 33d10').  The final component may be a
     * decimal fraction but the non-final components must be integers.  Instead
     * of using d, ', and &quot; to indicate degrees, minutes, and seconds, :
     * (colon) may be used to <i>separate</i> these components (numbers must
     * appear before and after each colon); thus 50d30'10.3&quot; may be
     * written as 50:30:10.3, 5.5' may be written 0:5.5, and so on.  The
     * integer parts of the minutes and seconds components must be less
     * than 60.  A single leading sign is permitted.  A hemisphere designator
     * (N, E, W, S) may be added to the beginning or end of the string.  The
     * result is multiplied by the implied sign of the hemisphere designator
     * (negative for S and W).  In addition \e ind is set to DMS::LATITUDE if N
     * or S is present, to DMS::LONGITUDE if E or W is present, and to
     * DMS::NONE otherwise.  Throws an error on a malformed string.  No check
     * is performed on the range of the result.  Examples of legal and illegal
     * strings are
     * - <i>LEGAL</i> (all the entries on each line are equivalent)
     *   - -20.51125, 20d30'40.5&quot;S, -20&deg;30'40.5, -20d30.675,
     *     N-20d30'40.5&quot;, -20:30:40.5
     *   - 4d0'9, 4d9&quot;, 4d9'', 4:0:9, 004:00:09, 4.0025, 4.0025d, 4d0.15,
     *     04:.15
     *   - 4:59.99999999999999, 4:60.0, 4:59:59.9999999999999, 4:59:60.0, 5
     * - <i>ILLEGAL</i> (the exception thrown explains the problem)
     *   - 4d5&quot;4', 4::5, 4:5:, :4:5, 4d4.5'4&quot;, -N20.5, 1.8e2d, 4:60,
     *     4:59:60
     *
     * The decoding operation can also perform addition and subtraction
     * operations.  If the string includes <i>internal</i> signs (i.e., not at
     * the beginning nor immediately after an initial hemisphere designator),
     * then the string is split immediately before such signs and each piece is
     * decoded according to the above rules and the results added; thus
     * <code>S3-2.5+4.1N</code> is parsed as the sum of <code>S3</code>,
     * <code>-2.5</code>, <code>+4.1N</code>.  Any piece can include a
     * hemisphere designator; however, if multiple designators are given, they
     * must compatible; e.g., you cannot mix N and E.  In addition, the
     * designator can appear at the beginning or end of the first piece, but
     * must be at the end of all subsequent pieces (a hemisphere designator is
     * not allowed after the initial sign).  Examples of legal and illegal
     * combinations are
     * - <i>LEGAL</i> (these are all equivalent)
     *   - 070:00:45, 70:01:15W+0:0.5, 70:01:15W-0:0:30W, W70:01:15+0:0:30E
     * - <i>ILLEGAL</i> (the exception thrown explains the problem)
     *   - 70:01:15W+0:0:15N, W70:01:15+W0:0:15
     *
     * <b>WARNING:</b> "Exponential" notation is not recognized.  Thus
     * <code>7.0E1</code> is illegal, while <code>7.0E+1</code> is parsed as
     * <code>(7.0E) + (+1)</code>, yielding the same result as
     * <code>8.0E</code>.
     *
     * <b>NOTE:</b> At present, all the string handling in the C++
     * implementation %GeographicLib is with 8-bit characters.  The support for
     * unicode symbols for degrees, minutes, and seconds is therefore via the
     * <a href="https://en.wikipedia.org/wiki/UTF-8">UTF-8</a> encoding.  (The
     * JavaScript implementation of this class uses unicode natively, of
     * course.)
     *
     * Here is the list of Unicode symbols supported for degrees, minutes,
     * seconds, and the sign:
     * - degrees:
     *   - d, D lower and upper case letters
     *   - U+00b0 degree symbol (&deg;)
     *   - U+00ba masculine ordinal indicator
     *   - U+2070 superscript zero
     *   - U+02da ring above
     * - minutes:
     *   - ' apostrophe
     *   - U+2032 prime (&prime;)
     *   - U+00b4 acute accent
     *   - U+2019 right single quote (&rsquo;)
     * - seconds:
     *   - &quot; quotation mark
     *   - U+2033 double prime (&Prime;)
     *   - U+201d right double quote (&rdquo;)
     *   - '&nbsp;' any two consecutive symbols for minutes
     * - leading sign:
     *   - U+2212 minus sign (&minus;)
     * .
     * The codes with a leading zero byte, e.g., U+00b0, are accepted in their
     * UTF-8 coded form 0xc2 0xb0 and as a single byte 0xb0.
     **********************************************************************/
    static Math::real Decode(const std::string& dms, flag& ind);

    /**
     * Convert DMS to an angle.
     *
     * @param[in] d degrees.
     * @param[in] m arc minutes.
     * @param[in] s arc seconds.
     * @return angle (degrees)
     *
     * This does not propagate the sign on \e d to the other components,
     * so -3d20' would need to be represented as - DMS::Decode(3.0, 20.0) or
     * DMS::Decode(-3.0, -20.0).
     **********************************************************************/
    static Math::real Decode(real d, real m = 0, real s = 0)
    { return d + (m + s / 60) / 60; }

    /// \cond SKIP
    /**
     * <b>DEPRECATED</b> (use Utility::num, instead).
     * Convert a string to a real number.
     *
     * @param[in] str string input.
     * @exception GeographicErr if \e str is malformed.
     * @return decoded number.
     **********************************************************************/
    static Math::real Decode(const std::string& str)
    { return Utility::num<real>(str); }

    /**
     * <b>DEPRECATED</b> (use Utility::fract, instead).
     * Convert a string to a real number treating the case where the string is
     * a simple fraction.
     *
     * @param[in] str string input.
     * @exception GeographicErr if \e str is malformed.
     * @return decoded number.
     **********************************************************************/
    static Math::real DecodeFraction(const std::string& str)
    { return Utility::fract<real>(str); }
    /// \endcond

    /**
     * Convert a pair of strings to latitude and longitude.
     *
     * @param[in] dmsa first string.
     * @param[in] dmsb second string.
     * @param[out] lat latitude (degrees).
     * @param[out] lon longitude (degrees).
     * @param[in] longfirst if true assume longitude is given before latitude
     *   in the absence of hemisphere designators (default false).
     * @exception GeographicErr if \e dmsa or \e dmsb is malformed.
     * @exception GeographicErr if \e dmsa and \e dmsb are both interpreted as
     *   latitudes.
     * @exception GeographicErr if \e dmsa and \e dmsb are both interpreted as
     *   longitudes.
     * @exception GeographicErr if decoded latitude is not in [&minus;90&deg;,
     *   90&deg;].
     *
     * By default, the \e lat (resp., \e lon) is assigned to the results of
     * decoding \e dmsa (resp., \e dmsb).  However this is overridden if either
     * \e dmsa or \e dmsb contain a latitude or longitude hemisphere designator
     * (N, S, E, W).  If an exception is thrown, \e lat and \e lon are
     * unchanged.
     **********************************************************************/
    static void DecodeLatLon(const std::string& dmsa, const std::string& dmsb,
                             real& lat, real& lon,
                             bool longfirst = false);

    /**
     * Convert a string to an angle in degrees.
     *
     * @param[in] angstr input string.
     * @exception GeographicErr if \e angstr is malformed.
     * @exception GeographicErr if \e angstr includes a hemisphere designator.
     * @return angle (degrees)
     *
     * No hemisphere designator is allowed and no check is done on the range of
     * the result.
     **********************************************************************/
    static Math::real DecodeAngle(const std::string& angstr);

    /**
     * Convert a string to an azimuth in degrees.
     *
     * @param[in] azistr input string.
     * @exception GeographicErr if \e azistr is malformed.
     * @exception GeographicErr if \e azistr includes a N/S designator.
     * @return azimuth (degrees) reduced to the range [&minus;180&deg;,
     *   180&deg;).
     *
     * A hemisphere designator E/W can be used; the result is multiplied by
     * &minus;1 if W is present.
     **********************************************************************/
    static Math::real DecodeAzimuth(const std::string& azistr);

    /**
     * Convert angle (in degrees) into a DMS string (using d, ', and &quot;).
     *
     * @param[in] angle input angle (degrees)
     * @param[in] trailing DMS::component value indicating the trailing units
     *   of the string (this component is given as a decimal number if
     *   necessary).
     * @param[in] prec the number of digits after the decimal point for the
     *   trailing component.
     * @param[in] ind DMS::flag value indicating additional formatting.
     * @param[in] dmssep if non-null, use as the DMS separator character
     *   (instead of d, ', &quot; delimiters).
     * @exception std::bad_alloc if memory for the string can't be allocated.
     * @return formatted string
     *
     * The interpretation of \e ind is as follows:
     * - ind == DMS::NONE, signed result no leading zeros on degrees except in
     *   the units place, e.g., -8d03'.
     * - ind == DMS::LATITUDE, trailing N or S hemisphere designator, no sign,
     *   pad degrees to 2 digits, e.g., 08d03'S.
     * - ind == DMS::LONGITUDE, trailing E or W hemisphere designator, no
     *   sign, pad degrees to 3 digits, e.g., 008d03'W.
     * - ind == DMS::AZIMUTH, convert to the range [0, 360&deg;), no
     *   sign, pad degrees to 3 digits, e.g., 351d57'.
     * .
     * The integer parts of the minutes and seconds components are always given
     * with 2 digits.
     **********************************************************************/
    static std::string Encode(real angle, component trailing, unsigned prec,
                              flag ind = NONE, char dmssep = char(0));

    /**
     * Convert angle into a DMS string (using d, ', and &quot;) selecting the
     * trailing component based on the precision.
     *
     * @param[in] angle input angle (degrees)
     * @param[in] prec the precision relative to 1 degree.
     * @param[in] ind DMS::flag value indicated additional formatting.
     * @param[in] dmssep if non-null, use as the DMS separator character
     *   (instead of d, ', &quot; delimiters).
     * @exception std::bad_alloc if memory for the string can't be allocated.
     * @return formatted string
     *
     * \e prec indicates the precision relative to 1 degree, e.g., \e prec = 3
     * gives a result accurate to 0.1' and \e prec = 4 gives a result accurate
     * to 1&quot;.  \e ind is interpreted as in DMS::Encode with the additional
     * facility that DMS::NUMBER represents \e angle as a number in fixed
     * format with precision \e prec.
     **********************************************************************/
    static std::string Encode(real angle, unsigned prec, flag ind = NONE,
                              char dmssep = char(0)) {
      return ind == NUMBER ? Utility::str(angle, int(prec)) :
        Encode(angle,
               prec < 2 ? DEGREE : (prec < 4 ? MINUTE : SECOND),
               prec < 2 ? prec : (prec < 4 ? prec - 2 : prec - 4),
               ind, dmssep);
    }

    /**
     * Split angle into degrees and minutes
     *
     * @param[in] ang angle (degrees)
     * @param[out] d degrees (an integer returned as a real)
     * @param[out] m arc minutes.
     **********************************************************************/
    static void Encode(real ang, real& d, real& m) {
      d = int(ang); m = 60 * (ang - d);
    }

    /**
     * Split angle into degrees and minutes and seconds.
     *
     * @param[in] ang angle (degrees)
     * @param[out] d degrees (an integer returned as a real)
     * @param[out] m arc minutes (an integer returned as a real)
     * @param[out] s arc seconds.
     **********************************************************************/
    static void Encode(real ang, real& d, real& m, real& s) {
      d = int(ang); ang = 60 * (ang - d);
      m = int(ang); s = 60 * (ang - m);
    }

  };

} // namespace GeographicLib

#if defined(_MSC_VER)
#  pragma warning (pop)
#endif

#endif  // GEOGRAPHICLIB_DMS_HPP