On Tue, May 21, 2002 at 05:32:10PM +0200, Stig S. Bakken wrote:
> > I wasn't sure if I could just attach my file.c.patch file to this email
> > or not?
> 
> That's fine, but make sure the MIME type for the attachment is
> text/plain or the mailing list software will remove it.

Ok, here is my first try! :) (please let me know if its ok).

TIA

- Dean
? file.c.patch
Index: file.c
===================================================================
RCS file: /repository/php4/ext/standard/file.c,v
retrieving revision 1.229
diff -u -r1.229 file.c
--- file.c      12 May 2002 15:59:42 -0000      1.229
+++ file.c      21 May 2002 15:24:42 -0000
@@ -1928,168 +1928,196 @@
    Get line from file pointer and parse for CSV fields */
 PHP_FUNCTION(fgetcsv)
 {
-       char *temp, *tptr, *bptr, *lineEnd;
-       char delimiter = ',';   /* allow this to be set as parameter */
-
-       /* first section exactly as php_fgetss */
-
-       zval **fd, **bytes, **p_delim;
-       int len, type;
-       char *buf;
-       php_stream *stream;
-
-       switch(ZEND_NUM_ARGS()) {
-       case 2:
-               if (zend_get_parameters_ex(2, &fd, &bytes) == FAILURE) {
-                       WRONG_PARAM_COUNT;
-               }
-               break;
-
-       case 3:
-               if (zend_get_parameters_ex(3, &fd, &bytes, &p_delim) == FAILURE) {
-                       WRONG_PARAM_COUNT;
-               }
-               convert_to_string_ex(p_delim);
-               /* Make sure that there is at least one character in string */
-               if (Z_STRLEN_PP(p_delim) < 1) {
-                       WRONG_PARAM_COUNT;
-               }
-                       /* use first character from string */
-               delimiter = Z_STRVAL_PP(p_delim)[0];
-               break;
-
-       default:
-               WRONG_PARAM_COUNT;
-               /* NOTREACHED */
-               break;
-       }
-
-       stream = (php_stream*)zend_fetch_resource(fd TSRMLS_CC,-1, "File-Handle", 
&type, 1, le_stream);
-       ZEND_VERIFY_RESOURCE(stream);
-
-       convert_to_long_ex(bytes);
-       len = Z_LVAL_PP(bytes);
-       if (len < 0) {
-               php_error(E_WARNING, "length parameter to fgetcsv() may not be 
negative");
-               RETURN_FALSE;
-       }
-
-       buf = emalloc(len + 1);
-       /*needed because recv/read/gzread doesnt set null char at end*/
-       memset(buf, 0, len + 1);
-
-       if (php_stream_gets(stream, buf, len) == NULL)  {
-               efree(buf);
-               RETURN_FALSE;
-       }
-
-       /* Now into new section that parses buf for comma/quote delimited fields */
-
-       /* Strip trailing space from buf, saving end of line in case required for 
quoted field */
-
-       lineEnd = emalloc(len + 1);
-       bptr = buf;
-       tptr = buf + strlen(buf) -1;
-       while ( isspace((int) *tptr) && (*tptr!=delimiter) && (tptr > bptr) ) tptr--;
-       tptr++;
-       strcpy(lineEnd, tptr);
-
-       /* add single space - makes it easier to parse trailing null field */
-       *tptr++ = ' ';
-       *tptr = 0;
-
-       /* reserve workspace for building each individual field */
-
-       temp = emalloc(len);    /*      unlikely but possible! */
-       tptr = temp;
-
-       /* Initialize return array */
-       array_init(return_value);
-
-       /* Main loop to read CSV fields */
-       /* NB this routine will return a single null entry for a blank line */
-
-       do      {
-               /* 1. Strip any leading space */
-               while(isspace((int) *bptr) && (*bptr!=delimiter)) bptr++;
-               /* 2. Read field, leaving bptr pointing at start of next field */
-               if (*bptr == '"') {
-                       /* 2A. handle quote delimited field */
-                       bptr++;         /* move on to first character in field */
-                       while (*bptr) {
-                               if (*bptr == '"') {
-                                       /* handle the double-quote */
-                                       if ( *(bptr+1) == '"') {
-                                       /* embedded double quotes */
-                                               *tptr++ = *bptr; bptr +=2;
-                                       } else {
-                                       /* must be end of string - skip to start of 
next field or end */
-                                               while ( (*bptr != delimiter) && *bptr 
) bptr++;
-                                               if (*bptr == delimiter) bptr++;
-                                               *tptr=0;        /* terminate temporary 
string */
-                                               break;  /* .. from handling this field 
- resumes at 3. */
-                                       }
-                               } else {
-                               /* normal character */
-                                       *tptr++ = *bptr++;
-
-                                       if (*bptr == 0) {       /* embedded line end? 
*/
-                                               *(tptr-1)=0;            /* remove 
space character added on reading line */
-                                               strcat(temp, lineEnd);   /* add the 
embedded line end to the field */
-
-                                               /* read a new line from input, as at 
start of routine */
-                                               memset(buf, 0, len+1);
-
-                                               if (php_stream_gets(stream, buf, len) 
== NULL)  {
-                                                       efree(lineEnd); 
-                                                       efree(temp); 
-                                                       efree(buf);
-                                                       zval_ptr_dtor(&return_value);
-                                                       RETURN_FALSE;
-                                               }
-
-                                               bptr = buf;
-                                               tptr = buf + strlen(buf) -1;
-                                               while (isspace((int) *tptr) && 
(*tptr!=delimiter) && (tptr > bptr)) 
-                                                       tptr--;
-                                               tptr++; 
-                                               strcpy(lineEnd, tptr);
-                                               *tptr++ = ' ';  
-                                               *tptr = 0;
-
-                                               tptr = temp;      /* reset temp 
pointer to end of field as read so far */
-                                               while (*tptr) 
-                                                       tptr++;
-                                       }
-                               }
-                       }
-               } else {
-                       /* 2B. Handle non-quoted field */
-                       while ((*bptr != delimiter) && *bptr) 
-                               *tptr++ = *bptr++;
-                       *tptr=0;        /* terminate temporary string */
-
-                       if (strlen(temp)) {
-                               tptr--;
-                               while (isspace((int)*tptr) && (*tptr!=delimiter)) 
-                                       *tptr-- = 0;    /* strip any trailing spaces */
-                       }
-                       
-                       if (*bptr == delimiter) 
-                               bptr++;
-               }
-
-               /* 3. Now pass our field back to php */
-               add_next_index_string(return_value, temp, 1);
-               tptr = temp;
-       } while (*bptr);
-
-       efree(lineEnd);
-       efree(temp);
-       efree(buf);
+        char *temp, *tptr, *bptr, *lineEnd;
+        char delimiter = ',';   /* allow this to be set as parameter */
+        char enclosure = '"';   /* allow this to be set as parameter */
+
+        /* first section exactly as php_fgetss */
+
+        zval **fd, **bytes, **p_delim, **p_enclosure;
+        int len, type;
+        char *buf;
+        int issock=0;
+        int socketd=0;
+        void *what;
+
+        switch(ZEND_NUM_ARGS()) {
+        case 2:
+                if (zend_get_parameters_ex(2, &fd, &bytes) == FAILURE) {
+                        WRONG_PARAM_COUNT;
+                }
+                break;
+
+        case 3:
+                if (zend_get_parameters_ex(3, &fd, &bytes, &p_delim) == FAILURE) {
+                        WRONG_PARAM_COUNT;
+                }
+                convert_to_string_ex(p_delim);
+                /* Make sure that there is at least one character in string */
+                if (Z_STRLEN_PP(p_delim) < 1) {
+                        WRONG_PARAM_COUNT;
+                }
+                        /* use first character from string */
+                delimiter = Z_STRVAL_PP(p_delim)[0];
+                break;
+
+        case 4:
+                if (zend_get_parameters_ex(4, &fd, &bytes, &p_delim, &p_enclosure) == 
+FAILURE) {
+                        WRONG_PARAM_COUNT;
+                }
+                convert_to_string_ex(p_delim);
+                /* Make sure that there is at least one character in string */
+                if (Z_STRLEN_PP(p_delim) < 1) {
+                        WRONG_PARAM_COUNT;
+                }
+                        /* use first character from string */
+                delimiter = Z_STRVAL_PP(p_delim)[0];
+
+                convert_to_string_ex(p_enclosure);
+                /* Make sure that there is at least one character in string */
+                if (Z_STRLEN_PP(p_enclosure) < 1) {
+                        WRONG_PARAM_COUNT;
+                }
+                        /* use first character from string */
+                enclosure = Z_STRVAL_PP(p_enclosure)[0];
+
+                break;
+
+        default:
+                WRONG_PARAM_COUNT;
+                /* NOTREACHED */
+                break;
+        }
+        /* XXX: add stream support --Wez. */
+
+        what = zend_fetch_resource(fd TSRMLS_CC,-1, "File-Handle", &type, 3, 
+le_fopen, le_popen, le_socket);
+        ZEND_VERIFY_RESOURCE(what);
+
+        if (type == le_socket) {
+                issock  = 1;
+                socketd = *(int *) what;
+        }
+
+        convert_to_long_ex(bytes);
+        len = Z_LVAL_PP(bytes);
+        if (len < 0) {
+                php_error(E_WARNING, "length parameter to fgetcsv() may not be 
+negative");
+                RETURN_FALSE;
+        }
+
+        buf = emalloc(len + 1);
+        /*needed because recv doesnt set null char at end*/
+        memset(buf, 0, len + 1);
+        if (FP_FGETS(buf, len, socketd, (FILE *) what, issock) == NULL) {
+                efree(buf);
+                RETURN_FALSE;
+        }
+
+        /* Now into new section that parses buf for delimiter/enclosure fields */
+
+        /* Strip trailing space from buf, saving end of line in case required for 
+enclosure field */
+
+        lineEnd = emalloc(len + 1);
+        bptr = buf;
+        tptr = buf + strlen(buf) -1;
+        while ( isspace((int) *tptr) && (*tptr!=delimiter) && (tptr > bptr) ) tptr--;
+        tptr++;
+        strcpy(lineEnd, tptr);
+
+        /* add single space - makes it easier to parse trailing null field */
+        *tptr++ = ' ';
+        *tptr = 0;
+
+        /* reserve workspace for building each individual field */
+
+        temp = emalloc(len);    /*      unlikely but possible! */
+        tptr = temp;
+
+        /* Initialize return array */
+        array_init(return_value);
+
+        /* Main loop to read CSV fields */
+        /* NB this routine will return a single null entry for a blank line */
+
+        do      {
+                /* 1. Strip any leading space */
+                while(isspace((int) *bptr) && (*bptr!=delimiter)) bptr++;
+                /* 2. Read field, leaving bptr pointing at start of next field */
+                if (*bptr == enclosure) {
+                        /* 2A. handle enclosure delimited field */
+                        bptr++;         /* move on to first character in field */
+                        while (*bptr) {
+                                if (*bptr == enclosure) {
+                                        /* handle the enclosure */
+                                        if ( *(bptr+1) == enclosure) {
+                                        /* embedded enclosure */
+                                                *tptr++ = *bptr; bptr +=2;
+                                        } else {
+                                        /* must be end of string - skip to start of 
+next field or end */
+                                                while ( (*bptr != delimiter) && *bptr 
+) bptr++;
+                                                if (*bptr == delimiter) bptr++;
+                                                *tptr=0;        /* terminate 
+temporary string */
+                                                break;  /* .. from handling this 
+field - resumes at 3. */
+                                        }
+                                } else {
+                                /* normal character */
+                                        *tptr++ = *bptr++;
+
+                                        if (*bptr == 0) {       /* embedded line end? 
+*/
+                                                *(tptr-1)=0;            /* remove 
+space character added on reading line */
+                                                strcat(temp, lineEnd);   /* add the 
+embedded line end to the field */
+
+                                                /* read a new line from input, as at 
+start of routine */
+                                                memset(buf, 0, len+1);
+                                                if (FP_FGETS(buf, len, socketd, (FILE 
+*) what, issock) == NULL) {
+                                                        efree(lineEnd);
+                                                        efree(temp);
+                                                        efree(buf);
+                                                        zval_ptr_dtor(&return_value);
+                                                        RETURN_FALSE;
+                                                }
+
+                                                bptr = buf;
+                                                tptr = buf + strlen(buf) -1;
+                                                while (isspace((int) *tptr) && 
+(*tptr!=delimiter) && (tptr > bptr))
+                                                        tptr--;
+                                                tptr++;
+                                                strcpy(lineEnd, tptr);
+                                                *tptr++ = ' ';
+                                                *tptr = 0;
+
+                                                tptr = temp;      /* reset temp 
+pointer to end of field as read so far */
+                                                while (*tptr)
+                                                        tptr++;
+                                        }
+                                }
+                        }
+                } else {
+                        /* 2B. Handle non-enclosure field */
+                        while ((*bptr != delimiter) && *bptr)
+                                *tptr++ = *bptr++;
+                        *tptr=0;        /* terminate temporary string */
+
+                        if (strlen(temp)) {
+                                tptr--;
+                                while (isspace((int)*tptr) && (*tptr!=delimiter))
+                                        *tptr-- = 0;    /* strip any trailing spaces 
+*/
+                        }
+
+                        if (*bptr == delimiter)
+                                bptr++;
+                }
+
+                /* 3. Now pass our field back to php */
+                add_next_index_string(return_value, temp, 1);
+                tptr = temp;
+        } while (*bptr);
+
+        efree(lineEnd);
+        efree(temp);
+        efree(buf);
 }
 /* }}} */
-
 
 #if (!defined(PHP_WIN32) && !defined(__BEOS__) && HAVE_REALPATH) || defined(ZTS)
 /* {{{ proto string realpath(string path)

Attachment: msg38303/pgp00000.pgp
Description: PGP signature

Reply via email to