summaryrefslogtreecommitdiffstats
path: root/lib/qpath.h
blob: 697e4d089925bde53852311157b151e9400dec09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/* Some primitive path handling -- header
 * Copyright (C) 2009 Chris Hall (GMCH), Highwayman
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2, or (at your
 * option) any later version.
 *
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#ifndef _ZEBRA_QPATH_H
#define _ZEBRA_QPATH_H

#include "misc.h"
#include "qstring.h"
#include "memory.h"
#include "sys/stat.h"

/*==============================================================================
 * For these purposes a path is "parts" separated by one more '/' characters.
 *
 * As per POSIX, a pair of leading "//" (not three or more leading '/') is
 * very special.
 *
 * The following sexes of qpath are established after any "path reduction"
 * has been done.  Path reduction removes extraneous '/'.
 */

typedef enum qpath_sex qpath_sex_t ;

enum qpath_sex
{
  qp_empty,             /* nothing at all                       */
  qp_relative,          /* something, not starting '/'          */
  qp_root,              /* "/" all on its own                   */
  qp_absolute,          /* something, starting with single '/'  */
  qp_homed,             /* something, starting with '~'         */
  qp_double_root,       /* "//" all on its own                  */
  qp_double_absolute    /* something, starting with "//"        */
} ;

/* The qpath structure is largely a qstring, but one in which there is always
 * a body, even if it only contains "\0", and the len is kept up to date.
 */
struct qpath
{
  qstring_t     path ;          /* Embedded     */
} ;

typedef struct qpath  qpath_t[1] ;
typedef struct qpath* qpath ;

/*==============================================================================
 * Functions
 */

extern qpath qpath_init_new(qpath qp) ;
extern qpath qpath_reset(qpath qp, free_keep_b free_structure) ;
extern qpath qpath_clear(qpath qp) ;

Inline qpath qpath_new(void) ;
Inline qpath qpath_free(qpath qp) ;

Inline const char* qpath_string(qpath qp) ;
Inline char* qpath_char_string(qpath qp) ;
Inline char* qpath_char(qpath qp) ;
Inline ulen qpath_len(qpath qp) ;
Inline qstring qpath_qs(qpath qp) ;

extern qpath qpath_set(qpath dst, const char* src) ;
extern qpath qpath_set_n(qpath dst, const char* src, ulen n) ;
extern qpath qpath_set_qs(qpath dst, const qstring src) ;
extern qpath qpath_copy(qpath dst, const qpath src) ;
Inline qpath qpath_dup(const qpath qp) ;
Inline qpath qpath_dup_str(const char* src) ;

extern qpath qpath_getcwd(qpath dst) ;
extern qpath qpath_get_home(qpath qp, const char* name) ;
extern int qpath_setcwd(qpath dst) ;
extern int qpath_stat(qpath qp, struct stat* stat) ;
extern int qpath_stat_is_file(qpath qp) ;
extern int qpath_stat_is_directory(qpath qp) ;

extern qpath qpath_shave(qpath qp) ;
extern bool qpath_has_trailing_slash(qpath qp) ;

extern qpath qpath_append(qpath dst, const qpath src) ;
extern qpath qpath_append_qs(qpath dst, const qstring src) ;
extern qpath qpath_append_str(qpath dst, const char* src) ;
extern qpath qpath_append_str_n(qpath dst, const char* src, ulen n) ;

extern qpath qpath_extend(qpath dst, const qpath src) ;
extern qpath qpath_extend_qs(qpath dst, const qstring src) ;
extern qpath qpath_extend_str(qpath dst, const char* src) ;
extern qpath qpath_extend_str_n(qpath dst, const char* src, ulen n) ;

extern qpath qpath_prepend(qpath dst, const qpath src) ;
extern qpath qpath_prepend_qs(qpath dst, const qstring src) ;
extern qpath qpath_prepend_str(qpath dst, const char* src) ;
extern qpath qpath_prepend_str_n(qpath dst, const char* src, ulen n) ;

extern qpath qpath_make(const char* src, const qpath dir) ;

extern qpath qpath_complete(qpath dst, const qpath src) ;
extern qpath qpath_complete_qs(qpath dst, const qstring src) ;
extern qpath qpath_complete_str(qpath dst, const char* src) ;
extern qpath qpath_complete_str_n(qpath dst, const char* src, ulen n) ;

/*==============================================================================
 * Inline stuff
 */

/*------------------------------------------------------------------------------
 * Create new qpath.
 */
Inline qpath
qpath_new(void)
{
  return qpath_init_new(NULL) ;
} ;

/*------------------------------------------------------------------------------
 * Free qpath.
 */
Inline qpath
qpath_free(qpath qp)
{
  return qpath_reset(qp, free_it) ;
} ;

/*------------------------------------------------------------------------------
 * Duplicate qpath -- result will need to be freed.
 */
Inline qpath
qpath_dup(const qpath qp)
{
  return qpath_copy(NULL, qp) ;
} ;

/*------------------------------------------------------------------------------
 * Duplicate string as a qpath -- result will need to be freed.
 */
Inline qpath
qpath_dup_str(const char* src)
{
  return qpath_set(NULL, src) ;
} ;

/*------------------------------------------------------------------------------
 * Get *temporary* pointer to actual path contained in the given qpath.
 *
 * This is *temporary* to the extent that when the qpath is changed or freed,
 * this pointer will be INVALID -- you have been warned.
 *
 * This is a *const* pointer.
 *
 * For a NULL qpath, or an empty qpath, returns pointer to an empty string
 * ('\0' terminated "").
 */
Inline const char*
qpath_string(qpath qp)
{
  return (qp != NULL) ? qs_make_string(qp->path) : "" ;
} ;

/*------------------------------------------------------------------------------
 * Get *temporary* pointer to actual path contained in the given qpath.
 *
 * This is *temporary* to the extent that when the qpath is changed or freed,
 * this pointer will be INVALID -- you have been warned.
 *
 * For a NULL qpath, or an empty qpath, returns pointer to an empty string
 * ('\0' terminated "").
 */
Inline char*
qpath_char_string(qpath qp)
{
  static char empty[] = "" ;
  return (qp != NULL) ? qs_make_string(qp->path) : empty ;
} ;

/*------------------------------------------------------------------------------
 * Get *temporary* address of the path in given qpath -- NULL if NULL
 *
 * This is *temporary* to the extent that when the qpath is changed or freed,
 * this pointer will be INVALID -- you have been warned.
 *
 * NB: the path is not guaranteed to be '\0' terminated.
 */
Inline char*
qpath_char(qpath qp)
{
  return (qp != NULL) ? qs_char_nn(qp->path) : 0 ;
} ;

/*------------------------------------------------------------------------------
 * Get length of the given qpath -- zero if NULL
 */
Inline ulen
qpath_len(qpath qp)
{
  return (qp != NULL) ? qs_len_nn(qp->path) : 0 ;
} ;

/*------------------------------------------------------------------------------
 * Get *temporary* pointer to qstring rendering of the given path.
 *
 * This is *temporary* to the extent that when the qpath is changed or freed,
 * this pointer will be INVALID -- you have been warned.
 *
 * This is a *const* pointer.
 *
 * For a NULL qpath returns NULL qstring.
 */
Inline qstring
qpath_qs(qpath qp)
{
  return (qp != NULL) ? qp->path : NULL ;
} ;

#endif /* _ZEBRA_QPATH_H */