GRASS 8 Programmer's Manual  8.5.0dev(2025)-c070206eb1
legal_vname.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/legal_vname.c
3 
4  \brief Vector library - Check if map name is legal vector map name
5 
6  (C) 2001-2009 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 Radim Blazek
12  */
13 
14 #include <string.h>
15 #include <grass/vector.h>
16 #include <grass/glocale.h>
17 
18 /*!
19  \brief Check if output is legal vector name.
20 
21  Rule: [A-Za-z][A-Za-z0-9_]*
22 
23  Check also for SQL keywords.
24 
25  \param s filename to be checked
26 
27  \return 1 OK
28  \return -1 if name does not start with letter A..Za..z or if name does not
29  continue with A..Za..z0..9_
30  */
31 int Vect_legal_filename(const char *s)
32 {
33  /* full list of SQL keywords available at
34  https://www.postgresql.org/docs/8.2/static/sql-keywords-appendix.html
35  */
36  static const char *keywords[] = {"and", "or", "not", NULL};
37  char buf[GNAME_MAX];
38  int i;
39 
40  snprintf(buf, sizeof(buf), "%s", s);
41 
42  if (*s == '.' || *s == 0) {
43  G_warning(
44  _("Illegal vector map name <%s>. May not contain '.' or 'NULL'."),
45  buf);
46  return -1;
47  }
48 
49  /* file name must start with letter */
50  if (!((*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z'))) {
51  G_warning(_("Illegal vector map name <%s>. Must start with a letter."),
52  buf);
53  return -1;
54  }
55 
56  for (s++; *s; s++)
57  if (!((*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z') ||
58  (*s >= '0' && *s <= '9') || *s == '_')) {
59  G_warning(
60  _("Illegal vector map name <%s>. Character '%c' not allowed."),
61  buf, *s);
62  return -1;
63  }
64 
65  for (i = 0; keywords[i]; i++)
66  if (G_strcasecmp(buf, keywords[i]) == 0) {
67  G_warning(_("Illegal vector map name <%s>. SQL keyword cannot be "
68  "used as vector map name."),
69  buf);
70  return -1;
71  }
72 
73  return 1;
74 }
75 
76 /*!
77  \brief Check for input and output vector map name.
78 
79  Check
80  - output is legal vector name
81  - if can find input map
82  - if input was found in current mapset, check if input != output
83 
84  \param input input name
85  \param output output name
86  \param error error type G_FATAL_EXIT, G_FATAL_PRINT, G_FATAL_RETURN
87 
88  \return 0 OK
89  \return 1 error
90  */
91 int Vect_check_input_output_name(const char *input, const char *output,
92  int error)
93 {
94  const char *mapset;
95  char inm[GNAME_MAX], ims[GMAPSET_MAX];
96  char onm[GNAME_MAX], oms[GMAPSET_MAX];
97 
98  /* check for fully-qualified map name */
99  if (G_name_is_fully_qualified(output, onm, oms)) {
100  if (strcmp(oms, G_mapset()) != 0) {
101  if (error == G_FATAL_EXIT) {
102  G_fatal_error(_("Output vector map name <%s> is not in the "
103  "current mapset (%s)"),
104  output, G_mapset());
105  }
106  else if (error == G_FATAL_PRINT) {
107  G_warning(_("Output vector map name <%s> is not in the current "
108  "mapset (%s)"),
109  output, G_mapset());
110  return 1;
111  }
112  else { /* GV_FATAL_RETURN */
113  return 1;
114  }
115  }
116  output = onm;
117  }
118 
119  if (Vect_legal_filename(output) == -1) {
120  if (error == G_FATAL_EXIT) {
121  G_fatal_error(_("Output vector map name <%s> is not SQL compliant"),
122  output);
123  }
124  else if (error == G_FATAL_PRINT) {
125  G_warning(_("Output vector map name <%s> is not SQL compliant"),
126  output);
127  return 1;
128  }
129  else { /* GV_FATAL_RETURN */
130  return 1;
131  }
132  }
133 
134  if (G_name_is_fully_qualified(input, inm, ims)) {
135  if (strcasecmp(ims, "ogr") != 0)
136  mapset = G_find_vector2(input, "");
137  else
138  mapset = ims;
139  }
140  else
141  mapset = G_find_vector2(input, "");
142 
143  if (mapset == NULL) {
144  if (error == G_FATAL_EXIT) {
145  G_fatal_error(_("Vector map <%s> not found"), input);
146  }
147  else if (error == G_FATAL_PRINT) {
148  G_warning(_("Vector map <%s> not found"), input);
149  return 1;
150  }
151  else { /* GV_FATAL_RETURN */
152  return 1;
153  }
154  }
155 
156  if (strcmp(mapset, G_mapset()) == 0) {
157  if (G_name_is_fully_qualified(input, inm, ims)) {
158  input = inm;
159  }
160 
161  if (strcmp(input, output) == 0) {
162  if (error == G_FATAL_EXIT) {
163  G_fatal_error(_("Output vector map <%s> is used as input"),
164  output);
165  }
166  else if (error == G_FATAL_PRINT) {
167  G_warning(_("Output vector map <%s> is used as input"), output);
168  return 1;
169  }
170  else { /* GV_FATAL_RETURN */
171  return 1;
172  }
173  }
174  }
175 
176  return 0;
177 }
#define NULL
Definition: ccmath.h:32
int G_name_is_fully_qualified(const char *, char *, char *)
Check if map name is fully qualified (map @ mapset)
Definition: nme_in_mps.c:36
const char * G_find_vector2(const char *, const char *)
Find a vector map (look but don't touch)
Definition: find_vect.c:62
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
const char * G_mapset(void)
Get current mapset name.
Definition: gis/mapset.c:33
int int G_strcasecmp(const char *, const char *)
String compare ignoring case (upper or lower)
Definition: strings.c:47
#define G_FATAL_PRINT
Definition: gis.h:411
#define GMAPSET_MAX
Definition: gis.h:197
#define G_FATAL_EXIT
Definition: gis.h:410
#define GNAME_MAX
Definition: gis.h:196
#define _(str)
Definition: glocale.h:10
int Vect_check_input_output_name(const char *input, const char *output, int error)
Check for input and output vector map name.
Definition: legal_vname.c:91
int Vect_legal_filename(const char *s)
Check if output is legal vector name.
Definition: legal_vname.c:31
void output(const char *fmt,...)
#define strcasecmp
Definition: strings.h:8