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