⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 io.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* Deal with I/O statements & related stuff.   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,   Inc.   Contributed by Andy VaughtThis file is part of GCC.GCC is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the FreeSoftware Foundation; either version 2, or (at your option) any laterversion.GCC is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY orFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public Licensefor more details.You should have received a copy of the GNU General Public Licensealong with GCC; see the file COPYING.  If not, write to the FreeSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA02110-1301, USA.  */#include "config.h"#include "system.h"#include "flags.h"#include "gfortran.h"#include "match.h"#include "parse.h"gfc_st_label format_asterisk =  { -1, ST_LABEL_FORMAT, ST_LABEL_FORMAT, NULL, 0,    {NULL, NULL}, NULL, NULL};typedef struct{  const char *name, *spec;  bt type;}io_tag;static const io_tag	tag_file	= { "FILE", " file = %e", BT_CHARACTER },	tag_status	= { "STATUS", " status = %e", BT_CHARACTER},	tag_e_access	= {"ACCESS", " access = %e", BT_CHARACTER},	tag_e_form	= {"FORM", " form = %e", BT_CHARACTER},	tag_e_recl	= {"RECL", " recl = %e", BT_INTEGER},	tag_e_blank	= {"BLANK", " blank = %e", BT_CHARACTER},	tag_e_position	= {"POSITION", " position = %e", BT_CHARACTER},	tag_e_action	= {"ACTION", " action = %e", BT_CHARACTER},	tag_e_delim	= {"DELIM", " delim = %e", BT_CHARACTER},	tag_e_pad	= {"PAD", " pad = %e", BT_CHARACTER},	tag_unit	= {"UNIT", " unit = %e", BT_INTEGER},	tag_advance	= {"ADVANCE", " advance = %e", BT_CHARACTER},	tag_rec		= {"REC", " rec = %e", BT_INTEGER},	tag_format	= {"FORMAT", NULL, BT_CHARACTER},	tag_iomsg	= {"IOMSG", " iomsg = %e", BT_CHARACTER},	tag_iostat	= {"IOSTAT", " iostat = %v", BT_INTEGER},	tag_size	= {"SIZE", " size = %v", BT_INTEGER},	tag_exist	= {"EXIST", " exist = %v", BT_LOGICAL},	tag_opened	= {"OPENED", " opened = %v", BT_LOGICAL},	tag_named	= {"NAMED", " named = %v", BT_LOGICAL},	tag_name	= {"NAME", " name = %v", BT_CHARACTER},	tag_number	= {"NUMBER", " number = %v", BT_INTEGER},	tag_s_access	= {"ACCESS", " access = %v", BT_CHARACTER},	tag_sequential	= {"SEQUENTIAL", " sequential = %v", BT_CHARACTER},	tag_direct	= {"DIRECT", " direct = %v", BT_CHARACTER},	tag_s_form	= {"FORM", " form = %v", BT_CHARACTER},	tag_formatted	= {"FORMATTED", " formatted = %v", BT_CHARACTER},	tag_unformatted	= {"UNFORMATTED", " unformatted = %v", BT_CHARACTER},	tag_s_recl	= {"RECL", " recl = %v", BT_INTEGER},	tag_nextrec	= {"NEXTREC", " nextrec = %v", BT_INTEGER},	tag_s_blank	= {"BLANK", " blank = %v", BT_CHARACTER},	tag_s_position	= {"POSITION", " position = %v", BT_CHARACTER},	tag_s_action	= {"ACTION", " action = %v", BT_CHARACTER},	tag_read	= {"READ", " read = %v", BT_CHARACTER},	tag_write	= {"WRITE", " write = %v", BT_CHARACTER},	tag_readwrite	= {"READWRITE", " readwrite = %v", BT_CHARACTER},	tag_s_delim	= {"DELIM", " delim = %v", BT_CHARACTER},	tag_s_pad	= {"PAD", " pad = %v", BT_CHARACTER},	tag_iolength	= {"IOLENGTH", " iolength = %v", BT_INTEGER},	tag_convert     = {"CONVERT", " convert = %e", BT_CHARACTER},	tag_err		= {"ERR", " err = %l", BT_UNKNOWN},	tag_end		= {"END", " end = %l", BT_UNKNOWN},	tag_eor		= {"EOR", " eor = %l", BT_UNKNOWN};static gfc_dt *current_dt;#define RESOLVE_TAG(x, y) if (resolve_tag(x, y) == FAILURE) return FAILURE;/**************** Fortran 95 FORMAT parser  *****************//* FORMAT tokens returned by format_lex().  */typedef enum{  FMT_NONE, FMT_UNKNOWN, FMT_SIGNED_INT, FMT_ZERO, FMT_POSINT, FMT_PERIOD,  FMT_COMMA, FMT_COLON, FMT_SLASH, FMT_DOLLAR, FMT_POS, FMT_LPAREN,  FMT_RPAREN, FMT_X, FMT_SIGN, FMT_BLANK, FMT_CHAR, FMT_P, FMT_IBOZ, FMT_F,  FMT_E, FMT_EXT, FMT_G, FMT_L, FMT_A, FMT_D, FMT_H, FMT_END}format_token;/* Local variables for checking format strings.  The saved_token is   used to back up by a single format token during the parsing   process.  */static char *format_string;static int format_length, use_last_char;static format_token saved_token;static enum{ MODE_STRING, MODE_FORMAT, MODE_COPY }mode;/* Return the next character in the format string.  */static charnext_char (int in_string){  static char c;  if (use_last_char)    {      use_last_char = 0;      return c;    }  format_length++;  if (mode == MODE_STRING)    c = *format_string++;  else    {      c = gfc_next_char_literal (in_string);      if (c == '\n')	c = '\0';      if (mode == MODE_COPY)	*format_string++ = c;    }  c = TOUPPER (c);  return c;}/* Back up one character position.  Only works once.  */static voidunget_char (void){  use_last_char = 1;}/* Eat up the spaces and return a character. */static charnext_char_not_space(void){  char c;  do    {      c = next_char (0);    }  while (gfc_is_whitespace (c));  return c;}static int value = 0;/* Simple lexical analyzer for getting the next token in a FORMAT   statement.  */static format_tokenformat_lex (void){  format_token token;  char c, delim;  int zflag;  int negative_flag;  if (saved_token != FMT_NONE)    {      token = saved_token;      saved_token = FMT_NONE;      return token;    }  c = next_char_not_space ();    negative_flag = 0;  switch (c)    {    case '-':      negative_flag = 1;    case '+':      c = next_char_not_space ();      if (!ISDIGIT (c))	{	  token = FMT_UNKNOWN;	  break;	}      value = c - '0';      do	{	  c = next_char_not_space ();          if(ISDIGIT (c))            value = 10 * value + c - '0';	}      while (ISDIGIT (c) || gfc_is_whitespace(c));      unget_char ();      if (negative_flag)        value = -value;      token = FMT_SIGNED_INT;      break;    case '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':      zflag = (c == '0');      value = c - '0';      do	{	  c = next_char_not_space ();	  if (c != '0')	    zflag = 0;          if (ISDIGIT (c))            value = 10 * value + c - '0';	}      while (ISDIGIT (c));      unget_char ();      token = zflag ? FMT_ZERO : FMT_POSINT;      break;    case '.':      token = FMT_PERIOD;      break;    case ',':      token = FMT_COMMA;      break;    case ':':      token = FMT_COLON;      break;    case '/':      token = FMT_SLASH;      break;    case '$':      token = FMT_DOLLAR;      break;    case 'T':      c = next_char_not_space ();      if (c != 'L' && c != 'R')	unget_char ();      token = FMT_POS;      break;    case '(':      token = FMT_LPAREN;      break;    case ')':      token = FMT_RPAREN;      break;    case 'X':      token = FMT_X;      break;    case 'S':      c = next_char_not_space ();      if (c != 'P' && c != 'S')	unget_char ();      token = FMT_SIGN;      break;    case 'B':      c = next_char_not_space ();      if (c == 'N' || c == 'Z')	token = FMT_BLANK;      else	{	  unget_char ();	  token = FMT_IBOZ;	}      break;    case '\'':    case '"':      delim = c;      value = 0;      for (;;)	{	  c = next_char (1);	  if (c == '\0')	    {	      token = FMT_END;	      break;	    }	  if (c == delim)	    {	      c = next_char (1);	      if (c == '\0')		{		  token = FMT_END;		  break;		}	      if (c != delim)		{		  unget_char ();		  token = FMT_CHAR;		  break;		}	    }          value++;	}      break;    case 'P':      token = FMT_P;      break;    case 'I':    case 'O':    case 'Z':      token = FMT_IBOZ;      break;    case 'F':      token = FMT_F;      break;    case 'E':      c = next_char_not_space ();      if (c == 'N' || c == 'S')	token = FMT_EXT;      else	{	  token = FMT_E;	  unget_char ();	}      break;    case 'G':      token = FMT_G;      break;    case 'H':      token = FMT_H;      break;    case 'L':      token = FMT_L;      break;    case 'A':      token = FMT_A;      break;    case 'D':      token = FMT_D;      break;    case '\0':      token = FMT_END;      break;    default:      token = FMT_UNKNOWN;      break;    }  return token;}/* Check a format statement.  The format string, either from a FORMAT   statement or a constant in an I/O statement has already been parsed   by itself, and we are checking it for validity.  The dual origin   means that the warning message is a little less than great.  */static trycheck_format (void){  const char *posint_required	  = _("Positive width required");  const char *period_required	  = _("Period required");  const char *nonneg_required	  = _("Nonnegative width required");  const char *unexpected_element  = _("Unexpected element");  const char *unexpected_end	  = _("Unexpected end of format string");  const char *error;  format_token t, u;  int level;  int repeat;  try rv;  use_last_char = 0;  saved_token = FMT_NONE;  level = 0;  repeat = 0;  rv = SUCCESS;  t = format_lex ();  if (t != FMT_LPAREN)    {      error = _("Missing leading left parenthesis");      goto syntax;    }  t = format_lex ();  if (t == FMT_RPAREN)    goto finished;		/* Empty format is legal */  saved_token = t;format_item:  /* In this state, the next thing has to be a format item.  */  t = format_lex ();format_item_1:  switch (t)    {    case FMT_POSINT:      repeat = value;      t = format_lex ();      if (t == FMT_LPAREN)	{	  level++;	  goto format_item;	}      if (t == FMT_SLASH)	goto optional_comma;      goto data_desc;    case FMT_LPAREN:      level++;      goto format_item;    case FMT_SIGNED_INT:      /* Signed integer can only precede a P format.  */      t = format_lex ();      if (t != FMT_P)	{	  error = _("Expected P edit descriptor");	  goto syntax;	}      goto data_desc;    case FMT_P:      /* P requires a prior number.  */      error = _("P descriptor requires leading scale factor");      goto syntax;    case FMT_X:      /* X requires a prior number if we're being pedantic.  */      if (gfc_notify_std (GFC_STD_GNU, "Extension: X descriptor "			  "requires leading space count at %C")	  == FAILURE)	return FAILURE;      goto between_desc;    case FMT_SIGN:    case FMT_BLANK:      goto between_desc;    case FMT_CHAR:      goto extension_optional_comma;    case FMT_COLON:    case FMT_SLASH:      goto optional_comma;    case FMT_DOLLAR:      t = format_lex ();      if (gfc_notify_std (GFC_STD_GNU, "Extension: $ descriptor at %C")          == FAILURE)        return FAILURE;      if (t != FMT_RPAREN || level > 0)	{	  error = _("$ must be the last specifier");	  goto syntax;	}      goto finished;    case FMT_POS:    case FMT_IBOZ:    case FMT_F:    case FMT_E:    case FMT_EXT:    case FMT_G:    case FMT_L:    case FMT_A:    case FMT_D:      goto data_desc;    case FMT_H:      goto data_desc;    case FMT_END:      error = unexpected_end;      goto syntax;    default:      error = unexpected_element;      goto syntax;    }data_desc:  /* In this state, t must currently be a data descriptor.     Deal with things that can/must follow the descriptor.  */  switch (t)    {    case FMT_SIGN:    case FMT_BLANK:    case FMT_X:      break;    case FMT_P:      if (pedantic)	{	  t = format_lex ();	  if (t == FMT_POSINT)	    {	      error = _("Repeat count cannot follow P descriptor");	      goto syntax;	    }	  saved_token = t;	}      goto optional_comma;    case FMT_POS:    case FMT_L:      t = format_lex ();      if (t == FMT_POSINT)	break;      error = posint_required;      goto syntax;    case FMT_A:      t = format_lex ();      if (t != FMT_POSINT)	saved_token = t;      break;    case FMT_D:    case FMT_E:    case FMT_G:    case FMT_EXT:      u = format_lex ();      if (u != FMT_POSINT)	{	  error = posint_required;	  goto syntax;	}      u = format_lex ();      if (u != FMT_PERIOD)	{	  error = period_required;	  goto syntax;	}      u = format_lex ();      if (u != FMT_ZERO && u != FMT_POSINT)	{	  error = nonneg_required;	  goto syntax;	}      if (t == FMT_D)	break;      /* Look for optional exponent.  */      u = format_lex ();      if (u != FMT_E)	{	  saved_token = u;	}      else	{	  u = format_lex ();	  if (u != FMT_POSINT)	    {	      error = _("Positive exponent width required");	      goto syntax;	    }	}      break;    case FMT_F:      t = format_lex ();      if (t != FMT_ZERO && t != FMT_POSINT)	{	  error = nonneg_required;	  goto syntax;	}      t = format_lex ();      if (t != FMT_PERIOD)	{	  error = period_required;	  goto syntax;	}      t = format_lex ();      if (t != FMT_ZERO && t != FMT_POSINT)	{	  error = nonneg_required;	  goto syntax;	}      break;    case FMT_H:      if(mode == MODE_STRING)      {        format_string += value;        format_length -= value;      }      else      {        while(repeat >0)         {          next_char(1);          repeat -- ;         }      }     break;    case FMT_IBOZ:      t = format_lex ();      if (t != FMT_ZERO && t != FMT_POSINT)	{	  error = nonneg_required;	  goto syntax;	}      t = format_lex ();      if (t != FMT_PERIOD)	{	  saved_token = t;	}      else	{	  t = format_lex ();	  if (t != FMT_ZERO && t != FMT_POSINT)	    {	      error = nonneg_required;	      goto syntax;	    }	}      break;    default:      error = unexpected_element;      goto syntax;    }between_desc:  /* Between a descriptor and what comes next.  */  t = format_lex ();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -