2 * Description: This module contains miscellaneous routines
3 * such as for debugging/logging and string functions.
15 #include <sys/types.h>
20 #include "connection.h"
21 #include "multibyte.h"
24 * returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied
25 * (not including null term)
28 my_strcpy(char *dst
, ssize_t dst_len
, const char *src
, ssize_t src_len
)
33 if (src_len
== SQL_NULL_DATA
)
37 } else if (src_len
== SQL_NTS
)
38 src_len
= strlen(src
);
44 if (src_len
< dst_len
)
46 memcpy(dst
, src
, src_len
);
50 memcpy(dst
, src
, dst_len
- 1);
51 dst
[dst_len
- 1] = '\0'; /* truncated */
52 return STRCPY_TRUNCATED
;
61 * strncpy copies up to len characters, and doesn't terminate
62 * the destination string if src has len characters or more.
63 * instead, I want it to copy up to len-1 characters and always
64 * terminate the destination string.
66 char *strncpy_null(char *dst
, const char *src
, ssize_t len
)
72 /* Just in case, check for special lengths */
73 if (len
== SQL_NULL_DATA
)
77 } else if (len
== SQL_NTS
)
78 len
= strlen(src
) + 1;
80 for (i
= 0; src
[i
] && i
< len
- 1; i
++)
91 * Create a null terminated string (handling the SQL_NTS thing):
92 * 1. If buf is supplied, place the string in there
93 * (assumes enough space) and return buf.
94 * 2. If buf is not supplied, malloc space and return this string
97 char *make_string(const unsigned char *_s
, ssize_t len
, char *buf
, size_t bufsize
)
100 const char *s
= (const char *)_s
;
103 if (!s
|| SQL_NULL_DATA
== len
)
107 else if (SQL_NTS
== len
)
111 mylog("make_string invalid length=%d\n", len
);
116 strncpy_null(buf
, s
, bufsize
> length
? length
+ 1 : bufsize
);
120 inolog("malloc size=%d\n", length
);
121 str
= (char *)malloc(length
+ 1);
122 inolog("str=%p\n", str
);
126 strncpy_null(str
, s
, length
+ 1);
131 * Create a null terminated lower-case string if the
132 * original string contains upper-case characters.
133 * The SQL_NTS length is considered.
136 char *make_lstring_ifneeded(ConnectionClass
* conn
, const void *_s
,
137 ssize_t len
, BOOL ifallupper
)
139 const char *s
= (const char *)_s
;
140 ssize_t length
= len
;
143 if (s
&& (len
> 0 || (len
== SQL_NTS
&& (length
= strlen(s
)) > 0)))
149 make_encoded_str(&encstr
, conn
, s
);
150 for (i
= 0, ptr
= s
; i
< length
; i
++, ptr
++)
152 encoded_nextchar(&encstr
);
153 if (ENCODE_STATUS(encstr
) != 0)
155 if (ifallupper
&& islower(*ptr
))
164 if (tolower(*ptr
) != *ptr
)
168 str
= (char *)malloc(length
+ 1);
169 memcpy(str
, s
, length
);
172 str
[i
] = tolower(*ptr
);
182 * Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing.
183 * "fmt" must contain somewhere in it the single form '%.*s'.
184 * This is heavily used in creating queries for info routines (SQLTables, SQLColumns).
185 * This routine could be modified to use vsprintf() to handle multiple arguments.
187 char *my_strcat(char *buf
, const char *fmt
, const char *s
, ssize_t len
)
189 if (s
&& (len
> 0 || (len
== SQL_NTS
&& strlen(s
) > 0)))
191 size_t length
= (len
> 0) ? len
: strlen(s
);
193 size_t pos
= strlen(buf
);
195 sprintf(&buf
[pos
], fmt
, length
, s
);
201 char *schema_strcat(char *buf
, const char *fmt
, const char *s
,
202 ssize_t len
, const char *tbname
, int tbnmlen
,
203 ConnectionClass
* conn
)
208 * Note that this driver assumes the implicit schema is
209 * the CURRENT_SCHEMA() though it doesn't worth the
212 if (conn
->schema_support
&& tbname
213 && (tbnmlen
> 0 || tbnmlen
== SQL_NTS
))
214 return my_strcat(buf
, fmt
, CC_get_current_schema(conn
),
218 return my_strcat(buf
, fmt
, s
, len
);
222 void remove_newlines(char *string
)
224 size_t i
, len
= strlen(string
);
226 for (i
= 0; i
< len
; i
++)
228 if ((PG_LINEFEED
== string
[i
]) ||
229 (PG_CARRIAGE_RETURN
== string
[i
]))
239 for (i
= strlen(s
) - 1; i
>= 0; i
--)
251 * my_strcat1 is a extension of my_strcat.
252 * It can have 1 more parameter than my_strcat.
254 char *my_strcat1(char *buf
, const char *fmt
, const char *s1
,
255 const char *s
, ssize_t len
)
257 ssize_t length
= len
;
259 if (s
&& (len
> 0 || (len
== SQL_NTS
&& (length
= strlen(s
)) > 0)))
261 size_t pos
= strlen(buf
);
264 sprintf(&buf
[pos
], fmt
, s1
, length
, s
);
266 sprintf(&buf
[pos
], fmt
, length
, s
);
272 char *schema_strcat1(char *buf
, const char *fmt
, const char *s1
,
273 const char *s
, ssize_t len
, const char *tbname
,
274 int tbnmlen
, ConnectionClass
* conn
)
278 if (conn
->schema_support
&& tbname
279 && (tbnmlen
> 0 || tbnmlen
== SQL_NTS
))
280 return my_strcat1(buf
, fmt
, s1
, CC_get_current_schema(conn
),
284 return my_strcat1(buf
, fmt
, s1
, s
, len
);
288 * snprintf_add is a extension to snprintf
289 * It add format to buf at given pos
292 int snprintf_add(char *buf
, size_t size
, const char *format
, ...)
295 size_t pos
= strlen(buf
);
298 va_start(arglist
, format
);
299 len
= vsnprintf(buf
+ pos
, size
- pos
, format
, arglist
);
305 * snprintf_addlen is a extension to snprintf
306 * It returns strlen of buf every time (not -1 when truncated)
309 size_t snprintf_len(char *buf
, size_t size
, const char *format
, ...)
314 va_start(arglist
, format
);
315 if ((len
= vsnprintf(buf
, size
, format
, arglist
)) < 0)