Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
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 of the GNU General Public License as 00007 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 General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 5-June-95 - Original Version 00042 * 00043 * Description: 00044 * 00045 * Translate an OPC_IO subtree into the appropriate Fortran constructs. 00046 * Recursive translation of WN nodes should only use WN2F_Translate(), 00047 * with exception of IO_ITEMS which are handled locally! 00048 * 00049 * The Fortran I/O statements have the following syntax: 00050 * 00051 * <statement_keyword> <control_list> <I/O list> 00052 * 00053 * where 00054 * 00055 * <statement_keyword> ::= <IOS enumeration as defined in wio.h> 00056 * <control_list> ::= <IOU, IOF, and IOC items from wio.h> 00057 * <I/O list> ::= <IOL items from wio.h> 00058 * 00059 * ==================================================================== 00060 * ==================================================================== 00061 */ 00062 00063 00064 #include "whirl2f_common.h" 00065 #include "wio.h" 00066 #include "wutil.h" 00067 #include "PUinfo.h" /* In be/whirl2c directory */ 00068 #include "wn2f.h" 00069 #include "st2f.h" 00070 #include "ty2f.h" 00071 #include "tcon2f.h" 00072 #include "wn2f_io.h" 00073 #include "wn2f_load_store.h" 00074 00075 00076 /* A rather special IOC item to replace an IOF_LABEL item. This 00077 * value is only valid when WN2F_CONTEXT_origfmt_ioctrl is TRUE! 00078 */ 00079 static UINT32 Origfmt_Ioctrl_Label; 00080 static TOKEN_BUFFER Format_Stmts = NULL; 00081 static TOKEN_BUFFER Ios_Prefix_Tokens = NULL; 00082 00083 typedef void (*IO_STMT_HANDLER)(TOKEN_BUFFER, WN *, WN2F_CONTEXT); 00084 static IO_STMT_HANDLER Ios_Handler[IOSTATEMENT_LAST+1]; 00085 00086 00087 #define WN_IOITEM(x) (IOITEM) WN_io_item(x) 00088 #define WN_IOSTMT(x) (IOSTATEMENT) WN_io_statement(x) 00089 00090 /* several craylib/dope items represent a no-op by a zero inconst...*/ 00091 00092 #define IS_IO_NULL_OPR(wn) ((WN_operator(wn) == OPR_INTCONST) && (WN_const_val(wn) == 0)) 00093 00094 /*------------------------- Io Utility Routines -----------------------*/ 00095 /*---------------------------------------------------------------------*/ 00096 00097 static void 00098 WN2F_Append_IO_CtrlList(TOKEN_BUFFER tokens, 00099 WN *ios, 00100 INT from_kid, 00101 INT to_kid, 00102 BOOL use_keyword, 00103 WN2F_CONTEXT context) 00104 { 00105 /* Emit an IO control list (IOU, IOF, and IOC with explicit 00106 * keywords. 00107 */ 00108 BOOL emitted, emitted2; 00109 INT ios_kid; 00110 TOKEN_BUFFER item_buffer; 00111 00112 Append_Token_Special(tokens, '('); 00113 00114 /* Should we use keyword notation? */ 00115 if (use_keyword) 00116 set_WN2F_CONTEXT_keyword_ioctrl(context); 00117 00118 emitted = FALSE; /* No item before the next one, as of yet */ 00119 for (ios_kid = from_kid; ios_kid <= to_kid; ios_kid++) 00120 { 00121 item_buffer = New_Token_Buffer(); 00122 emitted2 = WN2F_io_item(item_buffer, WN_kid(ios, ios_kid), context); 00123 if (emitted2) 00124 { 00125 if (emitted) 00126 Append_Token_Special(tokens, ','); /* an item emitted earlier */ 00127 emitted = TRUE; 00128 } 00129 Append_And_Reclaim_Token_List(tokens, &item_buffer); 00130 } 00131 reset_WN2F_CONTEXT_origfmt_ioctrl(context); 00132 00133 Append_Token_Special(tokens, ')'); 00134 } /* WN2F_Append_IO_CtrlList */ 00135 00136 00137 static void 00138 WN2F_Append_IO_List(TOKEN_BUFFER tokens, 00139 WN *ios, 00140 INT from_kid, 00141 WN2F_CONTEXT context) 00142 { 00143 /* Emit an IOL list, starting at the given kid index and 00144 * continuing to the last kid. 00145 */ 00146 BOOL emitted; 00147 INT ios_kid; 00148 00149 for (ios_kid = from_kid; ios_kid < WN_kid_count(ios); ios_kid++) 00150 { 00151 emitted = WN2F_io_item(tokens, WN_kid(ios, ios_kid), context); 00152 if (emitted && (ios_kid+1 < WN_kid_count(ios))) 00153 Append_Token_Special(tokens, ','); 00154 } 00155 } /* WN2F_Append_IO_List */ 00156 00157 00158 /*---------------------- IO Item Handler-routines ---------------------*/ 00159 /*---------------------------------------------------------------------*/ 00160 00161 #define WN2F_IS_IOU(item) \ 00162 (WN_IOITEM(item) >= IOU_NONE && WN_IOITEM(item) <= IOU_INTERNAL) 00163 #define WN2F_IS_IOF(item) \ 00164 ((WN_IOITEM(item) >= IOF_NONE && WN_IOITEM(item) <= IOF_CR_FMTSRC_DOPE)) 00165 #define WN2F_IS_IOC(item) \ 00166 (WN_IOITEM(item) >= IOC_ACCESS && WN_IOITEM(item) <= IOC_ERRFLAG) 00167 #define WN2F_IS_IOL(item) \ 00168 ((WN_IOITEM(item) >= IOL_ARRAY && WN_IOITEM(item) <= IOL_VAR) || \ 00169 (WN_IOITEM(item) == IOL_DOPE)) 00170 00171 00172 static void 00173 WN2F_emit_ctrl(TOKEN_BUFFER tokens, const char *p , WN2F_CONTEXT context) 00174 { 00175 if (WN2F_CONTEXT_keyword_ioctrl(context)) 00176 { 00177 Append_Token_String(tokens,p); 00178 Append_Token_Special(tokens, '='); 00179 } 00180 } 00181 00182 static BOOL 00183 WN2F_io_unit(TOKEN_BUFFER tokens, 00184 WN *item, 00185 WN2F_CONTEXT context) 00186 { 00187 00188 BOOL emitted = TRUE; /* if a unit specifier was emitted */ 00189 const char * p = "UNIT"; 00190 const BOOL issue_asterisk = WN2F_CONTEXT_issue_ioc_asterisk(context); 00191 00192 /* Any arguments assumed to be by reference unless otherwise noted */ 00193 set_WN2F_CONTEXT_deref_addr(context); 00194 00195 switch (WN_io_item(item)) 00196 { 00197 case IOU_NONE: 00198 00199 if (WN2F_CONTEXT_cray_io(context) && 00200 issue_asterisk) 00201 { 00202 WN2F_emit_ctrl(tokens,p,context); 00203 Append_Token_Special(tokens, '*'); 00204 } else 00205 emitted = FALSE; /* eg: inquire by file */ 00206 00207 break; 00208 00209 case IOU_DEFAULT: /* asterisk or double astrisk */ 00210 00211 if (issue_asterisk){ 00212 WN2F_emit_ctrl(tokens,p,context); 00213 if (WN_const_val(WN_kid0(item)) == 0) 00214 Append_Token_String(tokens, "**"); 00215 else 00216 Append_Token_Special(tokens, '*'); 00217 } 00218 else 00219 emitted =FALSE; 00220 00221 break; 00222 00223 case IOU_EXTERNAL: /* unit number */ 00224 case IOU_DOPE: 00225 case IOU_INTERNAL: /* substring or array reference */ 00226 WN2F_emit_ctrl(tokens,p,context); 00227 WN2F_translate(tokens, WN_kid0(item), context); 00228 break; 00229 00230 default: 00231 ASSERT_DBG_WARN(FALSE, 00232 (DIAG_W2F_UNEXPECTED_IOU, 00233 IOITEM_name(WN_IOITEM(item)), "WN2F_io_unit")); 00234 WN2F_emit_ctrl(tokens,p,context); 00235 Append_Token_String(tokens, IOITEM_name(WN_IOITEM(item))); 00236 break; 00237 } /*switch*/ 00238 00239 return emitted; 00240 } /* WN2F_io_unit */ 00241 00242 00243 static BOOL 00244 WN2F_io_format(TOKEN_BUFFER tokens, 00245 WN *item, 00246 WN2F_CONTEXT context) 00247 { 00248 /* Return TRUE if a format or name-list specifier was emitted */ 00249 00250 BOOL emitted = TRUE; 00251 const char *p = "fmt"; 00252 00253 /* Any arguments assumed to be by reference unless otherwise noted */ 00254 set_WN2F_CONTEXT_deref_addr(context); 00255 00256 switch (WN_io_item(item)) 00257 { 00258 case IOF_NONE: 00259 if (WN2F_CONTEXT_cray_io(context) && 00260 WN2F_CONTEXT_fmt_io(context)) 00261 { 00262 WN2F_emit_ctrl(tokens,p,context); 00263 Append_Token_Special(tokens, '*'); 00264 } 00265 else 00266 emitted = FALSE; 00267 break; 00268 00269 case IOF_ASSIGNED_VAR: 00270 00271 /* The front-end should never generate these, since they are converted 00272 * into IOF_CHAR_EXPR items. Should we for any reason start regenerating 00273 * these, this is the place where it should occur. 00274 */ 00275 ASSERT_DBG_WARN(FALSE, 00276 (DIAG_W2F_UNEXPECTED_IOF, 00277 IOITEM_name(WN_IOITEM(item)), "WN2F_io_format")); 00278 Append_Token_String(tokens, IOITEM_name(WN_IOITEM(item))); 00279 #if 0 00280 WN2F_translate(tokens, WN_kid0(item), context); 00281 #endif 00282 break; 00283 00284 case IOF_LABEL: 00285 /* a FORMAT label or character-string expression */ 00286 00287 WN2F_emit_ctrl(tokens,p,context); 00288 if (WN2F_CONTEXT_origfmt_ioctrl(context)) 00289 Append_Token_String(tokens, 00290 Number_as_String(Origfmt_Ioctrl_Label, "%lld")); 00291 else 00292 WN2F_translate(tokens, WN_kid0(item), context); 00293 break; 00294 00295 case IOF_CHAR_EXPR: 00296 /* a character-substring expression */ 00297 00298 WN2F_emit_ctrl(tokens,p,context); 00299 WN2F_String_Argument(tokens, 00300 WN_kid0(item), /* base */ 00301 WN_kid1(item), /* length */ 00302 context); 00303 break; 00304 00305 case IOF_LIST_DIRECTED: 00306 WN2F_emit_ctrl(tokens,p,context); 00307 Append_Token_Special(tokens, '*'); 00308 break; 00309 00310 case IOF_NAMELIST_DIRECTED: 00311 WN2F_emit_ctrl(tokens,"NML",context); 00312 WN2F_translate(tokens, WN_kid(item,WN_kid_count(item)-1), context); 00313 Clear_BE_ST_w2fc_referenced(WN_st(WN_kid(item,WN_kid_count(item)-1))); 00314 /* don't dump out Namelist name and corresponding type 00315 * in *.w2f.f file.When call WN2F_translate,the namelist name(st entry) will 00316 * be set "referenced".Clear the flag.--------fzhao 00317 */ 00318 break; 00319 00320 case IOF_UNFORMATTED: 00321 emitted = FALSE; 00322 break; 00323 00324 case IOF_CR_PARSFMT: 00325 emitted = FALSE; 00326 break; 00327 00328 case IOF_CR_FMTSRC: 00329 case IOF_CR_FMTSRC_DOPE: 00330 { 00331 WN * kid0 = WN_kid0(item); 00332 if (IS_IO_NULL_OPR(kid0)) 00333 emitted = FALSE; 00334 else 00335 WN2F_translate(tokens, kid0, context); 00336 break; 00337 } 00338 default: 00339 ASSERT_DBG_WARN(FALSE, 00340 (DIAG_W2F_UNEXPECTED_IOF, 00341 IOITEM_name(WN_IOITEM(item)), "WN2F_io_format")); 00342 Append_Token_String(tokens, IOITEM_name(WN_IOITEM(item))); 00343 break; 00344 } /*switch*/ 00345 00346 return emitted; 00347 } /* WN2F_io_format */ 00348 00349 static BOOL 00350 WN2F_io_control(TOKEN_BUFFER tokens, 00351 WN *item, 00352 WN2F_CONTEXT context) 00353 { 00354 /* Return TRUE if a control specifier was emitted. 00355 */ 00356 BOOL emitted = TRUE; 00357 const IOITEM item_kind = WN_IOITEM(item); 00358 00359 switch (item_kind) 00360 { 00361 case IOC_KEY: 00362 /* TODO: associate this with IOC_KEY */ 00363 ASSERT_WARN(FALSE, (DIAG_UNIMPLEMENTED, 00364 Concat2_Strings("IOC", IOITEM_name(item_kind)))); 00365 Append_Token_String(tokens, IOITEM_name(item_kind)); 00366 Append_Token_Special(tokens, '='); 00367 Append_Token_String(tokens, "<???>"); 00368 break; 00369 00370 case IOC_KEY_START: 00371 case IOC_KEY_END: 00372 case IOC_KEY_CHARACTER: 00373 case IOC_KEY_INTEGER: 00374 case IOC_NML: /* TODO: remove from IOC enumeration! It is redundant */ 00375 ASSERT_WARN(FALSE, (DIAG_UNIMPLEMENTED, 00376 Concat2_Strings("IOC", IOITEM_name(item_kind)))); 00377 Append_Token_String(tokens, IOITEM_name(item_kind)); 00378 break; 00379 00380 case IOC_EXIST: 00381 case IOC_NAMED: 00382 case IOC_OPENED: 00383 /* LOGICAL argument */ 00384 ASSERT_FATAL(WN_kid_count(item) >= 1, 00385 (DIAG_W2F_UNEXPECTED_NUM_KIDS, 00386 WN_kid_count(item), 1, "WN2F_io_control")); 00387 Append_Token_String(tokens, IOITEM_name(item_kind)); 00388 Append_Token_Special(tokens, '='); 00389 set_WN2F_CONTEXT_has_logical_arg(context); 00390 if (TY_kind(WN_Tree_Type(WN_kid0(item))) != KIND_SCALAR) 00391 set_WN2F_CONTEXT_deref_addr(context); 00392 WN2F_translate(tokens, WN_kid0(item), context); 00393 reset_WN2F_CONTEXT_has_logical_arg(context); 00394 break; 00395 00396 case IOC_READONLY: 00397 case IOC_SHARED: 00398 case IOC_U: 00399 Append_Token_String(tokens, IOITEM_name(item_kind)); 00400 /* No argument */ 00401 break; 00402 00403 case IOC_VARFMT: 00404 emitted = FALSE; 00405 break; 00406 00407 case IOC_VARFMT_ORIGFMT: 00408 /* We assume a label-number already has been assigned for 00409 * this FORMAT statement into Origfmt_Ioctrl_Label. See 00410 * also IOF_LABEL. Expect the string argument to be an 00411 * LDA of a string-constant (ST of class CONST). Note that 00412 * a string-constant always is '\0' terminated. 00413 */ 00414 ASSERT_DBG_WARN((WN_opc_operator(WN_kid0(item)) == OPR_LDA && 00415 ST_class(WN_st(WN_kid0(item))) == CLASS_CONST), 00416 (DIAG_W2F_UNEXPECTED_IOC, 00417 IOITEM_name(WN_IOITEM(item)), "WN2F_io_control")); 00418 00419 if (Format_Stmts == NULL) 00420 Format_Stmts = New_Token_Buffer(); 00421 00422 reset_WN2F_CONTEXT_no_newline(context); 00423 WN2F_Stmt_Newline( 00424 Format_Stmts, 00425 Number_as_String(Origfmt_Ioctrl_Label, "%lld"), 00426 WN_linenum(item), context); 00427 00428 Append_Token_String(Format_Stmts, "FORMAT"); 00429 Append_Token_String(Format_Stmts, 00430 Targ_String_Address(STC_val(WN_st(WN_kid0(item))))); 00431 emitted = FALSE; /* Only emitted into Format_Stmts */ 00432 break; 00433 00434 case IOC_ERR: 00435 case IOC_EOR: 00436 case IOC_END: 00437 Append_Token_String(tokens, IOITEM_name(item_kind)); 00438 Append_Token_Special(tokens, '='); 00439 ASSERT_DBG_WARN((WN_opc_operator(WN_kid0(item)) == OPR_GOTO), 00440 (DIAG_W2F_UNEXPECTED_OPC,WN_opc_operator(item),"ERR/END/EOR=")); 00441 Append_Token_String(tokens, 00442 WHIRL2F_number_as_name(WN_label_number(WN_kid0(item)))); 00443 break; 00444 00445 case IOC_CR_FLFLAG: 00446 case IOC_CR_EDFLAG: 00447 case IOC_ERRFLAG: 00448 case IOC_CR_EEEFLAG: 00449 emitted = FALSE; 00450 break; 00451 00452 default: 00453 /* The usual case; an arbitrary non-logic expression argument, 00454 * which is usually an integral value, an array, or a character 00455 * string. 00456 */ 00457 Append_Token_String(tokens, IOITEM_name(item_kind)); 00458 Append_Token_Special(tokens, '='); 00459 if (TY_kind(WN_Tree_Type(WN_kid0(item))) != KIND_SCALAR) 00460 set_WN2F_CONTEXT_deref_addr(context); 00461 00462 /* if kid count > 1, then it's a character object */ 00463 00464 if (WN_kid_count(item) == 1) 00465 WN2F_translate(tokens, WN_kid0(item), context); 00466 else 00467 WN2F_String_Argument(tokens,WN_kid0(item),WN_kid1(item),context); 00468 break; 00469 } 00470 00471 return emitted; 00472 } /* WN2F_io_control */ 00473 00474 00475 00476 extern WN2F_STATUS 00477 WN2F_implied_do(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context); 00478 00479 static BOOL 00480 WN2F_io_list(TOKEN_BUFFER tokens, 00481 WN *item, 00482 WN2F_CONTEXT context) 00483 { 00484 const IOITEM item_kind = WN_IOITEM(item); 00485 00486 switch (item_kind) 00487 { 00488 case IOL_VAR: 00489 case IOL_ARRAY: 00490 case IOL_CHAR_ARRAY: 00491 case IOL_RECORD: 00492 if (WN_opc_operator(WN_kid0(item)) == OPR_LDID && 00493 ST_sclass(WN_st(WN_kid0(item))) == SCLASS_FORMAL && 00494 TY_Is_Pointer(WN_ty(WN_kid0(item))) && 00495 TY_Is_Pointer(TY_pointed(WN_ty(WN_kid0(item))))) 00496 { 00497 /* Work around a f77 bug 00498 */ 00499 WN_set_ty(WN_kid0(item), TY_pointed(WN_ty(WN_kid0(item)))); 00500 } 00501 set_WN2F_CONTEXT_deref_addr(context); /* Assume pass-by-reference */ 00502 WN2F_translate(tokens, WN_kid0(item), context); 00503 break; 00504 00505 case IOL_CHAR: 00506 { 00507 WN * len = WN_kid1(item); 00508 if (WN2F_CONTEXT_cray_io(context)) /* typecode is kid1 */ 00509 len = WN_kid2(item); 00510 00511 WN2F_String_Argument(tokens, 00512 WN_kid0(item), /* base */ 00513 len, /* length */ 00514 context); 00515 } 00516 break; 00517 00518 case IOL_EXPR: 00519 reset_WN2F_CONTEXT_deref_addr(context); /* Assume pass-by-value */ 00520 WN2F_translate(tokens, WN_kid0(item), context); 00521 break; 00522 00523 case IOL_IMPLIED_DO: 00524 case IOL_IMPLIED_DO_1TRIP: 00525 reset_WN2F_CONTEXT_deref_addr(context); /* Handled specially */ 00526 WN2F_implied_do(tokens, item, context); /* Defined in WN2F_stmt.c */ 00527 break; 00528 00529 case IOL_LOGICAL: 00530 set_WN2F_CONTEXT_has_logical_arg(context); 00531 reset_WN2F_CONTEXT_deref_addr(context); /* Assume pass-by-value */ 00532 WN2F_translate(tokens, WN_kid0(item), context); 00533 break; 00534 00535 case IOL_DOPE: 00536 { 00537 INT32 kids = WN_kid_count(item); 00538 00539 /* base address */ 00540 00541 set_WN2F_CONTEXT_deref_addr(context); 00542 WN2F_translate(tokens, WN_kid0(item), context); 00543 #if 0 //August 00544 if (kids > 2) /* implied do? */ 00545 { 00546 Append_Token_Special(tokens, '('); 00547 00548 /* Generate the subscript list - part may be in dope address, */ 00549 /* set up several stmts ago. may just get INTCONST(0) here */ 00550 00551 INT32 i = 2 ; 00552 while (i < kids) 00553 { 00554 WN2F_translate(tokens, WN_kid(item,i), context); 00555 00556 if (i++ < kids-1) 00557 Append_Token_Special(tokens, ','); 00558 } 00559 Append_Token_Special(tokens, ')'); 00560 } 00561 #endif 00562 } 00563 break ; 00564 00565 default: 00566 ASSERT_DBG_WARN(FALSE, 00567 (DIAG_W2F_UNEXPECTED_IOL, 00568 IOITEM_name(WN_IOITEM(item)), "WN2F_io_list")); 00569 Append_Token_String(tokens, IOITEM_name(WN_IOITEM(item))); 00570 break; 00571 } /* switch */ 00572 00573 return TRUE; 00574 } /* WN2F_io_list */ 00575 00576 00577 /*---------- IO Statement Handler-routines and Dispatch-array ---------*/ 00578 /*---------------------------------------------------------------------*/ 00579 00580 static void 00581 WN2F_ios_backspace(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00582 { 00583 /* The kids should be an IOU, followed a sequence of IOCs. Always 00584 * use the explicit UNIT keyword, unless there is exactly one kid an 00585 * it is an IOU. 00586 */ 00587 ASSERT_WARN(WN_IOSTMT(wn) == IOS_BACKSPACE || WN_IOSTMT(wn) == IOS_CR_BACKSPACE, 00588 (DIAG_W2F_UNEXPECTED_IOS, 00589 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_backspace")); 00590 00591 Append_Token_String(tokens, "BACKSPACE"); 00592 if (WN_kid_count(wn) == 1 && WN2F_IS_IOU(WN_kid0(wn))) 00593 (void)WN2F_io_item(tokens, WN_kid0(wn), context); 00594 else 00595 WN2F_Append_IO_CtrlList(tokens, 00596 wn, /* ios */ 00597 0, /* from kid*/ 00598 WN_kid_count(wn)-1, /* to kid*/ 00599 TRUE, /* use keyword control */ 00600 context); 00601 00602 } /* WN2F_ios_backspace */ 00603 00604 00605 static void 00606 WN2F_ios_close(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00607 { 00608 /* The kids should be an IOU, followed a sequence of IOCs. Always 00609 * use the explicit UNIT keyword. 00610 */ 00611 ASSERT_WARN(WN_IOSTMT(wn) == IOS_CLOSE || WN_IOSTMT(wn) == IOS_CR_CLOSE, 00612 (DIAG_W2F_UNEXPECTED_IOS, 00613 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_close")); 00614 00615 Append_Token_String(tokens, "CLOSE"); 00616 WN2F_Append_IO_CtrlList(tokens, 00617 wn, /* ios */ 00618 0, /* from kid*/ 00619 WN_kid_count(wn)-1, /* to kid*/ 00620 TRUE, /* use keyword control */ 00621 context); 00622 } /* WN2F_ios_close */ 00623 00624 00625 static void 00626 WN2F_ios_definefile(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00627 { 00628 /* The kids should be an IOU, followed a sequence of IOCs. Always 00629 * use the explicit UNIT keyword. 00630 */ 00631 ASSERT_FATAL(WN_io_statement(wn) == IOS_DEFINEFILE && 00632 WN_kid_count(wn) == 5 && 00633 WN_io_item(WN_kid(wn, 1)) == IOC_MAXREC && 00634 WN_io_item(WN_kid(wn, 2)) == IOC_RECL && 00635 WN_io_item(WN_kid(wn, 3)) == IOC_U && 00636 WN_io_item(WN_kid(wn, 4)) == IOC_ASSOCIATEVARIABLE, 00637 (DIAG_W2F_UNEXPECTED_IOS, 00638 IOSTATEMENT_name(WN_IOSTMT(wn)), 00639 "WN2F_ios_definefile")); 00640 00641 Append_Token_String(tokens, "DEFINE FILE"); 00642 00643 reset_WN2F_CONTEXT_keyword_ioctrl(context); 00644 WN2F_io_unit(tokens, WN_kid(wn, 0), context); 00645 Append_Token_Special(tokens, '('); 00646 00647 if (TY_kind(WN_Tree_Type(WN_kid0(WN_kid(wn, 1)))) != KIND_SCALAR) 00648 set_WN2F_CONTEXT_deref_addr(context); 00649 WN2F_translate(tokens, WN_kid0(WN_kid(wn, 1)), context); 00650 reset_WN2F_CONTEXT_deref_addr(context); 00651 Append_Token_Special(tokens, ','); 00652 00653 if (TY_kind(WN_Tree_Type(WN_kid0(WN_kid(wn, 2)))) != KIND_SCALAR) 00654 set_WN2F_CONTEXT_deref_addr(context); 00655 WN2F_translate(tokens, WN_kid0(WN_kid(wn, 2)), context); 00656 reset_WN2F_CONTEXT_deref_addr(context); 00657 Append_Token_Special(tokens, ','); 00658 00659 Append_Token_String(tokens, "U"); 00660 Append_Token_Special(tokens, ','); 00661 00662 if (TY_kind(WN_Tree_Type(WN_kid0(WN_kid(wn, 4)))) != KIND_SCALAR) 00663 set_WN2F_CONTEXT_deref_addr(context); 00664 WN2F_translate(tokens, WN_kid0(WN_kid(wn, 4)), context); 00665 Append_Token_Special(tokens, ')'); 00666 00667 } /* WN2F_ios_definefile */ 00668 00669 00670 static void 00671 WN2F_ios_delete(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00672 { 00673 /* The kids should be an IOU, followed a sequence of IOCs. Always 00674 * use the explicit UNIT keyword. 00675 */ 00676 ASSERT_WARN(WN_IOSTMT(wn) == IOS_DELETE, 00677 (DIAG_W2F_UNEXPECTED_IOS, 00678 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_delete")); 00679 00680 Append_Token_String(tokens, "DELETE"); 00681 WN2F_Append_IO_CtrlList(tokens, 00682 wn, /* ios */ 00683 0, /* from kid*/ 00684 WN_kid_count(wn)-1, /* to kid*/ 00685 TRUE, /* use keyword control */ 00686 context); 00687 } /* WN2F_ios_delete */ 00688 00689 00690 static void 00691 WN2F_ios_endfile(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00692 { 00693 /* The kids should be an IOU, followed a sequence of IOCs. Always 00694 * use the explicit UNIT keyword, unless there is exactly one kid an 00695 * it is an IOU. 00696 */ 00697 ASSERT_WARN(WN_IOSTMT(wn) == IOS_ENDFILE || WN_IOSTMT(wn) == IOS_CR_ENDFILE, 00698 (DIAG_W2F_UNEXPECTED_IOS, 00699 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_endfile")); 00700 00701 Append_Token_String(tokens, "ENDFILE"); 00702 if (WN_kid_count(wn) == 1 && WN2F_IS_IOU(WN_kid0(wn))) 00703 (void)WN2F_io_item(tokens, WN_kid0(wn), context); 00704 else 00705 WN2F_Append_IO_CtrlList(tokens, 00706 wn, /* ios */ 00707 0, /* from kid*/ 00708 WN_kid_count(wn)-1, /* to kid*/ 00709 TRUE, /* use keyword control */ 00710 context); 00711 00712 } /* WN2F_ios_endfile */ 00713 00714 00715 static void 00716 WN2F_ios_find(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00717 { 00718 /* The kids should be an IOU, followed a sequence of IOCs. Always 00719 * use the explicit UNIT keyword. 00720 */ 00721 ASSERT_WARN(WN_IOSTMT(wn) == IOS_FIND, 00722 (DIAG_W2F_UNEXPECTED_IOS, 00723 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_find")); 00724 00725 Append_Token_String(tokens, "FIND"); 00726 WN2F_Append_IO_CtrlList(tokens, 00727 wn, /* ios */ 00728 0, /* from kid*/ 00729 WN_kid_count(wn)-1, /* to kid*/ 00730 TRUE, /* use keyword control */ 00731 context); 00732 } /* WN2F_ios_find */ 00733 00734 00735 static void 00736 WN2F_ios_inquire(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00737 { 00738 /* The kids should be an optional IOU, followed a sequence of IOCs. 00739 * Always use the explicit UNIT keyword when the IOU is present. 00740 */ 00741 ASSERT_WARN(WN_IOSTMT(wn) == IOS_INQUIRE || WN_IOSTMT(wn) == IOS_CR_INQUIRE, 00742 (DIAG_W2F_UNEXPECTED_IOS, 00743 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_inquire")); 00744 00745 Append_Token_String(tokens, "INQUIRE"); 00746 WN2F_Append_IO_CtrlList(tokens, 00747 wn, /* ios */ 00748 0, /* from kid*/ 00749 WN_kid_count(wn)-1, /* to kid*/ 00750 TRUE, /* use keyword control */ 00751 context); 00752 } /* WN2F_ios_inquire */ 00753 00754 static void 00755 WN2F_ios_inqlength(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00756 { 00757 INT ios_kid; 00758 BOOL emitted = FALSE; 00759 ASSERT_WARN(WN_IOSTMT(wn) == IOS_INQLENGTH, 00760 (DIAG_W2F_UNEXPECTED_IOS, 00761 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_inqlength")); 00762 00763 Append_Token_String(tokens, "INQUIRE"); 00764 Append_Token_Special(tokens,'('); 00765 for (ios_kid=0; ios_kid<=WN_kid_count(wn)-1; ios_kid++) 00766 { 00767 WN *item = WN_kid(wn, ios_kid); 00768 if (WN2F_IS_IOC(item) && WN_IOITEM(item)==IOC_INQLENGTH_VAR){ 00769 Append_Token_String(tokens,"IOLENGTH ="); 00770 WN2F_translate(tokens, WN_kid0(item), context); 00771 Append_Token_Special(tokens,')'); 00772 } 00773 00774 if (WN2F_IS_IOL(item)) { 00775 TOKEN_BUFFER item_buffer = New_Token_Buffer(); 00776 if (WN2F_io_list(item_buffer, item, context)){ 00777 if (emitted ) 00778 Append_Token_Special(tokens, ','); 00779 else 00780 emitted = TRUE; 00781 Append_And_Reclaim_Token_List(tokens, &item_buffer); 00782 } 00783 } 00784 } 00785 reset_WN2F_CONTEXT_origfmt_ioctrl(context); 00786 00787 } /*WN2F_ios_inqlength*/ 00788 00789 static void 00790 WN2F_ios_namelist(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00791 { 00792 ASSERT_WARN(WN_IOSTMT(wn) == IOS_NAMELIST, 00793 (DIAG_W2F_UNEXPECTED_IOS, 00794 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_namelist")); 00795 00796 Append_Token_String(tokens, "NAMELIST"); 00797 Append_Token_Special(tokens, '/'); 00798 (void)WN2F_io_item(tokens, WN_kid1(wn), context); 00799 Append_Token_Special(tokens, '/'); 00800 00801 if (WN_kid_count(wn) > 2) 00802 WN2F_Append_IO_List(tokens, wn, 2, context); 00803 00804 } /* WN2F_ios_namelist */ 00805 00806 00807 static void 00808 WN2F_ios_open(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00809 { 00810 /* The kids should be an IOU, followed a sequence of IOCs. Always 00811 * use the explicit UNIT keyword. 00812 */ 00813 ASSERT_WARN(WN_IOSTMT(wn) == IOS_OPEN || WN_IOSTMT(wn) == IOS_CR_OPEN, 00814 (DIAG_W2F_UNEXPECTED_IOS, 00815 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_open")); 00816 00817 Append_Token_String(tokens, "OPEN"); 00818 WN2F_Append_IO_CtrlList(tokens, 00819 wn, /* ios */ 00820 0, /* from kid*/ 00821 WN_kid_count(wn)-1, /* to kid*/ 00822 TRUE, /* use keyword control */ 00823 context); 00824 } /* WN2F_ios_open */ 00825 00826 00827 static void 00828 WN2F_ios_rewind(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00829 { 00830 /* The kids should be an IOU, followed a sequence of IOCs. Always 00831 * use the explicit UNIT keyword, unless there is exactly one kid 00832 * and it is an IOU. 00833 */ 00834 ASSERT_WARN(WN_IOSTMT(wn) == IOS_REWIND || WN_IOSTMT(wn) == IOS_CR_REWIND, 00835 (DIAG_W2F_UNEXPECTED_IOS, 00836 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_rewind")); 00837 00838 Append_Token_String(tokens, "REWIND"); 00839 if (WN_kid_count(wn) == 1 && WN2F_IS_IOU(WN_kid0(wn))) 00840 (void)WN2F_io_item(tokens, WN_kid0(wn), context); 00841 else 00842 WN2F_Append_IO_CtrlList(tokens, 00843 wn, /* ios */ 00844 0, /* from kid*/ 00845 WN_kid_count(wn)-1, /* to kid*/ 00846 TRUE, /* use keyword control */ 00847 context); 00848 } /* WN2F_ios_rewind */ 00849 00850 00851 static void 00852 WN2F_ios_unlock(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00853 { 00854 /* The kids should be an IOU, followed a sequence of IOCs. Always 00855 * use the explicit UNIT keyword, unless there is exactly one kid an 00856 * it is an IOU. 00857 */ 00858 ASSERT_WARN(WN_IOSTMT(wn) == IOS_UNLOCK, 00859 (DIAG_W2F_UNEXPECTED_IOS, 00860 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_unlock")); 00861 00862 Append_Token_String(tokens, "UNLOCK"); 00863 if (WN_kid_count(wn) == 1 && WN2F_IS_IOU(WN_kid0(wn))) 00864 (void)WN2F_io_item(tokens, WN_kid0(wn), context); 00865 else 00866 WN2F_Append_IO_CtrlList(tokens, 00867 wn, /* ios */ 00868 0, /* from kid*/ 00869 WN_kid_count(wn)-1, /* to kid*/ 00870 TRUE, /* use keyword control */ 00871 context); 00872 00873 } /* WN2F_ios_unlock */ 00874 00875 00876 static void 00877 WN2F_ios_accept(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00878 { 00879 /* The kids should be an IOF, followed a sequence of IOLs. 00880 */ 00881 ASSERT_WARN(WN_IOSTMT(wn) == IOS_ACCEPT, 00882 (DIAG_W2F_UNEXPECTED_IOS, 00883 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_accept")); 00884 00885 Append_Token_String(tokens, "ACCEPT"); 00886 (void)WN2F_io_item(tokens, WN_kid0(wn), context); 00887 if (WN_kid_count(wn) > 1) 00888 { 00889 Append_Token_Special(tokens, ','); 00890 WN2F_Append_IO_List(tokens, wn, 1, context); 00891 } 00892 } /* WN2F_ios_accept */ 00893 00894 00895 static void 00896 WN2F_ios_decode(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00897 { 00898 /* The kids should be an IOU, followed by an IOF, followed by a 00899 * sequence of IOCs and a sequence of IOLs. Use keywords only 00900 * when the IOC list is non-empty. Note that the IOU contains 00901 * both the integer expression (c) and the scalar or array 00902 * reference (a) in "ENCODE (c, f, a [,IOSTAT=ios][,ERR=s]) iolist". 00903 */ 00904 INT iol_kid; 00905 00906 ASSERT_WARN(WN_IOSTMT(wn) == IOS_DECODE, 00907 (DIAG_W2F_UNEXPECTED_IOS, 00908 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_decode")); 00909 00910 /* This is needed for the translation of the number of characters and 00911 * the buffer we decode characters from. 00912 */ 00913 set_WN2F_CONTEXT_deref_addr(context); 00914 00915 Append_Token_String(tokens, "DECODE"); 00916 Append_Token_Special(tokens, '('); 00917 00918 /* Translate the number of characters */ 00919 ASSERT_WARN(WN_IOITEM(WN_kid0(wn)) == IOU_INTERNAL && 00920 WN_kid_count(WN_kid0(wn)) >= 2, 00921 (DIAG_W2F_UNEXPECTED_IOU, 00922 IOITEM_name(WN_IOITEM(WN_kid0(wn))), "WN2F_ios_decode")); 00923 WN2F_translate(tokens, WN_kid1(WN_kid0(wn)), context); 00924 00925 /* Translate the format */ 00926 Append_Token_Special(tokens, ','); 00927 (void)WN2F_io_item(tokens, WN_kid1(wn), context); 00928 00929 /* Translate the buffer we decode from */ 00930 Append_Token_Special(tokens, ','); 00931 WN2F_translate(tokens, WN_kid0(WN_kid0(wn)), context); 00932 00933 /* Translate the EOSTAT and the ERR items */ 00934 iol_kid = 2; 00935 if (WN_kid_count(wn) > 2 && WN2F_IS_IOC(WN_kid(wn, 2))) 00936 { 00937 iol_kid = 3; 00938 Append_Token_Special(tokens, ','); 00939 (void)WN2F_io_item(tokens, WN_kid(wn, 2), context); 00940 } 00941 if (WN_kid_count(wn) > 3 && WN2F_IS_IOC(WN_kid(wn, 3))) 00942 { 00943 iol_kid = 4; 00944 Append_Token_Special(tokens, ','); 00945 (void)WN2F_io_item(tokens, WN_kid(wn, 3), context); 00946 } 00947 Append_Token_Special(tokens, ')'); 00948 00949 /* Get the io_list */ 00950 if (WN_kid_count(wn) > iol_kid) 00951 WN2F_Append_IO_List(tokens, wn, iol_kid, context); 00952 00953 } /* WN2F_ios_decode */ 00954 00955 00956 static void 00957 WN2F_ios_encode(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 00958 { 00959 /* The kids should be an IOU, followed by an IOF, followed by a 00960 * sequence of IOCs and a sequence of IOLs. Use keywords only 00961 * when the IOC list is non-empty. Note that the IOU contains 00962 * both the integer expression (c) and the scalar or array 00963 * reference (a) in "ENCODE (c, f, a [,IOSTAT=ios][,ERR=s]) iolist". 00964 */ 00965 INT iol_kid; 00966 00967 ASSERT_WARN(WN_IOSTMT(wn) == IOS_ENCODE, 00968 (DIAG_W2F_UNEXPECTED_IOS, 00969 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_ENcode")); 00970 00971 /* This is needed for the translation of the number of characters and 00972 * the buffer we encode characters from. 00973 */ 00974 set_WN2F_CONTEXT_deref_addr(context); 00975 00976 Append_Token_String(tokens, "ENCODE"); 00977 Append_Token_Special(tokens, '('); 00978 00979 /* Translate the number of characters */ 00980 ASSERT_WARN(WN_IOITEM(WN_kid0(wn)) == IOU_INTERNAL && 00981 WN_kid_count(WN_kid0(wn)) >= 2, 00982 (DIAG_W2F_UNEXPECTED_IOU, 00983 IOITEM_name(WN_IOITEM(WN_kid0(wn))), "WN2F_ios_encode")); 00984 WN2F_translate(tokens, WN_kid1(WN_kid0(wn)), context); 00985 00986 /* Translate the format */ 00987 Append_Token_Special(tokens, ','); 00988 (void)WN2F_io_item(tokens, WN_kid1(wn), context); 00989 00990 /* Translate the buffer we encode from */ 00991 Append_Token_Special(tokens, ','); 00992 WN2F_translate(tokens, WN_kid0(WN_kid0(wn)), context); 00993 00994 /* Translate the EOSTAT and the ERR items */ 00995 iol_kid = 2; 00996 if (WN_kid_count(wn) > 2 && WN2F_IS_IOC(WN_kid(wn, 2))) 00997 { 00998 iol_kid = 3; 00999 Append_Token_Special(tokens, ','); 01000 (void)WN2F_io_item(tokens, WN_kid(wn, 2), context); 01001 } 01002 if (WN_kid_count(wn) > 3 && WN2F_IS_IOC(WN_kid(wn, 3))) 01003 { 01004 iol_kid = 4; 01005 Append_Token_Special(tokens, ','); 01006 (void)WN2F_io_item(tokens, WN_kid(wn, 3), context); 01007 } 01008 Append_Token_Special(tokens, ')'); 01009 01010 /* Get the io_list */ 01011 if (WN_kid_count(wn) > iol_kid) 01012 WN2F_Append_IO_List(tokens, wn, iol_kid, context); 01013 01014 } /* WN2F_ios_encode */ 01015 01016 01017 static void 01018 WN2F_ios_print(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01019 { 01020 INT iol_kid; 01021 01022 /* The kids should be an IOF, followed a sequence of IOLs. 01023 */ 01024 ASSERT_WARN(WN_IOSTMT(wn) == IOS_PRINT, 01025 (DIAG_W2F_UNEXPECTED_IOS, 01026 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_print")); 01027 01028 Append_Token_String(tokens, "PRINT"); 01029 01030 set_WN2F_CONTEXT_issue_ioc_asterisk(context); 01031 01032 /* We do not really expect to have a unit specification for a "PRINT" 01033 * statement, but just in the case one occurs anyway, we skip it here. 01034 */ 01035 if (WN2F_IS_IOU(WN_kid0(wn))) 01036 iol_kid = 2; /* kid 1 must be the format */ 01037 else 01038 iol_kid = 1; /* Missing unit number */ 01039 (void)WN2F_io_item(tokens, WN_kid(wn, iol_kid-1), context); 01040 if (WN_kid_count(wn) > iol_kid) 01041 { 01042 Append_Token_Special(tokens, ','); 01043 WN2F_Append_IO_List(tokens, wn, iol_kid, context); 01044 } 01045 01046 reset_WN2F_CONTEXT_issue_ioc_asterisk(context); 01047 01048 } /* WN2F_ios_print */ 01049 01050 01051 static void 01052 WN2F_ios_read(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01053 { 01054 /* The kids should be an IOU, followed by an IOF, followed by a 01055 * sequence of IOCs and a sequence of IOLs. Use keywords only 01056 * when the IOC list is non-empty. The IOL should be a sequence 01057 * of addresses into which the values read should be put. In 01058 * the whirl2f output these addresses must be dereferenced. 01059 */ 01060 INT iol_kid; 01061 BOOL use_keyword; 01062 01063 01064 Append_Token_String(tokens, "READ"); 01065 set_WN2F_CONTEXT_issue_ioc_asterisk(context); 01066 01067 /* Determine whether or not we have the "READ f [,iolist]" format. 01068 */ 01069 if (WN_IOITEM(WN_kid0(wn)) == IOU_DEFAULT && 01070 WN2F_IS_IOF(WN_kid1(wn)) && 01071 WN_IOITEM(WN_kid1(wn)) != IOF_NAMELIST_DIRECTED && 01072 (WN_kid_count(wn) == 2 || WN2F_IS_IOL(WN_kid(wn, 2)))) 01073 { 01074 (void)WN2F_io_item(tokens, WN_kid0(wn), context); 01075 iol_kid = 2; 01076 if (WN_kid_count(wn) > 2) 01077 Append_Token_Special(tokens, ','); 01078 } 01079 else 01080 { 01081 /* Determine if we should use the "unit=" or "fmt=" keyword notation, 01082 * and which kid is the last control specification item. 01083 */ 01084 use_keyword = (WN_kid_count(wn) > 2 && 01085 WN2F_IS_IOF(WN_kid(wn, 1)) && 01086 WN2F_IS_IOC(WN_kid(wn, 2))); 01087 for (iol_kid = 0; 01088 (iol_kid < WN_kid_count(wn)) && !WN2F_IS_IOL(WN_kid(wn, iol_kid)); 01089 iol_kid++); 01090 01091 /* Get the IOU, IOF, and IOC items */ 01092 WN2F_Append_IO_CtrlList(tokens, 01093 wn, /* ios */ 01094 0, /* from kid*/ 01095 iol_kid-1, /* to kid*/ 01096 use_keyword, /* use keyword control */ 01097 context); 01098 } 01099 01100 /* Get the io_list */ 01101 if (iol_kid < WN_kid_count(wn)) 01102 { 01103 set_WN2F_CONTEXT_deref_io_item(context); /* Assume pass-by-reference */ 01104 WN2F_Append_IO_List(tokens, wn, iol_kid, context); 01105 } 01106 01107 reset_WN2F_CONTEXT_issue_ioc_asterisk(context); 01108 01109 } /* WN2F_ios_read */ 01110 01111 01112 static void 01113 WN2F_ios_rewrite(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01114 { 01115 /* The kids should be an IOU, followed by an IOF, followed by a 01116 * sequence of IOCs and a sequence of IOLs. Use keywords only 01117 * when the IOC list is non-empty. 01118 */ 01119 INT iol_kid; 01120 BOOL use_keyword; 01121 01122 ASSERT_WARN(WN_IOSTMT(wn) == IOS_REWRITE, 01123 (DIAG_W2F_UNEXPECTED_IOS, 01124 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_rewrite")); 01125 01126 Append_Token_String(tokens, "REWRITE"); 01127 set_WN2F_CONTEXT_issue_ioc_asterisk(context); 01128 01129 /* Determine if we should use the "unit=" or "fmt=" keyword notation, 01130 * and which kid is the last control specification itemx. 01131 */ 01132 use_keyword = (WN_kid_count(wn) > 2 && 01133 WN2F_IS_IOF(WN_kid(wn, 1)) && 01134 WN2F_IS_IOC(WN_kid(wn, 2))); 01135 for (iol_kid = 0; 01136 (iol_kid < WN_kid_count(wn)) && !WN2F_IS_IOL(WN_kid(wn, iol_kid)); 01137 iol_kid++); 01138 01139 /* Get the IOU, IOF, and IOC items */ 01140 WN2F_Append_IO_CtrlList(tokens, 01141 wn, /* ios */ 01142 0, /* from kid*/ 01143 iol_kid-1, /* to kid*/ 01144 use_keyword, /* use keyword control */ 01145 context); 01146 01147 /* Get the io_list */ 01148 if (iol_kid < WN_kid_count(wn)) 01149 WN2F_Append_IO_List(tokens, wn, iol_kid, context); 01150 01151 reset_WN2F_CONTEXT_issue_ioc_asterisk(context); 01152 01153 } /* WN2F_ios_rewrite */ 01154 01155 01156 static void 01157 WN2F_ios_type(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01158 { 01159 /* The kids should be an IOF, followed a sequence of IOLs. 01160 */ 01161 ASSERT_WARN(WN_IOSTMT(wn) == IOS_TYPE, 01162 (DIAG_W2F_UNEXPECTED_IOS, 01163 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_type")); 01164 01165 Append_Token_String(tokens, "TYPE"); 01166 (void)WN2F_io_item(tokens, WN_kid0(wn), context); 01167 if (WN_kid_count(wn) > 1) 01168 { 01169 Append_Token_Special(tokens, ','); 01170 WN2F_Append_IO_List(tokens, wn, 1, context); 01171 } 01172 } /* WN2F_ios_type */ 01173 01174 01175 static void 01176 WN2F_ios_write(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01177 { 01178 /* The kids should be an IOU, followed by an IOF, followed by a 01179 * sequence of IOCs and a sequence of IOLs. Use keywords only 01180 * when the IOC list is non-empty. 01181 */ 01182 INT iol_kid; 01183 BOOL use_keyword; 01184 01185 Append_Token_String(tokens, "WRITE"); 01186 01187 set_WN2F_CONTEXT_issue_ioc_asterisk(context); 01188 01189 /* Determine if we should use the "unit=" or "fmt=" keyword notation, 01190 * and which kid is the last control specification item. 01191 */ 01192 use_keyword = (WN_kid_count(wn) > 2 && 01193 WN2F_IS_IOF(WN_kid(wn, 1)) && 01194 WN2F_IS_IOC(WN_kid(wn, 2))); 01195 for (iol_kid = 0; 01196 (iol_kid < WN_kid_count(wn)) && !WN2F_IS_IOL(WN_kid(wn, iol_kid)); 01197 iol_kid++); 01198 01199 /* Get the IOU, IOF, and IOC items */ 01200 WN2F_Append_IO_CtrlList(tokens, 01201 wn, /* ios */ 01202 0, /* from kid */ 01203 iol_kid-1, /* to kid */ 01204 use_keyword, /* use keyword control */ 01205 context); 01206 01207 /* Get the io_list */ 01208 if (iol_kid < WN_kid_count(wn)) 01209 WN2F_Append_IO_List(tokens, wn, iol_kid, context); 01210 01211 reset_WN2F_CONTEXT_issue_ioc_asterisk(context); 01212 01213 } /* WN2F_ios_write */ 01214 01215 01216 /*------------------------- Cray Library routines ---------------------*/ 01217 /*---------------------------------------------------------------------*/ 01218 01219 static void 01220 WN2F_ios_cr(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01221 { 01222 /* Craylibs IO - write/read The kids should be an IOS, with kids of IO_ITEMS */ 01223 01224 INT iol_kid; 01225 char * p ; 01226 01227 ASSERT_WARN(WN_IOSTMT(wn) == IOS_CR_FWF || 01228 WN_IOSTMT(wn) == IOS_CR_FWU || 01229 WN_IOSTMT(wn) == IOS_CR_FRF || 01230 WN_IOSTMT(wn) == IOS_CR_FRU, 01231 (DIAG_W2F_UNEXPECTED_IOS, 01232 IOSTATEMENT_name(WN_IOSTMT(wn)), "WN2F_ios_cr")); 01233 01234 set_WN2F_CONTEXT_issue_ioc_asterisk(context); 01235 01236 /* See if this is the first/last part of a 3-call IO stmt. If so punt */ 01237 /* - it just duplicates some detail from the main stmt. */ 01238 01239 for (iol_kid = 0; iol_kid < WN_kid_count(wn); iol_kid++) 01240 { 01241 WN * item = WN_kid(wn,iol_kid); 01242 if (WN_io_item(item) == IOC_CR_FLFLAG) 01243 { 01244 INT32 i = (WN_const_val(WN_kid0(item)) & 3); 01245 if (i != 0 && i != 3) 01246 return; 01247 else 01248 break; 01249 } 01250 } 01251 01252 /* decide if read/write formatted/unformatted */ 01253 01254 if (WN_IOSTMT(wn) == IOS_CR_FWF || WN_IOSTMT(wn) == IOS_CR_FRF) 01255 set_WN2F_CONTEXT_fmt_io(context) ; 01256 01257 if (WN_IOSTMT(wn) == IOS_CR_FRF || WN_IOSTMT(wn) == IOS_CR_FRU) 01258 p = "READ" ; 01259 else 01260 p = "WRITE"; 01261 01262 Append_Token_String(tokens,p); 01263 01264 01265 /* count items in control list */ 01266 01267 for (iol_kid = 0; 01268 (iol_kid < WN_kid_count(wn)) && !WN2F_IS_IOL(WN_kid(wn, iol_kid)); 01269 iol_kid++); 01270 01271 /* Get the IOU, IOF, and IOC items */ 01272 01273 WN2F_Append_IO_CtrlList(tokens, 01274 wn, /* ios */ 01275 0, /* from kid */ 01276 iol_kid-1, /* to kid */ 01277 FALSE, /* use keyword control */ 01278 context); 01279 01280 /* Get the io_list */ 01281 01282 if (iol_kid < WN_kid_count(wn)) 01283 WN2F_Append_IO_List(tokens, wn, iol_kid, context); 01284 01285 reset_WN2F_CONTEXT_issue_ioc_asterisk(context); 01286 01287 } /* WN2F_ios_cr */ 01288 01289 /*------------------------- Exported routines -------------------------*/ 01290 /*---------------------------------------------------------------------*/ 01291 01292 void WN2F_Io_initialize(void) 01293 { 01294 Ios_Handler[IOS_BACKSPACE] = &WN2F_ios_backspace; 01295 Ios_Handler[IOS_CLOSE] = &WN2F_ios_close; 01296 Ios_Handler[IOS_DEFINEFILE] = &WN2F_ios_definefile; 01297 Ios_Handler[IOS_DELETE] = &WN2F_ios_delete; 01298 Ios_Handler[IOS_ENDFILE] = &WN2F_ios_endfile; 01299 Ios_Handler[IOS_FIND] = &WN2F_ios_find; 01300 Ios_Handler[IOS_INQUIRE] = &WN2F_ios_inquire; 01301 Ios_Handler[IOS_NAMELIST] = &WN2F_ios_namelist; 01302 Ios_Handler[IOS_OPEN] = &WN2F_ios_open; 01303 Ios_Handler[IOS_REWIND] = &WN2F_ios_rewind; 01304 Ios_Handler[IOS_UNLOCK] = &WN2F_ios_unlock; 01305 Ios_Handler[IOS_ACCEPT] = &WN2F_ios_accept; 01306 Ios_Handler[IOS_DECODE] = &WN2F_ios_decode; 01307 Ios_Handler[IOS_ENCODE] = &WN2F_ios_encode; 01308 Ios_Handler[IOS_PRINT] = &WN2F_ios_print; 01309 Ios_Handler[IOS_READ] = &WN2F_ios_read; 01310 Ios_Handler[IOS_REWRITE] = &WN2F_ios_rewrite; 01311 Ios_Handler[IOS_TYPE] = &WN2F_ios_type; 01312 Ios_Handler[IOS_WRITE] = &WN2F_ios_write; 01313 Ios_Handler[IOS_CR_FWF] = &WN2F_ios_cr; 01314 Ios_Handler[IOS_CR_FRN] = &WN2F_ios_read; 01315 Ios_Handler[IOS_CR_FWN] = &WN2F_ios_write; 01316 Ios_Handler[IOS_CR_FWU] = &WN2F_ios_cr; 01317 Ios_Handler[IOS_CR_FRF] = &WN2F_ios_cr; 01318 Ios_Handler[IOS_CR_FRU] = &WN2F_ios_cr; 01319 Ios_Handler[IOS_CR_OPEN] = &WN2F_ios_open; 01320 Ios_Handler[IOS_CR_CLOSE] = &WN2F_ios_close; 01321 Ios_Handler[IOS_CR_REWIND] = &WN2F_ios_rewind; 01322 Ios_Handler[IOS_CR_INQUIRE] = &WN2F_ios_inquire; 01323 Ios_Handler[IOS_CR_ENDFILE] = &WN2F_ios_endfile; 01324 Ios_Handler[IOS_CR_BACKSPACE] = &WN2F_ios_backspace; 01325 Ios_Handler[IOS_INQLENGTH] = &WN2F_ios_inqlength; 01326 01327 01328 01329 } /* WN2F_Io_initialize */ 01330 01331 void WN2F_Io_finalize(void) 01332 { 01333 /* Do nothing for now! */ 01334 } /* WN2F_Io_finalize */ 01335 01336 static BOOL 01337 Is_Cray_IO(IOSTATEMENT ios) 01338 { 01339 BOOL res ; 01340 01341 res = (ios == IOS_CR_FWF) || 01342 (ios == IOS_CR_FWU) || 01343 (ios == IOS_CR_FRF) || 01344 (ios == IOS_CR_FRU) || 01345 (ios == IOS_CR_OPEN) || 01346 (ios == IOS_CR_CLOSE) || 01347 (ios == IOS_CR_REWIND) || 01348 (ios == IOS_CR_INQUIRE) || 01349 (ios == IOS_CR_ENDFILE) || 01350 (ios == IOS_CR_FRN) || 01351 (ios == IOS_CR_FWN) || 01352 (ios == IOS_CR_BACKSPACE); 01353 01354 return res ; 01355 } 01356 01357 TOKEN_BUFFER 01358 WN2F_io_prefix_tokens(void) 01359 { 01360 return Ios_Prefix_Tokens; 01361 } 01362 01363 WN2F_STATUS 01364 WN2F_io(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 01365 { 01366 INT ios_kid; 01367 TOKEN_BUFFER ios_tokens = New_Token_Buffer(); 01368 01369 ASSERT_DBG_FATAL(WN_opc_operator(wn) == OPR_IO, 01370 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_io")); 01371 01372 /* Should we use the string given by an IOC_VARFMT_ORIGFMT 01373 * for a IOF_LABEL? 01374 */ 01375 for (ios_kid = 0; 01376 (ios_kid < WN_kid_count(wn) && 01377 WN_io_item(WN_kid(wn, ios_kid)) != IOC_VARFMT_ORIGFMT); 01378 ios_kid++); 01379 if (ios_kid < WN_kid_count(wn)) 01380 { 01381 set_WN2F_CONTEXT_origfmt_ioctrl(context); 01382 Origfmt_Ioctrl_Label = W2CF_Symtab_Unique_Label(); 01383 } 01384 01385 /* Now dispatch to the appropriate handler routine for each 01386 * kind of IO statement, after beginning the statement on a 01387 * new line and setting the appropriate context flags. 01388 */ 01389 WN2F_Stmt_Newline(tokens, NULL/*label*/, WN_linenum(wn), context); 01390 set_WN2F_CONTEXT_io_stmt(context); 01391 set_WN2F_CONTEXT_no_newline(context); 01392 Ios_Prefix_Tokens = New_Token_Buffer(); 01393 01394 const IOSTATEMENT ios = WN_IOSTMT(wn); 01395 01396 if (Is_Cray_IO(ios)) 01397 set_WN2F_CONTEXT_cray_io(context) ; 01398 01399 if (Ios_Handler[ios] == NULL) 01400 { 01401 Append_Token_String(ios_tokens, "<<FLIST cannot handle "); 01402 Append_Token_String(ios_tokens, 01403 get_iostatement_name(ios)); 01404 Append_Token_String(ios_tokens, " io statement>>"); 01405 } 01406 else 01407 { 01408 Ios_Handler[ios](ios_tokens, wn, context); 01409 } 01410 01411 if (Ios_Prefix_Tokens != NULL) 01412 Append_And_Reclaim_Token_List(tokens, &Ios_Prefix_Tokens); 01413 Append_And_Reclaim_Token_List(tokens, &ios_tokens); 01414 if (Format_Stmts != NULL) 01415 Append_And_Reclaim_Token_List(tokens, &Format_Stmts); 01416 01417 reset_WN2F_CONTEXT_cray_io(context) ; 01418 01419 return EMPTY_WN2F_STATUS; 01420 } /* WN2F_io */ 01421 01422 01423 BOOL 01424 WN2F_io_item(TOKEN_BUFFER tokens, WN *item, WN2F_CONTEXT context) 01425 { 01426 /* Returns TRUE when something (anything) was emitted for this item. 01427 */ 01428 BOOL emitted = FALSE; 01429 01430 /* Any pointer-argument to an io-item should be dereferenced. Most 01431 * notably, this applies for an LDA of a character string in a FMT 01432 * specifier, but it also applies for a variety of other arguments. 01433 * Such dereferences are specified within the WN2F_io routines. 01434 */ 01435 if (WN2F_CONTEXT_deref_io_item(context)) 01436 set_WN2F_CONTEXT_deref_addr(context); 01437 else 01438 reset_WN2F_CONTEXT_deref_addr(context); 01439 01440 if (WN2F_IS_IOU(item)) 01441 emitted = WN2F_io_unit(tokens, item, context); 01442 else if (WN2F_IS_IOF(item)) 01443 emitted = WN2F_io_format(tokens, item, context); 01444 else if (WN2F_IS_IOC(item)) 01445 emitted = WN2F_io_control(tokens, item, context); 01446 else if (WN2F_IS_IOL(item)) 01447 emitted = WN2F_io_list(tokens, item, context); 01448 else 01449 ASSERT_DBG_WARN(FALSE, 01450 (DIAG_W2F_UNEXPECTED_IOL, 01451 (IOITEM_name(WN_IOITEM(item)) != NULL? 01452 IOITEM_name(WN_IOITEM(item)):"unknown_name"), 01453 "WN2F_io_item")); 01454 01455 return emitted; 01456 } /* WN2F_io_item */ 01457 01458 01459 01460 01461 01462 01463