예제 #1
0
void insert_profiler_code_line(const char* p_file_name,
  const char* p_function_name, size_t p_line_no)
{
  /* check if the entry already exists */
  for (size_t i = 0; i < the_data->nof_lines; ++i) {
    if (0 == strcmp(p_file_name,the_data->lines[i].file_name) &&
        p_line_no == the_data->lines[i].line_no) {
      if (0 == the_data->lines[i].function_name && 0 != p_function_name) {
        the_data->lines[i].function_name = mcopystr(p_function_name);
      }
      return;
    }
  }
  if (the_data->nof_lines == the_data->size) {
    /* database size reached, increase the buffer size (exponentially) */
    the_data->size *= 2;
    the_data->lines = (profiler_code_line_t*)Realloc(the_data->lines,
      the_data->size * sizeof(profiler_code_line_t));
  }
  the_data->lines[the_data->nof_lines].file_name = mcopystr(p_file_name);
  if (0 != p_function_name) {
    the_data->lines[the_data->nof_lines].function_name = mcopystr(p_function_name);
  }
  else {
    the_data->lines[the_data->nof_lines].function_name = 0;
  }
  the_data->lines[the_data->nof_lines].line_no = p_line_no;
  ++the_data->nof_lines;
}
예제 #2
0
void load_license_from_file(license_struct *lptr, const char *file_name)
{
    license_raw lraw;
    read_license(file_name, &lraw);
    check_license_signature(&lraw);
    decode_license(lptr, &lraw);
    lptr->license_file = mcopystr(file_name);
}
예제 #3
0
long gethostid(void)
{
    long hostid = 0;
    const char * const *subKey;
    size_t i;
    MD5_CTX context;
    unsigned char digest[MD5_DIGEST_LENGTH];

    MD5_Init(&context);

    for (subKey = keys; *subKey != NULL; subKey++) {
	const char * const *valueName;
	for (valueName = values; *valueName != NULL; valueName++) {
	    int ret = -13, type = -42;
	    size_t size = 0;
	    unsigned char *buffer;
            char * key = mcopystr(*subKey);
	    key = mputstr(key, *valueName);

	    ret = getreg(key, &type, 0, &size); /* query the size; ret always -1 */
	    if (size > 0) {
		buffer = Malloc(size);
		ret = getreg(key, &type, buffer, &size);
		if (ret == 0) {
		    switch (type) {
		    case WIN_REG_SZ:
		    case WIN_REG_EXPAND_SZ:
		    case WIN_REG_MULTI_SZ: {
		        /* getreg gave use _wide_ strings. Make them narrow.
			FIXME this assumes everybody is american and uses US-ASCII.
			It would be more correct to use iconv()
			but we don't know which codepage to convert to.
			*/
		        const unsigned char *from = buffer, *end = buffer + size;
			unsigned char *to = buffer;
			for (; from < end; ++from) { /* Yes, from is incremented twice */
			  *to++ = *from++;
			}
			size /= 2;
		    	break; }
		    default:
		    	break;
		    }
		    MD5_Update(&context, buffer, size);
		}
		Free(buffer);
	    }
	    Free(key);
	}
    }

    MD5_Final(digest, &context);
    for (i = 0; i < sizeof(hostid); i++) hostid |= digest[i] << (i * 8);
    return hostid;
}
예제 #4
0
static FILE *OpenTempFile(char **filename)
{
  FILE *fp;
#ifdef MINGW
  /* Function mkstemp() is not supported on MinGW */
  char *temp_name = tempnam(NULL, NULL);
  if (temp_name == NULL) {
    fprintf(stderr, "%s: creation of a temporary file failed: %s\n", progname,
      strerror(errno));
    exit(EXIT_FAILURE);
  }
  fp = fopen(temp_name, FOPEN_WRITE);
  if (fp == NULL) {
    fprintf(stderr, "%s: opening of temporary file `%s' failed: %s\n",
      progname, temp_name, strerror(errno));
    free(temp_name);
    exit(EXIT_FAILURE);
  }
  *filename = mcopystr(temp_name);
  free(temp_name);
#else
  int fd;
  *filename = mcopystr("/tmp/logmerge_XXXXXX");
  fd = mkstemp(*filename);
  if (fd < 0) {
    fprintf(stderr, "%s: creation of a temporary file based on template `%s' "
      "failed: %s\n", progname, *filename, strerror(errno));
    Free(*filename);
    exit(EXIT_FAILURE);
  }
  fp = fdopen(fd, FOPEN_WRITE);
  if (fp == NULL) {
    fprintf(stderr, "%s: system call fdopen() failed on temporary file `%s' "
      "(file descriptor %d): %s\n", progname, *filename, fd, strerror(errno));
    Free(*filename);
    exit(EXIT_FAILURE);
  }
#endif
  return fp;
}
예제 #5
0
static int GetEvent(FILE *fp, LogEvent *event)
{
    time_t prev_sec;
    unsigned long prev_usec;
    for ( ; ; ) {
	/* find and read timestamp */
	if (fgets(event->timestamp, TimeStampLength + 1, fp) == NULL) {
	    event->ignore = True;
	    return False;
	}
	event->start_line=event->line_ctr;
	if (FormatMatch(event->timestamp, TimeStampUsed)) break;
    }
    prev_sec = event->sec;
    prev_usec = event->usec;
    TS2long(&event->sec, &event->usec, event->timestamp);
    if (event->sec < prev_sec ||
	(event->sec == prev_sec && event->usec < prev_usec)) {
	event->wrap = 1;
    }
    event->ignore = False;
    for ( ; ; ) {
	size_t a;
	char buf[BUFFERSIZE];
	/* read the log-event */
	if (fgets(buf, sizeof(buf), fp) == NULL) {
	    /* EOF was detected */
	    if (event->data == NULL) event->data = mcopystr("\n");
	    else if (event->data[mstrlen(event->data) - 1] != '\n')
		event->data = mputc(event->data, '\n');
	    return False;
	}
	a = strlen(buf);
	if(FormatMatch(buf,TimeStampUsed)) {/*Did we read the next event's timestamp?*/
	    fseek(fp, -1L * a, SEEK_CUR);/*"unread" next event*/
	    break;
	} else if (buf[a - 1] == '\n') event->line_ctr++;
	event->data=mputstr(event->data, buf);/*append buffer to event-data*/
    }
    return True;
}
예제 #6
0
boolean get_profiler_code_line(const char *p_file_name,
  char **p_function_name, int *p_line_no)
{
  if (0 == last_file_name || 0 != strcmp(last_file_name, p_file_name)) {
    /* file parameter changed, reset the current index and store the new file name */
    current_index = 0;
    Free(last_file_name);
    last_file_name = mcopystr(p_file_name);
  }
  while (current_index < the_data->nof_lines) {
    /* find the first entry in the specified file and return it */
    if (0 == strcmp(p_file_name, the_data->lines[current_index].file_name)) {
      *p_function_name = the_data->lines[current_index].function_name;
      *p_line_no = the_data->lines[current_index].line_no;
      ++current_index;
      return TRUE;
    }
    ++current_index;
  }
  /* no entry found with the specified file name */
  return FALSE;
}
예제 #7
0
int verify_license(const license_struct *lptr)
{
    time_t current_time = time(NULL);
    int errflag = 0;

    if (current_time < lptr->valid_from) {
        fputs("The license key is not yet valid.\n", stderr);
	errflag = 1;
    }

    if (current_time > lptr->valid_until) {
        fputs("The license key has already expired.\n", stderr);
	errflag = 1;
    }

    if (lptr->limitation_type & LIMIT_HOST) {
	/* broken libc call gethostid() performs sign extension on some 64-bit
	 * Linux platforms, thus only the lowest 32 bits are considered */
	unsigned long host_id = (unsigned long)gethostid() & 0xffffffffUL;
	if (host_id != lptr->host_id) {
	    fprintf(stderr, "The license key is not valid for this host "
		"(%08lx).\n", host_id);
	    errflag = 1;
        }
    }

    if (lptr->limitation_type & LIMIT_USER) {
#ifdef MINGW
	TCHAR user_name[UNLEN + 1];
	DWORD buffer_size = sizeof(user_name);
	if (GetUserName(user_name, &buffer_size)) {
	    if (strcmp(user_name, lptr->login_name)) {
		fprintf(stderr, "The license key is not valid for this user "
		    "name (%s).\n", user_name);
		errflag = 1;
	    }
	} else {
	    fprintf(stderr, "Getting the current user name failed when "
		"verifying the license key. Windows error code: %d.\n",
		(int)GetLastError());
	    errflag = 1;
	}
#else
	uid_t process_uid = getuid();
        struct passwd *p;
	setpwent();
	p = getpwuid(process_uid);
	if (p == NULL) {
	    fprintf(stderr, "The current user ID (%d) does not have login "
		"name.\n", (int)process_uid);
	    errflag = 1;
	} else if (strcmp(p->pw_name, lptr->login_name)) {
	    /* First making a backup copy of the current login name because
	     * the subsequent getpwnam() call will overwrite it. */
	    char *login_name = mcopystr(p->pw_name);
	    /* Another chance: Trying to map the login name of the license key
	     * to a valid UID. Note that it is possible to associate several
	     * login names with the same UID. */
	    p = getpwnam(lptr->login_name);
	    if (p == NULL || p->pw_uid != process_uid) {
		fprintf(stderr, "The license key is not valid for this login "
		    "name (%s).\n", login_name);
		errflag = 1;
	    }
	    Free(login_name);
	}
	endpwent();
#endif
    }

    if (TTCN3_MAJOR < lptr->from_major ||
        (TTCN3_MAJOR == lptr->from_major && (TTCN3_MINOR < lptr->from_minor ||
	(TTCN3_MINOR == lptr->from_minor &&
	TTCN3_PATCHLEVEL < lptr->from_patchlevel)))) {
        /* Checking of to_{major,minor,patchlevel} removed when Titan moved
         * to major version 2 (licenses were valid up to 1.99pl99 only) */
            fputs("The license key is not valid for this version.\n", stderr);
	    errflag = 1;
    }
    
    if (errflag) {
      return 0;
    }

    if (lptr->valid_until - current_time < EXPIRY_WARNING * 86400) {
	time_t expiry_days = (lptr->valid_until - current_time) / 86400 + 1;
	fprintf(stderr, "Warning: The license key will expire within %ld "
	    "day%s.\n", (long)expiry_days, expiry_days > 1 ? "s" : "");
    }
    /* setpwent and getpwuid calls may use some system calls that fail.
     * We should ignore these error codes in future error messages. */
    errno = 0;
    return 1;
}
예제 #8
0
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);
}
예제 #9
0
int main(int argc,char *argv[])
{
    int a,b,c,processed_files=0,filename_count=0;
    char *outfile_name=NULL;
    int vflag=0,oflag=0;
#ifdef LICENSE
    license_struct lstr;
#endif
    progname=argv[0];
    atexit(DelTemp);
    signal(SIGINT,ControlChandler);
    while ((c = getopt(argc, argv, "vo:")) != -1) {
	switch (c) {
	case 'o':
	    outfile_name=optarg;
	    oflag = 1;
	    break;
	case 'v':
	    vflag=1;
	    break;
	default: Usage();return 0;
	}
    }
    if(oflag&&vflag){Usage();return 0;}/*both switches are used*/
	if(vflag) {
	fputs("Log Merger for the TTCN-3 Test Executor\n"
	    "Product number: " PRODUCT_NUMBER "\n"
	    "Version: " VERSION_STRING "\n"
	    "Build date: " __DATE__ " " __TIME__ "\n"
	    "Compiled with: " C_COMPILER_VERSION "\n\n"
	    COPYRIGHT_STRING "\n\n", stderr);
#ifdef LICENSE
	print_license_info();
#endif
	return 0;
    }
#ifdef LICENSE
    init_openssl();
    load_license(&lstr);
    if (!verify_license(&lstr)) {
      free_license(&lstr);
      free_openssl();
      exit(EXIT_FAILURE);
    }
    if (!check_feature(&lstr, FEATURE_LOGFORMAT)) {
	fputs("The license key does not allow the merging of log files.\n",
	    stderr);
	return 2;
    }
    free_license(&lstr);
    free_openssl();
#endif
    argc-=optind-1;argv+=optind-1;
    if(argc<2){Usage();return 0;}/*executed when no input file is given*/
    for(a=1;a<argc;a++) {/*find first file with a valid timestamp*/
	TimeStampUsed=GetTimeStampFormat(argv[a]);
	if(TimeStampUsed!=TSF_Undefined)break;
    }
    switch(TimeStampUsed) {
	case TSF_Seconds: fputs("Merging logs with timestamp "
	    "format \"seconds\" has no sense.\n", stderr); return 0;
	case TSF_Time: TimeStampLength=TIMELENGTH;break;
	case TSF_DateTime: TimeStampLength=DATETIMELENGTH;break;
	default: fputs("Unsupported timestamp format.\n", stderr); return 1;
    }
    for(a=1,c=0;a<argc;a++) {/*get files with valid timestamp format*/
	b=GetTimeStampFormat(argv[a]);
	if(TimeStampUsed==b) {/*file conains at least one valid timestamp*/
	    c++;
	    name_list_in=(char **)Realloc(name_list_in,c*sizeof(char *));
	    name_list_in[c-1] = mcopystr(argv[a]);
	} else if(b==TSF_Undefined)/*file contains no timestamp or uses a
					different format than the first match*/
		fprintf(stderr,"Warning: unknown format in %s\n",argv[a]);
	    else fprintf(stderr,"Warning: format mismatch in %s\n",argv[a]);
    }
    num_allfiles=c;
    if(num_allfiles<1){Usage();return 0;}/*no valid log file found*/
    if(oflag){/*switch [-o outfile] is used -> create outfile*/
	outfile = fopen(outfile_name, FOPEN_WRITE);
	if(outfile==NULL) {
	    fprintf(stderr,"Error creating %s %s\n",outfile_name,strerror(errno));
	    return 1;
	}
    } else {
	outfile = stdout;
    }
    while(1) {
	filename_count=num_allfiles;start_file=0;
	while(num_allfiles>0) {/*process files in name_list_in*/
	    processed_files=OpenMaxFiles(num_allfiles,name_list_in+start_file);
	    must_use_temp=True;/*if there are infiles remaining use tempfiles
				for all*/
	    if((processed_files<2)&&(num_allfiles>1)){fprintf(stderr,"Error: "
		"can not open enough files.\nMore descriptors required "
		"(set with the command `limit descriptors\')\n");return 1;}
	    if(infiles_processed==True)
		for(a=0;a<processed_files;a++) {
		    Free(EventList[a]->str_to_add);
		    EventList[a]->str_to_add = NULL;
		}
	    num_allfiles-=processed_files;
	    ProcessOpenFiles();
	    CloseAllFiles();
	    start_file+=processed_files;
	}
	must_use_temp=False;/*all infiles processed*/
	/*remove temporary files used in previous step*/
	if(infiles_processed==True)
	    for(a=0;a<filename_count;a++)remove(name_list_in[a]);
	infiles_processed=True;
	for(a=0;a<filename_count;a++)Free(name_list_in[a]);
	Free(name_list_in);
	if(num_tempfiles==0)break;/*no more file to process*/
	name_list_in=temp_file_list;/*process tempfiles*/
	num_allfiles=num_tempfiles;
	num_tempfiles=0;temp_file_list=NULL;
    }
    check_mem_leak(progname);
    return 0;
}