GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
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 GIS 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 convert 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 sprintf(intfmt, "%%0%zud", ndigits);
90 }
91 sprintf(intstr, intfmt, (int)integer);
92
93 if (ndecimals != 0) {
94 sprintf(decfmt, "_%%0%zud", ndecimals);
95 decimal = ((number - integer) * pow(10., (double)ndecimals));
96 sprintf(decstr, decfmt, (int)decimal);
97 }
98 result = G_malloc(strlen(intstr) + strlen(decstr) + 1);
99 sprintf(result, "%s%s", intstr, decstr);
100 return result;
101}
102
103/*!
104 * \brief Return the environmental basename variable or the default
105 * value
106 *
107 * return pointer to basename separator
108 */
110{
111 char *envvar = "GRASS_BASENAME_SEPARATOR";
112 char *envsep;
113
114 envsep = getenv(envvar);
115 return (envsep != NULL && strlen(envsep) > 0) ? envsep : GBASENAME_SEP;
116}
117
118/*!
119 * \brief join an array of strings using the basename separator
120 *
121 * \param strings is an array of strings
122 * \param len is the length of the array
123 *
124 * \return a joined string
125 */
126char *G_join_basename_strings(const char **strings, size_t len)
127{
128 size_t i, length, lensep;
129 char *result;
130 char *separator;
131
132 separator = G_get_basename_separator();
133
134 lensep = strlen(separator);
135 length = lensep * (len - 1) + 1;
136 for (i = 0; i < len; i++) {
137 length += strlen(strings[i]);
138 }
139 result = G_malloc(length);
140
141 if (result) {
142 strcpy(result, strings[0]);
143 for (i = 1; i < len; i++) {
144 strcat(result, separator);
145 strcat(result, strings[i]);
146 }
147 }
148
149 return result;
150}
151
152/*!
153 * \brief Generate the format string
154 *
155 * \param basename String with the basename
156 * \param digits Number of digits number
157 * \param decimals Number of decimal number
158 * \param filler String used to fill, default is 0
159 *
160 * \return Format string
161 */
162char *G_generate_basename(const char *basename, double number, size_t ndigits,
163 size_t ndecimals)
164{
165 char *separator, *numberstr, *result;
166
167 separator = G_get_basename_separator();
168 numberstr = G_double_to_basename_format(number, ndigits, ndecimals);
169
170 result =
171 G_malloc(strlen(basename) + strlen(separator) + strlen(numberstr) + 1);
172
173 if (result)
174 sprintf(result, "%s%s%s", basename, separator, numberstr);
175 return result;
176}
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:162
char * G_get_basename_separator(void)
Return the environmental basename variable or the default value.
Definition basename.c:109
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:126
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 strcpy
Definition parson.c:62
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition strings.c:47