コード例 #1
0
ファイル: encdec.c プロジェクト: BotondBaranyi/titan.core
char *genRawFieldChecker(char *src, const rawAST_coding_taglist *taglist,
  boolean is_equal)
{
  int i;
  for (i = 0; i < taglist->nElements; i++) {
    rawAST_coding_field_list *fields = taglist->fields + i;
    char *field_name = NULL;
    boolean first_expr = TRUE;
    int j;
    if (i > 0) src = mputstr(src, is_equal ? " || " : " && ");
    for (j = 0; j < fields->nElements; j++) {
      rawAST_coding_fields *field = fields->fields + j;
      if (j == 0) {
        /* this is the first field reference */
        if (field->fieldtype == UNION_FIELD)
          field_name = mputprintf(field_name,"(*field_%s)",field->nthfieldname);
        else
          field_name = mputprintf(field_name,"field_%s", field->nthfieldname);
      }
      else {
        /* this is not the first field reference */
        if (field->fieldtype == UNION_FIELD) {
          /* checking for the right selection within the union */
          if (first_expr) {
            if (taglist->nElements > 1) src = mputc(src, '(');
            first_expr = FALSE;
          }
          else src = mputstr(src, is_equal ? " && " : " || ");
          src = mputprintf(src, "%s.get_selection() %s %s%s%s", field_name,
            is_equal ? "==" : "!=", fields->fields[j - 1].type,
            "::ALT_", field->nthfieldname);
        }
        /* appending the current field name to the field reference */
        field_name = mputprintf(field_name, ".%s()", field->nthfieldname);
      }
      if (j < fields->nElements - 1 && field->fieldtype == OPTIONAL_FIELD) {
        /* this is not the last field in the chain and it is optional */
        if (first_expr) {
          if (taglist->nElements > 1) src = mputc(src, '(');
          first_expr = FALSE;
        }
        else src = mputstr(src, is_equal ? " && " : " || ");
        /* check for the presence */
        if (!is_equal) src = mputc(src, '!');
        src = mputprintf(src, "%s.ispresent()", field_name);
        /* add an extra () to the field reference */
        field_name = mputstr(field_name, "()");
      }
    }
    if (!first_expr) src = mputstr(src, is_equal ? " && " : " || ");
    /* compare the referred field with the given value */
    src = mputprintf(src, "%s %s %s", field_name, is_equal ? "==" : "!=",
      fields->value);
    if (!first_expr && taglist->nElements > 1) src = mputc(src, ')');
    Free(field_name);
  }
  return src;
}
コード例 #2
0
ファイル: encdec.c プロジェクト: BotondBaranyi/titan.core
char *genRawTagChecker(char *src, const rawAST_coding_taglist *taglist)
{
  int temp_tag, l;
  rawAST_coding_field_list temp_field;
  src = mputstr(src, "  RAW_enc_tree* temp_leaf;\n");
  for (temp_tag = 0; temp_tag < taglist->nElements; temp_tag++) {
    temp_field = taglist->fields[temp_tag];
    src = mputprintf(src, "  {\n"
      "  RAW_enc_tr_pos pr_pos%d;\n"
      "  pr_pos%d.level=myleaf.curr_pos.level+%d;\n"
      "  int new_pos%d[]={", temp_tag, temp_tag, temp_field.nElements, temp_tag);
    for (l = 0; l < temp_field.nElements; l++) {
      src= mputprintf(src, "%s%d", l ? "," : "", temp_field.fields[l].nthfield);
    }
    src = mputprintf(src, "};\n"
      "  pr_pos%d.pos=init_new_tree_pos(myleaf.curr_pos,%d,new_pos%d);\n"
      "  temp_leaf = myleaf.get_node(pr_pos%d);\n"
      "  if(temp_leaf != NULL){\n", temp_tag, temp_field.nElements, temp_tag, temp_tag);
    if (temp_field.value[0] != ' ') {
      src = mputprintf(src, "  %s new_val = %s;\n"
        "  new_val.RAW_encode(%s_descr_,*temp_leaf);\n",
        temp_field.fields[temp_field.nElements - 1].type, temp_field.value,
        temp_field.fields[temp_field.nElements - 1].typedescr);
    }
    else {
      src = mputprintf(src, "  %s.RAW_encode(%s_descr_,*temp_leaf);\n",
        temp_field.value, temp_field.fields[temp_field.nElements - 1].typedescr);
    }
    src = mputstr(src, "  } else");
  }
  src = mputstr(src, " {\n"
    "    TTCN_EncDec_ErrorContext::error\n"
    "      (TTCN_EncDec::ET_OMITTED_TAG, \"Encoding a tagged, but omitted"
    " value.\");\n"
    "  }\n");
  for (temp_tag = taglist->nElements - 1; temp_tag >= 0 ; temp_tag--) {
    src = mputprintf(src, "  free_tree_pos(pr_pos%d.pos);\n"
      "  }\n", temp_tag);
  }
  return src;
}
コード例 #3
0
ファイル: signature.c プロジェクト: enispes/titan.core
void defSignatureClasses(const signature_def *sdef, output_struct *output)
{
  char *decl = NULL, *def = NULL, *src = NULL;
  const char *name = sdef->name, *dispname = sdef->dispname;
  size_t i, num_in = 0, num_out = 0;

  for (i = 0; i < sdef->parameters.nElements; i++) {
    if (sdef->parameters.elements[i].direction != PAR_OUT) num_in++;
    if (sdef->parameters.elements[i].direction != PAR_IN) num_out++;
  }

  /*
   *
   * xxx_call class
   *
   */

  decl = mputprintf(decl, "class %s_call;\n", name);

  /* class definition */
  def = mputprintf(def, "class %s_call {\n", name);

  /* signature's in and inout parameters */
  for (i = 0; i < sdef->parameters.nElements; i++) {
    if (sdef->parameters.elements[i].direction != PAR_OUT)
      def = mputprintf(def, "%s param_%s;\n",
        sdef->parameters.elements[i].type,
        sdef->parameters.elements[i].name);
  }

  def = mputstr(def, "public:\n");

  /* parameters' access functions */
  for (i = 0; i < sdef->parameters.nElements; i++) {
    if (sdef->parameters.elements[i].direction != PAR_OUT) {
      def = mputprintf(def, "inline %s& %s() { return param_%s; }\n"
        "inline const %s& %s() const { return param_%s; }\n",
        sdef->parameters.elements[i].type,
        sdef->parameters.elements[i].name,
        sdef->parameters.elements[i].name,
        sdef->parameters.elements[i].type,
        sdef->parameters.elements[i].name,
        sdef->parameters.elements[i].name);
    }
  }

  if (num_in > 0) {
    /* encode_text function */
    def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
    src = mputprintf(src, "void %s_call::encode_text(Text_Buf& text_buf) "
      "const\n"
      "{\n", name);
    for(i = 0; i < sdef->parameters.nElements; i++) {
      if(sdef->parameters.elements[i].direction != PAR_OUT)
        src = mputprintf(src, "param_%s.encode_text(text_buf);\n",
          sdef->parameters.elements[i].name);
    }
    src = mputstr(src, "}\n\n");
    /* decode_text function */
    def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
    src = mputprintf(src, "void %s_call::decode_text(Text_Buf& text_buf)\n"
      "{\n", name);
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction!= PAR_OUT)
        src = mputprintf(src, "param_%s.decode_text(text_buf);\n",
          sdef->parameters.elements[i].name);
    }
    src = mputstr(src, "}\n\n");
  } else {
    def = mputstr(def, "inline void encode_text(Text_Buf&) const "
      "{ }\n"
      "inline void decode_text(Text_Buf&) { }\n");
  }

  /* log function */
  def = mputstr(def, "void log() const;\n");
  src = mputprintf(src, "void %s_call::log() const\n"
    "{\n", name);
  if (num_in > 0) {
    boolean first_param = TRUE;
    src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : { \");\n",
      dispname);
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction != PAR_OUT) {
        src = mputstr(src, "TTCN_Logger::log_event_str(\"");
        if (first_param) first_param = FALSE;
        else src = mputstr(src, ", ");
        src = mputprintf(src, "%s := \");\n"
          "param_%s.log();\n",
          sdef->parameters.elements[i].dispname,
          sdef->parameters.elements[i].name);
      }
    }
    src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
  } else {
    src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : { }\");\n",
      dispname);
  }
  src = mputstr(src, "}\n\n");

  def = mputstr(def, "};\n\n");
  /* end of xxx_call class*/

  /*
   *
   * xxx_call_redirect class (for getcall port-operation)
   *
   */
  decl = mputprintf(decl, "class %s_call_redirect;\n", name);

  /* class definition */
  def = mputprintf(def, "class %s_call_redirect {\n", name);

  /* parameter pointers */
  for (i = 0; i < sdef->parameters.nElements; i++) {
    if (sdef->parameters.elements[i].direction != PAR_OUT) {
      def = mputprintf(def, "%s *ptr_%s;\n",
        sdef->parameters.elements[i].type,
        sdef->parameters.elements[i].name);
    }
  }

  def = mputstr(def, "public:\n");

  if (num_in > 0) {
    /* constructor */
    boolean first_param = TRUE;
    def = mputprintf(def, "%s_call_redirect(", name);
    for (i = 0;i<sdef->parameters.nElements;i++) {
      if (sdef->parameters.elements[i].direction != PAR_OUT) {
        if (first_param) first_param = FALSE;
        else def = mputstr(def, ", ");
        def = mputprintf(def, "%s *par_%s = NULL",
          sdef->parameters.elements[i].type,
          sdef->parameters.elements[i].name);
      }
    }
    def = mputstr(def, ")\n"
      " : ");
    first_param = TRUE;
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction != PAR_OUT) {
        if (first_param) first_param = FALSE;
        else def = mputstr(def, ", ");
        def = mputprintf(def, "ptr_%s(par_%s)",
          sdef->parameters.elements[i].name,
          sdef->parameters.elements[i].name);
      }
    }
    def = mputstr(def, " { }\n");
  }
  /* otherwise constructor is not needed */

  /* set_parameters function (used for param redirect in getcall) */
  if (num_in > 0) {
    def = mputprintf(def, "void set_parameters(const %s_call& call_par) "
      "const;\n", name);
    src = mputprintf(src, "void %s_call_redirect::set_parameters(const "
      "%s_call& call_par) const\n"
      "{\n", name, name);
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction != PAR_OUT) {
        src = mputprintf(src, "if (ptr_%s != NULL) "
          "*ptr_%s = call_par.%s();\n",
          sdef->parameters.elements[i].name,
          sdef->parameters.elements[i].name,
          sdef->parameters.elements[i].name);
      }
    }
    src = mputstr(src, "}\n\n");
  } else {
    def = mputprintf(def, "inline void set_parameters(const %s_call&"
      ") const { }\n", name);
  }

  def = mputstr(def, "};\n\n");
  /* end of class xxx_call_redirect */


  if (!sdef->is_noblock) {
    /*
     *
     * xxx_reply class
     *
     */
    decl = mputprintf(decl, "class %s_reply;\n", name);

    /* class definition */
    def = mputprintf(def, "class %s_reply {\n", name);

    /* signature's out and inout parameters */
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction != PAR_IN) {
        def = mputprintf(def, "%s param_%s;\n",
          sdef->parameters.elements[i].type,
          sdef->parameters.elements[i].name);
      }
    }
    if (sdef->return_type != NULL) {
      def = mputprintf(def, "%s reply_value;\n", sdef->return_type);
    }

    def = mputstr(def, "public:\n");

    /* parameters' access functions */
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction != PAR_IN) {
        def = mputprintf(def, "inline %s& %s() { return param_%s; }\n"
          "inline const %s& %s() const { return param_%s; }\n",
          sdef->parameters.elements[i].type,
          sdef->parameters.elements[i].name,
          sdef->parameters.elements[i].name,
          sdef->parameters.elements[i].type,
          sdef->parameters.elements[i].name,
          sdef->parameters.elements[i].name);
      }
    }
    if (sdef->return_type != NULL) {
      def = mputprintf(def, "inline %s& return_value() "
        "{ return reply_value; }\n"
        "inline const %s& return_value() const "
        "{ return reply_value; }\n",
        sdef->return_type, sdef->return_type);
    }

    if (num_out > 0 || sdef->return_type != NULL) {
      /* encode_text function */
      def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
      src = mputprintf(src, "void %s_reply::encode_text(Text_Buf& "
        "text_buf) const\n"
        "{\n", name);
      for (i = 0; i < sdef->parameters.nElements; i++) {
        if (sdef->parameters.elements[i].direction != PAR_IN)
          src = mputprintf(src, "param_%s.encode_text(text_buf);\n",
            sdef->parameters.elements[i].name);
      }
      if (sdef->return_type != NULL)
        src = mputstr(src, "reply_value.encode_text(text_buf);\n");
      src = mputstr(src, "}\n\n");
      /* decode_text function */
      def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
      src = mputprintf(src, "void %s_reply::decode_text(Text_Buf& "
        "text_buf)\n"
        "{\n", name);
      for (i = 0; i < sdef->parameters.nElements; i++) {
        if (sdef->parameters.elements[i].direction != PAR_IN)
          src = mputprintf(src, "param_%s.decode_text(text_buf);\n",
            sdef->parameters.elements[i].name);
      }
      if (sdef->return_type != NULL)
        src = mputstr(src, "reply_value.decode_text(text_buf);\n");
      src = mputstr(src, "}\n\n");
    } else {
      def = mputstr(def, "inline void encode_text(Text_Buf&) "
        "const { }\n"
        "inline void decode_text(Text_Buf&) { }\n");
    }

    /* log function */
    def = mputstr(def, "void log() const;\n");
    src = mputprintf(src, "void %s_reply::log() const\n"
      "{\n", name);
    if (num_out > 0) {
      boolean first_param = TRUE;
      src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : { \");\n",
        dispname);
      for (i = 0; i < sdef->parameters.nElements; i++) {
        if (sdef->parameters.elements[i].direction != PAR_IN) {
          src = mputstr(src, "TTCN_Logger::log_event_str(\"");
          if (first_param) first_param = FALSE;
          else src = mputstr(src, ", ");
          src = mputprintf(src, "%s := \");\n"
            "param_%s.log();\n",
            sdef->parameters.elements[i].dispname,
            sdef->parameters.elements[i].name);
        }
      }
      if (sdef->return_type != NULL) {
        src = mputstr(src, "TTCN_Logger::log_event_str(\" } "
          "value \");\n"
          "reply_value.log();\n");
      } else {
        src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
      }
    } else if (sdef->return_type != NULL) {
      src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : { } "
        "value \");\n"
        "reply_value.log();\n", dispname);
    } else {
      src = mputprintf(src, "TTCN_Logger::log_event_str(\"%s : "
        "{ }\");\n", dispname);
    }
    src = mputstr(src, "}\n\n");

    def = mputstr(def, "};\n\n");
    /* end of xxx_reply class*/

    /*
     *
     * xxx_reply_redirect class (for getreply port-operation)
     *
     */
    decl = mputprintf(decl, "class %s_reply_redirect;\n", name);

    /* class definition */
    def = mputprintf(def, "class %s_reply_redirect {\n", name);

    /* parameter pointers */
    if (sdef->return_type != NULL) {
      def = mputprintf(def, "%s *ret_val_ptr;\n", sdef->return_type);
    }
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction != PAR_IN) {
        def = mputprintf(def, "%s *ptr_%s;\n",
          sdef->parameters.elements[i].type,
          sdef->parameters.elements[i].name);
      }
    }

    def = mputstr(def, "public:\n");

    if (num_out > 0 || sdef->return_type != NULL) {
      boolean first_param = TRUE;
      /* constructor */
      def = mputprintf(def, "%s_reply_redirect(", name);
      if (sdef->return_type != NULL) {
        def = mputprintf(def, "%s *return_ptr", sdef->return_type);
        first_param = FALSE;
      }
      for (i = 0; i < sdef->parameters.nElements; i++) {
        if(sdef->parameters.elements[i].direction != PAR_IN) {
          if (first_param) first_param = FALSE;
          else def = mputstr(def, ", ");
          def = mputprintf(def, "%s *par_%s = NULL",
            sdef->parameters.elements[i].type,
            sdef->parameters.elements[i].name);
        }
      }
      def = mputstr(def, ")\n"
        " : ");
      first_param = TRUE;
      if (sdef->return_type != NULL) {
        def = mputstr(def, "ret_val_ptr(return_ptr)");
        first_param = FALSE;
      }
      for (i = 0; i < sdef->parameters.nElements; i++) {
        if(sdef->parameters.elements[i].direction != PAR_IN) {
          if (first_param) first_param = FALSE;
          else def = mputstr(def, ", ");
          def = mputprintf(def, "ptr_%s(par_%s)",
            sdef->parameters.elements[i].name,
            sdef->parameters.elements[i].name);
        }
      }
      def = mputstr(def, " { }\n");
    }
    /* otherwise constructor is not needed */

    /* set_parameters function (used for param redirect in getreply) */
    if ((sdef->parameters.nElements - num_in) > 0
      || sdef->return_type != NULL) {
      /* if there are "out" or "inout" parameters or a "return" ... */
      def = mputprintf(def, "void set_parameters(const %s_reply& reply_par) "
        "const;\n", name);
      src = mputprintf(src, "void %s_reply_redirect::set_parameters(const "
        "%s_reply& reply_par) const\n"
        "{\n", name, name);
      for (i = 0; i < sdef->parameters.nElements; i++) {
        if (sdef->parameters.elements[i].direction != PAR_IN) {
          src = mputprintf(src, "if (ptr_%s != NULL) "
            "*ptr_%s = reply_par.%s();\n",
            sdef->parameters.elements[i].name,
            sdef->parameters.elements[i].name,
            sdef->parameters.elements[i].name);
        }
      }
      if (sdef->return_type!=NULL) {
        src = mputstr(src, "if (ret_val_ptr != NULL) "
          "*ret_val_ptr = reply_par.return_value();\n");
      }
      src = mputstr(src, "}\n\n");
    }
    else {
      def = mputprintf(def, "inline void set_parameters(const %s_reply&) "
        "const {}\n", name);
    }

    def = mputstr(def, "};\n\n");
    /* end of class xxx_reply_redirect */
  } /* if (!sdeff->is_noblock) */


  if (sdef->exceptions.nElements > 0) {
    char *selection_type, *unbound_value, *selection_prefix;

    selection_type = mcopystr("exception_selection_type");
    unbound_value = mcopystr("UNBOUND_VALUE");
    selection_prefix = mcopystr("ALT");

    /*
     *
     * xxx_exception class
     *
     */
    decl = mputprintf(decl, "class %s_exception;\n", name);
    /* class definition */
    def = mputprintf(def, "class %s_exception {\n", name);

    /* enum type */
    def = mputstr(def, "public:\n"
      "enum exception_selection_type { ");
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      def = mputprintf(def, "ALT_%s = %lu, ",
        sdef->exceptions.elements[i].altname, (unsigned long) i);
    }
    def = mputprintf(def, " UNBOUND_VALUE = %lu };\n"
          "private:\n", (unsigned long) sdef->exceptions.nElements);

    /* data members */
    def = mputprintf(def, "%s exception_selection;\n"
      "union {\n", selection_type);
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      def = mputprintf(def, "%s *field_%s;\n",
        sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].altname);
    }
    def = mputstr(def, "};\n");

    /* clean_up function */
    def = mputstr(def, "void clean_up();\n");
    src = mputprintf(src, "void %s_exception::clean_up()\n"
      "{\n"
      "switch (exception_selection) {\n", name);
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      src = mputprintf(src, "case %s_%s:\n"
        "delete field_%s;\n", selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname);
      if (i < sdef->exceptions.nElements - 1)
        src = mputstr(src, "break;\n");
    }
    src = mputprintf(src, "default:\n"
      "break;\n"
      "}\n"
      "exception_selection = %s;\n"
      "}\n\n", unbound_value);

    /* copy_value function */
    def = mputprintf(def, "void copy_value(const %s_exception& "
      "other_value);\n", name);
    src = mputprintf(src, "void %s_exception::copy_value(const "
      "%s_exception& other_value)\n"
      "{\n"
      "switch (other_value.exception_selection) {\n", name, name);
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      src = mputprintf(src, "case %s_%s:\n"
        "field_%s = new %s(*other_value.field_%s);\n"
        "break;\n", selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].altname);
    }
    src = mputprintf(src, "default:\n"
      "TTCN_error(\"Copying an uninitialized exception of signature "
      "%s.\");\n"
      "}\n"
      "exception_selection = other_value.exception_selection;\n"
      "}\n\n", name);

    /* default constructor */
    def = mputprintf(def, "public:\n"
      "%s_exception() : exception_selection(%s) { }\n", name,
      unbound_value);

    /* copy constructor */
    def = mputprintf(def, "%s_exception(const %s_exception& "
      "other_value) { copy_value(other_value); }\n", name, name);

    /* constructors (from exception types) */
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      def = mputprintf(def, "%s_exception(const %s& other_value);\n",
        name, sdef->exceptions.elements[i].name);
      src = mputprintf(src, "%s_exception::%s_exception(const "
        "%s& other_value)\n"
        "{\n"
        "field_%s = new %s(other_value);\n"
        "exception_selection = %s_%s;\n"
        "}\n\n", name, name, sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].name, selection_prefix,
        sdef->exceptions.elements[i].altname);
      def = mputprintf(def, "%s_exception(const %s_template& "
        "other_value);\n", name, sdef->exceptions.elements[i].name);
      src = mputprintf(src, "%s_exception::%s_exception(const "
        "%s_template& other_value)\n"
        "{\n"
        "field_%s = new %s(other_value.valueof());\n"
        "exception_selection = %s_%s;\n"
        "}\n\n", name, name, sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].name, selection_prefix,
        sdef->exceptions.elements[i].altname);
    }

    /* destructor */
    def = mputprintf(def, "~%s_exception() { clean_up(); }\n", name);

    /* assignment operator */
    def = mputprintf(def, "%s_exception& operator=(const %s_exception& "
      "other_value);\n", name, name);
    src = mputprintf(src, "%s_exception& %s_exception::operator=(const "
      "%s_exception& other_value)\n"
      "{\n"
      "if (this != &other_value) {\n"
      "clean_up();\n"
      "copy_value(other_value);\n"
      "}\n"
      "return *this;\n"
      "}\n\n", name, name, name);

    /* field (type) access functions */
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      def = mputprintf(def, "%s& %s_field();\n",
        sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].altname);
      src = mputprintf(src, "%s& %s_exception::%s_field()\n"
        "{\n"
        "if (exception_selection != %s_%s) {\n"
        "clean_up();\n"
        "field_%s = new %s;\n"
        "exception_selection = %s_%s;\n"
        "}\n"
        "return *field_%s;\n"
        "}\n\n", sdef->exceptions.elements[i].name, name,
        sdef->exceptions.elements[i].altname, selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].name,
        selection_prefix, sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname);
      def = mputprintf(def, "const %s& %s_field() const;\n",
        sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].altname);
      src = mputprintf(src, "const %s& %s_exception::%s_field() const\n"
        "{\n"
        "if (exception_selection != %s_%s) "
        "TTCN_error(\"Referencing to non-selected type %s in an "
        "exception of signature %s.\");\n"
        "return *field_%s;\n"
        "}\n\n", sdef->exceptions.elements[i].name, name,
        sdef->exceptions.elements[i].altname, selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].dispname, dispname,
        sdef->exceptions.elements[i].altname);
    }

    /* get_selection function */
    def = mputprintf(def, "inline %s get_selection() const "
      "{ return exception_selection; }\n", selection_type);

    /* encode_text function */
    def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
    src = mputprintf(src, "void %s_exception::encode_text(Text_Buf& "
      "text_buf) const\n"
      "{\n"
      "text_buf.push_int(exception_selection);\n"
      "switch (exception_selection) {\n", name);
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      src = mputprintf(src, "case %s_%s:\n"
        "field_%s->encode_text(text_buf);\n"
        "break;\n", selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname);
    }
    src = mputprintf(src, "default:\n"
      "TTCN_error(\"Text encoder: Encoding an uninitialized exception "
      "of signature %s.\");\n"
      "}\n"
      "}\n\n", dispname);

    /* decode_text function */
    def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
    src = mputprintf(src, "void %s_exception::decode_text(Text_Buf& "
      "text_buf)\n"
      "{\n"
      "switch ((%s)text_buf.pull_int().get_val()) {\n", name, selection_type);
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      src = mputprintf(src, "case %s_%s:\n"
        "%s_field().decode_text(text_buf);\n"
        "break;\n", selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname);
    }
    src = mputprintf(src, "default:\n"
      "TTCN_error(\"Text decoder: Unrecognized selector was received "
      "for an exception of signature %s.\");\n"
      "}\n"
      "}\n\n", dispname);

    /* log function */
    def = mputstr(def, "void log() const;\n");
    src = mputprintf(src, "void %s_exception::log() const\n"
      "{\n"
      "TTCN_Logger::log_event_str(\"%s, \");\n"
      "switch (exception_selection) {\n",
      name, dispname);
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      src = mputprintf(src, "case %s_%s:\n"
        "TTCN_Logger::log_event_str(\"%s : \");\n"
        "field_%s->log();\n"
        "break;\n", selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].dispname,
        sdef->exceptions.elements[i].altname);
    }
    src = mputstr(src, "default:\n"
      "TTCN_Logger::log_event_str(\"<uninitialized exception>\");\n"
      "}\n"
      "}\n\n");

    def = mputstr(def, "};\n\n");
    /* end of xxx_exception class*/

    Free(selection_type);
    selection_type = mprintf("%s_exception::exception_selection_type", name);
    Free(unbound_value);
    unbound_value = mprintf("%s_exception::UNBOUND_VALUE", name);
    Free(selection_prefix);
    selection_prefix = mprintf("%s_exception::ALT", name);

    /*
     *
     * simple xxx_exception_template for the catch port-operator
     * only with constructors, a log/match function and value redirect
     *
     */
    decl = mputprintf(decl, "class %s_exception_template;\n", name);

    def = mputprintf(def, "class %s_exception_template {\n", name);

    /* data members */
    /* exception-selection enum */
    def = mputprintf(def, "%s exception_selection;\n", selection_type);
    /* union of all possible exceptions (templates) */
    def = mputstr(def, "union {\n");
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      def = mputprintf(def, "const %s_template *field_%s;\n",
        sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].altname);
    }
    def = mputstr(def, "};\n");
    /* union of all possible value redirect pointers */
    def = mputstr(def, "union {\n");
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      def = mputprintf(def, "%s *ptr_%s;\n",
        sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].altname);
    }
    def = mputstr(def, "};\n"
      "public:\n");
    /* constructors (for all possible template + redirect pointer pairs) */
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      def = mputprintf(def, "%s_exception_template(const %s_template& "
        "init_template, %s *value_ptr = NULL);\n", name,
        sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].name);
      src = mputprintf(src, "%s_exception_template::%s_exception_template"
        "(const %s_template& init_template, %s *value_ptr)\n"
        "{\n"
        "exception_selection = %s_%s;\n"
        "field_%s = &init_template;\n"
        "ptr_%s = value_ptr;\n"
        "}\n\n", name, name, sdef->exceptions.elements[i].name,
        sdef->exceptions.elements[i].name, selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname);
    }

    /* match function */
    def = mputprintf(def, "boolean match(const %s_exception& other_value) "
      "const;\n", name);
    src = mputprintf(src, "boolean %s_exception_template::match(const "
      "%s_exception& other_value) const\n"
      "{\n"
      "if (exception_selection != other_value.get_selection()) "
      "return FALSE;\n"
      "switch (exception_selection) {\n", name, name);
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      src = mputprintf(src, "case %s_%s:\n"
        "return field_%s->match(other_value.%s_field());\n",
        selection_prefix, sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname);
    }
    src = mputprintf(src, "default:\n"
      "TTCN_error(\"Internal error: Invalid selector when matching an "
      "exception of signature %s.\");\n"
      "return FALSE;\n"
      "}\n"
      "}\n\n", dispname);

    /* log_match function */
    def = mputprintf(def, "void log_match(const %s_exception& other_value) "
      "const;\n", name);
    src = mputprintf(src, "void %s_exception_template::log_match(const "
      "%s_exception& other_value) const\n"
      "{\n"
      "TTCN_Logger::log_event_str(\"%s, \");\n"
      "if (exception_selection == other_value.get_selection()) {\n"
      "switch (exception_selection) {\n", name, name, dispname);
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      src = mputprintf(src, "case %s_%s:\n"
        "TTCN_Logger::log_event_str(\"%s : \");\n"
        "field_%s->log_match(other_value.%s_field());\n"
        "break;\n", selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].dispname,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname);
    }
    src = mputstr(src, "default:\n"
      "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
      "}\n"
      "} else {\n"
      "other_value.log();\n"
      "TTCN_Logger::log_event_str(\" with \");\n"
      "switch (exception_selection) {\n");
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      src = mputprintf(src, "case %s_%s:\n"
        "TTCN_Logger::log_event_str(\"%s : \");\n"
        "field_%s->log();\n"
        "break;\n", selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].dispname,
        sdef->exceptions.elements[i].altname);
    }
    src = mputstr(src, "default:\n"
      "TTCN_Logger::log_event_str(\"<invalid selector>\");\n"
      "}\n"
      "if (match(other_value)) "
      "TTCN_Logger::log_event_str(\" matched\");\n"
      "else TTCN_Logger::log_event_str(\" unmatched\");\n"
      "}\n"
      "}\n\n");

    /* set_value function */
    def = mputprintf(def, "void set_value(const %s_exception& "
      "source_value) const;\n", name);
    src = mputprintf(src, "void %s_exception_template::set_value(const "
      "%s_exception& source_value) const\n"
      "{\n"
      "if (exception_selection == source_value.get_selection()) {\n"
      "switch (exception_selection) {\n", name, name);
    for (i = 0; i < sdef->exceptions.nElements; i++) {
      src = mputprintf(src, "case %s_%s:\n"
        "if (ptr_%s != NULL) *ptr_%s = source_value.%s_field();\n"
        "return;\n", selection_prefix,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname,
        sdef->exceptions.elements[i].altname);
    }
    src = mputprintf(src, "default:\n"
      "break;\n"
      "}\n"
      "}\n"
      "TTCN_error(\"Internal error: Invalid selector when performing "
      "value redirect on an exception of signature %s.\");\n"
      "}\n\n", dispname);

    def = mputstr(def, "};\n\n");
    /* end of class xxx_exception_template */

    Free(selection_type);
    Free(unbound_value);
    Free(selection_prefix);
  } /* if (sdef->exceptions.nElements > 0) */

  /*
   * template class
   */

  decl = mputprintf(decl, "class %s_template;\n", name);

  def = mputprintf(def, "class %s_template {\n", name);

  /* parameters */
  for (i = 0; i < sdef->parameters.nElements; i++) {
    def = mputprintf(def, "%s_template param_%s;\n",
      sdef->parameters.elements[i].type,
      sdef->parameters.elements[i].name);
  }
  if (sdef->return_type != NULL) {
    def = mputprintf(def, "mutable %s_template reply_value;\n",
      sdef->return_type);
  }

  def = mputstr(def, "public:\n");
  /* constructor */
  if (sdef->parameters.nElements > 0 || sdef->return_type != NULL) {
    boolean first_param = TRUE;
    def = mputprintf(def, "%s_template();\n", name);
    src = mputprintf(src, "%s_template::%s_template()\n"
      " : ", name, name);
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (first_param) first_param = FALSE;
      else src = mputstr(src, ", ");
      src = mputprintf(src, "param_%s(ANY_VALUE)",
        sdef->parameters.elements[i].name);
    }
    if (sdef->return_type != NULL) {
      if (first_param) /*first_param = FALSE*/;
      else src = mputstr(src, ", ");
      src = mputstr(src, "reply_value(ANY_VALUE)");
    }
    src = mputstr(src, "\n"
      "{\n"
      "}\n\n");
  } else {
    def = mputprintf(def, "%s_template() { }\n", name);
  }

  if (sdef->parameters.nElements == 0) {
    /* constructor and assignment operator for parameter-less signatures */
    if (sdef->return_type != NULL) {
      def = mputprintf(def, "%s_template(null_type null_value);\n",
        name);
      src = mputprintf(src,
        "%s_template::%s_template(null_type)\n"
        " : reply_value(ANY_VALUE)\n"
        "{\n"
        "}\n\n", name, name);
    } else {
      def = mputprintf(def, "%s_template(null_type) { }\n",
        name);
    }
    def = mputprintf(def, "inline %s_template& operator=(null_type)"
      " { return *this; }\n", name);
  }

  /* parameter access functions */
  for (i = 0; i < sdef->parameters.nElements; i++) {
    def = mputprintf(def, "inline %s_template& %s() { return param_%s; }\n"
      "inline const %s_template& %s() const { return param_%s; }\n",
      sdef->parameters.elements[i].type,
      sdef->parameters.elements[i].name,
      sdef->parameters.elements[i].name,
      sdef->parameters.elements[i].type,
      sdef->parameters.elements[i].name,
      sdef->parameters.elements[i].name);
  }
  if (sdef->return_type != NULL) {
    def = mputprintf(def, "inline %s_template& return_value() const "
      "{ return reply_value; }\n", sdef->return_type);
  }

  /* create_call function for creating xxx_call signature-value */
  if (num_in > 0) {
    def = mputprintf(def, "%s_call create_call() const;\n", name);
    src = mputprintf(src, "%s_call %s_template::create_call() const\n"
      "{\n"
      "%s_call ret_val;\n", name, name, name);
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction != PAR_OUT) {
        src = mputprintf(src, "ret_val.%s() = param_%s.valueof();\n",
          sdef->parameters.elements[i].name,
          sdef->parameters.elements[i].name);
      }
    }
    src = mputstr(src, "return ret_val;\n"
      "}\n\n");
  } else {
    def = mputprintf(def, "inline %s_call create_call() const "
      "{ return %s_call(); }\n", name, name);
  }

  if (!sdef->is_noblock) {
    /* create_reply function for creating xxx_reply signature-value */
    if (num_out > 0 || sdef->return_type != NULL) {
      def = mputprintf(def, "%s_reply create_reply() const;\n", name);
      src = mputprintf(src, "%s_reply %s_template::create_reply() const\n"
        "{\n"
        "%s_reply ret_val;\n", name, name, name);
      for (i = 0; i < sdef->parameters.nElements; i++) {
        if (sdef->parameters.elements[i].direction != PAR_IN) {
          src = mputprintf(src, "ret_val.%s() = "
            "param_%s.valueof();\n",
            sdef->parameters.elements[i].name,
            sdef->parameters.elements[i].name);
        }
      }
      if (sdef->return_type != NULL) {
        src = mputstr(src, "ret_val.return_value() = "
          "reply_value.valueof();\n");
      }
      src = mputstr(src, "return ret_val;\n"
        "}\n\n");
    } else {
      def = mputprintf(def, "inline %s_reply create_reply() const "
        "{ return %s_reply(); }\n", name, name);
    }
  }

  /* match_call function for matching with xxx_call signature-value */
  if (num_in > 0) {
    boolean first_param = TRUE;
    def = mputprintf(def, "boolean match_call(const %s_call& match_value) "
      "const;\n", name);
    src = mputprintf(src, "boolean %s_template::match_call(const %s_call& "
      "match_value) const\n"
      "{\n"
      "return ", name, name);
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction != PAR_OUT) {
        if (first_param) first_param = FALSE;
        else src = mputstr(src, " &&\n");
        src = mputprintf(src, "param_%s.match(match_value.%s())",
          sdef->parameters.elements[i].name,
          sdef->parameters.elements[i].name);
      }
    }
    src = mputstr(src, ";\n"
      "}\n\n");
  } else {
    def = mputprintf(def, "inline boolean match_call(const %s_call&"
      ") const { return TRUE; }\n", name);
  }

  if (!sdef->is_noblock) {
    if (num_out > 0 || sdef->return_type != NULL) {
      boolean first_param = TRUE;
      /* match_reply function for matching with xxx_reply value */
      def = mputprintf(def, "boolean match_reply(const %s_reply& "
        "match_value) const;\n", name);
      src = mputprintf(src, "boolean %s_template::match_reply(const "
        "%s_reply& match_value) const\n"
        "{\n"
        "return ", name, name);
      for (i = 0; i < sdef->parameters.nElements; i++) {
        if(sdef->parameters.elements[i].direction != PAR_IN) {
          if (first_param) first_param = FALSE;
          else src = mputstr(src, " &&\n");
          src = mputprintf(src, "param_%s.match(match_value.%s())",
            sdef->parameters.elements[i].name,
            sdef->parameters.elements[i].name);
        }
      }
      if (sdef->return_type != NULL) {
        if (first_param) /*first_param = FALSE*/;
        else src = mputstr(src, " &&\n");
        src = mputstr(src,
          "reply_value.match(match_value.return_value())");
      }
      src = mputstr(src, ";\n"
        "}\n\n");
    } else {
      def = mputprintf(def, "inline boolean match_reply(const %s_reply&"
        ") const { return TRUE; }\n", name);
    }
  }

  /* set_value_template function */
  if (sdef->return_type != NULL) {
    def = mputprintf(def, "const %s_template& set_value_template(const "
      "%s_template& new_template) const;\n", name, sdef->return_type);
    src = mputprintf(src,
      "const %s_template& %s_template::set_value_template"
      "(const %s_template& new_template) const\n"
      "{\n"
      "reply_value = new_template;\n"
      "return *this;\n"
      "}\n\n", name, name, sdef->return_type);
  }

  /* log function */
  def = mputstr(def, "void log() const;\n");
  src = mputprintf(src, "void %s_template::log() const\n"
    "{\n", name);
  if (sdef->parameters.nElements >= 1) {
    for (i = 0; i < sdef->parameters.nElements; i++) {
      src = mputstr(src, "TTCN_Logger::log_event_str(\"");
      if (i == 0) src = mputc(src, '{');
      else src = mputc(src, ',');
      src = mputprintf(src, " %s := \");\n"
        "param_%s.log();\n", sdef->parameters.elements[i].dispname,
        sdef->parameters.elements[i].name);
    }
    src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
  } else {
    src = mputstr(src, "TTCN_Logger::log_event_str(\"{ }\");\n");
  }
  src = mputstr(src, "}\n\n");

  /* log_match_call function */
  def = mputprintf(def, "void log_match_call(const %s_call& match_value) "
    "const;\n", name);
  src = mputprintf(src, "void %s_template::log_match_call(const %s_call& "
    , name, name);
  if (num_in > 0) {
    boolean first_param = TRUE;
    src = mputstr(src, "match_value) const\n{\n");
    for (i = 0; i < sdef->parameters.nElements; i++) {
      if (sdef->parameters.elements[i].direction != PAR_OUT) {
        src = mputstr(src, "TTCN_Logger::log_event_str(\"");
        if (first_param) {
          src = mputc(src, '{');
          first_param = FALSE;
        } else src = mputc(src, ',');
        src = mputprintf(src, " %s := \");\n"
          "param_%s.log_match(match_value.%s());\n",
          sdef->parameters.elements[i].dispname,
          sdef->parameters.elements[i].name,
          sdef->parameters.elements[i].name);
      }
    }
    src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
  } else {
    src = mputstr(src, ") const\n{\n"
      "TTCN_Logger::log_event_str(\"{ } with { } matched\");\n");
  }
  src = mputstr(src, "}\n\n");

  if (!sdef->is_noblock) {
    /* log_match_reply function */
    def = mputprintf(def, "void log_match_reply(const %s_reply& match_value) "
      "const;\n", name);
    src = mputprintf(src, "void %s_template::log_match_reply(const %s_reply& "
      , name, name);
    if (num_out > 0) {
      boolean first_param = TRUE;
      src = mputstr(src, "match_value) const\n{\n");
      for (i = 0; i < sdef->parameters.nElements; i++) {
        if (sdef->parameters.elements[i].direction != PAR_IN) {
          src = mputstr(src, "TTCN_Logger::log_event_str(\"");
          if (first_param) {
            src = mputc(src, '{');
            first_param = FALSE;
          } else src = mputc(src, ',');
          src = mputprintf(src, " %s := \");\n"
            "param_%s.log_match(match_value.%s());\n",
            sdef->parameters.elements[i].dispname,
            sdef->parameters.elements[i].name,
            sdef->parameters.elements[i].name);
        }
      }
      if (sdef->return_type != NULL) {
        src = mputstr(src, "TTCN_Logger::log_event_str(\" } value "
          "\");\n"
          "reply_value.log_match(match_value.return_value());\n");
      } else {
        src = mputstr(src, "TTCN_Logger::log_event_str(\" }\");\n");
      }
    } else {
      if (sdef->return_type != NULL) {
        src = mputstr(src, "match_value) const\n{\n"
          "TTCN_Logger::log_event_str(\"{ } with { } "
          "matched value \");\n"
          "reply_value.log_match(match_value.return_value());\n");
      } else {
        src = mputstr(src, ") const\n{\n"
          "TTCN_Logger::log_event_str(\"{ } with { } "
          "matched\");\n");
      }
    }
    src = mputstr(src, "}\n\n");
  }

  if (sdef->parameters.nElements > 0) {
    /* encode_text function */
    def = mputstr(def, "void encode_text(Text_Buf& text_buf) const;\n");
    src = mputprintf(src, "void %s_template::encode_text(Text_Buf& "
      "text_buf) const\n"
      "{\n", name);
    for (i = 0; i < sdef->parameters.nElements; i++) {
      src = mputprintf(src, "param_%s.encode_text(text_buf);\n",
        sdef->parameters.elements[i].name);
    }
    src = mputstr(src, "}\n\n");
    /* decode_text function */
    def = mputstr(def, "void decode_text(Text_Buf& text_buf);\n");
    src = mputprintf(src, "void %s_template::decode_text(Text_Buf& "
      "text_buf)\n"
      "{\n", name);
    for (i = 0; i < sdef->parameters.nElements; i++) {
      src = mputprintf(src, "param_%s.decode_text(text_buf);\n",
        sdef->parameters.elements[i].name);
    }
    src = mputstr(src, "}\n\n");
  } else {
    def = mputstr(def, "inline void encode_text(Text_Buf&) const "
      "{ }\n"
      "inline void decode_text(Text_Buf&) { }\n");
  }

  /* end of template definition */
  def = mputstr(def, "};\n\n");

  output->header.class_decls = mputstr(output->header.class_decls, decl);
  Free(decl);

  output->header.class_defs = mputstr(output->header.class_defs, def);
  Free(def);

  output->source.methods = mputstr(output->source.methods, src);
  Free(src);
}
コード例 #4
0
ファイル: functionref.c プロジェクト: enispes/titan.core
void defFunctionrefTemplate(const funcref_def *fdef, output_struct *output)
{
  char *def = NULL, *src = NULL;
  const char *name = fdef->name;
  const char *dispname = fdef->dispname;
  char *fat_string = NULL;

  switch(fdef->type) {
  case FUNCTION:
    fat_string = mputstr(fat_string, "function");
    break;
  case ALTSTEP:
    fat_string = mputstr(fat_string, "altstep");
    break;
  case TESTCASE:
    fat_string = mputstr(fat_string, "testcase");
    break;
  }

  /* class declaration */
    output->header.class_decls = mputprintf(output->header.class_decls,
      "class %s_template;\n", name);

  /* class definition */
  def = mputprintf(def,"class %s_template : public Base_Template {\n"
    "union {\n"
    "%s::function_pointer single_value;\n"
    "struct {\n"
    "unsigned int n_values;\n"
    "%s_template *list_value;\n"
    "} value_list;\n"
    "};\n\n", name, name, name);

  /* copy template */
  def = mputprintf(def,"  void copy_template(const %s_template& other_value);\n"
    , name);
  src = mputprintf(src,"void %s_template::copy_template(const %s_template& "
      "other_value)\n"
    "{\n"
    "switch(other_value.template_selection) {\n"
    "case SPECIFIC_VALUE:\n"
    "single_value = other_value.single_value;\n"
    "break;\n"
    "case OMIT_VALUE:\n"
    "case ANY_VALUE:\n"
    "case ANY_OR_OMIT:\n"
    "break;\n"
    "case VALUE_LIST:\n"
    "case COMPLEMENTED_LIST:\n"
    "value_list.n_values = other_value.value_list.n_values;\n"
    "value_list.list_value = new %s_template[value_list.n_values];\n"
    "for(unsigned int i = 0; i < value_list.n_values; i++)\n"
    "value_list.list_value[i] = other_value.value_list.list_value[i];\n"
    "break;\n"
    "default:\n"
    "TTCN_error(\"Copying an unitialized/unsupported %s template.\");\n"
    "}\n"
    "set_selection(other_value);\n"
    "}\n\n", name, name, name, dispname);

  /* constructors */
  def = mputprintf(def,"public:\n"
    "%s_template();\n", name);
  src = mputprintf(src,"%s_template::%s_template()\n"
    "{\n}\n\n", name, name);
  def = mputprintf(def,"%s_template(template_sel other_value);\n", name);
  src = mputprintf(src,"%s_template::%s_template(template_sel other_value)\n"
    "  : Base_Template(other_value)\n"
    "{\n"
    "check_single_selection(other_value);\n"
    "}\n\n", name, name);
  def = mputprintf(def,"%s_template(%s::function_pointer other_value);\n"
    , name, name);
  src = mputprintf(src,"%s_template::%s_template(%s::function_pointer "
      "other_value)\n"
    "  : Base_Template(SPECIFIC_VALUE)\n"
    "{\n"
    "single_value = other_value;\n"
    "}\n\n", name, name, name);
  def = mputprintf(def,"%s_template(const %s& other_value);\n", name, name);
  src = mputprintf(src,"%s_template::%s_template(const %s& other_value)\n"
    "  :Base_Template(SPECIFIC_VALUE)\n"
    "{\n"
    "other_value.must_bound(\"Creating a template from an unbound %s value."
      "\");\n"
    "single_value = other_value.referred_function;\n"
    "}\n\n", name, name, name, dispname);
  def = mputprintf(def,"%s_template(const OPTIONAL<%s>& other_value);\n"
    , name, name);
  src = mputprintf(src,"%s_template::%s_template(const OPTIONAL<%s>& "
      "other_value)\n"
    "{\n"
    "if(other_value.ispresent()) {\n"
    "set_selection(SPECIFIC_VALUE);\n"
    "single_value = ((const %s&)other_value()).referred_function;\n"
    "} else set_selection(OMIT_VALUE);\n"
    "}\n\n", name, name, name, name);
  def = mputprintf(def,"%s_template(const %s_template& other_value);\n"
    , name, name);
  src = mputprintf(src,"%s_template::%s_template(const %s_template& "
      "other_value)\n"
    "  :Base_Template()\n" /* yes, the default constructor */
    "{\n"
    "copy_template(other_value);\n"
    "}\n\n", name, name, name);

  /* destructor */
  def = mputprintf(def,"~%s_template();\n", name);
  src = mputprintf(src,"%s_template::~%s_template()\n"
    "{\n"
    "  clean_up();\n"
    "}\n\n", name, name);

  /* clean up */
  def = mputstr(def,"void clean_up();\n");
  src = mputprintf(src,"void %s_template::clean_up()"
    "{\n"
    "if(template_selection == VALUE_LIST ||\n"
    "template_selection == COMPLEMENTED_LIST)\n"
    "delete[] value_list.list_value;\n"
    "template_selection = UNINITIALIZED_TEMPLATE;\n"
    "}\n\n", name);

  /* operator = */
  def = mputprintf(def,"%s_template& operator=(template_sel other_value);\n"
    , name);
  src = mputprintf(src,"%s_template& %s_template::operator=(template_sel "
      "other_value)\n"
    "{\n"
    "check_single_selection(other_value);\n"
    "clean_up();\n"
    "set_selection(other_value);\n"
    "return *this;\n"
    "}\n\n", name, name);
  def = mputprintf(def,"%s_template& operator=(%s::function_pointer "
      "other_value);\n", name, name);
  src = mputprintf(src,"%s_template& %s_template::operator="
      "(%s::function_pointer other_value)\n"
    "{\n"
    "clean_up();\n"
    "set_selection(SPECIFIC_VALUE);\n"
    "single_value = other_value;\n"
    "return *this;"
    "}\n\n", name, name, name);
  def = mputprintf(def,"%s_template& operator=(const %s& other_value);\n"
    , name, name);
  src = mputprintf(src,"%s_template& %s_template::operator="
      "(const %s& other_value)\n"
    "{\n"
    "other_value.must_bound(\"Assignment of an unbound %s value to a "
      "template.\");\n"
    "clean_up();\n"
    "set_selection(SPECIFIC_VALUE);\n"
    "single_value = other_value.referred_function;\n"
    "return *this;\n"
    "}\n\n", name, name, name, dispname);
  def = mputprintf(def,"%s_template& operator=(const OPTIONAL<%s>& "
      "other_value);\n", name, name);
  src = mputprintf(src,"%s_template& %s_template::operator=(const "
      "OPTIONAL<%s>& other_value)\n"
    "{\n"
    "clean_up();\n"
    "if(other_value.ispresent()) { \n"
    "set_selection(SPECIFIC_VALUE);\n"
    "single_value = ((const %s&)other_value()).referred_function;\n"
    "} else set_selection(OMIT_VALUE);\n"
    "return *this;"
    "}\n\n", name, name, name, name);
  def = mputprintf(def,"%s_template& operator=(const %s_template& "
      "other_value);\n", name, name);
  src = mputprintf(src,"%s_template& %s_template::operator=(const %s_template& "
      "other_value)\n"
    "{\n"
    "if(&other_value != this) {\n"
    "clean_up();"
    "copy_template(other_value);\n"
    "}\n"
    "return *this;\n"
    "}\n\n", name ,name, name);

  /* match functions */
  def = mputprintf(def,"boolean match(%s::function_pointer "
      "other_value) const;\n", name);
  src = mputprintf(src,"boolean %s_template::match(%s::function_pointer "
      "other_value) const\n"
    "{\n"
    "switch(template_selection) {\n"
    "case SPECIFIC_VALUE:\n"
    "return single_value == other_value;\n"
    "case OMIT_VALUE:\n"
    "return FALSE;\n"
    "case ANY_VALUE:\n"
    "case ANY_OR_OMIT:\n"
    "return TRUE;\n"
    "case VALUE_LIST:\n"
    "case COMPLEMENTED_LIST:\n"
    "for(unsigned int i = 0; i < value_list.n_values; i++)\n"
    "if(value_list.list_value[i].match(other_value))\n"
    "return template_selection == VALUE_LIST;\n"
    "return template_selection == COMPLEMENTED_LIST;\n"
    "default:\n"
    "TTCN_error(\"Matching with an unitialized/unsupported %s template."
      "\");\n"
    "};\n"
    "return FALSE;\n"
    "}\n\n", name, name, dispname);
  def = mputprintf(def,"boolean match(const %s& other_value) const;\n", name);
  src = mputprintf(src,"boolean %s_template::match(const %s& other_value) "
      "const\n"
    "{\n"
	"  if (!other_value.is_bound()) return FALSE;\n"
    "return match(other_value.referred_function);\n"
    "}\n\n", name, name);

  /* value of function */
  def = mputprintf(def,"%s valueof() const;\n", name);
  src = mputprintf(src,"%s %s_template::valueof() const\n"
    "{\n"
    "if(template_selection != SPECIFIC_VALUE || is_ifpresent)\n"
    "TTCN_error(\"Performing a valueof or send operation on a "
      "non-specific %s template.\");\n"
    "return single_value;\n}\n\n", name, name, dispname);

  /* set type */
  def = mputstr(def,"void set_type(template_sel template_type, "
      "unsigned int list_length);\n");
  src = mputprintf(src,"void %s_template::set_type(template_sel template_type, "
      "unsigned int list_length)\n"
    "{\n"
    "if(template_type != VALUE_LIST && "
    "template_type != COMPLEMENTED_LIST)\n"
    "TTCN_error(\"Setting an invalid type for an %s template.\");\n"
    "clean_up();\n"
    "set_selection(template_type);\n"
    "value_list.n_values = list_length;\n"
    "value_list.list_value = new %s_template[list_length];\n"
    "}\n\n", name, dispname, name);

  /* list item */
  def = mputprintf(def,"%s_template& list_item(unsigned int list_index) "
      "const;\n", name);
  src = mputprintf(src,"%s_template& %s_template::list_item("
      "unsigned int list_index) const\n"
    "{\n"
    "if(template_selection != VALUE_LIST && "
    "template_selection != COMPLEMENTED_LIST)\n"
    "TTCN_error(\"Accessing a list element of a non-list template of "
      "type %s\");\n"
    "if(list_index >= value_list.n_values)\n"
    "TTCN_error(\"Index overflow in a value list template of type %s."
      "\");\n"
    "return value_list.list_value[list_index];\n"
    "}\n\n", name, name, dispname, dispname);

  if (use_runtime_2) {
    /* functions in alternative runtime */
    def = mputstr(def,
      "void valueofv(Base_Type* value) const;\n"
      "void set_value(template_sel other_value);\n"
      "void copy_value(const Base_Type* other_value);\n"
      "Base_Template* clone() const;\n"
      "const TTCN_Typedescriptor_t* get_descriptor() const;\n"
      "boolean matchv(const Base_Type* other_value) const;\n"
      "void log_matchv(const Base_Type* match_value) const;\n");
    src = mputprintf(src,
      "void %s_template::valueofv(Base_Type* value) const "
        "{ *(static_cast<%s*>(value)) = valueof(); }\n"
      "void %s_template::set_value(template_sel other_value) "
        "{ *this = other_value; }\n"
      "void %s_template::copy_value(const Base_Type* other_value) "
        "{ *this = *(static_cast<const %s*>(other_value)); }\n"
      "Base_Template* %s_template::clone() const "
        "{ return new %s_template(*this); }\n"
      "const TTCN_Typedescriptor_t* %s_template::get_descriptor() const "
        "{ return &%s_descr_; }\n"
      "boolean %s_template::matchv(const Base_Type* other_value) const "
        "{ return match(*(static_cast<const %s*>(other_value))); }\n"
      "void %s_template::log_matchv(const Base_Type* match_value) const "
        " { log_match(*(static_cast<const %s*>(match_value))); }\n",
      name, name,
      name,
      name, name,
      name, name,
      name, name,
      name, name,
      name, name);
  }

  /* log function */
  def = mputstr(def,"void log() const;\n");
  src = mputprintf(src,"void %s_template::log() const\n"
    "{\n"
    "switch(template_selection) {\n"
    "case SPECIFIC_VALUE:\n"
    "Module_List::log_%s((genericfunc_t)single_value);\n"
    "break;\n"
    "case COMPLEMENTED_LIST:\n"
    "TTCN_Logger::log_event_str(\"complement \");\n"
    "case VALUE_LIST:\n"
    "TTCN_Logger::log_char('(');\n"
    "for(unsigned int i = 0; i < value_list.n_values; i++) {\n"
    "if(i > 0) TTCN_Logger::log_event_str(\", \");\n"
    "value_list.list_value[i].log();\n"
    "}\n"
    "TTCN_Logger::log_char(')');\n"
    "break;\n"
    "default:\n"
    "log_generic();\n"
    "}\n"
    "log_ifpresent();\n"
    "}\n\n", name, fat_string);

  /* log_match function */
  def = mputprintf(def,"void log_match(const %s& match_value) const;\n", name);
  src = mputprintf(src,"void %s_template::log_match(const %s& match_value) "
      "const\n"
    "{\n"
    "log();\n"
    "TTCN_Logger::log_event_str(\" with \");\n"
    "match_value.log();\n"
    "if(match(match_value)) TTCN_Logger::log_event_str(\" matched\");\n"
    "else TTCN_Logger::log_event_str(\" unmatched\");\n"
    "}\n\n", name, name);

  /* encode_text / decode_text */
  def = mputstr(def,"void encode_text(Text_Buf& text_buf) const;\n");
  src = mputprintf(src,"void %s_template::encode_text(Text_Buf&", name);
  if (fdef->runs_on_self) {
    src = mputprintf(src, ") const\n"
      "{\n"
      "TTCN_error(\"Templates of type %s cannot be sent to "
      "other test components.\");\n", dispname);
  } else {
    src = mputprintf(src, " text_buf) const\n"
      "{\n"
      "encode_text_base(text_buf);\n"
      "switch(template_selection) {\n"
      "case OMIT_VALUE:\n"
      "case ANY_VALUE:\n"
      "case ANY_OR_OMIT:\n"
      "break;\n"
      "case SPECIFIC_VALUE:\n"
      "Module_List::encode_%s(text_buf, (genericfunc_t)single_value);\n"
      "break;\n"
      "case VALUE_LIST:\n"
      "case COMPLEMENTED_LIST:\n"
      "text_buf.push_int(value_list.n_values);\n"
      "for(unsigned int i = 0; i < value_list.n_values; i++)\n"
      "value_list.list_value[i].encode_text(text_buf);\n"
      "break;\n"
      "default:\n"
      "TTCN_error(\"Text encoder: Encoding an uninitialized/unsupported template "
        "of type %s.\");\n"
      "}\n", fat_string, dispname);
  }
  src = mputstr(src,"}\n\n");
  def = mputstr(def,"void decode_text(Text_Buf& text_buf);\n");
  src = mputprintf(src,"void %s_template::decode_text(Text_Buf&", name);
  if (fdef->runs_on_self) {
    src = mputprintf(src, ")\n"
      "{\n"
      "TTCN_error(\"Templates of type %s cannot be received "
      "from other test components.\");\n", dispname);
  } else {
    src = mputprintf(src, " text_buf)\n"
      "{\n"
      "clean_up();\n"
      "decode_text_base(text_buf);\n"
      "switch(template_selection) {\n"
      "case OMIT_VALUE:\n"
      "case ANY_VALUE:\n"
      "case ANY_OR_OMIT:\n"
      "break;\n"
      "case SPECIFIC_VALUE:\n"
      "Module_List::decode_%s(text_buf,(genericfunc_t*)&single_value);\n"
      "break;\n"
      "case VALUE_LIST:\n"
      "case COMPLEMENTED_LIST:\n"
      "value_list.n_values = text_buf.pull_int().get_val();\n"
      "value_list.list_value = new %s_template[value_list.n_values];\n"
      "for(unsigned int i = 0; i < value_list.n_values; i++)\n"
      "value_list.list_value[i].decode_text(text_buf);\n"
      "default:\n"
      "TTCN_error(\"Text decoder: An unknown/unsupported selection was received "
        "in a template of type %s.\");\n"
      "}\n", fat_string, name, dispname);
  }
  src = mputstr(src,"}\n\n");

  /* TTCN-3 ispresent() function */
  def = mputstr(def, "boolean is_present() const;\n");
  src = mputprintf(src,
    "boolean %s_template::is_present() const\n"
    "{\n"
    "if (template_selection==UNINITIALIZED_TEMPLATE) return FALSE;\n"
    "return !match_omit();\n"
    "}\n\n", name);

  /* match_omit() */
  def = mputstr(def, "boolean match_omit() const;\n");
  src = mputprintf(src,
    "boolean %s_template::match_omit() const\n"
    "{\n"
    "if (is_ifpresent) return TRUE;\n"
    "switch (template_selection) {\n"
    "case OMIT_VALUE:\n"
    "case ANY_OR_OMIT:\n"
    "return TRUE;\n"
    "case VALUE_LIST:\n"
    "case COMPLEMENTED_LIST:\n"
    "for (unsigned int i=0; i<value_list.n_values; i++)\n"
    "if (value_list.list_value[i].match_omit())\n"
    "return template_selection==VALUE_LIST;\n"
    "return template_selection==COMPLEMENTED_LIST;\n"
    "default:\n"
    "return FALSE;\n"
    "}\n"
    "return FALSE;\n"
    "}\n\n", name);

  /* set_param */
  def = mputstr(def,"void set_param(Module_Param& param);\n");
  src = mputprintf(src,"void %s_template::set_param(Module_Param& param)\n"
    "{\n"
    "  param.error(\"Not supported.\");\n"
    "}\n\n", name);

  if (!use_runtime_2) {
    /* check template restriction */
    def = mputstr(def, "void check_restriction(template_res t_res, "
      "const char* t_name=NULL) const;\n");
    src = mputprintf(src,
      "void %s_template::check_restriction"
        "(template_res t_res, const char* t_name) const\n"
      "{\n"
      "if (template_selection==UNINITIALIZED_TEMPLATE) return;\n"
      "switch ((t_name&&(t_res==TR_VALUE))?TR_OMIT:t_res) {\n"
      "case TR_VALUE:\n"
      "if (!is_ifpresent && template_selection==SPECIFIC_VALUE) return;\n"
      "break;\n"
      "case TR_OMIT:\n"
      "if (!is_ifpresent && (template_selection==OMIT_VALUE || "
        "template_selection==SPECIFIC_VALUE)) return;\n"
      "break;\n"
      "case TR_PRESENT:\n"
      "if (!match_omit()) return;\n"
      "break;\n"
      "default:\n"
      "return;\n"
      "}\n"
      "TTCN_error(\"Restriction `%%s' on template of type %%s violated.\", "
        "get_res_name(t_res), t_name ? t_name : \"%s\");\n"
      "}\n\n", name, dispname);
  }

  def = mputstr(def,"};\n\n");

  Free(fat_string);

  output->header.class_defs = mputstr(output->header.class_defs, def);
  Free(def);

  output->source.methods = mputstr(output->source.methods, src);
  Free(src);
}
コード例 #5
0
ファイル: functionref.c プロジェクト: enispes/titan.core
void defFunctionrefClass(const funcref_def *fdef, output_struct *output)
{
  char *def = NULL, *src = NULL;
  const char *name = fdef->name;
  const char *dispname = fdef->dispname;

  const char *return_type, *fat_string;

  if (fdef->return_type != NULL) return_type = fdef->return_type;
  else return_type = "void";

  switch (fdef->type) {
  case FUNCTION:
    fat_string = "function";
    break;
  case ALTSTEP:
    fat_string = "altstep";
    break;
  case TESTCASE:
    fat_string = "testcase";
    break;
  default:
    fat_string = NULL;
    FATAL_ERROR("defFunctionrefClass(): invalid type");
  }

  /* class declaration code */
  output->header.class_decls = mputprintf(output->header.class_decls,
    "class %s;\n", name);

  /* class definition */
  def = mputprintf(def,
#ifndef NDEBUG
    "// written by %s in " __FILE__ " at %d\n"
#endif
    "class %s : public Base_Type {\n"
    "public:\n"
#ifndef NDEBUG
      , __FUNCTION__, __LINE__
#endif
    , name);

  switch(fdef->type){
  case FUNCTION:
    def = mputstr(def, "typedef ");
    /* work-around for GCC versions earlier than 3.4:
     * parse error occurs within the typedef if the return type is the same
     * as the function type itself */
    if (!strcmp(name, return_type)) def = mputstr(def, "class ");
    def = mputprintf(def, "%s (*function_pointer)(%s);\n"
      "typedef void (*start_pointer)(const COMPONENT& "
	"component_reference", return_type, fdef->formal_par_list);
    if (fdef->formal_par_list[0] != '\0') def = mputstr(def, ", ");
    def = mputprintf(def, "%s);\n", fdef->formal_par_list);
    break;
  case ALTSTEP:
    def = mputprintf(def, "typedef void (*standalone_pointer)(%s);\n"
      "typedef Default_Base* (*activate_pointer)(%s);\n"
      "typedef alt_status (*function_pointer)(%s);\n", fdef->formal_par_list,
      fdef->formal_par_list, fdef->formal_par_list);
    break;
  case TESTCASE:
    def = mputprintf(def, "typedef verdicttype (*function_pointer)(%s);\n",
      fdef->formal_par_list);
    break;
  }

  def = mputprintf(def,
    "private:\n"
    "friend class %s_template;\n"
    "friend boolean operator==(%s::function_pointer value, "
      "const %s& other_value);\n"
    "function_pointer referred_function;\n"
    , name, name, name);

  /* default constructor */
  def = mputprintf(def,"public:\n"
    "%s();\n", name);
  src = mputprintf(src,"%s::%s()\n"
    "{\n"
    "referred_function = NULL;\n"
    "}\n\n", name, name);

    def = mputprintf(def,"%s(function_pointer other_value);\n", name);
    src = mputprintf(src,"%s::%s(function_pointer other_value)\n"
      "{\n"
      "referred_function = other_value;\n"
      "}\n\n", name, name);

  /* copy constructor */
  def = mputprintf(def,"%s(const %s& other_value);\n", name, name);
  src = mputprintf(src,"%s::%s(const %s& other_value)\n"
    ": Base_Type()" /* call the *default* constructor as before */
    "{\n"
    "other_value.must_bound(\"Copying an unbound %s value.\");\n"
    "referred_function = other_value.referred_function;\n"
    "}\n\n", name, name, name, dispname);

  /* operator= */
  def =mputprintf(def,"%s& operator=(function_pointer other_value);\n", name);
  src =mputprintf(src,"%s& %s::operator=(function_pointer other_value)\n"
    "{\n"
    "referred_function = other_value;\n"
    "return *this;\n"
    "}\n\n", name, name);

  def = mputprintf(def,"%s& operator=(const %s& other_value);\n",
    name, name);
  src = mputprintf(src,"%s& %s::operator=(const %s& other_value)\n"
    "{\n"
    "other_value.must_bound(\"Assignment of an unbound value.\");\n"
    "referred_function = other_value.referred_function;\n"
    "return *this;\n"
    "}\n\n", name, name, name);

  /* operator ==*/
  def = mputstr(def,"boolean operator==(function_pointer other_value) "
      "const;\n");
  src = mputprintf(src,"boolean %s::operator==(function_pointer other_value) "
      "const\n"
    "{\n"
    "must_bound(\"Unbound left operand of %s comparison.\");\n"
    "return referred_function == other_value;\n"
    "}\n\n", name, dispname);
  def = mputprintf(def,"boolean operator==(const %s& other_value) const;\n"
    , name);
  src = mputprintf(src,"boolean %s::operator==(const %s& other_value) const\n"
    "{\n"
    "must_bound(\"Unbound left operand of %s comparison.\");\n"
    "other_value.must_bound(\"Unbound right operand of %s comparison.\");\n"
    "return referred_function == other_value.referred_function;\n"
    "}\n\n", name, name, dispname, dispname);

  /* operator != */
  def = mputprintf(def,"inline boolean operator!=(function_pointer other_value)"
      " const\n"
    "{ return !(*this == other_value); }\n"
    "inline boolean operator!=(const %s& other_value) const\n"
    "{ return !(*this == other_value); }\n\n", name);

  switch(fdef->type) {
  case FUNCTION:
    def = mputprintf(def,"%s invoke(%s) const;\n"
      , return_type, fdef->formal_par_list);
    src = mputprintf(src,"%s %s::invoke(%s) const\n"
      "{\n"
      "must_bound(\"Call of unbound function.\");\n"
      "if(referred_function == "
        "(%s::function_pointer)Module_List::get_fat_null())\n"
      "TTCN_error(\"null reference cannot be invoked.\");\n"
      "%sreferred_function(%s);\n"
      "}\n\n", return_type, name, fdef->formal_par_list, name
        , fdef->return_type!= NULL? "return ": "", fdef->actual_par_list);
    if(fdef->is_startable) {
      def = mputprintf(def,"void start(const COMPONENT& component_reference%s"
          "%s) const;\n", strcmp(fdef->formal_par_list,"")?", ":""
        , fdef->formal_par_list);
      src = mputprintf(src,"void %s::start(const COMPONENT& "
          "component_reference%s%s) const\n{\n"
        "((%s::start_pointer)Module_List::lookup_start_by_function_address"
          "((genericfunc_t)referred_function))(component_reference%s%s);\n"
        "}\n\n", name, strcmp(fdef->formal_par_list,"")?", ":""
        , fdef->formal_par_list, name, strcmp(fdef->formal_par_list,"")?", ":""
        , fdef->actual_par_list);
    }
    break;
  case ALTSTEP:
    def = mputprintf(def,"void invoke_standalone(%s) const;\n",
      fdef->formal_par_list);
    src = mputprintf(src,"void %s::invoke_standalone(%s) const\n"
      "{\n"
      "((%s::standalone_pointer)"
        "Module_List::lookup_standalone_address_by_altstep_address("
        "(genericfunc_t)referred_function))(%s);\n"
      "}\n\n", name, fdef->formal_par_list, name, fdef->actual_par_list);

    def = mputprintf(def,"Default_Base *activate(%s) const;\n"
      , fdef->formal_par_list);
    src = mputprintf(src,"Default_Base *%s::activate(%s) const\n"
    "{\n"
    "return ((%s::activate_pointer)"
        "Module_List::lookup_activate_address_by_altstep_address("
        "(genericfunc_t)referred_function))(%s);\n"
    "}\n\n", name, fdef->formal_par_list, name, fdef->actual_par_list);

    def = mputprintf(def,"alt_status invoke(%s) const;\n"
      , fdef->formal_par_list);
    src = mputprintf(src,"alt_status %s::invoke(%s) const\n"
      "{\n"
      "must_bound(\"Call of an unbound altstep.\");\n"
      "if(referred_function == "
        "(%s::function_pointer)Module_List::get_fat_null())\n"
      "TTCN_error(\"null reference cannot be invoked.\");\n"
      "return referred_function(%s);\n"
      "}\n", name, fdef->formal_par_list, name, fdef->actual_par_list);

    break;
  case TESTCASE:
    def = mputprintf(def,"verdicttype execute(%s) const;\n",
      fdef->formal_par_list);
    src = mputprintf(src,"verdicttype %s::execute(%s) const\n"
      "{\n"
      "must_bound(\"Call of unbound testcase.\");\n"
      "if(referred_function == "
        "(%s::function_pointer)Module_List::get_fat_null())\n"
      "TTCN_error(\"null reference cannot be executed.\");\n"
      "return referred_function(%s);\n"
      "}\n\n", name, fdef->formal_par_list, name, fdef->actual_par_list);
    break;
  }

  /* bound check */
  def = mputstr(def,"inline boolean is_bound() "
    "const { return referred_function != NULL; }\n");
  /* value check */
  def = mputstr(def,"inline boolean is_value() "
    "const { return referred_function != NULL; }\n");
  def = mputstr(def,"inline void clean_up() "
    "{ referred_function = NULL; }\n");
  def = mputstr(def,"inline void must_bound(const char *err_msg) const\n"
    "{ if (referred_function == NULL) TTCN_error(\"%s\", err_msg); }\n\n");




  if (use_runtime_2) {
    /* functions in alternative runtime */
    def = mputstr(def,
      "boolean is_equal(const Base_Type* other_value) const;\n"
      "void set_value(const Base_Type* other_value);\n"
      "Base_Type* clone() const;\n"
      "const TTCN_Typedescriptor_t* get_descriptor() const;\n");
    src = mputprintf(src,
      "boolean %s::is_equal(const Base_Type* other_value) const "
        "{ return *this == *(static_cast<const %s*>(other_value)); }\n"
      "void %s::set_value(const Base_Type* other_value) "
        "{ *this = *(static_cast<const %s*>(other_value)); }\n"
      "Base_Type* %s::clone() const { return new %s(*this); }\n"
      "const TTCN_Typedescriptor_t* %s::get_descriptor() const "
        "{ return &%s_descr_; }\n",
      name, name,
      name, name,
      name, name,
      name, name);
  } else {
    def = mputstr(def,
      "inline boolean is_present() const { return is_bound(); }\n");
  }

  /* log */
  def = mputstr(def,"void log() const;\n");
  src = mputprintf(src,"void %s::log() const\n"
    "{\n"
    "Module_List::log_%s((genericfunc_t)referred_function);\n"
    "}\n\n",name, fat_string);

  /* set_param */
  def = mputstr(def,"void set_param(Module_Param& param);\n");
  src = mputprintf(src,"void %s::set_param(Module_Param& param)\n"
    "{\n"
    "  param.error(\"Not supported.\");\n"
    "}\n\n", name);

  /* encode_text / decode_text */
  def = mputstr(def,"void encode_text(Text_Buf& text_buf) const;\n");
  src = mputprintf(src,"void %s::encode_text(Text_Buf&", name);
  if (fdef->runs_on_self) {
    src = mputprintf(src, ") const\n"
      "{\n"
      "TTCN_error(\"Values of type %s cannot be sent to "
      "other test components.\");\n", dispname);
  } else {
    src = mputprintf(src, " text_buf) const\n"
      "{\n"
      "Module_List::encode_%s(text_buf,"
      "(genericfunc_t)referred_function);\n", fat_string);
  }
  src = mputstr(src,"}\n\n");
  def = mputstr(def,"void decode_text(Text_Buf& text_buf);\n");
  src = mputprintf(src,"void %s::decode_text(Text_Buf&", name);
  if (fdef->runs_on_self) {
    src = mputprintf(src, ")\n"
      "{\n"
      "TTCN_error(\"Values of type %s cannot be received "
      "from other test components.\");\n", dispname);
  } else {
    src = mputprintf(src, " text_buf)\n"
      "{\n"
      "Module_List::decode_%s(text_buf,"
      "(genericfunc_t*)&referred_function);\n", fat_string);
  }
  src = mputstr(src,"}\n\n");
  def = mputstr(def, "};\n\n");

  def = mputprintf(def,"extern boolean operator==(%s::function_pointer value,"
      " const %s& other_value);\n", name, name);
  src = mputprintf(src,"boolean operator==(%s::function_pointer value, "
      "const %s& other_value)\n"
    "{\n"
    "other_value.must_bound(\"Unbound right operand of %s comparison.\");\n"
    "return value == other_value.referred_function;\n"
    "}\n\n", name, name, dispname);
  def = mputprintf(def,"inline boolean operator!=(%s::function_pointer value,"
      " const %s& other_value)\n"
    "{ return !(value == other_value); } \n\n", name, name);

  output->header.class_defs = mputstr(output->header.class_defs, def);
  Free(def);

  output->source.methods = mputstr(output->source.methods, src);
  Free(src);
}
コード例 #6
0
ファイル: encdec.c プロジェクト: BotondBaranyi/titan.core
void def_encdec(const char *p_classname,
                char **p_classdef, char **p_classsrc,
                boolean ber, boolean raw, boolean text, boolean xer,
                boolean json, boolean is_leaf)
{
  char *def=NULL;
  char *src=NULL;

  def=mputstr
    (def,
     "void encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&,"
     " TTCN_EncDec::coding_t, ...) const;\n"
     "void decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&,"
     " TTCN_EncDec::coding_t, ...);\n");
  if(ber)
    def=mputstr(def,
     "ASN_BER_TLV_t* BER_encode_TLV(const TTCN_Typedescriptor_t& p_td,"
     " unsigned p_coding) const;\n"
     "boolean BER_decode_TLV(const TTCN_Typedescriptor_t& p_td, const"
     " ASN_BER_TLV_t& p_tlv, unsigned L_form);\n"
     );
  if(raw)
    def=mputprintf(def,
     "int RAW_encode(const TTCN_Typedescriptor_t&, RAW_enc_tree&) const;\n"
     "int RAW_decode(const TTCN_Typedescriptor_t&, TTCN_Buffer&,"
     " int, raw_order_t, boolean no_err=FALSE,"
     "int sel_field=-1, boolean first_call=TRUE);\n"
     );
  if(text)
    def=mputprintf(def,
     "int TEXT_encode(const TTCN_Typedescriptor_t&, TTCN_Buffer&) const;\n"
     "int TEXT_decode(const TTCN_Typedescriptor_t&,"
     "TTCN_Buffer&, Limit_Token_List&, boolean no_err=FALSE,"
     "boolean first_call=TRUE);\n"
     );
  if (xer) /* XERSTUFF encdec function headers */
    def=mputprintf(def,
#ifndef NDEBUG
      "// written by %s in " __FILE__ " at %d\n"
#endif
      "int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int,"
      "unsigned int, int, embed_values_enc_struct_t*) const;\n"
      "int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, "
      "unsigned int, embed_values_dec_struct_t*);\n"
      "static boolean can_start(const char *name, const char *uri, "
      "XERdescriptor_t const& xd, unsigned int, unsigned int);\n"
      "%s"
#ifndef NDEBUG
      , __FUNCTION__, __LINE__
#endif
      , use_runtime_2 ?
        "boolean can_start_v(const char *name, const char *uri, "
        "XERdescriptor_t const& xd, unsigned int, unsigned int);\n" : ""
    );
  if(json) {
    def = mputprintf(def,
      "int JSON_encode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&) const;\n"
      "int JSON_decode(const TTCN_Typedescriptor_t&, JSON_Tokenizer&, boolean);\n");
  }

  src=mputprintf(src,
     "void %s::encode(const TTCN_Typedescriptor_t& p_td,"
     " TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...) const\n"
     "{\n"
     "  va_list pvar;\n"
     "  va_start(pvar, p_coding);\n"
     "  switch(p_coding) {\n"
     "  case TTCN_EncDec::CT_BER: {\n"
     "    TTCN_EncDec_ErrorContext ec(\"While BER-encoding type"
     " '%%s': \", p_td.name);\n"
     "    unsigned BER_coding=va_arg(pvar, unsigned);\n"
     "    BER_encode_chk_coding(BER_coding);\n"
     "    ASN_BER_TLV_t *tlv=BER_encode_TLV(p_td, BER_coding);\n"
     "    tlv->put_in_buffer(p_buf);\n"
     "    ASN_BER_TLV_t::destruct(tlv);\n"
     "    break;}\n"
     "  case TTCN_EncDec::CT_RAW: {\n"
     "    TTCN_EncDec_ErrorContext ec(\"While RAW-encoding type"
     " '%%s': \", p_td.name);\n"
     "    if(!p_td.raw)\n"
     "      TTCN_EncDec_ErrorContext::error_internal\n"
     "        (\"No RAW descriptor available for type '%%s'.\", p_td.name);\n"
     "    RAW_enc_tr_pos rp;\n"
     "    rp.level=0;\n"
     "    rp.pos=NULL;\n"
     "    RAW_enc_tree root(%s, NULL, &rp, 1, p_td.raw);\n"
     "    RAW_encode(p_td, root);\n"
     "    root.put_to_buf(p_buf);\n"
     "    break;}\n"
     "  case TTCN_EncDec::CT_TEXT: {\n"
     "    TTCN_EncDec_ErrorContext ec("
     "\"While TEXT-encoding type '%%s': \", p_td.name);\n"
     "    if(!p_td.text)\n"
     "      TTCN_EncDec_ErrorContext::error_internal\n"
     "      (\"No TEXT descriptor available for type '%%s'.\", p_td.name);\n"
     "    TEXT_encode(p_td,p_buf);\n"
     "    break;}\n"
     /* XERSTUFF encoder */
     "  case TTCN_EncDec::CT_XER: {\n"
     "    TTCN_EncDec_ErrorContext ec("
     "\"While XER-encoding type '%%s': \", p_td.name);\n"
     "    unsigned XER_coding=va_arg(pvar, unsigned);\n"
     "    XER_encode_chk_coding(XER_coding, p_td);\n"
      /* Do not use %s_xer_ here. It supplies the XER descriptor of oldtype
       * even if encoding newtype for:
       * <ttcn>type newtype oldtype;</ttcn> */
     "    XER_encode(*(p_td.xer),p_buf, XER_coding, 0, 0, 0);\n"
     "    p_buf.put_c('\\n');\n" /* make sure it has a newline */
     "    break;}\n"
     "  case TTCN_EncDec::CT_JSON: {\n"
     "    TTCN_EncDec_ErrorContext ec("
     "\"While JSON-encoding type '%%s': \", p_td.name);\n"
     "    if(!p_td.json)\n"
     "      TTCN_EncDec_ErrorContext::error_internal\n"
     "        (\"No JSON descriptor available for type '%%s'.\", p_td.name);\n"
     "    JSON_Tokenizer tok(va_arg(pvar, int) != 0);\n"
     "    JSON_encode(p_td, tok);\n"
     "    p_buf.put_s(tok.get_buffer_length(), (const unsigned char*)tok.get_buffer());\n"
     "    break;}\n"
     "  default:\n"
     "    TTCN_error(\"Unknown coding method requested to encode"
     " type '%%s'\", p_td.name);\n"
     "  }\n"
     "  va_end(pvar);\n"
     "}\n"
     "\n"
    , p_classname, is_leaf?"TRUE":"FALSE"
    );

  src=mputprintf(src,
#ifndef NDEBUG
     "// written by %s in " __FILE__ " at %d\n"
#endif
     "void %s::decode(const TTCN_Typedescriptor_t& p_td,"
     " TTCN_Buffer& p_buf, TTCN_EncDec::coding_t p_coding, ...)\n"
     "{\n"
     "  va_list pvar;\n"
     "  va_start(pvar, p_coding);\n"
     "  switch(p_coding) {\n"
     "  case TTCN_EncDec::CT_BER: {\n"
     "    TTCN_EncDec_ErrorContext ec(\"While BER-decoding type"
     " '%%s': \", p_td.name);\n"
     "    unsigned L_form=va_arg(pvar, unsigned);\n"
     "    ASN_BER_TLV_t tlv;\n"
     "    BER_decode_str2TLV(p_buf, tlv, L_form);\n"
     "    BER_decode_TLV(p_td, tlv, L_form);\n"
     "    if(tlv.isComplete) p_buf.increase_pos(tlv.get_len());\n"
     "    break;}\n"
     "  case TTCN_EncDec::CT_RAW: {\n"
     "    TTCN_EncDec_ErrorContext ec(\"While RAW-decoding"
     " type '%%s': \", p_td.name);\n"
     "    if(!p_td.raw)\n"
     "      TTCN_EncDec_ErrorContext::error_internal\n"
     "        (\"No RAW descriptor available for type '%%s'.\", p_td.name);\n"
     "    raw_order_t r_order;\n"
     "    switch(p_td.raw->top_bit_order) {\n"
     "    case TOP_BIT_LEFT:\n"
     "      r_order=ORDER_LSB;\n"
     "      break;\n"
     "    case TOP_BIT_RIGHT:\n"
     "    default:\n"
     "      r_order=ORDER_MSB;\n"
     "    }\n"
     "    int rawr = RAW_decode(p_td, p_buf, p_buf.get_len()*8, r_order);\n"
     "    if(rawr<0) switch (-rawr) {\n"
     "    case TTCN_EncDec::ET_INCOMPL_MSG:\n"
     "    case TTCN_EncDec::ET_LEN_ERR:\n"
     "      ec.error((TTCN_EncDec::error_type_t)-rawr, "
     "\"Can not decode type '%%s', because incomplete message was received\", "
     "p_td.name);\n"
     "      break;\n"
     "    case 1:\n" /* from the generic -1 return value */
     "    default:\n"
     "      ec.error(TTCN_EncDec::ET_INVAL_MSG, "
     "\"Can not decode type '%%s', because invalid "
     "message was received\", p_td.name);\n"
     "      break;\n"
     "    }\n"
     "    break;}\n"
     "  case TTCN_EncDec::CT_TEXT: {\n"
     "    Limit_Token_List limit;\n"
     "    TTCN_EncDec_ErrorContext ec(\"While TEXT-decoding type '%%s': \","
     " p_td.name);\n"
     "    if(!p_td.text)\n"
     "      TTCN_EncDec_ErrorContext::error_internal\n"
     "        (\"No TEXT descriptor available for type '%%s'.\", p_td.name);\n"
     "    const unsigned char *b_data=p_buf.get_data();\n"
     "    if(b_data[p_buf.get_len()-1]!='\\0'){\n"
     "      p_buf.set_pos(p_buf.get_len());\n"
     "      p_buf.put_zero(8,ORDER_LSB);\n"
     "      p_buf.rewind();\n"
     "    }\n"
     "    if(TEXT_decode(p_td,p_buf,limit)<0)\n"
     "      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"
     "\"Can not decode type '%%s', because invalid or incomplete"
     " message was received\", p_td.name);\n"
     "    break;}\n"
     /* XERSTUFF decoder */
     "  case TTCN_EncDec::CT_XER: {\n"
     "    TTCN_EncDec_ErrorContext ec("
     "\"While XER-decoding type '%%s': \", p_td.name);\n"
     "    unsigned XER_coding=va_arg(pvar, unsigned);\n"
     "    XER_encode_chk_coding(XER_coding, p_td);\n"
     "    XmlReaderWrap reader(p_buf);\n"
     "    for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {\n"
     "      if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;\n"
     "    }\n"
     "    XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);\n"
     "    size_t bytes = reader.ByteConsumed();\n"
     "    p_buf.set_pos(bytes);\n"
     "    break;}\n"
     "  case TTCN_EncDec::CT_JSON: {\n"
     "    TTCN_EncDec_ErrorContext ec(\"While JSON-decoding type '%%s': \","
     " p_td.name);\n"
     "    if(!p_td.json)\n"
     "      TTCN_EncDec_ErrorContext::error_internal\n"
     "        (\"No JSON descriptor available for type '%%s'.\", p_td.name);\n"
     "    JSON_Tokenizer tok((const char*)p_buf.get_data(), p_buf.get_len());\n"
     "    if(JSON_decode(p_td, tok, FALSE)<0)\n"
     "      ec.error(TTCN_EncDec::ET_INCOMPL_MSG,"
     "\"Can not decode type '%%s', because invalid or incomplete"
     " message was received\", p_td.name);\n"
     "    p_buf.set_pos(tok.get_buf_pos());\n"
     "    break;}\n"
     "  default:\n"
     "    TTCN_error(\"Unknown coding method requested to decode"
     " type '%%s'\", p_td.name);\n"
     "  }\n"
     "  va_end(pvar);\n"
     "}\n\n"
#ifndef NDEBUG
     , __FUNCTION__, __LINE__
#endif
     , p_classname);

  *p_classdef=mputstr(*p_classdef, def);
  Free(def);
  *p_classsrc=mputstr(*p_classsrc, src);
  Free(src);
}