[R-gregmisc-users] SF.net SVN: r-gregmisc:[1851] trunk/SASxport/src/SASxport.c
Brought to you by:
warnes
From: <wa...@us...> - 2014-07-21 13:38:25
|
Revision: 1851 http://sourceforge.net/p/r-gregmisc/code/1851 Author: warnes Date: 2014-07-21 13:38:15 +0000 (Mon, 21 Jul 2014) Log Message: ----------- - Return to using get_IBM_double, but add reverse_double before the call if running on BIGENDIAN machine. Modified Paths: -------------- trunk/SASxport/src/SASxport.c Modified: trunk/SASxport/src/SASxport.c =================================================================== --- trunk/SASxport/src/SASxport.c 2014-07-20 02:17:21 UTC (rev 1850) +++ trunk/SASxport/src/SASxport.c 2014-07-21 13:38:15 UTC (rev 1851) @@ -39,16 +39,16 @@ #define HEADER_END "HEADER RECORD!!!!!!!000000000000000000000000000000 " #define LIB_HEADER HEADER_BEG HEADER_TYPE_LIBRARY HEADER_END -#define MEM_HEADER HEADER_BEG HEADER_TYPE_MEMBER \ +#define MEM_HEADER HEADER_BEG HEADER_TYPE_MEMBER \ "HEADER RECORD!!!!!!!000000000000000001600000000" #define DSC_HEADER HEADER_BEG HEADER_TYPE_DSCRPTR HEADER_END -#define NAM_HEADER HEADER_BEG HEADER_TYPE_NAMESTR \ +#define NAM_HEADER HEADER_BEG HEADER_TYPE_NAMESTR \ "HEADER RECORD!!!!!!!000000" #define OBS_HEADER HEADER_BEG HEADER_TYPE_OBS HEADER_END #define BLANK24 " " -#define GET_RECORD(rec, fp, len) \ - (int) fread((rec), sizeof(char), (size_t) (len), (fp)) +#define GET_RECORD(rec, fp, len) \ + (int) fread((rec), sizeof(char), (size_t) (len), (fp)) #define IS_SASNA_CHAR(c) ((c) == 0x5f || (c) == 0x2e || \ (0x41 <= (c) && (c) <= 0x5a)) @@ -62,232 +62,232 @@ static double get_IBM_double(char* c, size_t len) { -/* Conversion from IBM 360 format to double */ -/* - * IBM format: - * 6 5 0 - * 3 1 0 - * - * SEEEEEEEMMMM ......... MMMM - * - * Sign bit, 7 bit exponent, 56 bit fraction. Exponent is - * excess 64. The fraction is multiplied by a power of 16 of - * the actual exponent. Normalized floating point numbers are - * represented with the radix point immediately to the left of - * the high order hex fraction digit. - */ - unsigned int i, upper, lower; - /* exponent is expressed here as - excess 70 (=64+6) to accomodate - integer conversion of c[1] to c[4] */ - char negative = c[0] & 0x80; - // needs to be signed: char is not on Raspbian - signed char exponent = (c[0] & 0x7f) - 70; - double value; - char buf[4], ibuf[8]; + /* Conversion from IBM 360 format to double */ + /* + * IBM format: + * 6 5 0 + * 3 1 0 + * + * SEEEEEEEMMMM ......... MMMM + * + * Sign bit, 7 bit exponent, 56 bit fraction. Exponent is + * excess 64. The fraction is multiplied by a power of 16 of + * the actual exponent. Normalized floating point numbers are + * represented with the radix point immediately to the left of + * the high order hex fraction digit. + */ + unsigned int i, upper, lower; + /* exponent is expressed here as + excess 70 (=64+6) to accomodate + integer conversion of c[1] to c[4] */ + char negative = c[0] & 0x80; + // needs to be signed: char is not on Raspbian + signed char exponent = (c[0] & 0x7f) - 70; + double value; + char buf[4], ibuf[8]; - if (len < 2 || len > 8) - error(_("invalid field length in numeric variable")); + if (len < 2 || len > 8) + error(_("invalid field length in numeric variable")); - /* this effectively zero-pads c: */ - memset(ibuf, 0, (size_t) 8); - memcpy(ibuf, c, len); - c = ibuf; - /* check for missing value */ - /* This isn't really right: NAs are ' ', '.', A-Z plus zero fill */ - if (c[1] == '\0' && c[0] != '\0') return R_NaReal; - /* convert c[1] to c[3] to an int */ - buf[0] = '\0'; - for (i = 1; i < 4; i++) buf[i] = c[i]; - char_to_uint(buf, upper); - /* convert c[4] to c[7] to an int */ - for (i = 0; i < 4; i++) buf[i] = c[i + 4]; - char_to_uint(buf, lower); - /* initialize the constant if needed */ - value = ((double) upper + ((double) lower)/Two32) * - pow(16., (double) exponent); - if (negative) value = -value; - return value; + /* this effectively zero-pads c: */ + memset(ibuf, 0, (size_t) 8); + memcpy(ibuf, c, len); + c = ibuf; + /* check for missing value */ + /* This isn't really right: NAs are ' ', '.', A-Z plus zero fill */ + if (c[1] == '\0' && c[0] != '\0') return R_NaReal; + /* convert c[1] to c[3] to an int */ + buf[0] = '\0'; + for (i = 1; i < 4; i++) buf[i] = c[i]; + char_to_uint(buf, upper); + /* convert c[4] to c[7] to an int */ + for (i = 0; i < 4; i++) buf[i] = c[i + 4]; + char_to_uint(buf, lower); + /* initialize the constant if needed */ + value = ((double) upper + ((double) lower)/Two32) * + pow(16., (double) exponent); + if (negative) value = -value; + return value; } static int get_nam_header(FILE *fp, struct SAS_XPORT_namestr *namestr, int length) { - char record[141]; - int n; + char record[141]; + int n; - record[length] = '\0'; - n = GET_RECORD(record, fp, length); - if(n != length) - return 0; + record[length] = '\0'; + n = GET_RECORD(record, fp, length); + if(n != length) + return 0; - char_to_short(record, namestr->ntype); - char_to_short(record+2, namestr->nhfun); - char_to_short(record+4, namestr->nlng); - char_to_short(record+6, namestr->nvar0); - memcpy(namestr->nname, record + 8, 8); - memcpy(namestr->nlabel, record + 16, 40); - memcpy(namestr->nform, record + 56, 8); - char_to_short(record+64, namestr->nfl); - char_to_short(record+66, namestr->nfd); - char_to_short(record+68, namestr->nfj); - memcpy(namestr->nfill, record + 70, 2); - memcpy(namestr->niform, record + 72, 8); - char_to_short(record+80, namestr->nifl); - char_to_short(record+82, namestr->nifd); - char_to_int(record+84, namestr->npos); - return 1; + char_to_short(record, namestr->ntype); + char_to_short(record+2, namestr->nhfun); + char_to_short(record+4, namestr->nlng); + char_to_short(record+6, namestr->nvar0); + memcpy(namestr->nname, record + 8, 8); + memcpy(namestr->nlabel, record + 16, 40); + memcpy(namestr->nform, record + 56, 8); + char_to_short(record+64, namestr->nfl); + char_to_short(record+66, namestr->nfd); + char_to_short(record+68, namestr->nfj); + memcpy(namestr->nfill, record + 70, 2); + memcpy(namestr->niform, record + 72, 8); + char_to_short(record+80, namestr->nifl); + char_to_short(record+82, namestr->nifd); + char_to_int(record+84, namestr->npos); + return 1; } static int get_lib_header(FILE *fp, struct SAS_XPORT_header *head) { - char record[81]; - int n; + char record[81]; + int n; - n = GET_RECORD(record, fp, 80); - if(n != 80 || strncmp(LIB_HEADER, record, 80) != 0) - error(_("file not in SAS transfer format")); + n = GET_RECORD(record, fp, 80); + if(n != 80 || strncmp(LIB_HEADER, record, 80) != 0) + error(_("file not in SAS transfer format")); - n = GET_RECORD(record, fp, 80); - if(n != 80) - return 0; - record[80] = '\0'; - memcpy(head->sas_symbol[0], record, 8); - memcpy(head->sas_symbol[1], record+8, 8); - memcpy(head->saslib, record+16, 8); - memcpy(head->sasver, record+24, 8); - memcpy(head->sas_os, record+32, 8); - if((strrchr(record+40, ' ') - record) != 63) - return 0; - memcpy(head->sas_create, record+64, 16); + n = GET_RECORD(record, fp, 80); + if(n != 80) + return 0; + record[80] = '\0'; + memcpy(head->sas_symbol[0], record, 8); + memcpy(head->sas_symbol[1], record+8, 8); + memcpy(head->saslib, record+16, 8); + memcpy(head->sasver, record+24, 8); + memcpy(head->sas_os, record+32, 8); + if((strrchr(record+40, ' ') - record) != 63) + return 0; + memcpy(head->sas_create, record+64, 16); - n = GET_RECORD(record, fp, 80); - if(n != 80) - return 0; - record[80] = '\0'; - memcpy(head->sas_mod, record, 16); - if((strrchr(record+16, ' ') - record) != 79) - return 0; - return 1; + n = GET_RECORD(record, fp, 80); + if(n != 80) + return 0; + record[80] = '\0'; + memcpy(head->sas_mod, record, 16); + if((strrchr(record+16, ' ') - record) != 79) + return 0; + return 1; } static int get_mem_header(FILE *fp, struct SAS_XPORT_member *member) { - char record[81]; - int n; + char record[81]; + int n; - n = GET_RECORD(record, fp, 80); - if(n != 80 || strncmp(DSC_HEADER, record, 80) != 0) - error(_("file not in SAS transfer format")); + n = GET_RECORD(record, fp, 80); + if(n != 80 || strncmp(DSC_HEADER, record, 80) != 0) + error(_("file not in SAS transfer format")); - n = GET_RECORD(record, fp, 80); - if(n != 80) - return 0; - record[80] = '\0'; - memcpy(member->sas_symbol, record, 8); - memcpy(member->sas_dsname, record+8, 8); - memcpy(member->sasdata, record+16, 8); - memcpy(member->sasver, record+24, 8); - memcpy(member->sas_osname, record+32, 8); - if((strrchr(record+40, ' ') - record) != 63) - return 0; - memcpy(member->sas_create, record+64, 16); + n = GET_RECORD(record, fp, 80); + if(n != 80) + return 0; + record[80] = '\0'; + memcpy(member->sas_symbol, record, 8); + memcpy(member->sas_dsname, record+8, 8); + memcpy(member->sasdata, record+16, 8); + memcpy(member->sasver, record+24, 8); + memcpy(member->sas_osname, record+32, 8); + if((strrchr(record+40, ' ') - record) != 63) + return 0; + memcpy(member->sas_create, record+64, 16); - n = GET_RECORD(record, fp, 80); - if(n != 80) - return 0; - record[80] = '\0'; - memcpy(member->sas_mod, record, 16); + n = GET_RECORD(record, fp, 80); + if(n != 80) + return 0; + record[80] = '\0'; + memcpy(member->sas_mod, record, 16); - memcpy(member->sas_dslabel, record+32, 40); - memcpy(member->sas_dstype, record+72, 8); + memcpy(member->sas_dslabel, record+32, 40); + memcpy(member->sas_dstype, record+72, 8); - return 1; + return 1; } static int init_xport_info(FILE *fp) { - char record[81]; - int n; - int namestr_length; + char record[81]; + int n; + int namestr_length; - struct SAS_XPORT_header *lib_head; + struct SAS_XPORT_header *lib_head; - lib_head = Calloc(1, struct SAS_XPORT_header); + lib_head = Calloc(1, struct SAS_XPORT_header); - if(!get_lib_header(fp, lib_head)) { - Free(lib_head); - error(_("SAS transfer file has incorrect library header")); - } - + if(!get_lib_header(fp, lib_head)) { Free(lib_head); + error(_("SAS transfer file has incorrect library header")); + } - n = GET_RECORD(record, fp, 80); - if(n != 80 || - strncmp(MEM_HEADER, record, 75) != 0 || - strncmp(" ", record+78, 2) != 0 ) - error(_("file not in SAS transfer format")); - record[78] = '\0'; - sscanf(record+75, "%d", &namestr_length); + Free(lib_head); - return namestr_length; + n = GET_RECORD(record, fp, 80); + if(n != 80 || + strncmp(MEM_HEADER, record, 75) != 0 || + strncmp(" ", record+78, 2) != 0 ) + error(_("file not in SAS transfer format")); + record[78] = '\0'; + sscanf(record+75, "%d", &namestr_length); + + return namestr_length; } static int init_mem_info(FILE *fp, char *name, char *dslabel, char *dstype) { - int length, n; - char record[81]; - char *tmp; - struct SAS_XPORT_member *mem_head; + int length, n; + char record[81]; + char *tmp; + struct SAS_XPORT_member *mem_head; - mem_head = Calloc(1, struct SAS_XPORT_member); - if(!get_mem_header(fp, mem_head)) { - Free(mem_head); - error(_("SAS transfer file has incorrect member header")); - } + mem_head = Calloc(1, struct SAS_XPORT_member); + if(!get_mem_header(fp, mem_head)) { + Free(mem_head); + error(_("SAS transfer file has incorrect member header")); + } - n = GET_RECORD(record, fp, 80); - record[80] = '\0'; - if(n != 80 || strncmp(NAM_HEADER, record, 54) != 0 || - (strrchr(record+58, ' ') - record) != 79) { - Free(mem_head); - error(_("file not in SAS transfer format")); - } - record[58] = '\0'; - sscanf(record+54, "%d", &length); + n = GET_RECORD(record, fp, 80); + record[80] = '\0'; + if(n != 80 || strncmp(NAM_HEADER, record, 54) != 0 || + (strrchr(record+58, ' ') - record) != 79) { + Free(mem_head); + error(_("file not in SAS transfer format")); + } + record[58] = '\0'; + sscanf(record+54, "%d", &length); - tmp = strchr(mem_head->sas_dsname, ' '); - n = (int)(tmp - mem_head->sas_dsname); - if(n > 0) { - if (n > 8) - n = 8; - strncpy(name, mem_head->sas_dsname, n); - name[n] = '\0'; - } else name[0] = '\0'; + tmp = strchr(mem_head->sas_dsname, ' '); + n = (int)(tmp - mem_head->sas_dsname); + if(n > 0) { + if (n > 8) + n = 8; + strncpy(name, mem_head->sas_dsname, n); + name[n] = '\0'; + } else name[0] = '\0'; - /* Extract data set label, and trim trailing blanks */ - strncpy(dslabel, mem_head->sas_dslabel, 40); - for(int i=40-1; i>0; i--) - if( isspace(dslabel[i]) ) - dslabel[i] = '\0'; - else - break; + /* Extract data set label, and trim trailing blanks */ + strncpy(dslabel, mem_head->sas_dslabel, 40); + for(int i=40-1; i>0; i--) + if( isspace(dslabel[i]) ) + dslabel[i] = '\0'; + else + break; - /* Extract data set type */ - strncpy(dstype, mem_head->sas_dstype, 8); - for(int i=8-1; i>0; i--) - if( isspace(dstype[i]) ) - dstype[i] = '\0'; - else - break; + /* Extract data set type */ + strncpy(dstype, mem_head->sas_dstype, 8); + for(int i=8-1; i>0; i--) + if( isspace(dstype[i]) ) + dstype[i] = '\0'; + else + break; - Free(mem_head); + Free(mem_head); - return length; + return length; } static int @@ -310,176 +310,176 @@ int *nifd, int *npos) { - char *tmp; - char record[81]; - int i, n, totwidth, nlength, restOfCard; - struct SAS_XPORT_namestr *nam_head; + char *tmp; + char record[81]; + int i, n, totwidth, nlength, restOfCard; + struct SAS_XPORT_namestr *nam_head; - nam_head = Calloc(nvars, struct SAS_XPORT_namestr); + nam_head = Calloc(nvars, struct SAS_XPORT_namestr); - for(i = 0; i < nvars; i++) { - if(!get_nam_header(fp, nam_head+i, namestr_length)) { - Free(nam_head); - error(_("SAS transfer file has incorrect library header")); - } + for(i = 0; i < nvars; i++) { + if(!get_nam_header(fp, nam_head+i, namestr_length)) { + Free(nam_head); + error(_("SAS transfer file has incorrect library header")); } + } - *headpad = 480 + nvars * namestr_length; - i = *headpad % 80; - if(i > 0) { - i = 80 - i; - if (fseek(fp, i, SEEK_CUR) != 0) { - Free(nam_head); - error(_("file not in SAS transfer format")); - } - (*headpad) += i; + *headpad = 480 + nvars * namestr_length; + i = *headpad % 80; + if(i > 0) { + i = 80 - i; + if (fseek(fp, i, SEEK_CUR) != 0) { + Free(nam_head); + error(_("file not in SAS transfer format")); } + (*headpad) += i; + } - n = GET_RECORD(record, fp, 80); - if(n != 80 || strncmp(OBS_HEADER, record, 80) != 0) { - Free(nam_head); - error(_("file not in SAS transfer format")); - } + n = GET_RECORD(record, fp, 80); + if(n != 80 || strncmp(OBS_HEADER, record, 80) != 0) { + Free(nam_head); + error(_("file not in SAS transfer format")); + } - for(i = 0; i < nvars; i++) { - int nname_len = 0, nlabel_len = 0, nform_len = 0, niform_len=0; - char tmpname[41]; + for(i = 0; i < nvars; i++) { + int nname_len = 0, nlabel_len = 0, nform_len = 0, niform_len=0; + char tmpname[41]; - /* Variable storage type */ - ntype[i] = (int) ((nam_head[i].ntype == 1) ? REALSXP : STRSXP); + /* Variable storage type */ + ntype[i] = (int) ((nam_head[i].ntype == 1) ? REALSXP : STRSXP); - /* Storage length */ - nlng[i] = nam_head[i].nlng; + /* Storage length */ + nlng[i] = nam_head[i].nlng; - /* Variable number */ - nvar0[i] = nam_head[i].nvar0; + /* Variable number */ + nvar0[i] = nam_head[i].nvar0; - /* Position of var in observation */ - npos[i] = nam_head[i].npos; + /* Position of var in observation */ + npos[i] = nam_head[i].npos; - /* Variable name */ - nname_len = 8; - while (nname_len && nam_head[i].nname[nname_len-1] == ' ') - nname_len--; - strncpy(tmpname, nam_head[i].nname, nname_len); - tmpname[nname_len] = '\0'; - SET_STRING_ELT(nname, i, mkChar(tmpname)); + /* Variable name */ + nname_len = 8; + while (nname_len && nam_head[i].nname[nname_len-1] == ' ') + nname_len--; + strncpy(tmpname, nam_head[i].nname, nname_len); + tmpname[nname_len] = '\0'; + SET_STRING_ELT(nname, i, mkChar(tmpname)); - /* Variable label */ - nlabel_len = 40; - while (nlabel_len && nam_head[i].nlabel[nlabel_len-1] == ' ') - nlabel_len--; - strncpy(tmpname, nam_head[i].nlabel, nlabel_len); - tmpname[nlabel_len] = '\0'; - SET_STRING_ELT(nlabel, i, mkChar(tmpname)); + /* Variable label */ + nlabel_len = 40; + while (nlabel_len && nam_head[i].nlabel[nlabel_len-1] == ' ') + nlabel_len--; + strncpy(tmpname, nam_head[i].nlabel, nlabel_len); + tmpname[nlabel_len] = '\0'; + SET_STRING_ELT(nlabel, i, mkChar(tmpname)); - /* Variable format name */ - nform_len = 8; - while (nform_len && nam_head[i].nform[nform_len-1] == ' ') - nform_len--; - strncpy(tmpname, nam_head[i].nform, nform_len); - tmpname[nform_len] = '\0'; - SET_STRING_ELT(nform, i, mkChar(tmpname)); + /* Variable format name */ + nform_len = 8; + while (nform_len && nam_head[i].nform[nform_len-1] == ' ') + nform_len--; + strncpy(tmpname, nam_head[i].nform, nform_len); + tmpname[nform_len] = '\0'; + SET_STRING_ELT(nform, i, mkChar(tmpname)); - /* Format length */ - nfl[i] = nam_head[i].nfl;; + /* Format length */ + nfl[i] = nam_head[i].nfl;; - /* Format digits */ - nfd[i] = nam_head[i].nfd;; + /* Format digits */ + nfd[i] = nam_head[i].nfd;; - /* Variable iformat name */ - niform_len = 8; - while (niform_len && nam_head[i].niform[niform_len-1] == ' ') - niform_len--; - strncpy(tmpname, nam_head[i].niform, niform_len); - tmpname[niform_len] = '\0'; - SET_STRING_ELT(niform, i, mkChar(tmpname)); + /* Variable iformat name */ + niform_len = 8; + while (niform_len && nam_head[i].niform[niform_len-1] == ' ') + niform_len--; + strncpy(tmpname, nam_head[i].niform, niform_len); + tmpname[niform_len] = '\0'; + SET_STRING_ELT(niform, i, mkChar(tmpname)); - /* Format length */ - nifl[i] = nam_head[i].nifl;; + /* Format length */ + nifl[i] = nam_head[i].nifl;; - /* Format digits */ - nifd[i] = nam_head[i].nifd;; + /* Format digits */ + nifd[i] = nam_head[i].nifd;; - } + } - Free(nam_head); + Free(nam_head); - totwidth = 0; - for(i = 0; i < nvars; i++) - totwidth += nlng[i]; + totwidth = 0; + for(i = 0; i < nvars; i++) + totwidth += nlng[i]; - nlength = 0; - tmp = Calloc(totwidth <= 80 ? 81 : (totwidth+1), char); - restOfCard = 0; - *tailpad = 0; - while(!feof(fp)) { - int allSpace = 1; - fpos_t currentPos; + nlength = 0; + tmp = Calloc(totwidth <= 80 ? 81 : (totwidth+1), char); + restOfCard = 0; + *tailpad = 0; + while(!feof(fp)) { + int allSpace = 1; + fpos_t currentPos; -/* restOfCard = 80 - (ftell(fp) % 80); */ - if (fgetpos(fp, ¤tPos)) { - error(_("problem accessing SAS XPORT file")); - } + /* restOfCard = 80 - (ftell(fp) % 80); */ + if (fgetpos(fp, ¤tPos)) { + error(_("problem accessing SAS XPORT file")); + } - n = GET_RECORD(tmp, fp, restOfCard); - if (n != restOfCard) { - allSpace = 0; - } else { - for (i = 0; i < restOfCard; i++) { - if (tmp[i] != ' ') { - allSpace = 0; - break; - } - } + n = GET_RECORD(tmp, fp, restOfCard); + if (n != restOfCard) { + allSpace = 0; + } else { + for (i = 0; i < restOfCard; i++) { + if (tmp[i] != ' ') { + allSpace = 0; + break; } - if (allSpace) { - n = GET_RECORD(record, fp, 80); - if (n < 1) { - *tailpad = restOfCard; - break; - } - if(n == 80 && strncmp(MEM_HEADER, record, 75) == 0 && - strncmp(" ", record+78, 2) == 0) { - *tailpad = restOfCard; - record[78] = '\0'; - sscanf(record+75, "%d", &namestr_length); - break; - } - } - else /* beware that the previous member can end on card - * boundary with no padding */ - if (restOfCard == 80 && n == 80 && - strncmp(MEM_HEADER, tmp, 75) == 0 && - strncmp(" ", tmp+78, 2) == 0) { - strncpy(record, tmp, 80); - *tailpad = 0; - record[78] = '\0'; - sscanf(record+75, "%d", &namestr_length); - break; - } + } + } + if (allSpace) { + n = GET_RECORD(record, fp, 80); + if (n < 1) { + *tailpad = restOfCard; + break; + } + if(n == 80 && strncmp(MEM_HEADER, record, 75) == 0 && + strncmp(" ", record+78, 2) == 0) { + *tailpad = restOfCard; + record[78] = '\0'; + sscanf(record+75, "%d", &namestr_length); + break; + } + } + else /* beware that the previous member can end on card + * boundary with no padding */ + if (restOfCard == 80 && n == 80 && + strncmp(MEM_HEADER, tmp, 75) == 0 && + strncmp(" ", tmp+78, 2) == 0) { + strncpy(record, tmp, 80); + *tailpad = 0; + record[78] = '\0'; + sscanf(record+75, "%d", &namestr_length); + break; + } - if (fsetpos(fp, ¤tPos)) { - error(_("problem accessing SAS XPORT file")); - } + if (fsetpos(fp, ¤tPos)) { + error(_("problem accessing SAS XPORT file")); + } - n = GET_RECORD(tmp, fp, totwidth); - if (n != totwidth) { - if (!feof(fp)) { - error(_("problem accessing SAS XPORT file")); - } - *tailpad = n; - break; - } - restOfCard = (restOfCard >= totwidth)? - (restOfCard - totwidth): - (80 - (totwidth - restOfCard)%80); - nlength++; + n = GET_RECORD(tmp, fp, totwidth); + if (n != totwidth) { + if (!feof(fp)) { + error(_("problem accessing SAS XPORT file")); + } + *tailpad = n; + break; } - *length = nlength; - Free(tmp); + restOfCard = (restOfCard >= totwidth)? + (restOfCard - totwidth): + (80 - (totwidth - restOfCard)%80); + nlength++; + } + *length = nlength; + Free(tmp); - return (feof(fp)?-1:namestr_length); + return (feof(fp)?-1:namestr_length); } /* @@ -488,42 +488,42 @@ static SEXP getListElement(SEXP list, char *str) { - SEXP names; - SEXP elmt = (SEXP) NULL; - const char *tempChar; - int i; + SEXP names; + SEXP elmt = (SEXP) NULL; + const char *tempChar; + int i; - names = getAttrib(list, R_NamesSymbol); + names = getAttrib(list, R_NamesSymbol); - for (i = 0; i < LENGTH(list); i++) { - tempChar = CHAR(STRING_ELT(names, i)); - if( strcmp(tempChar,str) == 0) { - elmt = VECTOR_ELT(list, i); - break; - } + for (i = 0; i < LENGTH(list); i++) { + tempChar = CHAR(STRING_ELT(names, i)); + if( strcmp(tempChar,str) == 0) { + elmt = VECTOR_ELT(list, i); + break; } - return elmt; + } + return elmt; } #define VAR_INFO_LENGTH 16 const char *cVarInfoNames[VAR_INFO_LENGTH] = { - "headpad", - "type", - "width", - "index", - "position", - "name", - "label", - "format", - "flength", - "fdigits", - "iformat", - "iflength", - "ifdigits", - "sexptype", - "tailpad", - "length" + "headpad", + "type", + "width", + "index", + "position", + "name", + "label", + "format", + "flength", + "fdigits", + "iformat", + "iflength", + "ifdigits", + "sexptype", + "tailpad", + "length" }; #define XPORT_VAR_HEADPAD(varinfo) VECTOR_ELT(varinfo, 0) @@ -564,214 +564,210 @@ SEXP xport_info(SEXP xportFile) { - FILE *fp; - int i, namestrLength, memLength, ansLength; - char dsname[9]; - char dslabel[41]; - char dstype[9]; - SEXP ans, ansNames, varInfoNames, varInfo; - SEXP char_numeric, char_character; - SEXP dfLabel, dfType; + FILE *fp; + int i, namestrLength, memLength, ansLength; + char dsname[9]; + char dslabel[41]; + char dstype[9]; + SEXP ans, ansNames, varInfoNames, varInfo; + SEXP char_numeric, char_character; + SEXP dfLabel, dfType; - PROTECT(varInfoNames = allocVector(STRSXP, VAR_INFO_LENGTH)); - for(i = 0; i < VAR_INFO_LENGTH; i++) - SET_STRING_ELT(varInfoNames, i, mkChar(cVarInfoNames[i])); + PROTECT(varInfoNames = allocVector(STRSXP, VAR_INFO_LENGTH)); + for(i = 0; i < VAR_INFO_LENGTH; i++) + SET_STRING_ELT(varInfoNames, i, mkChar(cVarInfoNames[i])); - PROTECT(char_numeric = mkChar("numeric")); - PROTECT(char_character = mkChar("character")); + PROTECT(char_numeric = mkChar("numeric")); + PROTECT(char_character = mkChar("character")); - if(!isValidString(xportFile)) - error(_("first argument must be a file name")); - fp = fopen(R_ExpandFileName(CHAR(STRING_ELT(xportFile, 0))), "rb"); - if (!fp) - error(_("unable to open file: '%s'"), strerror(errno)); - namestrLength = init_xport_info(fp); + if(!isValidString(xportFile)) + error(_("first argument must be a file name")); + fp = fopen(R_ExpandFileName(CHAR(STRING_ELT(xportFile, 0))), "rb"); + if (!fp) + error(_("unable to open file: '%s'"), strerror(errno)); + namestrLength = init_xport_info(fp); - ansLength = 0; - PROTECT(ans = allocVector(VECSXP, 0)); - PROTECT(ansNames = allocVector(STRSXP, 0)); + ansLength = 0; + PROTECT(ans = allocVector(VECSXP, 0)); + PROTECT(ansNames = allocVector(STRSXP, 0)); - while(!feof(fp)) - { - memLength = init_mem_info(fp, dsname, dslabel, dstype); + while(!feof(fp)) + { + memLength = init_mem_info(fp, dsname, dslabel, dstype); - PROTECT(varInfo = allocVector(VECSXP, VAR_INFO_LENGTH)); - setAttrib(varInfo, R_NamesSymbol, varInfoNames); + PROTECT(varInfo = allocVector(VECSXP, VAR_INFO_LENGTH)); + setAttrib(varInfo, R_NamesSymbol, varInfoNames); - dslabel[40] = '\n'; - PROTECT(dfLabel = allocVector(STRSXP, 1)); - SET_STRING_ELT(dfLabel, 0, mkChar(dslabel)); - setAttrib(varInfo, install("label" ), dfLabel); + dslabel[40] = '\n'; + PROTECT(dfLabel = allocVector(STRSXP, 1)); + SET_STRING_ELT(dfLabel, 0, mkChar(dslabel)); + setAttrib(varInfo, install("label" ), dfLabel); - dstype[8] = '\n'; - PROTECT(dfType = allocVector(STRSXP, 1)); - SET_STRING_ELT(dfType, 0, mkChar(dstype)); - setAttrib(varInfo, install("SAStype"), dfType ); + dstype[8] = '\n'; + PROTECT(dfType = allocVector(STRSXP, 1)); + SET_STRING_ELT(dfType, 0, mkChar(dstype)); + setAttrib(varInfo, install("SAStype"), dfType ); - SET_XPORT_VAR_TYPE(varInfo, allocVector(STRSXP, memLength)); - SET_XPORT_VAR_WIDTH(varInfo, allocVector(INTSXP, memLength)); - SET_XPORT_VAR_INDEX(varInfo, allocVector(INTSXP, memLength)); - SET_XPORT_VAR_POSITION(varInfo, allocVector(INTSXP, memLength)); - SET_XPORT_VAR_NAME(varInfo, allocVector(STRSXP, memLength)); - SET_XPORT_VAR_LABEL(varInfo, allocVector(STRSXP, memLength)); - SET_XPORT_VAR_FORM(varInfo, allocVector(STRSXP, memLength)); - SET_XPORT_VAR_FLENGTH(varInfo, allocVector(INTSXP, memLength)); - SET_XPORT_VAR_FDIGITS(varInfo, allocVector(INTSXP, memLength)); - SET_XPORT_VAR_IFORM(varInfo, allocVector(STRSXP, memLength)); - SET_XPORT_VAR_IFLENGTH(varInfo, allocVector(INTSXP, memLength)); - SET_XPORT_VAR_IFDIGITS(varInfo, allocVector(INTSXP, memLength)); - SET_XPORT_VAR_SEXPTYPE(varInfo, allocVector(INTSXP, memLength)); - SET_XPORT_VAR_HEADPAD(varInfo, allocVector(INTSXP, 1)); - SET_XPORT_VAR_TAILPAD(varInfo, allocVector(INTSXP, 1)); - SET_XPORT_VAR_LENGTH(varInfo, allocVector(INTSXP, 1)); + SET_XPORT_VAR_TYPE(varInfo, allocVector(STRSXP, memLength)); + SET_XPORT_VAR_WIDTH(varInfo, allocVector(INTSXP, memLength)); + SET_XPORT_VAR_INDEX(varInfo, allocVector(INTSXP, memLength)); + SET_XPORT_VAR_POSITION(varInfo, allocVector(INTSXP, memLength)); + SET_XPORT_VAR_NAME(varInfo, allocVector(STRSXP, memLength)); + SET_XPORT_VAR_LABEL(varInfo, allocVector(STRSXP, memLength)); + SET_XPORT_VAR_FORM(varInfo, allocVector(STRSXP, memLength)); + SET_XPORT_VAR_FLENGTH(varInfo, allocVector(INTSXP, memLength)); + SET_XPORT_VAR_FDIGITS(varInfo, allocVector(INTSXP, memLength)); + SET_XPORT_VAR_IFORM(varInfo, allocVector(STRSXP, memLength)); + SET_XPORT_VAR_IFLENGTH(varInfo, allocVector(INTSXP, memLength)); + SET_XPORT_VAR_IFDIGITS(varInfo, allocVector(INTSXP, memLength)); + SET_XPORT_VAR_SEXPTYPE(varInfo, allocVector(INTSXP, memLength)); + SET_XPORT_VAR_HEADPAD(varInfo, allocVector(INTSXP, 1)); + SET_XPORT_VAR_TAILPAD(varInfo, allocVector(INTSXP, 1)); + SET_XPORT_VAR_LENGTH(varInfo, allocVector(INTSXP, 1)); - namestrLength = - next_xport_info(fp, namestrLength, memLength, - INTEGER(XPORT_VAR_HEADPAD(varInfo)), - INTEGER(XPORT_VAR_TAILPAD(varInfo)), - INTEGER(XPORT_VAR_LENGTH(varInfo)), - INTEGER(XPORT_VAR_SEXPTYPE(varInfo)), - INTEGER(XPORT_VAR_WIDTH(varInfo)), - INTEGER(XPORT_VAR_INDEX(varInfo)), - XPORT_VAR_NAME(varInfo), - XPORT_VAR_LABEL(varInfo), - XPORT_VAR_FORM(varInfo), - INTEGER(XPORT_VAR_FLENGTH(varInfo)), - INTEGER(XPORT_VAR_FDIGITS(varInfo)), - XPORT_VAR_IFORM(varInfo), - INTEGER(XPORT_VAR_IFLENGTH(varInfo)), - INTEGER(XPORT_VAR_IFDIGITS(varInfo)), - INTEGER(XPORT_VAR_POSITION(varInfo)) - ); + namestrLength = + next_xport_info(fp, namestrLength, memLength, + INTEGER(XPORT_VAR_HEADPAD(varInfo)), + INTEGER(XPORT_VAR_TAILPAD(varInfo)), + INTEGER(XPORT_VAR_LENGTH(varInfo)), + INTEGER(XPORT_VAR_SEXPTYPE(varInfo)), + INTEGER(XPORT_VAR_WIDTH(varInfo)), + INTEGER(XPORT_VAR_INDEX(varInfo)), + XPORT_VAR_NAME(varInfo), + XPORT_VAR_LABEL(varInfo), + XPORT_VAR_FORM(varInfo), + INTEGER(XPORT_VAR_FLENGTH(varInfo)), + INTEGER(XPORT_VAR_FDIGITS(varInfo)), + XPORT_VAR_IFORM(varInfo), + INTEGER(XPORT_VAR_IFLENGTH(varInfo)), + INTEGER(XPORT_VAR_IFDIGITS(varInfo)), + INTEGER(XPORT_VAR_POSITION(varInfo)) + ); - for(i = 0; i < memLength; i++) { - int *ntype = INTEGER(XPORT_VAR_SEXPTYPE(varInfo)); - SET_STRING_ELT(XPORT_VAR_TYPE(varInfo), i, - (ntype[i] == REALSXP) ? char_numeric : - char_character); - } - PROTECT(ans = lengthgets(ans, ansLength+1)); - PROTECT(ansNames = lengthgets(ansNames, ansLength+1)); + for(i = 0; i < memLength; i++) { + int *ntype = INTEGER(XPORT_VAR_SEXPTYPE(varInfo)); + SET_STRING_ELT(XPORT_VAR_TYPE(varInfo), i, + (ntype[i] == REALSXP) ? char_numeric : + char_character); + } + PROTECT(ans = lengthgets(ans, ansLength+1)); + PROTECT(ansNames = lengthgets(ansNames, ansLength+1)); -/* PROTECT(newAns = allocVector(VECSXP, ansLength+1)); */ -/* PROTECT(newAnsNames = allocVector(STRSXP, ansLength+1)); */ + /* PROTECT(newAns = allocVector(VECSXP, ansLength+1)); */ + /* PROTECT(newAnsNames = allocVector(STRSXP, ansLength+1)); */ -/* for(i = 0; i < ansLength; i++) { */ -/* SET_VECTOR_ELT(newAns, i, VECTOR_ELT(ans, i)); */ -/* SET_STRING_ELT(newAnsNames, i, STRING_ELT(ansNames, i)); */ -/* } */ -/* ans = newAns; */ -/* ansNames = newAnsNames; */ + /* for(i = 0; i < ansLength; i++) { */ + /* SET_VECTOR_ELT(newAns, i, VECTOR_ELT(ans, i)); */ + /* SET_STRING_ELT(newAnsNames, i, STRING_ELT(ansNames, i)); */ + /* } */ + /* ans = newAns; */ + /* ansNames = newAnsNames; */ - SET_STRING_ELT(ansNames , ansLength, mkChar(dsname )); - SET_VECTOR_ELT(ans, ansLength, varInfo); - ansLength++; + SET_STRING_ELT(ansNames , ansLength, mkChar(dsname )); + SET_VECTOR_ELT(ans, ansLength, varInfo); + ansLength++; - UNPROTECT(7); - PROTECT(ans); - PROTECT(ansNames); + UNPROTECT(7); + PROTECT(ans); + PROTECT(ansNames); } - setAttrib(ans, R_NamesSymbol, ansNames); - UNPROTECT(5); - fclose(fp); - return ans; + setAttrib(ans, R_NamesSymbol, ansNames); + UNPROTECT(5); + fclose(fp); + return ans; } SEXP xport_read(SEXP xportFile, SEXP xportInfo) { - int i, j, k, n; - int nvar; - int ansLength, dataLength, totalWidth; - int dataHeadPad, dataTailPad; - int *dataWidth; - int *dataPosition; - SEXPTYPE *dataType; - char *record, *tmpchar, *c; - FILE *fp; - SEXP ans, names, data, dataInfo, dataName; - double dbl; + int i, j, k, n; + int nvar; + int ansLength, dataLength, totalWidth; + int dataHeadPad, dataTailPad; + int *dataWidth; + int *dataPosition; + SEXPTYPE *dataType; + char *record, *tmpchar, *c; + FILE *fp; + SEXP ans, names, data, dataInfo, dataName; + double dbl; - ansLength = LENGTH(xportInfo); - PROTECT(ans = allocVector(VECSXP, ansLength)); - names = getAttrib(xportInfo, R_NamesSymbol); - setAttrib(ans, R_NamesSymbol, names); + ansLength = LENGTH(xportInfo); + PROTECT(ans = allocVector(VECSXP, ansLength)); + names = getAttrib(xportInfo, R_NamesSymbol); + setAttrib(ans, R_NamesSymbol, names); - if(!isValidString(xportFile)) - error(_("first argument must be a file name")); - fp = fopen(R_ExpandFileName(CHAR(STRING_ELT(xportFile, 0))), "rb"); - if (!fp) - error(_("unable to open file: '%s'"), strerror(errno)); - if (fseek(fp, 240, SEEK_SET) != 0) - error(_("problem reading SAS XPORT file '%s'"), - CHAR(STRING_ELT(xportFile, 0))); + if(!isValidString(xportFile)) + error(_("first argument must be a file name")); + fp = fopen(R_ExpandFileName(CHAR(STRING_ELT(xportFile, 0))), "rb"); + if (!fp) + error(_("unable to open file: '%s'"), strerror(errno)); + if (fseek(fp, 240, SEEK_SET) != 0) + error(_("problem reading SAS XPORT file '%s'"), + CHAR(STRING_ELT(xportFile, 0))); - for(i = 0; i < ansLength; i++) { - dataInfo = VECTOR_ELT(xportInfo, i); - dataName = getListElement(dataInfo, "name"); - nvar = LENGTH(dataName); - dataLength = asInteger(getListElement(dataInfo, "length")); - SET_VECTOR_ELT(ans, i, data = allocVector(VECSXP, nvar)); - setAttrib(data, R_NamesSymbol, dataName); - dataType = (SEXPTYPE *) INTEGER(getListElement(dataInfo, "sexptype")); - for(j = 0; j < nvar; j++) - SET_VECTOR_ELT(data, j, allocVector(dataType[j], dataLength)); + for(i = 0; i < ansLength; i++) { + dataInfo = VECTOR_ELT(xportInfo, i); + dataName = getListElement(dataInfo, "name"); + nvar = LENGTH(dataName); + dataLength = asInteger(getListElement(dataInfo, "length")); + SET_VECTOR_ELT(ans, i, data = allocVector(VECSXP, nvar)); + setAttrib(data, R_NamesSymbol, dataName); + dataType = (SEXPTYPE *) INTEGER(getListElement(dataInfo, "sexptype")); + for(j = 0; j < nvar; j++) + SET_VECTOR_ELT(data, j, allocVector(dataType[j], dataLength)); - dataWidth = INTEGER(getListElement(dataInfo, "width")); - dataPosition = INTEGER(getListElement(dataInfo, "position")); + dataWidth = INTEGER(getListElement(dataInfo, "width")); + dataPosition = INTEGER(getListElement(dataInfo, "position")); - totalWidth = 0; - for(j = 0; j < nvar; j++) - totalWidth += dataWidth[j]; - record = Calloc(totalWidth + 1, char); + totalWidth = 0; + for(j = 0; j < nvar; j++) + totalWidth += dataWidth[j]; + record = Calloc(totalWidth + 1, char); - dataHeadPad = asInteger(getListElement(dataInfo, "headpad")); - dataTailPad = asInteger(getListElement(dataInfo, "tailpad")); - fseek(fp, dataHeadPad, SEEK_CUR); + dataHeadPad = asInteger(getListElement(dataInfo, "headpad")); + dataTailPad = asInteger(getListElement(dataInfo, "tailpad")); + fseek(fp, dataHeadPad, SEEK_CUR); - for(j = 0; j < dataLength; j++) { - n = GET_RECORD(record, fp, totalWidth); - if(n != totalWidth) { - error(_("problem reading SAS transport file")); - } + for(j = 0; j < dataLength; j++) { + n = GET_RECORD(record, fp, totalWidth); + if(n != totalWidth) { + error(_("problem reading SAS transport file")); + } - for(k = nvar-1; k >= 0; k--) { - tmpchar = record + dataPosition[k]; - if(dataType[k] == REALSXP) { + for(k = nvar-1; k >= 0; k--) { + tmpchar = record + dataPosition[k]; + if(dataType[k] == REALSXP) + { +#ifdef BIGENDIAN + reverse_double(tmpchar); +#endif - /* REAL(VECTOR_ELT(data, k))[j] = */ - /* get_IBM_double(tmpchar, dataWidth[k]); */ + REAL(VECTOR_ELT(data, k))[j] = + get_IBM_double(tmpchar, dataWidth[k]); + } + else + { + tmpchar[dataWidth[k]] = '\0'; + /* strip trailing blanks */ + c = tmpchar + dataWidth[k]; + while (c-- > tmpchar && *c == ' ') + *c ='\0'; - ibm2ieee( (unsigned char*) &dbl, - (unsigned char*) tmpchar, - 1 ); + SET_STRING_ELT(VECTOR_ELT(data, k), j, + (c < tmpchar) ? R_BlankString : + mkChar(tmpchar)); + } + } + } - /* convert from big-endian layout */ - to_bigend( (unsigned char*) &dbl, sizeof(double) ); + fseek(fp, dataTailPad, SEEK_CUR); - REAL(VECTOR_ELT(data, k))[j] = dbl; - - } else { - tmpchar[dataWidth[k]] = '\0'; - /* strip trailing blanks */ - c = tmpchar + dataWidth[k]; - while (c-- > tmpchar && *c == ' ') - *c ='\0'; - - SET_STRING_ELT(VECTOR_ELT(data, k), j, - (c < tmpchar) ? R_BlankString : - mkChar(tmpchar)); - } - } - } - - fseek(fp, dataTailPad, SEEK_CUR); - - Free(record); - } - UNPROTECT(1); - fclose(fp); - return ans; + Free(record); + } + UNPROTECT(1); + fclose(fp); + return ans; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |