|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpiimpl.h"
|
|
Packit Service |
c5cf8c |
#include "errcodes.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include <string.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* This file contains the routines needed to implement the MPI routines that
|
|
Packit Service |
c5cf8c |
* can add error classes and codes during runtime. This file is organized
|
|
Packit Service |
c5cf8c |
* so that applications that do not use the MPI-2 routines to create new
|
|
Packit Service |
c5cf8c |
* error codes will not load any of this code.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* ROMIO has been customized to provide error messages with the same tools
|
|
Packit Service |
c5cf8c |
* as the rest of MPICH and will not rely on the dynamically assigned
|
|
Packit Service |
c5cf8c |
* error classes. This leaves all of the classes and codes for the user.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Because we have customized ROMIO, we do not need to implement
|
|
Packit Service |
c5cf8c |
* instance-specific messages for the dynamic error codes.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Local data structures.
|
|
Packit Service |
c5cf8c |
A message may be associated with each class and code.
|
|
Packit Service |
c5cf8c |
Since we limit the number of user-defined classes and code (no more
|
|
Packit Service |
c5cf8c |
than 256 of each), we allocate an array of pointers to the messages here.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
We *could* allow 256 codes with each class. However, we don't expect
|
|
Packit Service |
c5cf8c |
any need for this many codes, so we simply allow 256 (actually
|
|
Packit Service |
c5cf8c |
ERROR_MAX_NCODE) codes, and distribute these among the error codes.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
A user-defined error code has the following format. The ERROR_xxx
|
|
Packit Service |
c5cf8c |
is the macro that may be used to extract the data (usually a MASK and
|
|
Packit Service |
c5cf8c |
a (right)shift)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
[0-6] Class (same as predefined error classes); ERROR_CLASS_MASK
|
|
Packit Service |
c5cf8c |
[7] Is dynamic; ERROR_DYN_MASK and ERROR_DYN_SHIFT
|
|
Packit Service |
c5cf8c |
[8-18] Code index (for messages); ERROR_GENERIC_MASK and ERROR_GENERIC_SHIFT
|
|
Packit Service |
c5cf8c |
[19-31] Zero (unused but defined as zero)
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int not_initialized = 1; /* This allows us to use atomic decr */
|
|
Packit Service |
c5cf8c |
static const char *(user_class_msgs[ERROR_MAX_NCLASS]) = {
|
|
Packit Service |
c5cf8c |
0};
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static const char *(user_code_msgs[ERROR_MAX_NCODE]) = {
|
|
Packit Service |
c5cf8c |
0};
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int first_free_class = 1; /* class 0 is reserved */
|
|
Packit Service |
c5cf8c |
static int first_free_code = 1; /* code 0 is reserved */
|
|
Packit Service |
c5cf8c |
static const char empty_error_string[1] = { 0 };
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Forward reference */
|
|
Packit Service |
c5cf8c |
static const char *get_dynerr_string(int code);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This external allows this package to define the routine that converts
|
|
Packit Service |
c5cf8c |
dynamically assigned codes and classes to their corresponding strings.
|
|
Packit Service |
c5cf8c |
A cleaner implementation could replace this exposed global with a method
|
|
Packit Service |
c5cf8c |
defined in the error_string.c file that allowed this package to set
|
|
Packit Service |
c5cf8c |
the routine. */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int MPIR_Dynerrcodes_finalize(void *);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Local routine to initialize the data structures for the dynamic
|
|
Packit Service |
c5cf8c |
error classes and codes.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPIR_Init_err_dyncodes is called if not_initialized is true.
|
|
Packit Service |
c5cf8c |
Because all of the routines in this file are called by the
|
|
Packit Service |
c5cf8c |
MPI_Add_error_xxx routines, and those routines use the SINGLE_CS
|
|
Packit Service |
c5cf8c |
when the implementation is multithreaded, these routines (until
|
|
Packit Service |
c5cf8c |
we implement finer-grain thread-synchronization) need not worry about
|
|
Packit Service |
c5cf8c |
multiple threads
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
static void MPIR_Init_err_dyncodes(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: Does this need a thread-safe init? */
|
|
Packit Service |
c5cf8c |
not_initialized = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < ERROR_MAX_NCLASS; i++) {
|
|
Packit Service |
c5cf8c |
user_class_msgs[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
for (i = 0; i < ERROR_MAX_NCODE; i++) {
|
|
Packit Service |
c5cf8c |
user_code_msgs[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* Set the routine to provides access to the dynamically created
|
|
Packit Service |
c5cf8c |
* error strings */
|
|
Packit Service |
c5cf8c |
MPIR_Process.errcode_to_string = get_dynerr_string;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Add a finalize handler to free any allocated space */
|
|
Packit Service |
c5cf8c |
MPIR_Add_finalize(MPIR_Dynerrcodes_finalize, (void *) 0, 9);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#undef FUNCNAME
|
|
Packit Service |
c5cf8c |
#define FUNCNAME MPIR_Err_set_msg
|
|
Packit Service |
c5cf8c |
#undef FCNAME
|
|
Packit Service |
c5cf8c |
#define FCNAME MPL_QUOTE(FUNCNAME)
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
MPIR_Err_set_msg - Change the message for an error code or class
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Input Parameters:
|
|
Packit Service |
c5cf8c |
+ code - Error code or class
|
|
Packit Service |
c5cf8c |
- msg - New message to use
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Notes:
|
|
Packit Service |
c5cf8c |
This routine is needed to implement 'MPI_Add_error_string'.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int MPIR_Err_set_msg(int code, const char *msg_string)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int errcode, errclass;
|
|
Packit Service |
c5cf8c |
size_t msg_len;
|
|
Packit Service |
c5cf8c |
char *str;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (not_initialized) {
|
|
Packit Service |
c5cf8c |
/* Just to keep the rest of the code more robust, we'll
|
|
Packit Service |
c5cf8c |
* initialize the dynamic error codes *anyway*, but this is
|
|
Packit Service |
c5cf8c |
* an error (see MPI_Add_error_string in the standard) */
|
|
Packit Service |
c5cf8c |
MPIR_Init_err_dyncodes();
|
|
Packit Service |
c5cf8c |
return MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
|
|
Packit Service |
c5cf8c |
"MPIR_Err_set_msg", __LINE__,
|
|
Packit Service |
c5cf8c |
MPI_ERR_ARG, "**argerrcode", "**argerrcode %d", code);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Error strings are attached to a particular error code, not class.
|
|
Packit Service |
c5cf8c |
* As a special case, if the code is 0, we use the class message */
|
|
Packit Service |
c5cf8c |
errclass = code & ERROR_CLASS_MASK;
|
|
Packit Service |
c5cf8c |
errcode = (code & ERROR_GENERIC_MASK) >> ERROR_GENERIC_SHIFT;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (code & ~(ERROR_CLASS_MASK | ERROR_DYN_MASK | ERROR_GENERIC_MASK)) {
|
|
Packit Service |
c5cf8c |
/* Check for invalid error code */
|
|
Packit Service |
c5cf8c |
return MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
|
|
Packit Service |
c5cf8c |
FCNAME, __LINE__,
|
|
Packit Service |
c5cf8c |
MPI_ERR_ARG, "**argerrcode", "**argerrcode %d", code);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* --------------------------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
msg_len = strlen(msg_string);
|
|
Packit Service |
c5cf8c |
str = (char *) MPL_malloc(msg_len + 1, MPL_MEM_BUFFER);
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (!str) {
|
|
Packit Service |
c5cf8c |
return MPIR_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
|
|
Packit Service |
c5cf8c |
FCNAME, __LINE__, MPI_ERR_OTHER,
|
|
Packit Service |
c5cf8c |
"**nomem", "**nomem %s %d", "error message string", msg_len);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* --------------------------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
MPL_strncpy(str, msg_string, msg_len + 1);
|
|
Packit Service |
c5cf8c |
if (errcode) {
|
|
Packit Service |
c5cf8c |
if (errcode < first_free_code) {
|
|
Packit Service |
c5cf8c |
if (user_code_msgs[errcode]) {
|
|
Packit Service |
c5cf8c |
MPL_free((void *) (user_code_msgs[errcode]));
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
user_code_msgs[errcode] = (const char *) str;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* FIXME : Unallocated error code? */
|
|
Packit Service |
c5cf8c |
MPL_free(str);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
if (errclass < first_free_class) {
|
|
Packit Service |
c5cf8c |
if (user_class_msgs[errclass]) {
|
|
Packit Service |
c5cf8c |
MPL_free((void *) (user_class_msgs[errclass]));
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
user_class_msgs[errclass] = (const char *) str;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* FIXME : Unallocated error code? */
|
|
Packit Service |
c5cf8c |
MPL_free(str);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return MPI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
MPIR_Err_add_class - Creata a new error class
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Return value:
|
|
Packit Service |
c5cf8c |
An error class. Returns -1 if no more classes are available.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Notes:
|
|
Packit Service |
c5cf8c |
This is used to implement 'MPI_Add_error_class'; it may also be used by a
|
|
Packit Service |
c5cf8c |
device to add device-specific error classes.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Predefined classes are handled directly; this routine is not used to
|
|
Packit Service |
c5cf8c |
initialize the predefined MPI error classes. This is done to reduce the
|
|
Packit Service |
c5cf8c |
number of steps that must be executed when starting an MPI program.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
This routine should be run within a SINGLE_CS in the multithreaded case.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int MPIR_Err_add_class(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int new_class;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (not_initialized)
|
|
Packit Service |
c5cf8c |
MPIR_Init_err_dyncodes();
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get new class */
|
|
Packit Service |
c5cf8c |
new_class = first_free_class;
|
|
Packit Service |
c5cf8c |
++first_free_class;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (new_class >= ERROR_MAX_NCLASS) {
|
|
Packit Service |
c5cf8c |
/* Fail if out of classes */
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Note that the MPI interface always adds an error class without
|
|
Packit Service |
c5cf8c |
* a string. */
|
|
Packit Service |
c5cf8c |
user_class_msgs[new_class] = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return (new_class | ERROR_DYN_MASK);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
MPIR_Err_add_code - Create a new error code that is associated with an
|
|
Packit Service |
c5cf8c |
existing error class
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Input Parameters:
|
|
Packit Service |
c5cf8c |
. class - Error class to which the code belongs.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Return value:
|
|
Packit Service |
c5cf8c |
An error code.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Notes:
|
|
Packit Service |
c5cf8c |
This is used to implement 'MPI_Add_error_code'; it may also be used by a
|
|
Packit Service |
c5cf8c |
device to add device-specific error codes.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int MPIR_Err_add_code(int class)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int new_code;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Note that we can add codes to existing classes, so we may
|
|
Packit Service |
c5cf8c |
* need to initialize the dynamic error routines in this function */
|
|
Packit Service |
c5cf8c |
if (not_initialized)
|
|
Packit Service |
c5cf8c |
MPIR_Init_err_dyncodes();
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get the new code */
|
|
Packit Service |
c5cf8c |
new_code = first_free_code;
|
|
Packit Service |
c5cf8c |
++first_free_code;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* --BEGIN ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
if (new_code >= ERROR_MAX_NCODE) {
|
|
Packit Service |
c5cf8c |
/* Fail if out of codes */
|
|
Packit Service |
c5cf8c |
return -1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* --END ERROR HANDLING-- */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Create the full error code */
|
|
Packit Service |
c5cf8c |
new_code = class | (new_code << ERROR_GENERIC_SHIFT);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: For robustness, we should make sure that the associated string
|
|
Packit Service |
c5cf8c |
* is initialized to null */
|
|
Packit Service |
c5cf8c |
return new_code;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
get_dynerr_string - Get the message string that corresponds to a
|
|
Packit Service |
c5cf8c |
dynamically created error class or code
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Input Parameters:
|
|
Packit Service |
c5cf8c |
+ code - An error class or code. If a code, it must have been created by
|
|
Packit Service |
c5cf8c |
'MPIR_Err_create_code'.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Return value:
|
|
Packit Service |
c5cf8c |
A pointer to a null-terminated text string with the corresponding error
|
|
Packit Service |
c5cf8c |
message. A null return indicates an error; usually the value of 'code' is
|
|
Packit Service |
c5cf8c |
neither a valid error class or code.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Notes:
|
|
Packit Service |
c5cf8c |
This routine is used to implement 'MPI_ERROR_STRING'. It is only called
|
|
Packit Service |
c5cf8c |
for dynamic error codes.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
static const char *get_dynerr_string(int code)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int errcode, errclass;
|
|
Packit Service |
c5cf8c |
const char *errstr = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Error strings are attached to a particular error code, not class.
|
|
Packit Service |
c5cf8c |
* As a special case, if the code is 0, we use the class message */
|
|
Packit Service |
c5cf8c |
errclass = code & ERROR_CLASS_MASK;
|
|
Packit Service |
c5cf8c |
errcode = (code & ERROR_GENERIC_MASK) >> ERROR_GENERIC_SHIFT;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (code & ~(ERROR_CLASS_MASK | ERROR_DYN_MASK | ERROR_GENERIC_MASK)) {
|
|
Packit Service |
c5cf8c |
/* Check for invalid error code */
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (errcode) {
|
|
Packit Service |
c5cf8c |
if (errcode < first_free_code) {
|
|
Packit Service |
c5cf8c |
errstr = user_code_msgs[errcode];
|
|
Packit Service |
c5cf8c |
if (!errstr)
|
|
Packit Service |
c5cf8c |
errstr = empty_error_string;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
if (errclass < first_free_class) {
|
|
Packit Service |
c5cf8c |
errstr = user_class_msgs[errclass];
|
|
Packit Service |
c5cf8c |
if (!errstr)
|
|
Packit Service |
c5cf8c |
errstr = empty_error_string;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return errstr;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int MPIR_Dynerrcodes_finalize(void *p ATTRIBUTE((unused)))
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPL_UNREFERENCED_ARG(p);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (not_initialized == 0) {
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < first_free_class; i++) {
|
|
Packit Service |
c5cf8c |
if (user_class_msgs[i])
|
|
Packit Service |
c5cf8c |
MPL_free((char *) user_class_msgs[i]);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (i = 0; i < first_free_code; i++) {
|
|
Packit Service |
c5cf8c |
if (user_code_msgs[i])
|
|
Packit Service |
c5cf8c |
MPL_free((char *) user_code_msgs[i]);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return 0;
|
|
Packit Service |
c5cf8c |
}
|