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

📄 sclproc.c

📁 scl解析文件,欢迎大家学习共享,解析算法值得学习
💻 C
📖 第 1 页 / 共 5 页
字号:
    return (SD_FAILURE);	/* not enough space left to add this	*/
    }
  strcpy (tdl_ctxt->tdlptr, text_to_add);
  tdl_ctxt->tdlptr += len_added;
  tdl_ctxt->len_avail -= len_added;
  return (SD_SUCCESS);
  }
/************************************************************************/
/*			tdladd_sdo					*/
/* NOTE: if (error) returned, caller should break out of loop.		*/
/* RETURNS:	SD_SUCCESS or error code				*/
/************************************************************************/
static ST_RET tdladd_sdo (
	TDLADD_CTXT *tdl_ctxt,
	SCL_INFO *scl_info,
	ST_CHAR *FC,		/* FC to match	*/
	ST_CHAR *name,		/* SDO name	*/
	ST_CHAR *type)		/* SDO type	*/
  {
SCL_DOTYPE *scl_dotype;
SCL_DA *scl_da;
ST_CHAR work_buf [100];		/* temporary buffer for writing TDL	*/
ST_RET retcode;
ST_CHAR *save_start;			/* to save initial ptr		*/
ST_INT save_avail;			/* to save initial len avail	*/
ST_CHAR *save_ptr_after_head;	/* to save ptr after header written	*/

  /* Save initial ptr and len available.	*/
  save_start = tdl_ctxt->tdlptr;
  save_avail = tdl_ctxt->len_avail;

  /* First add SDO name (passed to this funct). May need rollback later	*/
  sprintf (work_buf, "(%s){", name);
  if (tdladd_string (tdl_ctxt, work_buf)!=SD_SUCCESS)
    return (SD_FAILURE);	/* error (already logged)	*/

  save_ptr_after_head = tdl_ctxt->tdlptr;	/* save ptr after header written*/

  /* Find DOType whose "id" matches the SDO "type".	*/
  scl_dotype = scl_find_dotype (scl_info, type);
  if (scl_dotype)
    {
    /* Find all DA or SDO in this DO that match the FC	*/
    /* NOTE: linked list is in reverse order from data in SCL file,	*/
    /*     so get off list in reverse order.				*/
    for (scl_da = (SCL_DA *) list_find_last ((DBL_LNK *) scl_dotype->daHead);
         scl_da != NULL;
         scl_da = (SCL_DA *) list_find_prev ((DBL_LNK *) scl_dotype->daHead, (DBL_LNK *) scl_da))
      {
      if (scl_da->objtype == SCL_OBJTYPE_SDO)
        {		/* ERROR: just break & ret NULL	*/	
        SXLOG_ERR1 ("SDO named '%s' defined inside another SDO: not supported.", scl_da->name);
        return (SD_FAILURE);	/* error	*/
        }
      else
        {	/* objtype must be SCL_OBJTYPE_DA	*/
        if (strcmp (scl_da->fc, FC) == 0)	/* FC of this DA matches FC	*/
          {
          retcode = tdladd_da_or_bda (tdl_ctxt, scl_info, scl_da->name, scl_da->bType,
                    scl_da->type, scl_da->count);
          if (retcode != SD_SUCCESS)	/* error (already logged)	*/
            return (retcode);			/* error	*/
          }
        }
      }	/* end "for (scl_da...)" loop	*/
   
    }
  else
    {
    SXLOG_ERR1 ("SDO type '%s' cannot be found", type);
    return (SD_FAILURE);	/* error	*/
    }

  if (tdl_ctxt->tdlptr > save_ptr_after_head)
    {		/* tdl was added. Finish it.	*/
    if (tdladd_string (tdl_ctxt, "},\n")!=SD_SUCCESS)
      return (SD_FAILURE);	/* error (already logged)	*/
    }
  else
    {				/* SDO is empty so rollback changes	*/
    tdl_ctxt->tdlptr = save_start;		/* restore orig ptr		*/
    tdl_ctxt->len_avail = save_avail;	/* restore orig len		*/
    *save_start = '\0';			/* write NULL at orig ptr	*/
    }
  return (SD_SUCCESS);	/* only successful return	*/
  }
/************************************************************************/
/*			tdladd_da_or_bda				*/
/* NOTE: if (error) returned, caller should break out of loop.	*/
/* RETURNS:	SD_SUCCESS or error code				*/
/************************************************************************/
static ST_RET tdladd_da_or_bda (
	TDLADD_CTXT *tdl_ctxt,
	SCL_INFO *scl_info,
	ST_CHAR *name,		/* DA or BDA name	*/
	ST_CHAR *bType,		/* DA or BDA bType	*/
	ST_CHAR *type,		/* DA or BDA type	*/
	ST_UINT count)		/* DA or BDA count	*/
  {
ST_CHAR work_buf [100];		/* temporary buffer for writing TDL	*/
ST_RET retcode;
ST_CHAR *save_start;			/* to save initial ptr		*/
ST_INT save_avail;			/* to save initial len avail	*/
ST_CHAR *raw_tdl;

  /* Save initial ptr and len available.	*/
  save_start = tdl_ctxt->tdlptr;
  save_avail = tdl_ctxt->len_avail;

  /* Add DA or BDA name for ANY "bType"	*/
  sprintf (work_buf, "(%s)", name);
  if (tdladd_string (tdl_ctxt, work_buf)!=SD_SUCCESS)
    return (SD_FAILURE);	/* error (already logged)	*/

  /* If count!=0, this is array.	*/
  if (count)
    {				/* this DA is array	*/
    sprintf (work_buf, "[%u:", count);
    if (tdladd_string (tdl_ctxt, work_buf)!=SD_SUCCESS)
      return (SD_FAILURE);	/* error (already logged)	*/
    }

  /* Add different text depending on "bType" (Struct, Enum, or BasicType).	*/
  if (strcmp (bType, "Struct") == 0)
    {
    /* NOTE: this may cause recursion		*/
    /* (i.e. tdladd_da_struct may call tdladd_da_or_bda).*/
    retcode = tdladd_da_struct (tdl_ctxt, scl_info, type);
    if (retcode != SD_SUCCESS)
      {
      SXLOG_ERR1 ("SCL ERROR: Can't create TDL for BDA Struct type=%s", type);
      return (retcode);
      }
    }
  else if (strcmp (bType, "Enum") == 0)
    {
    /* DEBUG: for now assume all enums are 8-bit	*/
    /* Someday may need to chk for maximum "EnumVal ord" to determine # of bits	*/
    if (tdladd_string (tdl_ctxt, "Byte,")!=SD_SUCCESS)
      return (SD_FAILURE);	/* error (already logged)	*/
    }
  else
    {				/* must be BasicType, convert to raw TDL*/
    /* NOTE: converting these to raw TDL makes later conversion	*/
    /*       from TDL to RUNTIME_TYPE much more efficient.	*/
    raw_tdl = btype_to_raw_tdl (bType);
    if (raw_tdl == NULL)
      {
      SXLOG_ERR2 ("Unrecognized bType=%s for DA or BDA name=%s", bType, name);
      return (SD_FAILURE);	/* error (already logged)	*/
      }

    if (tdladd_string (tdl_ctxt, raw_tdl)!=SD_SUCCESS)
      return (SD_FAILURE);	/* error (already logged)	*/

    if (tdladd_string (tdl_ctxt, ",")!=SD_SUCCESS)
      return (SD_FAILURE);	/* error (already logged)	*/
    }

  /* If count!=0, this is array.	*/
  if (count)
    {				/* this BDA is array	*/
    if (tdladd_string (tdl_ctxt, "],")!=SD_SUCCESS)
      return (SD_FAILURE);	/* error (already logged)	*/
    }

  assert (strlen(save_start));	/* must never never be empty	*/
  return (SD_SUCCESS);	/* only successful return	*/
  }
/************************************************************************/
/*			tdladd_da_struct				*/
/* Concatinate the TDL for DA that is "Struct".				*/
/* RETURNS:	SD_SUCCESS or error code				*/
/************************************************************************/
static ST_RET tdladd_da_struct (
	TDLADD_CTXT *tdl_ctxt,
	SCL_INFO *scl_info,
	ST_CHAR *type_id)
  {
SCL_DATYPE *scl_datype;
SCL_BDA *scl_bda;
ST_RET retcode;
ST_CHAR *save_start;			/* to save initial ptr		*/
ST_INT save_avail;			/* to save initial len avail	*/

  /* Save initial ptr and len available.	*/
  save_start = tdl_ctxt->tdlptr;
  save_avail = tdl_ctxt->len_avail;

  scl_datype = scl_find_datype (scl_info, type_id);
  if (scl_datype)
    {
    if (tdladd_string (tdl_ctxt, "{")!=SD_SUCCESS)
      return (SD_FAILURE);	/* error (already logged)	*/

    /* Add TDL for all BDA in this DAType.	*/
    /* NOTE: linked list is in reverse order from data in SCL file,	*/
    /*     so get off list in reverse order.				*/
    for (scl_bda = (SCL_BDA *) list_find_last ((DBL_LNK *) scl_datype->bdaHead);
         scl_bda != NULL;
         scl_bda = (SCL_BDA *) list_find_prev ((DBL_LNK *) scl_datype->bdaHead, (DBL_LNK *) scl_bda))
      {
      retcode = tdladd_da_or_bda (tdl_ctxt, scl_info, scl_bda->name, scl_bda->bType,
              scl_bda->type, scl_bda->count);
      if (retcode != SD_SUCCESS)	/* error (already logged)	*/
        return (retcode);			/* error	*/
      }	/* end "for (scl_bda...)" loop	*/

    if (tdladd_string (tdl_ctxt, "},")!=SD_SUCCESS)
      return (SD_FAILURE);	/* error (already logged)	*/
    }
  else
    {
    SXLOG_ERR1 ("SCL ERROR: DAType id=%s not found", type_id);
    return (SD_FAILURE);	/* error	*/
    }

  return (SD_SUCCESS);	/* only successful return	*/
  }
/************************************************************************/
/*			tdladd_do					*/
/* Concatinate the TDL for one DO to the specified buffer "tdlbuf".	*/
/* RETURNS:	SD_SUCCESS or error code				*/
/************************************************************************/
static ST_RET tdladd_do (
	TDLADD_CTXT *tdl_ctxt,
	char *FC,
	SCL_INFO *scl_info,
	ST_CHAR *do_name,
	SCL_DOTYPE *scl_dotype)
  {
SCL_DA *scl_da;
ST_CHAR work_buf [100];		/* temporary buffer for writing TDL	*/
ST_RET retcode;
ST_CHAR *save_start;			/* to save initial ptr		*/
ST_INT save_avail;			/* to save initial len avail	*/
ST_CHAR *save_ptr_after_head;	/* to save ptr after header written	*/

  /* Save initial ptr and len available.	*/
  save_start = tdl_ctxt->tdlptr;
  save_avail = tdl_ctxt->len_avail;

  sprintf (work_buf, "(%s){", do_name);
  assert (strlen (work_buf) < sizeof (work_buf));

  if (tdladd_string (tdl_ctxt, work_buf)!=SD_SUCCESS)
    return (SD_FAILURE);	/* error (already logged)	*/

  save_ptr_after_head = tdl_ctxt->tdlptr;	/* save ptr after header written*/

  /* Find all DA or SDO in this DO that match the FC	*/
  /* NOTE: linked list is in reverse order from data in SCL file,	*/
  /*     so get off list in reverse order.				*/
  for (scl_da = (SCL_DA *) list_find_last ((DBL_LNK *) scl_dotype->daHead);
       scl_da != NULL;
       scl_da = (SCL_DA *) list_find_prev ((DBL_LNK *) scl_dotype->daHead, (DBL_LNK *) scl_da))
    {
    if (scl_da->objtype == SCL_OBJTYPE_SDO)
      {
      /* Only "name" and "type" used for SDO.	*/
      retcode = tdladd_sdo (tdl_ctxt, scl_info, FC, scl_da->name, scl_da->type);
      if (retcode != SD_SUCCESS)		/* error (already logged)	*/
        return (retcode);			/* error	*/
      }
    else
      {	/* objtype must be SCL_OBJTYPE_DA	*/
      if (strcmp (scl_da->fc, FC) == 0)	/* FC of this DA matches FC	*/
        {
        retcode = tdladd_da_or_bda (tdl_ctxt, scl_info, scl_da->name, scl_da->bType,
                  scl_da->type, scl_da->count);
        if (retcode != SD_SUCCESS)	/* error (already logged)	*/
          return (retcode);			/* error	*/
        }
      }
    }	/* end "for (scl_da...)" loop	*/

  if (tdl_ctxt->tdlptr > save_ptr_after_head)
    {		/* tdl was added. Finish it.	*/
    if (tdladd_string (tdl_ctxt, "},\n")!=SD_SUCCESS)
      return (SD_FAILURE);	/* error (already logged)	*/
    }
  else
    {				/* DO is empty so rollback changes	*/
    tdl_ctxt->tdlptr = save_start;		/* restore orig ptr		*/
    tdl_ctxt->len_avail = save_avail;	/* restore orig len		*/
    *save_start = '\0';			/* write NULL at orig ptr	*/
    }

  return (SD_SUCCESS);	/* only successful return	*/
  }
/************************************************************************/
/*			tdladd_fc					*/
/* RETURNS:	SD_SUCCESS or error code				*/
/* Add the TDL for one FC at the current pointer (tdl_ctxt->tdlptr).	*/
/* Increase (tdl_ctxt->tdlptr) by the number of bytes added.		*/
/* Decrease (tdl_ctxt->len_avail) by the number of bytes added.		*/
/************************************************************************/
static ST_RET tdladd_fc (
	TDLADD_CTXT *tdl_ctxt,
	ST_CHAR *FC,
	SCL_INFO *scl_info,
	SCL_LNTYPE *scl_lntype)
  {
SCL_DO *scl_do;
SCL_DOTYPE *scl_dotype;
ST_CHAR work_buf [100];		/* temporary buffer for writing TDL	*/
ST_RET retcode;
ST_CHAR *save_start;			/* to save initial ptr		*/
ST_INT save_avail;			/* to save initial len avail	*/
ST_CHAR *save_ptr_after_head;	/* to save ptr after header written	*/

  /* Save initial ptr and len available.	*/
  save_start = tdl_ctxt->tdlptr;
  save_avail = tdl_ctxt->len_avail;

  /* Add component name for this FC. May have to remove later if no DA's found*/
  sprintf (work_buf, "(%s){\n", FC);
  assert (strlen (work_buf) < sizeof (work_buf));
  if (tdladd_string (tdl_ctxt, work_buf)!=SD_SUCCESS)
    return (SD_FAILURE);

  save_ptr_after_head = tdl_ctxt->tdlptr;	/* save ptr after header written*/

  /* NOTE: linked list is in reverse order from data in SCL file,	*/
  /*     so get off list in reverse order.				*/
  for (scl_do = (SCL_DO *) list_find_last ((DBL_LNK *) scl_lntype->doHead);
       scl_do != NULL;
       scl_do = (SCL_DO *) list_find_prev ((DBL_LNK *) scl_lntype->doHead, (DBL_LNK *) scl_do))
    {
    /* Find DOType for this DO.	*/
    scl_dotype = scl_find_dotype (scl_info, scl_do->type);
    if (scl_dotype)	/* found DOType	*/
      {
      retcode = tdladd_do (tdl_ctxt, FC, scl_info, scl_do->name, scl_dotype);
      if (retcode != SD_SUCCESS)
        {
        SXLOG_ERR1 ("ERROR adding TDL for DO='%s'", scl_do->name);
        return (retcode);
        }
      }
    else
      {	/* can't find DOType for this DO. Cannot continue.	*/
      SXLOG_ERR2 ("Cannot find DOType='%s' for DO='%s'.",

⌨️ 快捷键说明

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