ruby-pg 0.7.9.2008.01.28 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/LICENSE DELETED
@@ -1,58 +0,0 @@
1
- Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.co.jp>.
2
- You can redistribute it and/or modify it under either the terms of the GPL
3
- (see COPYING.txt file), or the conditions below:
4
-
5
- 1. You may make and give away verbatim copies of the source form of the
6
- software without restriction, provided that you duplicate all of the
7
- original copyright notices and associated disclaimers.
8
-
9
- 2. You may modify your copy of the software in any way, provided that
10
- you do at least ONE of the following:
11
-
12
- a) place your modifications in the Public Domain or otherwise
13
- make them Freely Available, such as by posting said
14
- modifications to Usenet or an equivalent medium, or by allowing
15
- the author to include your modifications in the software.
16
-
17
- b) use the modified software only within your corporation or
18
- organization.
19
-
20
- c) rename any non-standard executables so the names do not conflict
21
- with standard executables, which must also be provided.
22
-
23
- d) make other distribution arrangements with the author.
24
-
25
- 3. You may distribute the software in object code or executable
26
- form, provided that you do at least ONE of the following:
27
-
28
- a) distribute the executables and library files of the software,
29
- together with instructions (in the manual page or equivalent)
30
- on where to get the original distribution.
31
-
32
- b) accompany the distribution with the machine-readable source of
33
- the software.
34
-
35
- c) give non-standard executables non-standard names, with
36
- instructions on where to get the original software distribution.
37
-
38
- d) make other distribution arrangements with the author.
39
-
40
- 4. You may modify and include the part of the software into any other
41
- software (possibly commercial). But some files in the distribution
42
- are not written by the author, so that they are not under this terms.
43
-
44
- They are gc.c(partly), utils.c(partly), regex.[ch], st.[ch] and some
45
- files under the ./missing directory. See each file for the copying
46
- condition.
47
-
48
- 5. The scripts and library files supplied as input to or produced as
49
- output from the software do not automatically fall under the
50
- copyright of the software, but belong to whomever generated them,
51
- and may be sold commercially, and may be aggregated with this
52
- software.
53
-
54
- 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
55
- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
56
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57
- PURPOSE.
58
-
data/README DELETED
@@ -1,125 +0,0 @@
1
- ================================================================================
2
- ruby-pg: Ruby interface to PostgreSQL RDBMS
3
- ================================================================================
4
-
5
- This library is copyrighted by the authors.
6
-
7
- Authors:
8
- * Yukihiro Matsumoto <matz@ruby-lang.org>
9
- Author of Ruby.
10
- * Eiji Matsumoto <usagi@ruby.club.or.jp>
11
- One of users who loves Ruby.
12
- * Jeff Davis <ruby-pg@j-davis.com>
13
-
14
- Thanks to:
15
- * Noboru Saitou <noborus@netlab.jp>
16
- Past maintainer.
17
- * Dave Lee
18
- Past maintainer.
19
- * Guy Decoux ts <decoux@moulon.inra.fr>
20
-
21
- Maintainer:
22
- Jeff Davis <ruby-pg@j-davis.com>
23
-
24
- Copying:
25
- You may redistribute this software under the terms of the GPL,
26
- included in the file named GPL; or under the same terms as Ruby,
27
- included in the file name LICENSE.
28
-
29
- - Summary
30
-
31
- This is the extension library to access a PostgreSQL database from Ruby.
32
- This library works with PostgreSQL 7.4 and later.
33
-
34
- - Requirements
35
-
36
- Ruby 1.8 or later.
37
- PostgreSQL 7.4 or later installed.
38
-
39
- It may work with earlier versions as well, but those are
40
- not regularly tested.
41
-
42
- - How to install ?
43
-
44
- Follow the instructions below to compile and install:
45
-
46
- ruby extconf.rb
47
- make
48
- su (if necessary)
49
- make install
50
-
51
- You may need to specify the directory name for the include files and the
52
- -lpq library by using
53
-
54
- --with-pgsql-include=<include file directory>
55
- --with-pgsql-lib=<library directory>
56
-
57
- For example:
58
-
59
- ruby extconf.rb --with-pgsql-include=/usr/local/pgsql/include \
60
- --with-pgsql-lib=/usr/local/pgsql/lib
61
-
62
- - Modules
63
-
64
- 'pg': The 'pg' module is the newer module, that has been greatly improved, and
65
- is almost a complete rewrite. It is not backwards compatible. Use this module
66
- for newly written code. It should be more stable, less buggy, and has more
67
- features.
68
-
69
- 'postgres': Older module, maintained for backwards compatibility. It
70
- has known flaws that aren't reasonably fixable without breaking backwards
71
- compatibility. Use this module if you have code that already works, and
72
- you just want the fixes that I've committed to this module (for instance,
73
- this module is compatible with PostgreSQL 8.3).
74
-
75
- - How to use ?
76
-
77
- This gem builds and installs two PostgreSQL database adapters, 'postgres'
78
- and 'pg'. 'postgres' is currently (Jan 2008) the recommended PostgreSQL
79
- adapter for use with Rails.
80
-
81
- The standard way to download and install the most current stable
82
- version of the postgres gem (from http://gems.rubyforge.org) is to use
83
- the RubyGem package manager. You may need to supply RubyGem with the
84
- location of the libpq library and the libpq.h and libpq/libpq-fs.h
85
- files, and may need to run as root.
86
- If you installed from source on a Unix system you can locate these
87
- libpq files with:
88
- find <path to install directory> -name "libpq-fe.h" -print
89
- With binary distributions, you may need to install additional
90
- PostgreSQL development libraries to get these files.
91
-
92
- Then run:
93
- sudo gem install postgres -- --with-pgsql-include-dir=<location of
94
- Postgresql>/include --with-pgsql-lib-dir=<location of Postgresql/lib
95
-
96
- Example:
97
- on Mac OS X with PostgreSQL in /Library/PostgreSQL8 use
98
- --with-pgsql-include-dir=/Library/PostgreSQL8/include --with-pgsql-lib-
99
- dir=/Library/PostgreSQL8/lib
100
-
101
- To use the postgres adapter with Rails:
102
- refer to it as
103
- adapter: postgresql
104
- in your database:yaml file
105
-
106
- The pg adapter cannot be used with Rails yet and is available for
107
- testing and developer use.
108
-
109
- To use these modules in Ruby directly (not Rails), refer to the RDoc
110
- documentation.
111
-
112
- - Acknowledgments
113
-
114
- We are thankful to the people at the ruby-list and ruby-dev mailing lists.
115
- And to the people who developed PostgreSQL.
116
-
117
- - Copying
118
-
119
- This library is copyrighted by its authors; Yukihiro Matsumoto, and Eiji
120
- Matsumoto.
121
-
122
- Portions copyright Laika, Inc.
123
-
124
-
125
-
@@ -1,529 +0,0 @@
1
- /************************************************
2
-
3
- compat.c -
4
-
5
- Author: matz
6
- created at: Tue May 13 20:07:35 JST 1997
7
-
8
- Author: ematsu
9
- modified at: Wed Jan 20 16:41:51 1999
10
-
11
- $Author: jdavis $
12
- $Date: 2007-12-04 14:25:44 -0800 (Tue, 04 Dec 2007) $
13
- ************************************************/
14
-
15
- #include <ctype.h>
16
- #include "compat.h"
17
-
18
- #ifdef PG_BEFORE_080300
19
- int
20
- PQconnectionNeedsPassword(PGconn *conn)
21
- {
22
- rb_raise(rb_eStandardError,
23
- "PQconnectionNeedsPassword not supported by this client version.");
24
- }
25
-
26
- int
27
- PQconnectionUsedPassword(PGconn *conn)
28
- {
29
- rb_raise(rb_eStandardError,
30
- "PQconnectionUsedPassword not supported by this client version.");
31
- }
32
-
33
- int
34
- lo_truncate(PGconn *conn, int fd, size_t len)
35
- {
36
- rb_raise(rb_eStandardError, "lo_truncate not supported by this client version.");
37
- }
38
- #endif /* PG_BEFORE_080300 */
39
-
40
- #ifdef PG_BEFORE_080200
41
- int
42
- PQisthreadsafe()
43
- {
44
- return Qfalse;
45
- }
46
-
47
- int
48
- PQnparams(const PGresult *res)
49
- {
50
- rb_raise(rb_eStandardError, "PQnparams not supported by this client version.");
51
- }
52
-
53
- Oid
54
- PQparamtype(const PGresult *res, int param_number)
55
- {
56
- rb_raise(rb_eStandardError, "PQparamtype not supported by this client version.");
57
- }
58
-
59
- PGresult *
60
- PQdescribePrepared(PGconn *conn, const char *stmtName)
61
- {
62
- rb_raise(rb_eStandardError, "PQdescribePrepared not supported by this client version.");
63
- }
64
-
65
- PGresult *
66
- PQdescribePortal(PGconn *conn, const char *portalName)
67
- {
68
- rb_raise(rb_eStandardError, "PQdescribePortal not supported by this client version.");
69
- }
70
-
71
- int
72
- PQsendDescribePrepared(PGconn *conn, const char *stmtName)
73
- {
74
- rb_raise(rb_eStandardError, "PQsendDescribePrepared not supported by this client version.");
75
- }
76
-
77
- int
78
- PQsendDescribePortal(PGconn *conn, const char *portalName)
79
- {
80
- rb_raise(rb_eStandardError, "PQsendDescribePortal not supported by this client version.");
81
- }
82
-
83
- char *
84
- PQencryptPassword(const char *passwd, const char *user)
85
- {
86
- rb_raise(rb_eStandardError, "PQencryptPassword not supported by this client version.");
87
- }
88
- #endif /* PG_BEFORE_080200 */
89
-
90
- #ifdef PG_BEFORE_080100
91
- Oid
92
- lo_create(PGconn *conn, Oid lobjId)
93
- {
94
- rb_raise(rb_eStandardError, "lo_create not supported by this client version.");
95
- }
96
- #endif /* PG_BEFORE_080100 */
97
-
98
- #ifdef PG_BEFORE_080000
99
- PGresult *
100
- PQprepare(PGconn *conn, const char *stmtName, const char *query,
101
- int nParams, const Oid *paramTypes)
102
- {
103
- rb_raise(rb_eStandardError, "PQprepare not supported by this client version.");
104
- }
105
-
106
- int
107
- PQsendPrepare(PGconn *conn, const char *stmtName, const char *query,
108
- int nParams, const Oid *paramTypes)
109
- {
110
- rb_raise(rb_eStandardError, "PQsendPrepare not supported by this client version.");
111
- }
112
-
113
- int
114
- PQserverVersion(const PGconn* conn)
115
- {
116
- rb_raise(rb_eStandardError, "PQserverVersion not supported by this client version.");
117
- }
118
- #endif /* PG_BEFORE_080000 */
119
-
120
- #ifdef PG_BEFORE_070400
121
- PGresult *
122
- PQexecParams(PGconn *conn, const char *command, int nParams,
123
- const Oid *paramTypes, const char * const * paramValues, const int *paramLengths,
124
- const int *paramFormats, int resultFormat)
125
- {
126
- rb_raise(rb_eStandardError, "PQexecParams not supported by this client version.");
127
- }
128
-
129
- PGTransactionStatusType
130
- PQtransactionStatus(const PGconn *conn)
131
- {
132
- rb_raise(rb_eStandardError, "PQtransactionStatus not supported by this client version.");
133
- }
134
-
135
- char *
136
- PQparameterStatus(const PGconn *conn, const char *paramName)
137
- {
138
- rb_raise(rb_eStandardError, "PQparameterStatus not supported by this client version.");
139
- }
140
-
141
- int
142
- PQprotocolVersion(const PGconn *conn)
143
- {
144
- rb_raise(rb_eStandardError, "PQprotocolVersion not supported by this client version.");
145
- }
146
-
147
- PGresult
148
- *PQexecPrepared(PGconn *conn, const char *stmtName, int nParams,
149
- const char * const *ParamValues, const int *paramLengths, const int *paramFormats,
150
- int resultFormat)
151
- {
152
- rb_raise(rb_eStandardError, "PQexecPrepared not supported by this client version.");
153
- }
154
-
155
- int
156
- PQsendQueryParams(PGconn *conn, const char *command, int nParams,
157
- const Oid *paramTypes, const char * const * paramValues, const int *paramLengths,
158
- const int *paramFormats, int resultFormat)
159
- {
160
- rb_raise(rb_eStandardError, "PQsendQueryParams not supported by this client version.");
161
- }
162
-
163
- int
164
- PQsendQueryPrepared(PGconn *conn, const char *stmtName, int nParams,
165
- const char * const *ParamValues, const int *paramLengths, const int *paramFormats,
166
- int resultFormat)
167
- {
168
- rb_raise(rb_eStandardError, "PQsendQueryPrepared not supported by this client version.");
169
- }
170
-
171
- int
172
- PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
173
- {
174
- rb_raise(rb_eStandardError, "PQputCopyData not supported by this client version.");
175
- }
176
-
177
- int
178
- PQputCopyEnd(PGconn *conn, const char *errormsg)
179
- {
180
- rb_raise(rb_eStandardError, "PQputCopyEnd not supported by this client version.");
181
- }
182
-
183
- int
184
- PQgetCopyData(PGconn *conn, char **buffer, int async)
185
- {
186
- rb_raise(rb_eStandardError, "PQgetCopyData not supported by this client version.");
187
- }
188
-
189
- PGVerbosity
190
- PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity)
191
- {
192
- rb_raise(rb_eStandardError, "PQsetErrorVerbosity not supported by this client version.");
193
- }
194
-
195
- Oid
196
- PQftable(const PGresult *res, int column_number)
197
- {
198
- rb_raise(rb_eStandardError, "PQftable not supported by this client version.");
199
- }
200
-
201
- int
202
- PQftablecol(const PGresult *res, int column_number)
203
- {
204
- rb_raise(rb_eStandardError, "PQftablecol not supported by this client version.");
205
- }
206
-
207
- int
208
- PQfformat(const PGresult *res, int column_number)
209
- {
210
- rb_raise(rb_eStandardError, "PQfformat not supported by this client version.");
211
- }
212
- #endif /* PG_BEFORE_070400 */
213
-
214
- #ifdef PG_BEFORE_070300
215
- size_t
216
- PQescapeStringConn(PGconn *conn, char *to, const char *from,
217
- size_t length, int *error)
218
- {
219
- return PQescapeString(to,from,length);
220
- }
221
-
222
- unsigned char *
223
- PQescapeByteaConn(PGconn *conn, const unsigned char *from,
224
- size_t from_length, size_t *to_length)
225
- {
226
- return PQescapeBytea(from, from_length, to_length);
227
- }
228
- #endif /* PG_BEFORE_070300 */
229
-
230
-
231
- /**************************************************************************
232
-
233
- IF ANY CODE IS COPIED FROM POSTGRESQL, PLACE IT AFTER THIS COMMENT.
234
-
235
- ***************************************************************************
236
-
237
- Portions of code after this point were copied from the PostgreSQL source
238
- distribution, available at http://www.postgresql.org
239
-
240
- ***************************************************************************
241
-
242
- Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
243
-
244
- Portions Copyright (c) 1994, The Regents of the University of California
245
-
246
- Permission to use, copy, modify, and distribute this software and its
247
- documentation for any purpose, without fee, and without a written agreement
248
- is hereby granted, provided that the above copyright notice and this
249
- paragraph and the following two paragraphs appear in all copies.
250
-
251
- IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
252
- DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
253
- LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
254
- DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
255
- POSSIBILITY OF SUCH DAMAGE.
256
-
257
- THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
258
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
259
- AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
260
- ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
261
- PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
262
-
263
- **************************************************************************/
264
-
265
- #ifndef HAVE_PQSETCLIENTENCODING
266
- int
267
- PQsetClientEncoding(PGconn *conn, const char *encoding)
268
- {
269
- char qbuf[128];
270
- static const char query[] = "set client_encoding to '%s'";
271
- PGresult *res;
272
- int status;
273
-
274
- if (!conn || conn->status != CONNECTION_OK)
275
- return -1;
276
-
277
- if (!encoding)
278
- return -1;
279
-
280
- /* check query buffer overflow */
281
- if (sizeof(qbuf) < (sizeof(query) + strlen(encoding)))
282
- return -1;
283
-
284
- /* ok, now send a query */
285
- sprintf(qbuf, query, encoding);
286
- res = PQexec(conn, qbuf);
287
-
288
- if (res == NULL)
289
- return -1;
290
- if (res->resultStatus != PGRES_COMMAND_OK)
291
- status = -1;
292
- else
293
- {
294
- /*
295
- * In protocol 2 we have to assume the setting will stick, and adjust
296
- * our state immediately. In protocol 3 and up we can rely on the
297
- * backend to report the parameter value, and we'll change state at
298
- * that time.
299
- */
300
- if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
301
- pqSaveParameterStatus(conn, "client_encoding", encoding);
302
- status = 0; /* everything is ok */
303
- }
304
- PQclear(res);
305
- return status;
306
- }
307
- #endif /* HAVE_PQSETCLIENTENCODING */
308
-
309
- #ifndef HAVE_PQESCAPESTRING
310
- /*
311
- * Escaping arbitrary strings to get valid SQL literal strings.
312
- *
313
- * Replaces "\\" with "\\\\" and "'" with "''".
314
- *
315
- * length is the length of the source string. (Note: if a terminating NUL
316
- * is encountered sooner, PQescapeString stops short of "length"; the behavior
317
- * is thus rather like strncpy.)
318
- *
319
- * For safety the buffer at "to" must be at least 2*length + 1 bytes long.
320
- * A terminating NUL character is added to the output string, whether the
321
- * input is NUL-terminated or not.
322
- *
323
- * Returns the actual length of the output (not counting the terminating NUL).
324
- */
325
- size_t
326
- PQescapeString(char *to, const char *from, size_t length)
327
- {
328
- const char *source = from;
329
- char *target = to;
330
- size_t remaining = length;
331
-
332
- while (remaining > 0 && *source != '\0')
333
- {
334
- switch (*source)
335
- {
336
- case '\\':
337
- *target++ = '\\';
338
- *target++ = '\\';
339
- break;
340
-
341
- case '\'':
342
- *target++ = '\'';
343
- *target++ = '\'';
344
- break;
345
-
346
- default:
347
- *target++ = *source;
348
- break;
349
- }
350
- source++;
351
- remaining--;
352
- }
353
-
354
- /* Write the terminating NUL character. */
355
- *target = '\0';
356
-
357
- return target - to;
358
- }
359
-
360
- /*
361
- * PQescapeBytea - converts from binary string to the
362
- * minimal encoding necessary to include the string in an SQL
363
- * INSERT statement with a bytea type column as the target.
364
- *
365
- * The following transformations are applied
366
- * '\0' == ASCII 0 == \\000
367
- * '\'' == ASCII 39 == \'
368
- * '\\' == ASCII 92 == \\\\
369
- * anything < 0x20, or > 0x7e ---> \\ooo
370
- * (where ooo is an octal expression)
371
- */
372
- unsigned char *
373
- PQescapeBytea(const unsigned char *bintext, size_t binlen, size_t *bytealen)
374
- {
375
- const unsigned char *vp;
376
- unsigned char *rp;
377
- unsigned char *result;
378
- size_t i;
379
- size_t len;
380
-
381
- /*
382
- * empty string has 1 char ('\0')
383
- */
384
- len = 1;
385
-
386
- vp = bintext;
387
- for (i = binlen; i > 0; i--, vp++)
388
- {
389
- if (*vp < 0x20 || *vp > 0x7e)
390
- len += 5; /* '5' is for '\\ooo' */
391
- else if (*vp == '\'')
392
- len += 2;
393
- else if (*vp == '\\')
394
- len += 4;
395
- else
396
- len++;
397
- }
398
-
399
- rp = result = (unsigned char *) malloc(len);
400
- if (rp == NULL)
401
- return NULL;
402
-
403
- vp = bintext;
404
- *bytealen = len;
405
-
406
- for (i = binlen; i > 0; i--, vp++)
407
- {
408
- if (*vp < 0x20 || *vp > 0x7e)
409
- {
410
- (void) sprintf(rp, "\\\\%03o", *vp);
411
- rp += 5;
412
- }
413
- else if (*vp == '\'')
414
- {
415
- rp[0] = '\\';
416
- rp[1] = '\'';
417
- rp += 2;
418
- }
419
- else if (*vp == '\\')
420
- {
421
- rp[0] = '\\';
422
- rp[1] = '\\';
423
- rp[2] = '\\';
424
- rp[3] = '\\';
425
- rp += 4;
426
- }
427
- else
428
- *rp++ = *vp;
429
- }
430
- *rp = '\0';
431
-
432
- return result;
433
- }
434
-
435
- #define ISFIRSTOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '3')
436
- #define ISOCTDIGIT(CH) ((CH) >= '0' && (CH) <= '7')
437
- #define OCTVAL(CH) ((CH) - '0')
438
-
439
- /*
440
- * PQunescapeBytea - converts the null terminated string representation
441
- * of a bytea, strtext, into binary, filling a buffer. It returns a
442
- * pointer to the buffer (or NULL on error), and the size of the
443
- * buffer in retbuflen. The pointer may subsequently be used as an
444
- * argument to the function free(3). It is the reverse of PQescapeBytea.
445
- *
446
- * The following transformations are made:
447
- * \\ == ASCII 92 == \
448
- * \ooo == a byte whose value = ooo (ooo is an octal number)
449
- * \x == x (x is any character not matched by the above transformations)
450
- */
451
- unsigned char *
452
- PQunescapeBytea(const unsigned char *strtext, size_t *retbuflen)
453
- {
454
- size_t strtextlen,
455
- buflen;
456
- unsigned char *buffer,
457
- *tmpbuf;
458
- size_t i,
459
- j;
460
-
461
- if (strtext == NULL)
462
- return NULL;
463
-
464
- strtextlen = strlen(strtext);
465
-
466
- /*
467
- * Length of input is max length of output, but add one to avoid
468
- * unportable malloc(0) if input is zero-length.
469
- */
470
- buffer = (unsigned char *) malloc(strtextlen + 1);
471
- if (buffer == NULL)
472
- return NULL;
473
-
474
- for (i = j = 0; i < strtextlen;)
475
- {
476
- switch (strtext[i])
477
- {
478
- case '\\':
479
- i++;
480
- if (strtext[i] == '\\')
481
- buffer[j++] = strtext[i++];
482
- else
483
- {
484
- if ((ISFIRSTOCTDIGIT(strtext[i])) &&
485
- (ISOCTDIGIT(strtext[i + 1])) &&
486
- (ISOCTDIGIT(strtext[i + 2])))
487
- {
488
- int byte;
489
-
490
- byte = OCTVAL(strtext[i++]);
491
- byte = (byte << 3) + OCTVAL(strtext[i++]);
492
- byte = (byte << 3) + OCTVAL(strtext[i++]);
493
- buffer[j++] = byte;
494
- }
495
- }
496
-
497
- /*
498
- * Note: if we see '\' followed by something that isn't a
499
- * recognized escape sequence, we loop around having done
500
- * nothing except advance i. Therefore the something will
501
- * be emitted as ordinary data on the next cycle. Corner
502
- * case: '\' at end of string will just be discarded.
503
- */
504
- break;
505
-
506
- default:
507
- buffer[j++] = strtext[i++];
508
- break;
509
- }
510
- }
511
- buflen = j; /* buflen is the length of the dequoted
512
- * data */
513
-
514
- /* Shrink the buffer to be no larger than necessary */
515
- /* +1 avoids unportable behavior when buflen==0 */
516
- tmpbuf = realloc(buffer, buflen + 1);
517
-
518
- /* It would only be a very brain-dead realloc that could fail, but... */
519
- if (!tmpbuf)
520
- {
521
- free(buffer);
522
- return NULL;
523
- }
524
-
525
- *retbuflen = buflen;
526
- return tmpbuf;
527
- }
528
- #endif
529
-