GRASS 8 Programmer's Manual 8.6.0dev(2026)-1d1e47ad9d
Loading...
Searching...
No Matches
basename.c
Go to the documentation of this file.
1/*!
2 * \file lib/gis/basename.c
3 *
4 * \brief GIS Library - Program basename routines.
5 *
6 * (C) 2001-2014 by the GRASS Development Team
7 *
8 * This program is free software under the GNU General Public License
9 * (>=v2). Read the file COPYING that comes with GRASS for details.
10 *
11 * \author GRASS Development Team
12 */
13
14#include <grass/gis.h>
15
16#include <math.h>
17#include <stdio.h>
18#include <ctype.h>
19#include <string.h>
20#include <stdlib.h>
21
22/*!
23 * \brief Truncates filename to the base part (before the last '.')
24 * if it matches the extension, otherwise leaves it unchanged.
25 *
26 * Checks if a filename matches a certain file extension
27 * (case insensitive) and if so, truncates the string to the
28 * base file name (cf. basename Unix command)
29 *
30 * \param filename string containing filename
31 * \param desired_ext string containing extension to look for (case
32 * insensitive)
33 *
34 * \return pointer to filename
35 */
36char *G_basename(char *filename, const char *desired_ext)
37{
38 /* Find the last . in the filename */
39 char *dot = strrchr(filename, '.');
40
41 if (dot && G_strcasecmp(dot + 1, desired_ext) == 0)
42 *dot = '\0';
43
44 return filename;
45}
46
47/*!
48 * \brief Get number of decimals from a string
49 *
50 * \param str String to analyse
51 *
52 * \return number of decimals
53 */
54size_t G_get_num_decimals(const char *str)
55{
56 int sep = '.';
57 size_t len;
58 char *sep_ptr = strchr(str, sep);
59
60 if (sep_ptr == NULL)
61 return 0;
62 len = strlen(str);
63 return len - (size_t)(sep_ptr - str) - 1;
64}
65
66/*!
67 * \brief Convert a double to a string substituting the dot with underscore
68 * 12.3456 => '12_3456'
69 *
70 * \param number the double number that will be converted to string
71 * \param ndigits the number of integer digits in the output string
72 * \param ndecimals the number of decimals in the output string
73 *
74 * \return a formatted string
75 */
76char *G_double_to_basename_format(double number, size_t ndigits,
77 size_t ndecimals)
78{
79 double integer, decimal;
80
81 integer = floor(number);
82 char intfmt[GNAME_MAX] = "%d";
83 char intstr[GNAME_MAX];
84 char decfmt[GNAME_MAX] = "";
85 char decstr[GNAME_MAX] = "";
86 char *result;
87
88 if (ndigits != 0) {
89 snprintf(intfmt, sizeof(intfmt), "%%0%zud", ndigits);
90 }
91 snprintf(intstr, sizeof(intstr), intfmt, (int)integer);
92
93 if (ndecimals != 0) {
94 snprintf(decfmt, sizeof(decfmt), "_%%0%zud", ndecimals);
95 decimal = ((number - integer) * pow(10., (double)ndecimals));
96 snprintf(decstr, sizeof(decstr), decfmt, (int)decimal);
97 }
98 size_t len = strlen(intstr) + strlen(decstr) + 1;
99 result = G_malloc(len);
100 snprintf(result, len, "%s%s", intstr, decstr);
101 return result;
102}
103
104/*!
105 * \brief Return the environmental basename variable or the default
106 * value
107 *
108 * return pointer to basename separator
109 */
111{
112 char *envvar = "GRASS_BASENAME_SEPARATOR";
113 char *envsep;
114
116 return (envsep != NULL && strlen(envsep) > 0) ? envsep : GBASENAME_SEP;
117}
118
119/*!
120 * \brief join an array of strings using the basename separator
121 *
122 * \param strings is an array of strings
123 * \param len is the length of the array
124 *
125 * \return a joined string
126 */
127char *G_join_basename_strings(const char **strings, size_t len)
128{
129 size_t i, length, lensep;
130 char *result;
131 char *separator;
132
134
136 length = lensep * (len - 1) + 1;
137 for (i = 0; i < len; i++) {
138 length += strlen(strings[i]);
139 }
140 result = G_malloc(length);
141
142 if (result) {
143 strcpy(result, strings[0]);
144 for (i = 1; i < len; i++) {
145 strcat(result, separator);
146 strcat(result, strings[i]);
147 }
148 }
149
150 return result;
151}
152
153/*!
154 * \brief Generate the format string
155 *
156 * \param basename String with the basename
157 * \param number The double number that will be converted to string
158 * \param ndigits The number of integer digits in the output string
159 * \param ndecimals The number of decimals in the output string
160 *
161 * \return Format string
162 */
163char *G_generate_basename(const char *basename, double number, size_t ndigits,
164 size_t ndecimals)
165{
166 char *separator, *numberstr, *result;
167
170
171 size_t len = strlen(basename) + strlen(separator) + strlen(numberstr) + 1;
172 result = G_malloc(len);
173
174 if (result)
175 snprintf(result, len, "%s%s%s", basename, separator, numberstr);
176 return result;
177}
size_t G_get_num_decimals(const char *str)
Get number of decimals from a string.
Definition basename.c:54
char * G_generate_basename(const char *basename, double number, size_t ndigits, size_t ndecimals)
Generate the format string.
Definition basename.c:163
char * G_get_basename_separator(void)
Return the environmental basename variable or the default value.
Definition basename.c:110
char * G_double_to_basename_format(double number, size_t ndigits, size_t ndecimals)
Convert a double to a string substituting the dot with underscore 12.3456 => '12_3456'.
Definition basename.c:76
char * G_join_basename_strings(const char **strings, size_t len)
join an array of strings using the basename separator
Definition basename.c:127
char * G_basename(char *filename, const char *desired_ext)
Truncates filename to the base part (before the last '.') if it matches the extension,...
Definition basename.c:36
#define NULL
Definition ccmath.h:32
#define G_malloc(n)
Definition defs/gis.h:139
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
Definition strings.c:47
#define GNAME_MAX
Definition gis.h:196
#define GBASENAME_SEP
Definition gis.h:202
#define strcpy
Definition parson.c:66