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

📄 io.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 4 页
字号:
  return SUCCESS;}/* Free a gfc_filepos structure.  */voidgfc_free_filepos (gfc_filepos * fp){  gfc_free_expr (fp->unit);  gfc_free_expr (fp->iomsg);  gfc_free_expr (fp->iostat);  gfc_free (fp);}/* Match elements of a REWIND, BACKSPACE, ENDFILE, or FLUSH statement.  */static matchmatch_file_element (gfc_filepos * fp){  match m;  m = match_etag (&tag_unit, &fp->unit);  if (m != MATCH_NO)    return m;  m = match_out_tag (&tag_iomsg, &fp->iomsg);  if (m != MATCH_NO)    return m;  m = match_out_tag (&tag_iostat, &fp->iostat);  if (m != MATCH_NO)    return m;  m = match_ltag (&tag_err, &fp->err);  if (m != MATCH_NO)    return m;  return MATCH_NO;}/* Match the second half of the file-positioning statements, REWIND,   BACKSPACE, ENDFILE, or the FLUSH statement.  */static matchmatch_filepos (gfc_statement st, gfc_exec_op op){  gfc_filepos *fp;  match m;  fp = gfc_getmem (sizeof (gfc_filepos));  if (gfc_match_char ('(') == MATCH_NO)    {      m = gfc_match_expr (&fp->unit);      if (m == MATCH_ERROR)	goto cleanup;      if (m == MATCH_NO)	goto syntax;      goto done;    }  m = match_file_element (fp);  if (m == MATCH_ERROR)    goto done;  if (m == MATCH_NO)    {      m = gfc_match_expr (&fp->unit);      if (m == MATCH_ERROR)	goto done;      if (m == MATCH_NO)	goto syntax;    }  for (;;)    {      if (gfc_match_char (')') == MATCH_YES)	break;      if (gfc_match_char (',') != MATCH_YES)	goto syntax;      m = match_file_element (fp);      if (m == MATCH_ERROR)	goto cleanup;      if (m == MATCH_NO)	goto syntax;    }done:  if (gfc_match_eos () != MATCH_YES)    goto syntax;  if (gfc_pure (NULL))    {      gfc_error ("%s statement not allowed in PURE procedure at %C",		 gfc_ascii_statement (st));      goto cleanup;    }  new_st.op = op;  new_st.ext.filepos = fp;  return MATCH_YES;syntax:  gfc_syntax_error (st);cleanup:  gfc_free_filepos (fp);  return MATCH_ERROR;}trygfc_resolve_filepos (gfc_filepos * fp){  RESOLVE_TAG (&tag_unit, fp->unit);  RESOLVE_TAG (&tag_iostat, fp->iostat);  RESOLVE_TAG (&tag_iomsg, fp->iomsg);  if (gfc_reference_st_label (fp->err, ST_LABEL_TARGET) == FAILURE)    return FAILURE;  return SUCCESS;}/* Match the file positioning statements: ENDFILE, BACKSPACE, REWIND,   and the FLUSH statement.  */matchgfc_match_endfile (void){  return match_filepos (ST_END_FILE, EXEC_ENDFILE);}matchgfc_match_backspace (void){  return match_filepos (ST_BACKSPACE, EXEC_BACKSPACE);}matchgfc_match_rewind (void){  return match_filepos (ST_REWIND, EXEC_REWIND);}matchgfc_match_flush (void){  if (gfc_notify_std (GFC_STD_F2003, "Fortran 2003: FLUSH statement at %C") == FAILURE)    return MATCH_ERROR;  return match_filepos (ST_FLUSH, EXEC_FLUSH);}/******************** Data Transfer Statements *********************/typedef enum{ M_READ, M_WRITE, M_PRINT, M_INQUIRE }io_kind;/* Return a default unit number.  */static gfc_expr *default_unit (io_kind k){  int unit;  if (k == M_READ)    unit = 5;  else    unit = 6;  return gfc_int_expr (unit);}/* Match a unit specification for a data transfer statement.  */static matchmatch_dt_unit (io_kind k, gfc_dt * dt){  gfc_expr *e;  if (gfc_match_char ('*') == MATCH_YES)    {      if (dt->io_unit != NULL)	goto conflict;      dt->io_unit = default_unit (k);      return MATCH_YES;    }  if (gfc_match_expr (&e) == MATCH_YES)    {      if (dt->io_unit != NULL)	{	  gfc_free_expr (e);	  goto conflict;	}      dt->io_unit = e;      return MATCH_YES;    }  return MATCH_NO;conflict:  gfc_error ("Duplicate UNIT specification at %C");  return MATCH_ERROR;}/* Match a format specification.  */static matchmatch_dt_format (gfc_dt * dt){  locus where;  gfc_expr *e;  gfc_st_label *label;  where = gfc_current_locus;  if (gfc_match_char ('*') == MATCH_YES)    {      if (dt->format_expr != NULL || dt->format_label != NULL)	goto conflict;      dt->format_label = &format_asterisk;      return MATCH_YES;    }  if (gfc_match_st_label (&label) == MATCH_YES)    {      if (dt->format_expr != NULL || dt->format_label != NULL)	{	  gfc_free_st_label (label);	  goto conflict;	}      if (gfc_reference_st_label (label, ST_LABEL_FORMAT) == FAILURE)	return MATCH_ERROR;      dt->format_label = label;      return MATCH_YES;    }  if (gfc_match_expr (&e) == MATCH_YES)    {      if (dt->format_expr != NULL || dt->format_label != NULL)	{	  gfc_free_expr (e);	  goto conflict;	}      dt->format_expr = e;      return MATCH_YES;    }  gfc_current_locus = where;	/* The only case where we have to restore */  return MATCH_NO;conflict:  gfc_error ("Duplicate format specification at %C");  return MATCH_ERROR;}/* Traverse a namelist that is part of a READ statement to make sure   that none of the variables in the namelist are INTENT(IN).  Returns   nonzero if we find such a variable.  */static intcheck_namelist (gfc_symbol * sym){  gfc_namelist *p;  for (p = sym->namelist; p; p = p->next)    if (p->sym->attr.intent == INTENT_IN)      {	gfc_error ("Symbol '%s' in namelist '%s' is INTENT(IN) at %C",		   p->sym->name, sym->name);	return 1;      }  return 0;}/* Match a single data transfer element.  */static matchmatch_dt_element (io_kind k, gfc_dt * dt){  char name[GFC_MAX_SYMBOL_LEN + 1];  gfc_symbol *sym;  match m;  if (gfc_match (" unit =") == MATCH_YES)    {      m = match_dt_unit (k, dt);      if (m != MATCH_NO)	return m;    }  if (gfc_match (" fmt =") == MATCH_YES)    {      m = match_dt_format (dt);      if (m != MATCH_NO)	return m;    }  if (gfc_match (" nml = %n", name) == MATCH_YES)    {      if (dt->namelist != NULL)	{	  gfc_error ("Duplicate NML specification at %C");	  return MATCH_ERROR;	}      if (gfc_find_symbol (name, NULL, 1, &sym))	return MATCH_ERROR;      if (sym == NULL || sym->attr.flavor != FL_NAMELIST)	{	  gfc_error ("Symbol '%s' at %C must be a NAMELIST group name",		     sym != NULL ? sym->name : name);	  return MATCH_ERROR;	}      dt->namelist = sym;      if (k == M_READ && check_namelist (sym))	return MATCH_ERROR;      return MATCH_YES;    }  m = match_etag (&tag_rec, &dt->rec);  if (m != MATCH_NO)    return m;  m = match_out_tag (&tag_iomsg, &dt->iomsg);  if (m != MATCH_NO)    return m;  m = match_out_tag (&tag_iostat, &dt->iostat);  if (m != MATCH_NO)    return m;  m = match_ltag (&tag_err, &dt->err);  if (m == MATCH_YES)    dt->err_where = gfc_current_locus;  if (m != MATCH_NO)    return m;  m = match_etag (&tag_advance, &dt->advance);  if (m != MATCH_NO)    return m;  m = match_out_tag (&tag_size, &dt->size);  if (m != MATCH_NO)    return m;  m = match_ltag (&tag_end, &dt->end);  if (m == MATCH_YES)    {      if (k == M_WRITE)       {         gfc_error ("END tag at %C not allowed in output statement");         return MATCH_ERROR;       }      dt->end_where = gfc_current_locus;    }  if (m != MATCH_NO)    return m;  m = match_ltag (&tag_eor, &dt->eor);  if (m == MATCH_YES)    dt->eor_where = gfc_current_locus;  if (m != MATCH_NO)    return m;  return MATCH_NO;}/* Free a data transfer structure and everything below it.  */voidgfc_free_dt (gfc_dt * dt){  if (dt == NULL)    return;  gfc_free_expr (dt->io_unit);  gfc_free_expr (dt->format_expr);  gfc_free_expr (dt->rec);  gfc_free_expr (dt->advance);  gfc_free_expr (dt->iomsg);  gfc_free_expr (dt->iostat);  gfc_free_expr (dt->size);  gfc_free (dt);}/* Resolve everything in a gfc_dt structure.  */trygfc_resolve_dt (gfc_dt * dt){  gfc_expr *e;  RESOLVE_TAG (&tag_format, dt->format_expr);  RESOLVE_TAG (&tag_rec, dt->rec);  RESOLVE_TAG (&tag_advance, dt->advance);  RESOLVE_TAG (&tag_iomsg, dt->iomsg);  RESOLVE_TAG (&tag_iostat, dt->iostat);  RESOLVE_TAG (&tag_size, dt->size);  e = dt->io_unit;  if (gfc_resolve_expr (e) == SUCCESS      && (e->ts.type != BT_INTEGER	  && (e->ts.type != BT_CHARACTER	      || e->expr_type != EXPR_VARIABLE)))    {      gfc_error	("UNIT specification at %L must be an INTEGER expression or a "	 "CHARACTER variable", &e->where);      return FAILURE;    }  if (e->ts.type == BT_CHARACTER)    {      if (gfc_has_vector_index (e))	{	  gfc_error ("Internal unit with vector subscript at %L",		     &e->where);	  return FAILURE;	}    }  if (e->rank && e->ts.type != BT_CHARACTER)    {      gfc_error ("External IO UNIT cannot be an array at %L", &e->where);      return FAILURE;    }  if (dt->err)    {      if (gfc_reference_st_label (dt->err, ST_LABEL_TARGET) == FAILURE)	return FAILURE;      if (dt->err->defined == ST_LABEL_UNKNOWN)	{	  gfc_error ("ERR tag label %d at %L not defined",		      dt->err->value, &dt->err_where);	  return FAILURE;	}    }  if (dt->end)    {      if (gfc_reference_st_label (dt->end, ST_LABEL_TARGET) == FAILURE)	return FAILURE;      if (dt->end->defined == ST_LABEL_UNKNOWN)	{	  gfc_error ("END tag label %d at %L not defined",		      dt->end->value, &dt->end_where);	  return FAILURE;	}    }  if (dt->eor)    {      if (gfc_reference_st_label (dt->eor, ST_LABEL_TARGET) == FAILURE)	return FAILURE;      if (dt->eor->defined == ST_LABEL_UNKNOWN)	{	  gfc_error ("EOR tag label %d at %L not defined",		      dt->eor->value, &dt->eor_where);	  return FAILURE;	}    }  /* Check the format label actually exists.  */  if (dt->format_label && dt->format_label != &format_asterisk      && dt->format_label->defined == ST_LABEL_UNKNOWN)    {      gfc_error ("FORMAT label %d at %L not defined", dt->format_label->value,	         &dt->format_label->where);      return FAILURE;    }  return SUCCESS;}/* Given an io_kind, return its name.  */static const char *io_kind_name (io_kind k){  const char *name;  switch (k)    {    case M_READ:      name = "READ";      break;    case M_WRITE:      name = "WRITE";      break;    case M_PRINT:      name = "PRINT";      break;    case M_INQUIRE:      name = "INQUIRE";      break;    default:      gfc_internal_error ("io_kind_name(): bad I/O-kind");    }  return name;}/* Match an IO iteration statement of the form:   ( [<IO element> ,] <IO element>, I = <expr>, <expr> [, <expr> ] )   which is equivalent to a single IO element.  This function is   mutually recursive with match_io_element().  */static match match_io_element (io_kind k, gfc_code **);static matchmatch_io_iterator (io_kind k, gfc_code ** result){  gfc_code *head, *tail, *new;  gfc_iterator *iter;  locus old_loc;  match m;  int n;  iter = NULL;  head = NULL;  old_loc = gfc_current_locus;  if (gfc_match_char ('(') != MATCH_YES)    return MATCH_NO;  m = match_io_element (k, &head);  tail = head;  if (m != MATCH_YES || gfc_match_char (',') != MATCH_YES)    {      m = MATCH_NO;      goto cleanup;    }  /* Can't be anything but an IO iterator.  Build a list.  */  iter = gfc_get_iterator ();  for (n = 1;; n++)    {      m = gfc_match_iterator (iter, 0);      if (m == MATCH_ERROR)	goto cleanup;      if (m == MATCH_YES)	{	  gfc_check_do_variable (iter->var->symtree);	  break;	}      m = match_io_element (k, &new);      if (m == MATCH_ERROR)	goto cleanup;      if (m == MATCH_NO)	{	  if (n > 2)	    goto syntax;	  goto cleanup;	}      tail = gfc_append_code (tail, new);      if (gfc_match_char (',') != MATCH_YES)	{	  if (n > 2)	    goto syntax;	  m = MATCH_NO;	  goto cleanup;	}    }  if (gfc_match_char (')') != MATCH_YES)    goto syntax;  new = gfc_get_code ();  new->op = EXEC_DO;  new->ext.iterator = iter;  new->block = gfc_get_code ();  new->block->op = EXEC_DO;  new->block->next = head;  *result = new;  return MATCH_YES;syntax:  gfc_error ("Syntax error in I/O iterator at %C");  m = MATCH_ERROR;cleanup:  gfc_free_iterator (iter, 1);  gfc_free_statements (head);  gfc_current_locus = old_loc;  return m;}/* Match a single element of an IO list, which is either a single   expression or an IO Iterator.  */static matchmatch_io_element (io_kind k, gfc_code ** cpp){  gfc_expr *expr;  gfc_code *cp;  match m;  expr = NULL;  m = match_io_iterator (k, cpp);  if (m == MATCH_YES)    return MATCH_YES;  if (k == M_READ)    {      m = gfc_match_variable (&expr, 0);      if (m == MATCH_NO)	gfc_error ("Expected variable in READ statement at %C");    }  else    {      m = gfc_match_expr (&expr);      if (m == MATCH_NO)	gfc_error ("Expected expression in %s statement at %C",		   io_kind_name (k));    }  if (m == MATCH_YES)    switch (k)      {      case M_READ:	if (expr->symtree->n.sym->attr.intent == INTENT_IN)	  {	    gfc_error	      ("Variable '%s' in input list at %C cannot be INTENT(IN)",	       expr->symtree->n.sym->name);	    m = MATCH_ERROR;	  }	if (gfc_pure (NULL)	    && gfc_impure_variable (expr->symtree->n.sym)	    && current_dt->io_unit->ts.type == BT_CHARACTER)	  {	    gfc_error ("Cannot read to variable '%s' in PURE procedure at %C",		       expr->symtree->n.sym->name);	    m = MATCH_ERROR;	  }	if (gfc_check_do_variable (expr->symtree))	  m = MATCH_ERROR;	break;      case M_WRITE:	if (current_dt->io_unit->ts.type == BT_CHARACTER	    && gfc_pure (NULL)	    && current_dt->io_unit->expr_type == EXPR_VARIABLE	    && gfc_impure_variable (current_dt->io_unit->symtree->n.sym))	  {	    gfc_error	      ("Cannot write to internal file unit '%s' at %C inside a "	       "PURE procedure", current_dt->io_unit->symtree->n.sym->name);	    m = MATCH_ERROR;	  }	break;      default:	break;      }

⌨️ 快捷键说明

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