OpenCOBOL 1.1pre-rel
|
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 }