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