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

📄 list_read.c

📁 gcc-fortran,linux使用fortran的编译软件。很好用的。
💻 C
📖 第 1 页 / 共 4 页
字号:
	  p = write_block (dtp, 5);#endif	  if (!p)	    goto query_return;#ifdef HAVE_CRLF	  memcpy (p, "&end\r\n", 6);#else	  memcpy (p, "&end\n", 5);#endif	}      /* Flush the stream to force immediate output.  */      flush (dtp->u.p.current_unit->s);      unlock_unit (dtp->u.p.current_unit);    }query_return:  /* Restore the current unit.  */  dtp->u.p.current_unit = temp_unit;  dtp->u.p.mode = READING;  return;}/* Reads and stores the input for the namelist object nl.  For an array,   the function loops over the ranges defined by the loop specification.   This default to all the data or to the specification from a qualifier.   nml_read_obj recursively calls itself to read derived types. It visits   all its own components but only reads data for those that were touched   when the name was parsed.  If a read error is encountered, an attempt is   made to return to read a new object name because the standard allows too   little data to be available.  On the other hand, too much data is an   error.  */static trynml_read_obj (st_parameter_dt *dtp, namelist_info * nl, index_type offset,	      namelist_info **pprev_nl, char *nml_err_msg,	      index_type clow, index_type chigh){  namelist_info * cmp;  char * obj_name;  int nml_carry;  int len;  int dim;  index_type dlen;  index_type m;  index_type obj_name_len;  void * pdata ;  /* This object not touched in name parsing.  */  if (!nl->touched)    return SUCCESS;  dtp->u.p.repeat_count = 0;  eat_spaces (dtp);  len = nl->len;  switch (nl->type)  {    case GFC_DTYPE_INTEGER:    case GFC_DTYPE_LOGICAL:      dlen = len;      break;    case GFC_DTYPE_REAL:      dlen = size_from_real_kind (len);      break;    case GFC_DTYPE_COMPLEX:      dlen = size_from_complex_kind (len);      break;    case GFC_DTYPE_CHARACTER:      dlen = chigh ? (chigh - clow + 1) : nl->string_length;      break;    default:      dlen = 0;    }  do    {      /* Update the pointer to the data, using the current index vector  */      pdata = (void*)(nl->mem_pos + offset);      for (dim = 0; dim < nl->var_rank; dim++)	pdata = (void*)(pdata + (nl->ls[dim].idx - nl->dim[dim].lbound) *		 nl->dim[dim].stride * nl->size);      /* Reset the error flag and try to read next value, if	 dtp->u.p.repeat_count=0  */      dtp->u.p.nml_read_error = 0;      nml_carry = 0;      if (--dtp->u.p.repeat_count <= 0)	{	  if (dtp->u.p.input_complete)	    return SUCCESS;	  if (dtp->u.p.at_eol)	    finish_separator (dtp);	  if (dtp->u.p.input_complete)	    return SUCCESS;	  /* GFC_TYPE_UNKNOWN through for nulls and is detected	     after the switch block.  */	  dtp->u.p.saved_type = GFC_DTYPE_UNKNOWN;	  free_saved (dtp);          switch (nl->type)	  {	  case GFC_DTYPE_INTEGER:	      read_integer (dtp, len);              break;	  case GFC_DTYPE_LOGICAL:	      read_logical (dtp, len);              break;	  case GFC_DTYPE_CHARACTER:	      read_character (dtp, len);              break;	  case GFC_DTYPE_REAL:	      read_real (dtp, len);              break;	  case GFC_DTYPE_COMPLEX:              read_complex (dtp, len, dlen);              break;	  case GFC_DTYPE_DERIVED:	    obj_name_len = strlen (nl->var_name) + 1;	    obj_name = get_mem (obj_name_len+1);	    strcpy (obj_name, nl->var_name);	    strcat (obj_name, "%");	    /* Now loop over the components. Update the component pointer	       with the return value from nml_write_obj.  This loop jumps	       past nested derived types by testing if the potential	       component name contains '%'.  */	    for (cmp = nl->next;		 cmp &&		   !strncmp (cmp->var_name, obj_name, obj_name_len) &&		   !strchr (cmp->var_name + obj_name_len, '%');		 cmp = cmp->next)	      {		if (nml_read_obj (dtp, cmp, (index_type)(pdata - nl->mem_pos),				  pprev_nl, nml_err_msg, clow, chigh)		    == FAILURE)		  {		    free_mem (obj_name);		    return FAILURE;		  }		if (dtp->u.p.input_complete)		  {		    free_mem (obj_name);		    return SUCCESS;		  }	      }	    free_mem (obj_name);	    goto incr_idx;          default:	    st_sprintf (nml_err_msg, "Bad type for namelist object %s",			nl->var_name);	    internal_error (&dtp->common, nml_err_msg);	    goto nml_err_ret;          }        }      /* The standard permits array data to stop short of the number of	 elements specified in the loop specification.  In this case, we	 should be here with dtp->u.p.nml_read_error != 0.  Control returns to	 nml_get_obj_data and an attempt is made to read object name.  */      *pprev_nl = nl;      if (dtp->u.p.nml_read_error)	return SUCCESS;      if (dtp->u.p.saved_type == GFC_DTYPE_UNKNOWN)	goto incr_idx;      /* Note the switch from GFC_DTYPE_type to BT_type at this point.	 This comes about because the read functions return BT_types.  */      switch (dtp->u.p.saved_type)      {	case BT_COMPLEX:	case BT_REAL:	case BT_INTEGER:	case BT_LOGICAL:	  memcpy (pdata, dtp->u.p.value, dlen);	  break;	case BT_CHARACTER:	  m = (dlen < dtp->u.p.saved_used) ? dlen : dtp->u.p.saved_used;	  pdata = (void*)( pdata + clow - 1 );	  memcpy (pdata, dtp->u.p.saved_string, m);	  if (m < dlen)	    memset ((void*)( pdata + m ), ' ', dlen - m);	break;	default:	  break;      }      /* Break out of loop if scalar.  */      if (!nl->var_rank)	break;      /* Now increment the index vector.  */incr_idx:      nml_carry = 1;      for (dim = 0; dim < nl->var_rank; dim++)	{	  nl->ls[dim].idx += nml_carry * nl->ls[dim].step;	  nml_carry = 0;	  if (((nl->ls[dim].step > 0) && (nl->ls[dim].idx > nl->ls[dim].end))	      ||	      ((nl->ls[dim].step < 0) && (nl->ls[dim].idx < nl->ls[dim].end)))	    {	      nl->ls[dim].idx = nl->ls[dim].start;	      nml_carry = 1;	    }        }    } while (!nml_carry);  if (dtp->u.p.repeat_count > 1)    {       st_sprintf (nml_err_msg, "Repeat count too large for namelist object %s" ,		   nl->var_name );       goto nml_err_ret;    }  return SUCCESS;nml_err_ret:  return FAILURE;}/* Parses the object name, including array and substring qualifiers.  It   iterates over derived type components, touching those components and   setting their loop specifications, if there is a qualifier.  If the   object is itself a derived type, its components and subcomponents are   touched.  nml_read_obj is called at the end and this reads the data in   the manner specified by the object name.  */static trynml_get_obj_data (st_parameter_dt *dtp, namelist_info **pprev_nl,		  char *nml_err_msg){  char c;  namelist_info * nl;  namelist_info * first_nl = NULL;  namelist_info * root_nl = NULL;  int dim;  int component_flag;  char parse_err_msg[30];  index_type clow, chigh;  /* Look for end of input or object name.  If '?' or '=?' are encountered     in stdin, print the node names or the namelist to stdout.  */  eat_separator (dtp);  if (dtp->u.p.input_complete)    return SUCCESS;  if (dtp->u.p.at_eol)    finish_separator (dtp);  if (dtp->u.p.input_complete)    return SUCCESS;  c = next_char (dtp);  switch (c)    {    case '=':      c = next_char (dtp);      if (c != '?')	{	  st_sprintf (nml_err_msg, "namelist read: missplaced = sign");	  goto nml_err_ret;	}      nml_query (dtp, '=');      return SUCCESS;    case '?':      nml_query (dtp, '?');      return SUCCESS;    case '$':    case '&':      nml_match_name (dtp, "end", 3);      if (dtp->u.p.nml_read_error)	{	  st_sprintf (nml_err_msg, "namelist not terminated with / or &end");	  goto nml_err_ret;	}    case '/':      dtp->u.p.input_complete = 1;      return SUCCESS;    default :      break;    }  /* Untouch all nodes of the namelist and reset the flag that is set for     derived type components.  */  nml_untouch_nodes (dtp);  component_flag = 0;  /* Get the object name - should '!' and '\n' be permitted separators?  */get_name:  free_saved (dtp);  do    {      push_char (dtp, tolower(c));      c = next_char (dtp);    } while (!( c=='=' || c==' ' || c=='\t' || c =='(' || c =='%' ));  unget_char (dtp, c);  /* Check that the name is in the namelist and get pointer to object.     Three error conditions exist: (i) An attempt is being made to     identify a non-existent object, following a failed data read or     (ii) The object name does not exist or (iii) Too many data items     are present for an object.  (iii) gives the same error message     as (i)  */  push_char (dtp, '\0');  if (component_flag)    {      size_t var_len = strlen (root_nl->var_name);      size_t saved_len	= dtp->u.p.saved_string ? strlen (dtp->u.p.saved_string) : 0;      char ext_name[var_len + saved_len + 1];      memcpy (ext_name, root_nl->var_name, var_len);      if (dtp->u.p.saved_string)	memcpy (ext_name + var_len, dtp->u.p.saved_string, saved_len);      ext_name[var_len + saved_len] = '\0';      nl = find_nml_node (dtp, ext_name);    }  else    nl = find_nml_node (dtp, dtp->u.p.saved_string);  if (nl == NULL)    {      if (dtp->u.p.nml_read_error && *pprev_nl)	st_sprintf (nml_err_msg, "Bad data for namelist object %s",		    (*pprev_nl)->var_name);      else	st_sprintf (nml_err_msg, "Cannot match namelist object name %s",		    dtp->u.p.saved_string);      goto nml_err_ret;    }  /* Get the length, data length, base pointer and rank of the variable.     Set the default loop specification first.  */  for (dim=0; dim < nl->var_rank; dim++)    {      nl->ls[dim].step = 1;      nl->ls[dim].end = nl->dim[dim].ubound;      nl->ls[dim].start = nl->dim[dim].lbound;      nl->ls[dim].idx = nl->ls[dim].start;    }/* Check to see if there is a qualifier: if so, parse it.*/  if (c == '(' && nl->var_rank)    {      if (nml_parse_qualifier (dtp, nl->dim, nl->ls, nl->var_rank,			       parse_err_msg) == FAILURE)	{	  st_sprintf (nml_err_msg, "%s for namelist variable %s",		      parse_err_msg, nl->var_name);	  goto nml_err_ret;	}      c = next_char (dtp);      unget_char (dtp, c);    }  /* Now parse a derived type component. The root namelist_info address     is backed up, as is the previous component level.  The  component flag     is set and the iteration is made by jumping back to get_name.  */  if (c == '%')    {      if (nl->type != GFC_DTYPE_DERIVED)	{	  st_sprintf (nml_err_msg, "Attempt to get derived component for %s",		      nl->var_name);	  goto nml_err_ret;	}      if (!component_flag)	first_nl = nl;      root_nl = nl;      component_flag = 1;      c = next_char (dtp);      goto get_name;    }  /* Parse a character qualifier, if present.  chigh = 0 is a default     that signals that the string length = string_length.  */  clow = 1;  chigh = 0;  if (c == '(' && nl->type == GFC_DTYPE_CHARACTER)    {      descriptor_dimension chd[1] = { {1, clow, nl->string_length} };      array_loop_spec ind[1] = { {1, clow, nl->string_length, 1} };      if (nml_parse_qualifier (dtp, chd, ind, 1, parse_err_msg) == FAILURE)	{	  st_sprintf (nml_err_msg, "%s for namelist variable %s",		      parse_err_msg, nl->var_name);	  goto nml_err_ret;	}      clow = ind[0].start;      chigh = ind[0].end;      if (ind[0].step != 1)	{	  st_sprintf (nml_err_msg,		      "Bad step in substring for namelist object %s",		      nl->var_name);	  goto nml_err_ret;	}      c = next_char (dtp);      unget_char (dtp, c);    }  /* If a derived type touch its components and restore the root     namelist_info if we have parsed a qualified derived type     component.  */  if (nl->type == GFC_DTYPE_DERIVED)    nml_touch_nodes (nl);  if (component_flag)    nl = first_nl;  /*make sure no extraneous qualifiers are there.*/  if (c == '(')    {      st_sprintf (nml_err_msg, "Qualifier for a scalar or non-character"		  " namelist object %s", nl->var_name);      goto nml_err_ret;    }/* According to the standard, an equal sign MUST follow an object name. The   following is possibly lax - it allows comments, blank lines and so on to   intervene.  eat_spaces (dtp); c = next_char (dtp); would be compliant*/  free_saved (dtp);  eat_separator (dtp);  if (dtp->u.p.input_complete)    return SUCCESS;  if (dtp->u.p.at_eol)    finish_separator (dtp);  if (dtp->u.p.input_complete)    return SUCCESS;  c = next_char (dtp);  if (c != '=')    {      st_sprintf (nml_err_msg, "Equal sign must follow namelist object name %s",		  nl->var_name);      goto nml_err_ret;    }  if (nml_read_obj (dtp, nl, 0, pprev_nl, nml_err_msg, clow, chigh) == FAILURE)    goto nml_err_ret;  return SUCCESS;nml_err_ret:  return FAILURE;}/* Entry point for namelist input.  Goes through input until namelist name  is matched.  Then cycles through nml_get_obj_data until the input is  completed or there is an error.  */voidnamelist_read (st_parameter_dt *dtp){  char c;  jmp_buf eof_jump;  char nml_err_msg[100];  /* Pointer to the previously read object, in case attempt is made to read     new object name.  Should this fail, error message can give previous     name.  */  namelist_info *prev_nl = NULL;  dtp->u.p.namelist_mode = 1;  dtp->u.p.input_complete = 0;  dtp->u.p.eof_jump = &eof_jump;  if (setjmp (eof_jump))    {      dtp->u.p.eof_jump = NULL;      generate_error (&dtp->common, ERROR_END, NULL);      return;    }  /* Look for &namelist_name .  Skip all characters, testing for $nmlname.     Exit on success or EOF. If '?' or '=?' encountered in stdin, print     node names or namelist on stdout.  */find_nml_name:  switch (c = next_char (dtp))    {    case '$':    case '&':          break;    case '=':      c = next_char (dtp);      if (c == '?')	nml_query (dtp, '=');      else	unget_char (dtp, c);      goto find_nml_name;    case '?':      nml_query (dtp, '?');    default:      goto find_nml_name;    }  /* Match the name of the namelist.  */  nml_match_name (dtp, dtp->namelist_name, dtp->namelist_name_len);  if (dtp->u.p.nml_read_error)    goto find_nml_name;  /* Ready to read namelist objects.  If there is an error in input     from stdin, output the error message and continue.  */  while (!dtp->u.p.input_complete)    {      if (nml_get_obj_data (dtp, &prev_nl, nml_err_msg) == FAILURE)	{	  gfc_unit *u;	  if (dtp->u.p.current_unit->unit_number != options.stdin_unit)	    goto nml_err_ret;	  u = find_unit (options.stderr_unit);	  st_printf ("%s\n", nml_err_msg);	  if (u != NULL)	    {	      flush (u->s);	      unlock_unit (u);	    }        }   }  dtp->u.p.eof_jump = NULL;  free_saved (dtp);  return;  /* All namelist error calls return from here */nml_err_ret:  dtp->u.p.eof_jump = NULL;  free_saved (dtp);  generate_error (&dtp->common, ERROR_READ_VALUE, nml_err_msg);  return;}

⌨️ 快捷键说明

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