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