Dear Sirs;
I have found a minor bug in ncgen on the HP9000/720 platform
which I have corrected in the following patch.
The bug is related to 8 bit characters in fortran and c strings.
Characters in HP-c are signextended when they are converted
to integers and this leads to negative integers in char() function
calls in the generated fortran code and abnormal termination of c
strings in the generated c code when 8 bit characters in strings
are encountered.
I modified the files main.c and generate.c by using "unsigned char"
instead of "char" in order to prevent signextension where needed
to eliminate this bug.
8 bit characters above '\0240' are legal printable characters in many
Europian languages including Icelandic. I modified to ncgen code for hpux
such that if STR8BIT is defined, then 8 bit printable characters are
treated as ordinary 7 bit characters in fortran (works only for hpux) and
c strings generated by ncgen.
Those who do not want this feature can drop the "-DSTR8BIT"
part in the "make ncgen" command below.
The patch is applied by writing the patch code below to a seperate file,
which may be named nc-hpux-patch2, and giving the following commands
(remember to substitude "/usr/contrib" with the appropriate path):
cd <netcdf home directory>
patch -p0 < nc-hpux-patch2
cd ncgen
make COPTS="-Aa -O -Dunix -Dhpux -D_HPUX_SOURCE -DSTR8BIT -Wl,-a,archive \
-L/usr/contrib/lib" ncgen
make DESTDIR=/usr/contrib INSTALL=install.bsd BINMODE=755 install
make clean
****************************** cut here ***************************************
*** ../netcdf.orig/ncgen/main.c Mon Dec 23 20:42:00 1991
--- ncgen/main.c Wed Jun 17 18:44:54 1992
***************
*** 4,9 ****
--- 4,15 ----
* $Header: /usr/local/home/russ/sdmsrc/netcdf/ncgen/RCS/main.c,v 1.8
1991/04/04 18:44:24 russ Exp $
*********************************************************************/
+ #ifdef hpux
+ #ifdef STR8BIT
+ #include <locale.h>
+ #endif
+ #endif
+
#include <stdio.h>
#include <string.h>
#include "ncvoid.h"
***************
*** 30,35 ****
--- 36,47 ----
extern char *optarg;
int c;
FILE *fp, *efopen();
+
+ #ifdef hpux
+ #ifdef STR8BIT
+ setlocale(LC_CTYPE,"");
+ #endif
+ #endif
#ifdef MDEBUG
malloc_debug(2) ; /* helps find malloc/free errors on Sun */
*** ../netcdf.orig/ncgen/generate.c Mon Dec 23 20:41:57 1991
--- ncgen/generate.c Wed Jun 17 18:10:40 1992
***************
*** 938,960 ****
--- 938,978 ----
char *valp; /* pointer to vector of characters*/
long len; /* number of characters in valp */
{
+ #ifdef hpux
+ static unsigned char *sp;
+ unsigned char *cp;
+ unsigned char *istr, *istr0; /* for null-terminated copy */
+ #else
static char *sp;
char *cp;
char *istr, *istr0; /* for null-terminated copy */
+ #endif
if(4*len+3 != (unsigned)(4*len+3)) {
derror("too much character data!");
exit(9);
}
+ #ifdef hpux
+ istr0 = istr = (unsigned char *) malloc((unsigned)(len + 1));
+ #else
istr0 = istr = (char *) malloc((unsigned)(len + 1));
+ #endif
if(istr == 0) {
derror("out of memory");
exit(3);
}
+ #ifdef hpux
+ strncpy((char *)istr, (char *) valp, (int)len);
+ #else
strncpy(istr, (char *) valp, (int)len);
+ #endif
istr[len] = '\0';
+ #ifdef hpux
+ sp = cp = (unsigned char *) malloc((unsigned)(4*len+3));
+ #else
sp = cp = (char *) malloc((unsigned)(4*len+3));
+ #endif
if(sp == 0) {
derror("out of memory");
exit(3);
***************
*** 973,979 ****
case '\?': *cp++ = '\\'; *cp++ = '?'; break;
case '\'': *cp++ = '\\'; *cp++ = '\''; break;
default:
! if (*istr < '\040' || *istr > '\176') { /* assumes ASCII */
static char octs[] = "01234567";
int rem = *istr%64;
*cp++ = '\\';
--- 991,1002 ----
case '\?': *cp++ = '\\'; *cp++ = '?'; break;
case '\'': *cp++ = '\\'; *cp++ = '\''; break;
default:
! #ifdef STR8BIT
! if (*istr < 040 ||
! (*istr > 0176 && *istr < 0240)) { /* assumes ASCII */
! #else
! if (*istr < 040 || *istr > 0176) { /* assumes ASCII */
! #endif
static char octs[] = "01234567";
int rem = *istr%64;
*cp++ = '\\';
***************
*** 990,996 ****
--- 1013,1023 ----
*cp++ = '"';
*cp = '\0';
free(istr0);
+ #ifdef hpux
+ return (char *)sp;
+ #else
return sp;
+ #endif
}
***************
*** 1006,1030 ****
char *str; /* pointer to vector of characters */
long ilen; /* number of characters in istr */
{
static char *ostr;
char *cp, tstr[12];
int was_print = 0; /* true if last character was printable
*/
char *istr, *istr0; /* for null-terminated copy */
-
if(12*ilen != (unsigned)(12*ilen)) {
derror("too much character data!");
exit(9);
}
istr0 = istr = (char *) malloc((unsigned) (ilen + 1));
if(istr == 0) {
derror("out of memory");
exit(3);
}
strncpy(istr, (char *) str, (int)ilen);
istr[ilen] = '\0';
ostr = cp = (char *) malloc((unsigned) (12*ilen));
if(ostr == 0) {
derror("out of memory");
exit(3);
--- 1033,1076 ----
char *str; /* pointer to vector of characters */
long ilen; /* number of characters in istr */
{
+ #ifdef hpux
+ static unsigned char *ostr;
+ unsigned char *cp, tstr[12];
+ int was_print = 0; /* true if last character was printable
*/
+ unsigned char *istr, *istr0; /* for null-terminated copy */
+ #else
static char *ostr;
char *cp, tstr[12];
int was_print = 0; /* true if last character was printable
*/
char *istr, *istr0; /* for null-terminated copy */
+ #endif
if(12*ilen != (unsigned)(12*ilen)) {
derror("too much character data!");
exit(9);
}
+
+ #ifdef hpux
+ istr0 = istr = (unsigned char *) malloc((unsigned) (ilen + 1));
+ #else
istr0 = istr = (char *) malloc((unsigned) (ilen + 1));
+ #endif
if(istr == 0) {
derror("out of memory");
exit(3);
}
+ #ifdef hpux
+ strncpy((char *) istr, (char *) str, (int)ilen);
+ #else
strncpy(istr, (char *) str, (int)ilen);
+ #endif
istr[ilen] = '\0';
+ #ifdef hpux
+ ostr = cp = (unsigned char *) malloc((unsigned) (12*ilen));
+ #else
ostr = cp = (char *) malloc((unsigned) (12*ilen));
+ #endif
if(ostr == 0) {
derror("out of memory");
exit(3);
***************
*** 1031,1039 ****
--- 1077,1091 ----
}
*ostr = '\0';
if (*istr == '\0') { /* empty string input, not legal in FORTRAN */
+ #ifdef hpux
+ strcat((char *)ostr,"' '");
+ free(istr0);
+ return (char *)ostr;
+ #else
strcat(ostr,"' '");
free(istr0);
return ostr;
+ #endif
}
if (isprint(*istr)) { /* handle first character in input */
*cp++ = '\'';
***************
*** 1046,1054 ****
--- 1098,1112 ----
*cp = '\0';
was_print = 1;
} else {
+ #ifdef hpux
+ sprintf((char *)tstr, "char(%d)", *istr);
+ strcat((char *)cp, (char *)tstr);
+ cp += strlen((char *)tstr);
+ #else
sprintf(tstr, "char(%d)", *istr);
strcat(cp, tstr);
cp += strlen(tstr);
+ #endif
was_print = 0;
}
istr++;
***************
*** 1056,1062 ****
--- 1114,1124 ----
while (*istr != '\0') { /* handle subsequent characters in input */
if (isprint(*istr)) {
if (! was_print) {
+ #ifdef hpux
+ strcat((char *)cp, "//'");
+ #else
strcat(cp, "//'");
+ #endif
cp += 3;
}
if (*istr == '\'') {
***************
*** 1072,1080 ****
--- 1134,1148 ----
*cp++ = '\'';
*cp = '\0';
}
+ #ifdef hpux
+ sprintf((char *)tstr, "//char(%d)", *istr);
+ strcat((char *)cp, (char *)tstr);
+ cp += strlen((char *)tstr);
+ #else
sprintf(tstr, "//char(%d)", *istr);
strcat(cp, tstr);
cp += strlen(tstr);
+ #endif
was_print = 0;
}
istr++;
***************
*** 1083,1089 ****
--- 1151,1161 ----
*cp++ = '\'';
*cp = '\0';
free(istr0);
+ #ifdef hpux
+ return (char *)ostr;
+ #else
return ostr;
+ #endif
}