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

📄 check_pack.c

📁 一个单元测试框架,主要和应用文件一起编译运行
💻 C
字号:
#include "config.h"#include <stdlib.h>#include <string.h>#include <stdio.h>#include <unistd.h>#include <stdint.h>#include "check.h"#include "check_error.h"#include "check_list.h"#include "check_impl.h"#include "check_pack.h"/* typedef an unsigned int that has at least 4 bytes */typedef uint32_t ck_uint32;static void  pack_int   (char **buf, int val);static int   upack_int  (char **buf);static void  pack_str   (char **buf, const char *str);static char *upack_str  (char **buf);static int   pack_ctx   (char **buf, CtxMsg  *cmsg);static int   pack_loc   (char **buf, LocMsg  *lmsg);static int   pack_fail  (char **buf, FailMsg *fmsg);static void  upack_ctx  (char **buf, CtxMsg  *cmsg);static void  upack_loc  (char **buf, LocMsg  *lmsg);static void  upack_fail (char **buf, FailMsg *fmsg);static void  check_type (int type, const char *file, int line);static enum ck_msg_type upack_type (char **buf);static void  pack_type  (char **buf, enum ck_msg_type type);static int   read_buf   (int fdes, char **buf);static int   get_result (char *buf, RcvMsg *rmsg);static void  rcvmsg_update_ctx (RcvMsg *rmsg, enum ck_result_ctx ctx);static void  rcvmsg_update_loc (RcvMsg *rmsg, const char *file, int line);static RcvMsg *rcvmsg_create (void);void rcvmsg_free (RcvMsg *rmsg);typedef int  (*pfun)  (char **, CheckMsg *);typedef void (*upfun) (char **, CheckMsg *);static pfun pftab [] = {  (pfun) pack_ctx,  (pfun) pack_fail,  (pfun) pack_loc};static upfun upftab [] = {  (upfun) upack_ctx,  (upfun) upack_fail,  (upfun) upack_loc};int pack (enum ck_msg_type type, char **buf, CheckMsg *msg){  if (buf == NULL)    return -1;  if (msg == NULL)    return 0;  check_type (type, __FILE__, __LINE__);  return pftab[type] (buf, msg);}int upack (char *buf, CheckMsg *msg, enum ck_msg_type *type){  char *obuf;  int nread;  if (buf == NULL)    return -1;  obuf = buf;  *type = upack_type (&buf);  check_type (*type, __FILE__, __LINE__);    upftab[*type] (&buf, msg);  nread = buf - obuf;  return nread;}static void pack_int (char **buf, int val){  unsigned char *ubuf = (unsigned char *) *buf;  ck_uint32 uval = val;  ubuf[0] = (uval >> 24) & 0xFF;  ubuf[1] = (uval >> 16) & 0xFF;  ubuf[2] = (uval >> 8)  & 0xFF;  ubuf[3] = uval & 0xFF;  *buf += 4;}static int upack_int (char **buf){  unsigned char *ubuf = (unsigned char *) *buf;  ck_uint32 uval;  uval = ((ubuf[0] << 24) | (ubuf[1] << 16) | (ubuf[2] << 8) | ubuf[3]);  *buf += 4;  return (int) uval;}static void pack_str (char **buf, const char *val){  int strsz;  if (val == NULL)    strsz = 0;  else    strsz = strlen (val);  pack_int (buf, strsz);    if (strsz > 0) {    memcpy (*buf, val, strsz);    *buf += strsz;  } }static char *upack_str (char **buf){  char *val;  int strsz;  strsz = upack_int (buf);  if (strsz > 0) {    val = emalloc (strsz + 1);    memcpy (val, *buf, strsz);    val[strsz] = 0;    *buf += strsz;  } else {    val = emalloc (1);    *val = 0;  }  return val;}static void pack_type (char **buf, enum ck_msg_type type){  pack_int (buf, (int) type);}static enum ck_msg_type upack_type (char **buf){  return (enum ck_msg_type) upack_int (buf);}  static int pack_ctx (char **buf, CtxMsg *cmsg){  char *ptr;  int len;  len = 4 + 4;  *buf = ptr = emalloc (len);    pack_type (&ptr, CK_MSG_CTX);  pack_int (&ptr, (int) cmsg->ctx);  return len;}static void upack_ctx (char **buf, CtxMsg *cmsg){  cmsg->ctx = upack_int (buf);}static int pack_loc (char **buf, LocMsg *lmsg){  char *ptr;  int len;  len = 4 + 4 + (lmsg->file ? strlen (lmsg->file) : 0) + 4;  *buf = ptr = emalloc (len);  pack_type (&ptr, CK_MSG_LOC);  pack_str (&ptr, lmsg->file);  pack_int (&ptr, lmsg->line);  return len;}static void upack_loc (char **buf, LocMsg *lmsg){  lmsg->file = upack_str (buf);  lmsg->line = upack_int (buf);}static int pack_fail (char **buf, FailMsg *fmsg){  char *ptr;  int len;  len = 4 + 4 + (fmsg->msg ? strlen (fmsg->msg) : 0);  *buf = ptr = emalloc (len);  pack_type (&ptr, CK_MSG_FAIL);  pack_str (&ptr, fmsg->msg);  return len;}static void upack_fail (char **buf, FailMsg *fmsg){  fmsg->msg = upack_str (buf);}static void check_type (int type, const char *file, int line){  if (type < 0 || type >= CK_MSG_LAST)    eprintf ("%s:%d:Bad message type arg", file, line);}void ppack (int fdes, enum ck_msg_type type, CheckMsg *msg){  char *buf;  int n;  ssize_t r;  n = pack (type, &buf, msg);  r = write (fdes, buf, n);  if (r == -1)    eprintf ("Error in ppack:",__FILE__,__LINE__);  free (buf);}static int read_buf (int fdes, char **buf){  char *readloc;  int n;  int nread = 0;  int size = 1;  int grow = 2;    *buf = emalloc(size);  readloc = *buf;  while (1) {    n = read (fdes, readloc, size - nread);    if (n == 0)      break;    if (n == -1)      eprintf ("Error in read_buf:", __FILE__, __LINE__);    nread += n;    size *= grow;    *buf = erealloc (*buf,size);    readloc = *buf + nread;  }  return nread;}    static int get_result (char *buf, RcvMsg *rmsg){  enum ck_msg_type type;  CheckMsg msg;  int n;  n = upack (buf, &msg, &type);  if (n == -1)    eprintf ("Error in upack", __FILE__, __LINE__);    if (type == CK_MSG_CTX) {    CtxMsg *cmsg = (CtxMsg *) &msg;    rcvmsg_update_ctx (rmsg, cmsg->ctx);  } else if (type == CK_MSG_LOC) {    LocMsg *lmsg = (LocMsg *) &msg;    if (rmsg->failctx == -1)    {      rcvmsg_update_loc (rmsg, lmsg->file, lmsg->line);    }    free (lmsg->file);  } else if (type == CK_MSG_FAIL) {          FailMsg *fmsg = (FailMsg *) &msg;    if (rmsg->msg == NULL)    {      rmsg->msg = emalloc (strlen (fmsg->msg) + 1);      strcpy (rmsg->msg, fmsg->msg);      rmsg->failctx = rmsg->lastctx;    }    else    {      /* Skip subsequent failure messages, only happens for CK_NOFORK */    }    free (fmsg->msg);  } else    check_type (type, __FILE__, __LINE__);  return n;}static void reset_rcv_test (RcvMsg *rmsg){  rmsg->test_line = -1;  rmsg->test_file = NULL;}static void reset_rcv_fixture (RcvMsg *rmsg){  rmsg->fixture_line = -1;  rmsg->fixture_file = NULL;}static RcvMsg *rcvmsg_create (void){  RcvMsg *rmsg;  rmsg = emalloc (sizeof (RcvMsg));  rmsg->lastctx = -1;  rmsg->failctx = -1;  rmsg->msg = NULL;  reset_rcv_test (rmsg);  reset_rcv_fixture (rmsg);  return rmsg;}void rcvmsg_free (RcvMsg *rmsg){  free(rmsg->fixture_file);  free(rmsg->test_file);  free(rmsg->msg);  free(rmsg);}static void rcvmsg_update_ctx (RcvMsg *rmsg, enum ck_result_ctx ctx){  if (rmsg->lastctx != -1)  {    free(rmsg->fixture_file);    reset_rcv_fixture (rmsg);  }  rmsg->lastctx = ctx;}static void rcvmsg_update_loc (RcvMsg *rmsg, const char *file, int line){  int flen = strlen(file);    if (rmsg->lastctx == CK_CTX_TEST) {    free(rmsg->test_file);    rmsg->test_line = line;    rmsg->test_file = emalloc (flen + 1);    strcpy (rmsg->test_file, file);  } else {    free(rmsg->fixture_file);    rmsg->fixture_line = line;    rmsg->fixture_file = emalloc (flen + 1);    strcpy (rmsg->fixture_file, file);  }}  RcvMsg *punpack (int fdes){  int nread, n;  char *buf;  char *obuf;  RcvMsg *rmsg;  nread = read_buf (fdes, &buf);  obuf = buf;  rmsg = rcvmsg_create ();    while (nread > 0) {    n = get_result (buf, rmsg);    nread -= n;    buf += n;  }  free (obuf);  if (rmsg->lastctx == -1) {    free (rmsg);    rmsg = NULL;  }  return rmsg;}

⌨️ 快捷键说明

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