OpenCOBOL 1.1pre-rel
termio.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2001-2009 Keisuke Nishida
00003  * Copyright (C) 2007-2009 Roger While
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Lesser General Public License
00007  * as published by the Free Software Foundation; either version 2.1,
00008  * or (at your option) any later version.
00009  * 
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU Lesser General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU Lesser General Public
00016  * License along with this library; see the file COPYING.LIB.  If
00017  * not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor
00018  * Boston, MA 02110-1301 USA
00019  */
00020 
00021 #include "config.h"
00022 
00023 #include <stdio.h>
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include <stdarg.h>
00027 #ifdef  HAVE_UNISTD_H
00028 #include <unistd.h>
00029 #endif
00030 #include <time.h>
00031 
00032 #include "move.h"
00033 #include "coblocal.h"
00034 #include "termio.h"
00035 #include "screenio.h"
00036 
00037 static unsigned char    *term_buff;
00038 static const int        bin_digits[] = { 1, 3, 5, 8, 10, 13, 15, 17, 20 };
00039 
00040 /*
00041  * DISPLAY
00042  */
00043 
00044 static void
00045 display_numeric (cob_field *f, FILE *fp)
00046 {
00047         int             i;
00048         int             digits;
00049         int             scale;
00050         int             size;
00051         cob_field_attr  attr;
00052         cob_field       temp;
00053         unsigned char   data[128];
00054 
00055         if (f->size == 0) {
00056                 return;
00057         }
00058         digits = COB_FIELD_DIGITS (f);
00059         scale = COB_FIELD_SCALE (f);
00060         size = digits + (COB_FIELD_HAVE_SIGN (f) ? 1 : 0);
00061         COB_ATTR_INIT (COB_TYPE_NUMERIC_DISPLAY, digits, scale, 0, NULL);
00062         temp.size = size;
00063         temp.data = data;
00064         temp.attr = &attr;
00065         if (COB_FIELD_HAVE_SIGN (f)) {
00066                 attr.flags = COB_FLAG_HAVE_SIGN | COB_FLAG_SIGN_SEPARATE;
00067                 if (COB_FIELD_SIGN_LEADING (f)
00068                     || COB_FIELD_TYPE (f) == COB_TYPE_NUMERIC_BINARY) {
00069                         attr.flags |= COB_FLAG_SIGN_LEADING;
00070                 }
00071         }
00072 
00073         cob_move (f, &temp);
00074         for (i = 0; i < size; ++i) {
00075                 putc (data[i], fp);
00076         }
00077 }
00078 
00079 static void
00080 pretty_display_numeric (cob_field *f, FILE *fp)
00081 {
00082         unsigned char   *p;
00083         int             i;
00084         int             digits;
00085         int             scale;
00086         int             size;
00087         cob_field_attr  attr;
00088         cob_field       temp;
00089         unsigned char   pic[64];
00090         unsigned char   data[256];
00091 
00092         if (f->size == 0) {
00093                 return;
00094         }
00095 /* RXW
00096         if (COB_FIELD_TYPE(f) == COB_TYPE_NUMERIC_BINARY) {
00097                 digits = bin_digits[f->size];
00098         } else {
00099 */
00100                 digits = COB_FIELD_DIGITS (f);
00101 /* RXW
00102         }
00103 */
00104         scale = COB_FIELD_SCALE (f);
00105         size = (digits + (COB_FIELD_HAVE_SIGN (f) ? 1 : 0)
00106                 + (scale > 0 ? 1 : 0));
00107         p = pic;
00108         temp.size = size;
00109         temp.data = data;
00110         temp.attr = &attr;
00111         COB_ATTR_INIT (COB_TYPE_NUMERIC_EDITED, digits, scale, 0, (char *)pic);
00112         memset (pic, 0, sizeof (pic));
00113         memset (data, 0, sizeof (data));
00114         if (COB_FIELD_HAVE_SIGN (f)) {
00115                 *p++ = '+';
00116                 i = 1;
00117                 memcpy (p, (unsigned char *)&i, sizeof(int));
00118                 p += sizeof(int);
00119         }
00120         if (scale > 0) {
00121                 *p++ = '9';
00122                 i = digits - scale;
00123                 memcpy (p, (unsigned char *)&i, sizeof(int));
00124                 p += sizeof(int);
00125                 *p++ = cob_current_module->decimal_point;
00126                 i = 1;
00127                 memcpy (p, (unsigned char *)&i, sizeof(int));
00128                 p += sizeof(int);
00129                 *p++ = '9';
00130                 i = scale;
00131                 memcpy (p, (unsigned char *)&i, sizeof(int));
00132                 p += sizeof(int);
00133         } else {
00134                 *p++ = '9';
00135                 i = digits;
00136                 memcpy (p, (unsigned char *)&i, sizeof(int));
00137                 p += sizeof(int);
00138         }
00139 
00140         cob_move (f, &temp);
00141         for (i = 0; i < size; ++i) {
00142                 putc (data[i], fp);
00143         }
00144 }
00145 
00146 static void
00147 display_alnum (cob_field *f, FILE *fp)
00148 {
00149         size_t  i;
00150 
00151         for (i = 0; i < f->size; ++i) {
00152                 putc (f->data[i], fp);
00153         }
00154 }
00155 
00156 static void
00157 display (cob_field *f, FILE *fp)
00158 {
00159         unsigned char   *p;
00160         int             n;
00161         cob_field       temp;
00162         cob_field_attr  attr;
00163 
00164         if (COB_FIELD_TYPE (f) == COB_TYPE_NUMERIC_DOUBLE) {
00165                 double f1doub;
00166 
00167                 memcpy ((char *)&f1doub, f->data, sizeof (double));
00168                 fprintf (fp, "%-.18lf", f1doub);
00169         } else if (COB_FIELD_TYPE (f) == COB_TYPE_NUMERIC_FLOAT) {
00170                 float f1float;
00171 
00172                 memcpy ((char *)&f1float, f->data, sizeof (float));
00173                 fprintf (fp, "%-.18lf", (double)f1float);
00174         } else if (COB_FIELD_IS_POINTER (f)) {
00175                 fprintf (fp, "0x");
00176 #ifdef WORDS_BIGENDIAN
00177                 p = f->data;
00178                 for (n = 0; n < sizeof(void *); ++n, ++p) {
00179 #else
00180                 p = f->data + sizeof(void *) - 1;
00181                 for (n = sizeof(void *) - 1; n >= 0; --n, --p) {
00182 #endif
00183                         fprintf (fp, "%x%x", *p >> 4, *p & 0xF);
00184                 }
00185         } else if (COB_FIELD_REAL_BINARY(f) ||
00186                    (COB_FIELD_TYPE(f) == COB_TYPE_NUMERIC_BINARY
00187                     && !cob_current_module->flag_pretty_display)) {
00188                 attr = *f->attr;
00189                 temp = *f;
00190                 attr.digits = bin_digits[f->size];
00191                 temp.attr = &attr;
00192                 display_numeric (&temp, fp);
00193         } else if (COB_FIELD_IS_NUMERIC (f)) {
00194                 if (cob_current_module->flag_pretty_display) {
00195                         pretty_display_numeric (f, fp);
00196                 } else {
00197                         display_numeric (f, fp);
00198                 }
00199         } else {
00200                 display_alnum (f, fp);
00201         }
00202 }
00203 
00204 void
00205 cob_display (const int outorerr, const int newline, const int varcnt, ...)
00206 {
00207         FILE            *fp;
00208         cob_field       *f;
00209         int             i;
00210         va_list         args;
00211 
00212         if (!outorerr && !cob_screen_initialized) {
00213                 fp = stdout;
00214         } else {
00215                 fp = stderr;
00216         }
00217         va_start (args, varcnt);
00218         for (i = 0; i < varcnt; ++i) {
00219                 f = va_arg (args, cob_field *);
00220                 display (f, fp);
00221         }
00222         va_end (args);
00223         if (newline) {
00224                 putc ('\n', fp);
00225                 fflush (fp);
00226         }
00227 }
00228 
00229 /*
00230  * ACCEPT
00231  */
00232 
00233 void
00234 cob_accept (cob_field *f)
00235 {
00236 /* RXW
00237         size_t          size;
00238 */
00239         cob_field_attr  attr;
00240         cob_field       temp;
00241 
00242         if (cob_screen_initialized) {
00243                 cob_field_accept (f, NULL, NULL, NULL, NULL, NULL, 0);
00244                 return;
00245         }
00246         temp.data = term_buff;
00247         temp.attr = &attr;
00248         COB_ATTR_INIT (COB_TYPE_ALPHANUMERIC, 0, 0, 0, NULL);
00249         /* read a line */
00250         if (fgets ((char *)term_buff, COB_MEDIUM_BUFF, stdin) == NULL) {
00251                 temp.size = 1;
00252                 term_buff[0] = ' ';
00253                 term_buff[1] = 0;
00254         } else {
00255                 temp.size = strlen ((char *)term_buff) - 1;
00256         }
00257         if (COB_FIELD_TYPE(f) == COB_TYPE_NUMERIC_DISPLAY) {
00258                 if (temp.size > f->size) {
00259                         temp.size = f->size;
00260                 }
00261         }
00262         cob_move (&temp, f);
00263 /* RXW
00264         if (isatty (fileno (stdin))) {
00265                 temp.size = strlen ((char *)term_buff) - 1;
00266                 cob_move (&temp, f);
00267         } else {
00268                 size = strlen ((char *)term_buff) - 1;
00269                 if (size > f->size) {
00270                         size = f->size;
00271                 }
00272                 memcpy (f->data, term_buff, size);
00273                 memset (f->data + size, ' ', f->size - size);
00274         }
00275 */
00276 }
00277 
00278 void
00279 cob_init_termio (void)
00280 {
00281         term_buff = cob_malloc (COB_MEDIUM_BUFF);
00282 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines