?? sclproc.c
字號:
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'.",
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -