From: Rasmus Lerdorf Date: Tue, 27 Apr 1999 13:06:58 +0000 (+0000) Subject: Add fgetcsv() here as well X-Git-Tag: BEFORE_PHP4_APACHE_MODULE_CHANGE~133 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=92905543f1456b76daa5ff48274740b2180b3937;p=php Add fgetcsv() here as well --- diff --git a/ext/standard/file.c b/ext/standard/file.c index e36c386355..af15917d17 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -196,6 +196,7 @@ function_entry php3_file_functions[] = { {"copy", php3_file_copy, NULL}, {"tempnam", php3_tempnam, NULL}, {"file", php3_file, NULL}, + {"fgetcsv", php3_fgetcsv, NULL}, PHP_FE(flock, NULL) {"get_meta_tags", php3_get_meta_tags, NULL}, {"set_socket_blocking", php3_set_socket_blocking, NULL}, @@ -1516,6 +1517,121 @@ PHPAPI int php3i_get_le_fp(void) return le_fp; } +/* {{{ proto array fgetcsv(int fp, int length) + get line from file pointer and parse for CSV fields */ +void php3_fgetcsv(INTERNAL_FUNCTION_PARAMETERS) { + char *temp, *tptr, *bptr; + char delimiter = ','; /* allow this to be set as parameter if required in future version? */ + + /* first section exactly as php3_fgetss */ + + pval *fd, *bytes; + FILE *fp; + int id, len, br, type; + char *buf, *p, *rbuf, *rp, c, lc; + int issock=0; + int *sock,socketd=0; + + if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &fd, &bytes) == FAILURE) { + WRONG_PARAM_COUNT; + } + + convert_to_long(fd); + convert_to_long(bytes); + + id = fd->value.lval; + len = bytes->value.lval; + + fp = php3_list_find(id,&type); + if (type==wsa_fp){ + issock=1; + sock = php3_list_find(id,&type); + socketd=*sock; + } + if ((!fp || (type!=le_fp && type!=le_pp)) && (!socketd || type!=wsa_fp)) { + php3_error(E_WARNING, "Unable to find file identifier %d", id); + RETURN_FALSE; + } + + buf = emalloc(sizeof(char) * (len + 1)); + /*needed because recv doesnt set null char at end*/ + memset(buf,0,len+1); + if (!(issock?SOCK_FGETS(buf,len,socketd):(int)fgets(buf, len, fp))) { + efree(buf); + RETURN_FALSE; + } + + /* Now into new section that parses buf for comma/quote delimited fields */ + + /* Strip trailing space from buf */ + + bptr = buf; + tptr = buf + strlen(buf) -1; + while ( isspace(*tptr) && (tptr > bptr) ) *tptr--=0; + + /* add single space - makes it easier to parse trailing null field */ + *++tptr = ' '; + *++tptr = 0; + + /* reserve workspace for building each individual field */ + + temp = emalloc(sizeof(char) * len); /* unlikely but possible! */ + tptr=temp; + + /* Initialize return array */ + if (array_init(return_value) == FAILURE) { + efree(temp); + efree(buf); + RETURN_FALSE; + } + + /* 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(*bptr) 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++; + } + } + } else { + /* 2B. Handle non-quoted field */ + while ( (*bptr != delimiter) && *bptr ) *tptr++ = *bptr++; + *tptr=0; /* terminate temporary string */ + if (strlen(temp)) { + tptr--; + while (isspace(*tptr)) *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(temp); + efree(buf); +} +/* }}} */ + /* * Local variables: * tab-width: 4 diff --git a/ext/standard/file.h b/ext/standard/file.h index e0f1340119..1274d4dcd7 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -46,6 +46,7 @@ extern void php3_fread(INTERNAL_FUNCTION_PARAMETERS); extern void php3_fgetc(INTERNAL_FUNCTION_PARAMETERS); extern void php3_fgets(INTERNAL_FUNCTION_PARAMETERS); extern void php3_fgetss(INTERNAL_FUNCTION_PARAMETERS); +extern void php3_fgetcsv(INTERNAL_FUNCTION_PARAMETERS); extern void php3_fwrite(INTERNAL_FUNCTION_PARAMETERS); extern void php3_rewind(INTERNAL_FUNCTION_PARAMETERS); extern void php3_ftell(INTERNAL_FUNCTION_PARAMETERS);