wnly.c

Go to the documentation of this file.
00001 /*
00002 
00003   Copyright (C) 2000, 2001, Silicon Graphics, Inc.  All Rights Reserved.
00004 
00005   This program is free software; you can redistribute it and/or modify it
00006   under the terms of version 2.1 of the GNU Lesser General Public License 
00007   as published by the Free Software Foundation.
00008 
00009   This program is distributed in the hope that it would be useful, but
00010   WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
00012 
00013   Further, this software is distributed without any warranty that it is
00014   free of the rightful claim of any third person regarding infringement 
00015   or the like.  Any license provided herein, whether implied or 
00016   otherwise, applies only to this software file.  Patent licenses, if
00017   any, provided herein do not apply to combinations of this program with 
00018   other software, or any other product whatsoever.  
00019 
00020   You should have received a copy of the GNU Lesser General Public 
00021   License along with this program; if not, write the Free Software 
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, 
00023   USA.
00024 
00025   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
00026   Mountain View, CA 94043, or:
00027 
00028   http://www.sgi.com
00029 
00030   For further information regarding this notice, see:
00031 
00032   http://oss.sgi.com/projects/GenInfo/NoticeExplan
00033 
00034 */
00035 
00036 
00037 
00038 #pragma ident "@(#) libf/fio/wnly.c     92.1    06/21/99 10:37:55"
00039 
00040 /*
00041  *      Namelist output
00042  */
00043 
00044 #include <stdio.h>
00045 #include <errno.h>
00046 #include <fortran.h>
00047 #include <memory.h>
00048 #include <malloc.h>
00049 #include <liberrno.h>
00050 #include <stdlib.h>
00051 #include <cray/fmtconv.h>
00052 #include "fio.h"
00053 #include "fmt.h"        
00054 #include "lio.h"
00055 #include "rnl.h"
00056 
00057 extern void _memwcpy (long *_S1, long *_S2, int _N);
00058 
00059 /*
00060  * YMP80 is true if the LISTIO_PRECISION environment variable is set to
00061  * 'YMP80'.  This is a compatibility mode which prints namelist output
00062  * in the same form as was seen in UNICOS 8.0.
00063  */
00064 
00065 #define YMP80   (_dreal8 == DREAL8_YMP80)
00066 
00067 /*
00068  * This structure contains an unpacked buffer where output is stored and,
00069  * for some bizarre reason, another unpacked buffer where output is formatted.
00070  * The first buffer is equated to the line buffer in the unit table and the
00071  * second buffer is malloc'ed to match (the code assumes that the two buffers
00072  * are the same size).  Someday, this BUFFERS structure can be tossed into
00073  * the bit bucket and much of this code can be replaced with the list-
00074  * directed output routines.
00075  */
00076 
00077 struct BUFFERS {
00078         long    *outbuff;       /* Output buffer                */
00079         long    *outptr;        /* Next free spot in outbuff    */
00080         int     outcnt;         /* Remaining space in outbuff   */
00081         long    *f_lbuf;        /* Buffer for formatting output */
00082         long    *f_lbufptr;     /* Next free spot in f_lbufptr  */
00083         int     f_lbufcnt;      /* Number of elements in f_lbuf */
00084         int     lcomma;         /* 1 => comma before next value */
00085 };
00086 
00087 static char     *char_rep(char *_P, int _Cn, unsigned int _Ln, int *_Lc,
00088                         struct BUFFERS *_Bp);
00089 
00090 static long     *find_rep(long *_P, int _Cn, int _In, int _Ty, int *_Lc,
00091                         struct BUFFERS *_Bp);
00092 
00093 static int      l_write(FIOSPTR css, unit *cup, void *dptr, unsigned elsize,
00094                         int count, int inc, int type, long recsize, int errf,
00095                         struct BUFFERS *bptr);
00096 
00097 static int      lw_A(FIOSPTR css, char *_P, int _Cl, long _Rc, unit *_Cu,
00098                         int _Er, struct BUFFERS *_Bp);
00099 
00100 static void     writ_rep(long repcnt, struct BUFFERS *buffers);
00101 
00102 /*
00103  * NLPUT adds a character to the output buffer.
00104  */
00105 
00106 #define NLPUT(x) {      \
00107         *(bptr->outptr)++       = (long) x;     \
00108         bptr->outcnt--;                         \
00109 }
00110 
00111 #define NLPUTS(string) {        \
00112         s       = string;       \
00113         while (c = *s++) {      \
00114                 NLPUT(c);       \
00115         }                       \
00116 }
00117 
00118 /* 
00119  * LPUT adds a character to the formatting buffer.
00120  */
00121 
00122 #define LPUT(x) {       \
00123         (*(bptr->f_lbufptr)++   = (long) x);    \
00124         bptr->f_lbufcnt++;                      \
00125 }
00126 
00127 #define LPUTS(string) {         \
00128         s       = string;       \
00129         while (c = *s++) {      \
00130                 LPUT(c);        \
00131         }                       \
00132 }
00133 
00134 /*
00135  * NLINE determines whether user specified new line for each variable.
00136  */
00137 
00138 #define NLINE() { \
00139         bptr->lcomma    = 0;    /* suppress commas except for arrays */ \
00140         if (OUT_LINE) { \
00141                 REPFLUSH();     /* Write out what's in outbuff */       \
00142         }               \
00143 }
00144 
00145 /*
00146  * REPFLUSH writes what's in outbuff.
00147  * Reset pointers and counters so we start at the beginning of the buffer.
00148  * The first character in outbuff is used for carriage control.
00149  */
00150 
00151 #define REPFLUSH() {                    \
00152         if (_fwch(cup, bptr->outbuff, recsize - bptr->outcnt, 1) < 0)\
00153                 RERR(css, errno);               \
00154         bptr->outptr    = bptr->outbuff;\
00155         *bptr->outptr++ = (long) ' ';   \
00156         *bptr->outptr++ = (long) ' ';   \
00157         bptr->outcnt    = recsize - 2;  \
00158 }
00159 
00160 /*
00161  * @WNL - write namelist
00162  *
00163  * @WNL 
00164  *      set up namelist and entry pointers
00165  *      output namelist name in proper format
00166  *      do
00167  *              output variable name
00168  *              output value based on type
00169  *              point to next entry
00170  *      output end line
00171  * end @WNL
00172  */
00173 
00174 int
00175 @WNL(
00176         _f_int          *unump,         /* Unit number or dataset name */
00177         Namelist        *nl,            /* Namelist structure */
00178         int             errf            /* Nonzero if ERR specified */
00179 )
00180 {
00181         unum_t          unum;
00182         int             errn;
00183         int             n, ss; 
00184         void            *vaddr;         /* variable address */
00185         unsigned        elsize;         /* size in bytes of the variable */
00186         long            recsize;        /* number of characters to output per
00187                                          * line.  Used by REPFLUSH.*/
00188         char            c;              /* needed by NLPUTS macro */
00189         char            *s;             /* needed by NLPUTS macro */
00190         unit            *cup;           /* unit pointer */
00191         Nlentry         *nlent;
00192         FIOSPTR         css;
00193         struct BUFFERS  wnlbuffers;
00194         struct BUFFERS  *bptr;
00195         bptr            = &wnlbuffers;
00196         bptr->f_lbuf    = NULL;
00197 
00198         unum            = *unump;
00199 
00200         GET_FIOS_PTR(css);
00201         STMT_BEGIN(unum, 0, T_WNL, NULL, css, cup);
00202 
00203         if (cup == NULL) {      /* if not connected */
00204                 cup     = _imp_open77(css, SEQ, FMT, unum, errf, &errn);
00205                 /*
00206                  * If the open failed, cup is NULL and errn contains
00207                  * the error number.
00208                  */
00209                 if (cup == NULL)
00210                         RERR(css, errn);
00211         }
00212 
00213         /* Set various unit table fields */
00214 
00215         cup->uflag      = (errf != 0 ? _UERRF : 0);
00216         cup->ulineptr   = cup->ulinebuf;
00217         cup->uwrt       = 1;            /* Set write flag */
00218 
00219         /* Set fields in the Fortran statement state structure */
00220 
00221         css->u.fmt.nonl         = 0;    /* Clear no-newline flag */
00222 
00223 
00224         if (cup->useq == 0)     /* If direct access file */
00225                 RERR(css, FESEQTIV); /* Sequential attempted on direct access */
00226 
00227         if (!cup->ufmt)         /* If unformatted file */
00228                 RERR(css, FEFMTTIV); /* Formatted attempted on unformatted */
00229 
00230         if ((cup->uaction & OS_WRITE) == 0) 
00231                 RERR(css, FENOWRIT);
00232 
00233         bptr            = &wnlbuffers;
00234         bptr->lcomma    = 0;
00235 
00236         /*
00237          * Set up record size.  The hierarchy for determining Namelist
00238          * output record size is as follows:
00239          *      1) RECL, if specified
00240          *      2) WNLLONG(), if set and does not exceed cup->urecsize
00241          *      3) list-directed output record size (cup->uldwsize)
00242          *
00243          * Note that while (1) and (3) are established at OPEN time, (2)
00244          * can be changed ``on the fly''; therefore, this check has to
00245          * be performed here.
00246          */
00247 
00248         recsize = cup->uldwsize;
00249 
00250         if (cup->urecl == 0 && _wnlrecsiz > 0)  /* No RECL and WNLLONG() set */
00251                         recsize = MIN(cup->urecsize, _wnlrecsiz);
00252 
00253         bptr->outcnt    = recsize - 1;  /* First char. for carriage control */
00254         bptr->outbuff   = cup->ulinebuf;
00255         bptr->outptr    = bptr->outbuff;
00256         *bptr->outptr++ = OUT_ECHO;     /* First character of first line */
00257         bptr->f_lbuf    = (long *) malloc((recsize + 1) * sizeof(long));
00258 
00259         if (bptr->f_lbuf == NULL)
00260                 RERR(css, FENOMEMY);    /* No memory */
00261 
00262         /* NAMELIST delimiter to output line */
00263 
00264         NLPUT(OUT_CHAR);                /* output delimiter */  
00265         NLPUTS(nl->nlname);             /* unpack group name to buffer */
00266         NLPUT(' ');
00267         NLPUT(' ');
00268         NLINE();        /* Did user specify new line for each variable? */
00269 
00270         nlent   = nl->nlvnames;
00271 
00272         do {
00273                 int     ntype;
00274 
00275                 ntype   = _old_namelist_to_f77_type_cnvt[nlent->na.type];
00276 
00277                 /*
00278                  * Always format output into f_lbufptr.
00279                  * After formatting, if it will fit, move it into outbuff.
00280                  * If it will not fit, write out what is already in outbuff,
00281                  * and then move in the newly formatted data.
00282                  */
00283 
00284                 bptr->f_lbufptr = bptr->f_lbuf; 
00285                 bptr->f_lbufcnt = 0;
00286 
00287                 LPUTS(nlent->varname);          /* output variable name */
00288                 LPUT(' ');
00289                 LPUT(OUT_EQ);                   /* output the replacement
00290                                                  * character. '=' by default. */
00291 
00292                 n       = (nlent->na.offdim) ? nlent->na.nels : 1;
00293 
00294                 if (ntype == DT_CHAR) {
00295                         _fcd f;
00296                         f       = *(_fcd *)(((unsigned long) nlent->va.varaddr +
00297                                         (long *)nl));
00298                         vaddr = _fcdtocp(f);
00299                         elsize = _fcdlen(f);
00300                 }
00301                 else {
00302                         vaddr   = (void *)nlent->va.varaddr;
00303                         elsize  = 0;
00304                 }
00305 
00306                 LPUT(' ');
00307 
00308                 /* Output value */
00309 
00310                 ss      = l_write(css, cup, vaddr, elsize, n, 1, ntype, recsize,
00311                                         errf, bptr);
00312 
00313                 if (ss != 0) {
00314                         RERR(css, ss);
00315                 }
00316 
00317                 NLINE();
00318 
00319                 nlent++;        /* point to next variable description */
00320 
00321         } while (nlent->varname[0]);
00322 
00323         if (bptr->outcnt < 6) {
00324                 REPFLUSH();     /* Make sure there's room for "  &END" */
00325                 bptr->outptr--; /* start in col. 2 */
00326                 bptr->outcnt++;
00327         }
00328 
00329         NLPUT(OUT_CHAR);
00330         NLPUTS("END");
00331         REPFLUSH();
00332 ret:
00333 
00334         STMT_END(cup, T_WNL, NULL, css);        /* Unlock the unit */
00335 
00336         if (bptr->f_lbuf != NULL)               /* Free formatting buffer */
00337                 free(bptr->f_lbuf);
00338 
00339         return(CFT77_RETVAL(ss));
00340 }
00341 
00342 /*
00343  * l_write - output the value.
00344  */
00345 
00346 static int
00347 l_write(
00348         FIOSPTR         css,
00349         unit            *cup,   /* Current unit pointer */
00350         void            *dptr,  /* Address of data */
00351         unsigned        elsize, /* Bytes per element (used for char type only)*/
00352         int             count,  /* Number of elements */
00353         int             inc,    /* Number of words per element */
00354         int             type,   /* Type of data */
00355         long            recsize,/* Number of characters to output per line */
00356         int             errf,
00357         struct BUFFERS  *bptr   /* Structure containing formatting buffers */
00358 )
00359 {
00360         unsigned int len77;
00361         char    *cp;            /* points to data if type is DT_CHAR */
00362         long    *ptr;           /* points to data if type is not DT_CHAR */
00363         long    ugly[ITEMBUFSIZ]; /* temporary buffer used for numeric output */
00364         long    dig;
00365         long    exp;
00366         long    mod;
00367         long    scl;
00368         long    ss;
00369         long    wid;
00370         long    *ib_ptr;        /* pointer into the current item buffer */
00371         long    *newp;
00372         int     lcount;         /* repeat count of current input data group */
00373         oc_func *gcf;           /* Generic NOCV-type conversion func */
00374         ftype_t f90type;
00375 
00376         if (type == DT_CHAR) {
00377                 /*
00378                  * Character data is unique in that one value may span
00379                  * more than one record when output. 
00380                  * When we can handle opening the output file with a
00381                  * 'DELIM=' descriptor (see Ansi 8x Fortran standard), this
00382                  * code will need to change. For now, delimit the constant
00383                  * with apostrophes, and double all internal apostrophes.
00384                  */
00385 
00386                 cp      = dptr;
00387                 len77   = elsize;
00388 
00389                 for (; count > 0; count-- ) {
00390 
00391                         bptr->lcomma    = 0;
00392 
00393                         if (count > 1) {
00394                                 /*
00395                                  * If we have an array of character data, 
00396                                  * determine if any values are repeated.
00397                                  */
00398                                 cp      = char_rep(cp, count, len77, &lcount,
00399                                                         bptr);
00400                                 count   = count - (lcount - 1);
00401                         }       
00402 
00403                         /* Write the character constant */
00404 
00405                         ss      = lw_A(css, cp, len77, recsize, cup, errf, bptr);
00406 
00407                         if (ss != 0) {
00408                                 RERR(css, ss);
00409                         }
00410 
00411                         cp      = cp + len77;
00412                 } /* for */
00413 
00414                 return(0);
00415 
00416         } /* if (type == DT_CHAR) */
00417 
00418         /* Noncharacter data */
00419 
00420         ptr     = (long *)dptr;
00421         f90type = _f77_to_f90_type_cnvt[type];
00422 
00423         if ((type == DT_DBLE) || (type == DT_CMPLX))
00424                 inc     = inc + inc;
00425 
00426         for (; count > 0; count--, ptr += inc) {
00427 
00428                 if (count > 1) {        /* find repeat values */
00429 
00430                         ptr     = find_rep(ptr, count, inc, type, &lcount,
00431                                                 bptr);
00432 
00433                         count   = count - (lcount - 1);
00434                 }
00435 
00436                 ib_ptr = bptr->f_lbufptr;
00437 
00438                 switch (type) {         /* set up for each data type */
00439 
00440                 case DT_NONE:
00441                         gcf = _s2uo;    mod = MODEUN;   wid = WOCTWRD;  
00442                         dig = WOCTWRD;  exp = 0;        scl = 0;
00443                         break;
00444 
00445                 case DT_SINT:
00446                 case DT_INT:
00447                         gcf = _s2ui;    mod = 0;        wid = WINT;     
00448                         dig = 1;        exp = 0;        scl = 0;
00449                         break;
00450 
00451                 case DT_REAL:
00452                 case DT_CMPLX:
00453                         gcf = _sd2uge;  mod = 0;        wid = WREAL8;
00454                         dig = _dreal8;  exp = DEXP8;    scl = 1;
00455                         if (YMP80) dig = 9;
00456                         break;
00457 
00458                 case DT_DBLE:
00459                         /*
00460                          * When printing with D format, decrease
00461                          * the digits by one because we are setting
00462                          * the scale factor to 1.  This ensures that
00463                          * _dreal16 digits of precision are printed.
00464                          */
00465                         gcf = _sd2udee; mod = MODEDP;   wid = WREAL16;
00466                         dig = _dreal16-1; exp = DEXP16; scl = 1;
00467                         if (YMP80) dig = 25;
00468                         break;
00469                 }
00470 
00471                 /*
00472                  *      Perform the output conversion.
00473                  */
00474 
00475                 switch (type) {         /* set up for each data type */
00476 
00477                 default:        /* Integer, Short Integer, Real, or Double */
00478 
00479 #if     _F_REAL16 == 1          /* suppress if _f_dble is not fully supported */
00480                         if (YMP80 && !cup->uft90 && type == DT_DBLE &&
00481                                 *(_f_dble *)ptr == 0.0) {
00482 
00483                                 static const char *zero_dp = "0.0E+00";
00484                                 ib_ptr += _unpack(zero_dp, ib_ptr,
00485                                                 strlen(zero_dp), -1);
00486                                 break;
00487                         }
00488 #endif
00489 
00490                         newp    = gcf(ptr, ugly, &mod, &wid, &dig, &exp, &scl);
00491 
00492                         if (type == DT_NONE)
00493                                 *newp++ = 'B';
00494 
00495                         ib_ptr  = ib_ptr + _wnl_beautify(f90type, ugly, newp,
00496                                                         ib_ptr, cup->uft90);
00497                         break;  
00498 
00499                 case DT_CMPLX:
00500 
00501                         *ib_ptr++       = '(';
00502 
00503                         newp    = gcf(ptr, ugly, &mod, &wid, &dig, &exp, &scl);
00504 
00505                         ib_ptr  = ib_ptr + _wnl_beautify(f90type, ugly, newp,
00506                                                 ib_ptr, cup->uft90);
00507 
00508                         *ib_ptr++       = COMMA;
00509 
00510                         newp    = gcf((_f_real *)ptr + 1, ugly,
00511                                         &mod, &wid, &dig, &exp, &scl);
00512 
00513                         ib_ptr  = ib_ptr + _wnl_beautify(f90type, ugly, newp,
00514                                                 ib_ptr, cup->uft90);
00515 
00516                         *ib_ptr++       = ')';
00517 
00518                         break;
00519 
00520                 case DT_LOG:
00521                         *ib_ptr++       = _lvtob(*(_f_log8 *)ptr)? 'T':'F';
00522                         break;
00523                 } /* switch */
00524 
00525                 /*
00526                  *      Update the item buffer pointers before using LPUT again.
00527                  */
00528                 bptr->f_lbufcnt += ib_ptr - bptr->f_lbufptr;
00529                 bptr->f_lbufptr = ib_ptr;
00530 
00531                 LPUT(OUT_SEP);
00532                 LPUT(' ');              /* put 2 blanks between items */
00533                 LPUT(' '); 
00534 
00535                 if (bptr->outcnt <= bptr->f_lbufcnt) {
00536                         /*
00537                          * If there is not enough room in the line buffer
00538                          * to copy the next output value, flush out the line
00539                          * and start a new line.
00540                          */
00541 
00542                         REPFLUSH();
00543                 }
00544 
00545                 bptr->f_lbufptr = bptr->f_lbuf;
00546 
00547                 _memwcpy(bptr->outptr, bptr->f_lbufptr, bptr->f_lbufcnt);
00548 
00549                 bptr->outptr   += bptr->f_lbufcnt;
00550                 bptr->outcnt   -= bptr->f_lbufcnt;
00551                 bptr->f_lbufptr = bptr->f_lbuf;
00552                 bptr->f_lbufcnt = 0;
00553         }
00554 
00555         return(0);
00556 
00557 ret:
00558         return(ss);
00559 }
00560 
00561 /*
00562  * find_rep: find and put out the repeat count.
00563  * Returns a pointer to the last repeated value.
00564  * Sets lcount to the repeat count.
00565  */
00566 
00567 static long *
00568 find_rep(
00569         long            *ptr,   /* Pointer to the value */
00570         int             count,  /* Number of elements in array */
00571         int             inc,    /* Size (in words) of each value */
00572         int             type,   /* Type of data */
00573         int             *lcount,/* Repeat count */
00574         struct BUFFERS  *bptr   /* Structure containing formatting buffers */
00575 )
00576 {
00577         int     i;
00578         long    *p1, *p2, *q1, *q2; 
00579 
00580         p1      = ptr;
00581         q1      = ptr + inc;
00582 
00583         if (type == DT_CMPLX || type == DT_DBLE) {
00584 
00585                 p2      = p1 + 1;
00586                 q2      = q1 + 1;
00587 
00588                 for (i = 1; i < count; i++) {
00589 
00590                         if ((*p1 != *q1) || (*p2 != *q2)) {
00591                                 break;
00592                         }
00593                         else {
00594                                 p1      = q1;
00595                                 p2      = p1 + 1;
00596                                 q1      = q1 + inc;
00597                                 q2      = q1 + 1;
00598                         }
00599                 }
00600         }
00601         else {
00602                 for (i = 1; i < count; i++) {
00603 
00604                         if (*p1 != *q1) {
00605                                 break;
00606                         }
00607                         else {
00608                                 p1      = q1;
00609                                 q1      = q1 + inc;
00610                         }
00611                 }
00612         }
00613 
00614         *lcount = (long) i;
00615 
00616         if (i > 1)              /* put out repeat count */
00617                 writ_rep(i, bptr);
00618 
00619         return(p1);
00620 }
00621 
00622 static void
00623 writ_rep(
00624         long            repcnt,/* Repeat count */
00625         struct BUFFERS  *bptr   /* Structure containing formatting buffers */
00626 )
00627 {
00628         long    mode;           /* Used by conversion routine */
00629         long    wid;
00630         long    dig;
00631         long    zero = 0;
00632         long    *newp;          /* Used by conversion routine */
00633         long    *q;
00634         long    buf[WINT];
00635 
00636         mode    = 0;
00637         wid     = WINT;
00638         dig     = 0;
00639 
00640         newp    = _s2ui((long*)&repcnt, buf, &mode, &wid, &dig, &zero, &zero);
00641 
00642         for (q = buf; q < newp; q++)
00643                 if ((char)*q != ' ')    /* suppress leading blanks */
00644                         break;
00645 
00646         while (q < newp) {
00647                 *bptr->f_lbufptr++      = *q++;
00648                 bptr->f_lbufcnt++;
00649         }
00650 
00651         *bptr->f_lbufptr++      = (long) '*';   /* put out '*' */
00652         bptr->f_lbufcnt++;
00653 }
00654 
00655 /*
00656  * char_rep: find and put out the repeat count for character data.
00657  * Returns a pointer to the last repeated value.
00658  * Sets lcount to the repeat count.
00659  */
00660 
00661 static char *
00662 char_rep(
00663         char            *ptr,   /* Pointer to first data value */
00664         int             count,  /* Number of elements in array */
00665         unsigned int    len77,  /* Length of character variable */      
00666         int             *lcount,/* Repeat count */
00667         struct BUFFERS  *bptr   /* Structure containing formatting buffers */
00668 )
00669 {
00670         int     i;
00671         char    *qptr;
00672 
00673         qptr    = ptr + len77;  /* point to start of next array */
00674 
00675         for (i = 1; i < count; i++) {
00676 
00677                 if (memcmp(ptr, qptr, len77))
00678                         break;
00679 
00680                 qptr    = qptr + len77;
00681         }
00682 
00683         *lcount = (long)i;
00684 
00685         if (i > 1)      /* put out repeat count */
00686                 writ_rep(i, bptr);
00687 
00688         return(ptr + (*lcount - 1) * len77);    
00689 }
00690 
00691 /*
00692  *      lw_A - write ASCII character data 
00693  */
00694 
00695 static int
00696 lw_A(
00697         FIOSPTR         css,
00698         char            *ptr,   /* Points to character data to be output */
00699         int             charlen,/* Length of data to be output */
00700         long            recsize,/* Number of characters per line for REPFLUSH */
00701         unit            *cup,   /* Unit table pointer */
00702         int             errf,   /* Error flag */
00703         struct BUFFERS  *bptr   /* Structure containing formatting buffers */
00704 )
00705 {
00706         int     m;
00707         char    *aposptr;
00708         int     ss;
00709         int     fflag;
00710         int     recmax;
00711 
00712         /*
00713          * Copy the data into the formatting buffer. The data is
00714          * surrounded by apostrophes. If there is an apostrophe in 
00715          * the data it must be output as two apostrophes.
00716          */
00717 
00718         fflag                   = 0;
00719         *bptr->f_lbufptr++      = (long) '\'';
00720         bptr->f_lbufcnt++;
00721 
00722         for (; charlen > 0; ) {
00723 
00724                 if (fflag == 0) {
00725                         recmax  = recsize - 2;
00726                         m       = MIN(charlen, recmax - bptr->f_lbufcnt);
00727                 }
00728                 else {
00729                         recmax  = recsize - 1;
00730                         m       = MIN(charlen, recmax - bptr->f_lbufcnt);
00731                 }
00732 
00733                 /* Is there an apostrophe in the data? */
00734 
00735                 aposptr = memchr(ptr, '\'', m);
00736 
00737                 if (aposptr != 0) {
00738                         /* aposptr points to next apostrophe */
00739                         m       = aposptr + 1 - ptr;
00740                         /* Move everything up to, and including, apostrophe */
00741 
00742                         (void) _unpack(ptr, bptr->f_lbufptr, m, -1);
00743 
00744                         *(bptr->f_lbufptr + m)  = '\''; /* Double apostrophe */
00745                         ptr                     = ptr + m;
00746                         charlen                 = charlen - m;
00747                         m++;
00748                 }
00749                 else {
00750                         /* Move everything */
00751 
00752                         (void) _unpack(ptr, bptr->f_lbufptr, m, -1);
00753 
00754                         ptr     = ptr + m;
00755                         charlen = charlen - m;
00756                 }
00757 
00758                 bptr->f_lbufptr += m;
00759                 bptr->f_lbufcnt += m;
00760                         
00761                 /*
00762                  * If we've filled a record, write it out.
00763                  */
00764 
00765                 if (bptr->f_lbufcnt >= recmax) {
00766                         if (bptr->outcnt <= bptr->f_lbufcnt) {
00767                                 REPFLUSH();
00768                                 /* If this is a continuation of one */
00769                                 /* character variable, start it in col. 2 */
00770                                 /* Otherwise, start it in col. 3 */
00771                                 if (fflag == 1) {
00772                                         bptr->outptr--; /* start in col. 2 */
00773                                         bptr->outcnt++;
00774                                 }
00775                                 fflag   = 1;
00776                         }
00777                         bptr->f_lbufptr = bptr->f_lbuf;
00778 
00779                         _memwcpy(bptr->outptr, bptr->f_lbufptr,
00780                                         bptr->f_lbufcnt);
00781 
00782                         bptr->outptr   += bptr->f_lbufcnt;
00783                         bptr->outcnt   -= bptr->f_lbufcnt;
00784                         bptr->f_lbufptr = bptr->f_lbuf;
00785                         bptr->f_lbufcnt = 0;
00786                 }
00787         } /* for */
00788 
00789         *bptr->f_lbufptr++      = (long) '\'';
00790         bptr->f_lbufcnt++;
00791 
00792         LPUT(OUT_SEP);
00793         LPUT(' ');
00794         LPUT(' ');
00795 
00796         bptr->lcomma    = 1;
00797 
00798         if (bptr->outcnt <= bptr->f_lbufcnt) {
00799                 /* If there is not enough room in outbuff to copy 
00800                  * in the contents of f_lbuf,
00801                  * write what's in outbuff
00802                  */
00803                 REPFLUSH();
00804                 /* If this is a continuation of 1 character variable, */
00805                 /* start it in col. 2. Otherwise, start it in col. 3*/
00806                 if (fflag == 1) {
00807                         bptr->outptr--; 
00808                         bptr->outcnt++;
00809                 }
00810         }
00811 
00812         bptr->f_lbufptr = bptr->f_lbuf;
00813 
00814         _memwcpy(bptr->outptr, bptr->f_lbufptr, bptr->f_lbufcnt);
00815 
00816         bptr->outptr   += bptr->f_lbufcnt;
00817         bptr->outcnt   -= bptr->f_lbufcnt;
00818         bptr->f_lbufptr = bptr->f_lbuf;
00819         bptr->f_lbufcnt = 0;
00820 
00821         return(0);
00822 
00823 ret:
00824         return(ss);
00825 }
00826 
00827 /*
00828  *      _wnl_beautify
00829  *
00830  *              Beautify numeric output by deleting blanks and
00831  *              truncating unnecessary trailing zeroes.  The altered
00832  *              ascii number is placed in "pretty".
00833  *
00834  *              Input is in this form: {LH part}[{E}{exponent}]
00835  *
00836  *              This routine is temporary, and is needed only as long
00837  *              as the YMP UNICOS 8.0 compatibility mode is preserved for
00838  *              namelist real output.
00839  *
00840  *      Return value:
00841  *              The number of characters in the beautified output.
00842  */
00843 int
00844 _wnl_beautify(
00845         ftype_t         typ90,  /* f90 data type of the number */
00846         long            *ugly,  /* the ugly ascii representation of a number */
00847         long            *p_limit,/* ptr to one past end of ascii data in ugly */
00848         long            *pretty,/* receives the beautified output */
00849         unsigned        isf90)  /* 1 iff Fortran 90 style printing of 0.E+0 */
00850 
00851 {
00852         int     ret;
00853 
00854         ret     = _beautify(typ90, ugly, p_limit, pretty, isf90);
00855 
00856 /*
00857  *      In YMP80 mode an extra 0 is always added in G-as-F conversions which
00858  *      have no digits following the decimal point.
00859  */
00860         if (YMP80 && !isf90 && typ90 == DVTYPE_REAL || typ90 == DVTYPE_COMPLEX){
00861                 if (pretty[ret - 1] == '.')
00862                         pretty[ret++]   = '0';
00863         }
00864 
00865         return (ret);
00866 }

Generated on Tue Nov 17 05:54:42 2009 for Open64 (mfef90, whirl2f, and IR tools) by  doxygen 1.6.1