Example #1
0
/* Prints a fatal error message and adds file and line number if parsing, then terminates. */
int Error(const char *format,...)
{
	va_list marker;
	POVMSObject msg;
	char localvsbuffer[1024];

	sprintf(localvsbuffer, "%s Error: ", Stage_Names[Stage].stage_name);

	va_start(marker, format);
	vsnprintf(localvsbuffer + strlen(localvsbuffer), 1023 - strlen(localvsbuffer), format, marker);
	va_end(marker);

	CleanupString(localvsbuffer);

	if((Stage == STAGE_PARSING) || (Stage == STAGE_INCLUDE_ERR) || (Stage == STAGE_FOUND_INSTEAD))
	{
		(void)POVMSObject_New(&msg, kPOVObjectClass_FileLoc);

		Where_Error(&msg);

		(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, localvsbuffer);
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Error, 0);
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_FatalError);
		(void)POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
		(void)POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);
	}
	else
	{
		(void)POVMSObject_New(&msg, kPOVObjectClass_FileLoc);
		(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, localvsbuffer);
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Error, 0);
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_FatalError);
		(void)POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
		(void)POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);
	}

	/* This could be just an "if" but we may add special messages later */
	if(Stage == STAGE_INCLUDE_ERR)
	{
		Warning(0, "Check that the file is in a directory specifed with a +L switch\n"
		           "or 'Library_Path=' .INI item. Standard include files are in the\n"
		           "include directory or folder. Please read your documentation carefully.");
	}

	Terminate_Tokenizer(); /* Closes scene file */

	POV_SHELLOUT(FATAL_SHL);

	povray_exit(1);

	return 0;
}
Example #2
0
int Send_ProgressUpdate(int progressState, int t)
{
	POVMSObject msg;
	int err = kNoErr;
	DBL time_dif;

	STOP_TIME
	time_dif = TIME_ELAPSED

	if((fabs(time_dif - Previous_t) >= t) || (t == 0))
	{
		Previous_t = time_dif;

		if(err == kNoErr)
			err = POVMSObject_New(&msg, kPOVObjectClass_Progress);

		if(err == kNoErr)
			err = POVMSUtil_SetBool(&msg, kPOVAttrib_ProgressStatus, true);

		if(err == kNoErr)
			err = BuildProgress(&msg, progressState);

		if(err == kNoErr)
			err = POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_Progress);
		if(err == kNoErr)
			err = POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);

		if(err == kNoErr)
			err = POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);
	}

	return err;
}
Example #3
0
int Send_RenderDone(bool withtime)
{
   POVMSObject msg;
   int err = kNoErr;
   int tp, th, tr;

   if (trender == 0.0)
   {
     STOP_TIME

     trender = TIME_ELAPSED
   }

   tp = tparse_total;
   if(tp <= 0)
     tp = tparse;
   th = tphoton_total;
   if(th <= 0)
     th = tphoton;
   tr = trender_total;
   if(tr <= 0)
     tr = trender;

   err = POVMSObject_New(&msg, kPOVMSType_WildCard);
   if(err == kNoErr)
      BuildRenderTime(&msg, kPOVAttrib_AnimationTime, tp, th, tr, tp + th + tr);
   if(err == kNoErr)
      err = POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_RenderDone);
   if(err == kNoErr)
      err = POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
   if(err == kNoErr)
      err = POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);

   return err;
}
Example #4
0
/* Prints a fatal error message and adds file and line number, then terminates. */
int ErrorAt(const char *filename, long line, unsigned long offset, const char *format, ...)
{
	va_list marker;
	POVMSObject msg;
	char localvsbuffer[1024];

	sprintf(localvsbuffer, "%s Error: ", Stage_Names[STAGE_PARSING].stage_name);

	va_start(marker, format);
	vsnprintf(localvsbuffer + strlen(localvsbuffer), 1023 - strlen(localvsbuffer), format, marker);
	va_end(marker);

	CleanupString(localvsbuffer);

	(void)POVMSObject_New(&msg, kPOVObjectClass_FileLoc);
	(void)POVMSUtil_SetString(&msg, kPOVAttrib_FileName, filename);
	(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Line, line);
	(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Column, 0);
	(void)POVMSUtil_SetLong(&msg, kPOVAttrib_FilePosition, offset);

	(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, localvsbuffer);
	(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Error, 0);
	(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_FatalError);
	(void)POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
	(void)POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);

	Terminate_Tokenizer(); /* Closes scene file */

	POV_SHELLOUT(FATAL_SHL);

	povray_exit(1);

	return 0;
}
Example #5
0
int Send_Progress(const char *statusString, int progressState)
{
	POVMSObject msg;
	int err = kNoErr;

	Previous_t = 0;

	if(err == kNoErr)
		err = POVMSObject_New(&msg, kPOVObjectClass_Progress);

	if(err == kNoErr)
		err = POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, statusString);
	if(err == kNoErr)
		err = POVMSUtil_SetBool(&msg, kPOVAttrib_ProgressStatus, false);

	if(err == kNoErr)
		err = BuildProgress(&msg, progressState);

	if(err == kNoErr)
		err = POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_Progress);
	if(err == kNoErr)
		err = POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);

	if(err == kNoErr)
		err = POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);

	return err;
}
void POVMS_Message::SetDestinationAddress(POVMSAddress addr)
{
	int err;

	err = POVMSMsg_SetDestinationAddress(&data, addr);
	if(err != kNoErr)
		throw err;
}
Example #7
0
/*
 * Use this routine to display non-fatal warning message if
 * opts.Language_Version is greater than level parameter.
 */
int Warning(unsigned int level, const char *format,...)
{
	va_list marker;
	POVMSObject msg;
	char localvsbuffer[1024];

	sprintf(localvsbuffer, "%s Warning: ", Stage_Names[Stage].stage_name);

	va_start(marker, format);
	vsnprintf(localvsbuffer + strlen(localvsbuffer), 1023 - strlen(localvsbuffer), format, marker);
	va_end(marker);

	CleanupString(localvsbuffer);

	if((opts.Warning_Level < 5) || ((opts.Warning_Level < 10) && (level == 0)))
		return 0;

	if(level >= opts.Language_Version)
		return 0;

	if((Stage == STAGE_PARSING) || (Stage == STAGE_INCLUDE_ERR) || (Stage == STAGE_FOUND_INSTEAD))
	{
		(void)POVMSObject_New(&msg, kPOVObjectClass_FileLoc);

		Where_Warning(&msg);

		(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, localvsbuffer);
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Warning, 0);
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_Warning);
		(void)POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
		(void)POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);
	}
	else
	{
		(void)POVMSObject_New(&msg, kPOVObjectClass_FileLoc);
		(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, localvsbuffer);
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Warning, 0);
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_Warning);
		(void)POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
		(void)POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);
	}

	Do_Cooperate(0);

	return 0;
}
Example #8
0
void POVMS_Message::SetDestinationAddress(POVMSAddress addr)
{
    int err;

    err = POVMSMsg_SetDestinationAddress(&data, addr);
    if(err != pov_base::kNoErr)
        throw POV_EXCEPTION_CODE(err);
}
Example #9
0
void DebugTextStreamBuffer::lineoutput(const char *str, unsigned int chars)
{
	POVMSObject msg;
	char buffer[256];

	buffer[0] = 0;
	strncat(buffer, str, min((unsigned int)252, chars));

	(void)POVMSObject_New(&msg, kPOVObjectClass_FileLoc);
	(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, buffer);
	(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_Debug);
	(void)POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
	(void)POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);
}
Example #10
0
int Send_RenderOptions()
{
   POVMSObject msg;
   int err = kNoErr;

   if(err == kNoErr)
      err = POVMSObject_New(&msg, kPOVObjectClass_ROptions);
   if(err == kNoErr)
      err = BuildRenderOptions(&msg);
   if(err == kNoErr)
      err = POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_RenderOptions);
   if(err == kNoErr)
      err = POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
   if(err == kNoErr)
      err = POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);

   return err;
}
Example #11
0
void MessageFactory::WarningAt(unsigned int level, const UCS2 *filename, POV_LONG line, POV_LONG column, POV_LONG offset, const char *format, ...)
{
	va_list marker;
	POVMSObject msg;
	char localvsbuffer[1024];

	sprintf(localvsbuffer, "%s Warning: ", stageName);

	va_start(marker, format);
	vsnprintf(localvsbuffer + strlen(localvsbuffer), 1023 - strlen(localvsbuffer), format, marker);
	va_end(marker);

	CleanupString(localvsbuffer);

	if((warningLevel < 5) || ((warningLevel < 10) && (level == 0)))
		return;

	if(level >= languageVersion)
		return;

	(void)POVMSObject_New(&msg, kPOVObjectClass_ControlData);
	(void)POVMSUtil_SetUCS2String(&msg, kPOVAttrib_FileName, filename);
	(void)POVMSUtil_SetLong(&msg, kPOVAttrib_Line, line);
	(void)POVMSUtil_SetLong(&msg, kPOVAttrib_Column, column);
	(void)POVMSUtil_SetLong(&msg, kPOVAttrib_FilePosition, offset);

	(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, localvsbuffer);
	(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Warning, 0);

	if(viewId != 0)
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_ViewId, viewId);
	else
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_SceneId, sceneId);

	if(viewId != 0)
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_ViewOutput, kPOVMsgIdent_Warning);
	else
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_SceneOutput, kPOVMsgIdent_Warning);

	(void)POVMSMsg_SetSourceAddress(&msg, sourceAddress);
	(void)POVMSMsg_SetDestinationAddress(&msg, destinationAddress);

	(void)POVMS_Send(NULL, &msg, NULL, kPOVMSSendMode_NoReply);
}
Example #12
0
int Send_RenderStarted(bool continuetrace)
{
   POVMSObject msg;
   int err = kNoErr;

   err = POVMSObject_New(&msg, kPOVMSType_WildCard);
   if(err == kNoErr)
      err = POVMSObject_Copy(gStartedStreamMessage, &msg);
   if(err == kNoErr)
      err = POVMSUtil_SetBool(&msg, kPOVAttrib_ContinueTrace, continuetrace);
   if(err == kNoErr)
      err = POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_RenderStarted);
   if(err == kNoErr)
      err = POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
   if(err == kNoErr)
      err = POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);

   return err;
}
Example #13
0
// filename defaults to NULL, and line, column, and offset default to -1
std::string MessageFactory::SendError(const char *format, va_list arglist, const UCS2 *filename, POV_LONG line, POV_LONG column, POV_LONG offset)
{
	POVMSObject msg;
	char localvsbuffer[1024];

	sprintf(localvsbuffer, "%s Error: ", stageName);
	vsnprintf(localvsbuffer + strlen(localvsbuffer), 1023 - strlen(localvsbuffer), format, arglist);
	CleanupString(localvsbuffer);

	(void)POVMSObject_New(&msg, kPOVObjectClass_ControlData);
	if (filename != NULL)
		(void)POVMSUtil_SetUCS2String(&msg, kPOVAttrib_FileName, filename);
	if (line != -1)
		(void)POVMSUtil_SetLong(&msg, kPOVAttrib_Line, line);
	if (column != -1)
		(void)POVMSUtil_SetLong(&msg, kPOVAttrib_Column, column);
	if (offset != -1)
		(void)POVMSUtil_SetLong(&msg, kPOVAttrib_FilePosition, offset);
	(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, localvsbuffer);
	(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Error, 0);

	if(viewId != 0)
	{
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_ViewId, viewId);
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_ViewOutput, kPOVMsgIdent_FatalError);
	}
	else
	{
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_SceneId, sceneId);
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_SceneOutput, kPOVMsgIdent_FatalError);
	}

	(void)POVMSMsg_SetSourceAddress(&msg, sourceAddress);
	(void)POVMSMsg_SetDestinationAddress(&msg, destinationAddress);

	(void)POVMS_Send(NULL, &msg, NULL, kPOVMSSendMode_NoReply);

	return std::string(localvsbuffer);
}
Example #14
0
int Send_FrameStatistics()
{
	POVMSObject msg;
	int err = kNoErr;

	if(err == kNoErr)
		err = POVMSObject_New(&msg, kPOVObjectClass_FStats);

    if(err == kNoErr)
        err = BuildRenderTime(&msg, kPOVAttrib_FrameTime, tparse_frame, tphoton_frame, trender_frame, tparse_frame+tphoton_frame+trender_frame);
    if(err == kNoErr)
        err = BuildRenderTime(&msg, kPOVAttrib_AnimationTime, tparse_total, tphoton_total, trender_total, tparse_total+tphoton_total+trender_total);

	if(err == kNoErr)
		err = POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_FrameStatistics);
	if(err == kNoErr)
		err = POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);

	if(err == kNoErr)
		err = POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);

	return err;
}
Example #15
0
int Send_RenderStatistics(bool total)
{
   POVMSObject msg;
   int err = kNoErr;

   if(err == kNoErr)
      err = POVMSObject_New(&msg, kPOVObjectClass_RStats);
   if(err == kNoErr)
   {
      if(total == true)
         err = BuildRenderStatistics(&msg, totalstats);
      else
         err = BuildRenderStatistics(&msg, stats);
   }
   if(err == kNoErr)
      err = POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_RenderStatistics);
   if(err == kNoErr)
      err = POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
   if(err == kNoErr)
      err = POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);

   return err;
}
Example #16
0
void MessageFactory::PossibleError(const char *format,...)
{
	va_list marker;
	POVMSObject msg;
	char localvsbuffer[1024];

	sprintf(localvsbuffer, "Possible %s Error: ", stageName);

	va_start(marker, format);
	vsnprintf(localvsbuffer + strlen(localvsbuffer), 1023 - strlen(localvsbuffer), format, marker);
	va_end(marker);

	CleanupString(localvsbuffer);

	if(warningLevel == 0)
		return;

	(void)POVMSObject_New(&msg, kPOVObjectClass_ControlData);
	(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, localvsbuffer);
	(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Error, 0);

	if(viewId != 0)
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_ViewId, viewId);
	else
		(void)POVMSUtil_SetInt(&msg, kPOVAttrib_SceneId, sceneId);

	if(viewId != 0)
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_ViewOutput, kPOVMsgIdent_Error);
	else
		(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_SceneOutput, kPOVMsgIdent_Error);

	(void)POVMSMsg_SetSourceAddress(&msg, sourceAddress);
	(void)POVMSMsg_SetDestinationAddress(&msg, destinationAddress);

	(void)POVMS_Send(NULL, &msg, NULL, kPOVMSSendMode_NoReply);
}
Example #17
0
/* Prints a non-fatal error message and adds file and line number */
int WarningAt(unsigned int level, const char *filename, long line, unsigned long offset, const char *format, ...)
{
	va_list marker;
	POVMSObject msg;
	char localvsbuffer[1024];

	sprintf(localvsbuffer, "%s Warning: ", Stage_Names[Stage].stage_name);

	va_start(marker, format);
	vsnprintf(localvsbuffer + strlen(localvsbuffer), 1023 - strlen(localvsbuffer), format, marker);
	va_end(marker);

	CleanupString(localvsbuffer);

	if((opts.Warning_Level < 5) || ((opts.Warning_Level < 10) && (level == 0)))
		return 0;

	if(level >= opts.Language_Version)
		return 0;

	(void)POVMSObject_New(&msg, kPOVObjectClass_FileLoc);
	(void)POVMSUtil_SetString(&msg, kPOVAttrib_FileName, filename);
	(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Line, line);
	(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Column, 0);
	(void)POVMSUtil_SetLong(&msg, kPOVAttrib_FilePosition, offset);

	(void)POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText, localvsbuffer);
	(void)POVMSUtil_SetInt(&msg, kPOVAttrib_Warning, 0);
	(void)POVMSMsg_SetupMessage(&msg, kPOVMsgClass_RenderOutput, kPOVMsgIdent_FatalError);
	(void)POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);
	(void)POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);

	Do_Cooperate(0);

	return 0;
}
Example #18
0
void Send_InitInfo()
{
   POVMSAttributeList attrlist;
   POVMSAttribute attr;
   POVMSObject msg;
   int err = kNoErr;

   if(err == kNoErr)
      err = POVMSObject_New(&msg, kPOVMSType_WildCard);

   if(err == kNoErr)
      err = POVMSUtil_SetString(&msg, kPOVAttrib_PlatformName, POVRAY_PLATFORM_NAME);
   if(err == kNoErr)
      err = POVMSUtil_SetFormatString(&msg, kPOVAttrib_CoreVersion,
                                      "Persistence of Vision(tm) Ray Tracer Version %s%s", POV_RAY_VERSION, COMPILER_VER);
   if(err == kNoErr)
      err = POVMSUtil_SetString(&msg, kPOVAttrib_EnglishText,
                                DISTRIBUTION_MESSAGE_1 "\n" DISTRIBUTION_MESSAGE_2 "\n" DISTRIBUTION_MESSAGE_3
                                "\nPOV-Ray is based on DKBTrace 2.12 by David K. Buck & Aaron A. Collins\n" POV_RAY_COPYRIGHT);
   if(err == kNoErr)
      err = POVMSUtil_SetBool(&msg, kPOVAttrib_Official, POV_RAY_IS_OFFICIAL);

   if(err == kNoErr)
      err = POVMSAttrList_New(&attrlist);
   if(err == kNoErr)
   {
      for(int i = 0; Primary_Developers[i] != NULL; i++)
      {
         err = POVMSAttr_New(&attr);
         if(err == kNoErr)
         {
            err = POVMSAttr_Set(&attr, kPOVMSType_CString, Primary_Developers[i], strlen(Primary_Developers[i]) + 1);
            if(err == kNoErr)
               err = POVMSAttrList_Append(&attrlist, &attr);
            else
               err = POVMSAttr_Delete(&attr);
         }
      }
   }
   if(err == kNoErr)
      err = POVMSObject_Set(&msg, &attrlist, kPOVAttrib_PrimaryDevs);

   if(err == kNoErr)
      err = POVMSAttrList_New(&attrlist);
   if(err == kNoErr)
   {
      for(int i = 0; Contributing_Authors[i] != NULL; i++)
      {
         err = POVMSAttr_New(&attr);
         if(err == kNoErr)
         {
            err = POVMSAttr_Set(&attr, kPOVMSType_CString, Contributing_Authors[i], strlen(Contributing_Authors[i]) + 1);
            if(err == kNoErr)
               err = POVMSAttrList_Append(&attrlist, &attr);
            else
               err = POVMSAttr_Delete(&attr);
         }
      }
   }
   if(err == kNoErr)
      err = POVMSObject_Set(&msg, &attrlist, kPOVAttrib_ContributingDevs);

   if(err == kNoErr)
      err = POVMSAttrList_New(&attrlist);
#ifndef DONT_SHOW_IMAGE_LIB_VERSIONS
   // ZLib library version and copyright notice
   if(err == kNoErr)
   {
      err = POVMSAttr_New(&attr);
      if(err == kNoErr)
      {
         const char *tempstr = pov_tsprintf("ZLib %s, Copyright 1995-1998 Jean-loup Gailly and Mark Adler", Extract_Version(zlibVersion()));
         err = POVMSAttr_Set(&attr, kPOVMSType_CString, (void *)tempstr, strlen(tempstr) + 1);
         if(err == kNoErr)
            err = POVMSAttrList_Append(&attrlist, &attr);
         else
            err = POVMSAttr_Delete(&attr);
      }
   }
   // LibPNG library version and copyright notice
   if(err == kNoErr)
   {
      err = POVMSAttr_New(&attr);
      if(err == kNoErr)
      {
         const char *tempstr = pov_tsprintf("LibPNG %s, Copyright 1998-2002 Glenn Randers-Pehrson", Extract_Version(png_get_libpng_ver(NULL)));
         err = POVMSAttr_Set(&attr, kPOVMSType_CString, (void *)tempstr, strlen(tempstr) + 1);
         if(err == kNoErr)
            err = POVMSAttrList_Append(&attrlist, &attr);
         else
            err = POVMSAttr_Delete(&attr);
      }
   }
   // LibJPEG library version and copyright notice
   if(err == kNoErr)
   {
      err = POVMSAttr_New(&attr);
      if(err == kNoErr)
      {
         const char *tempstr = pov_tsprintf("LibJPEG %s, Copyright 1998 Thomas G. Lane", Extract_Version(JVERSION));
         err = POVMSAttr_Set(&attr, kPOVMSType_CString, (void *)tempstr, strlen(tempstr) + 1);
         if(err == kNoErr)
            err = POVMSAttrList_Append(&attrlist, &attr);
         else
            err = POVMSAttr_Delete(&attr);
      }
   }
   // LibTIFF library version and copyright notice
   if(err == kNoErr)
   {
      err = POVMSAttr_New(&attr);
      if(err == kNoErr)
      {
         const char *tempstr = pov_tsprintf("LibTIFF %s, Copyright 1988-1997 Sam Leffler, 1991-1997 SGI", Extract_Version(TIFFGetVersion()));
         err = POVMSAttr_Set(&attr, kPOVMSType_CString, (void *)tempstr, strlen(tempstr) + 1);
         if(err == kNoErr)
            err = POVMSAttrList_Append(&attrlist, &attr);
         else
            err = POVMSAttr_Delete(&attr);
      }
   }
#endif
   if(err == kNoErr)
      err = POVMSObject_Set(&msg, &attrlist, kPOVAttrib_ImageLibVersions);

   if(err == kNoErr)
      err = POVMSMsg_SetupMessage(&msg, kPOVMsgClass_Miscellaneous, kPOVMsgIdent_InitInfo);
   if(err == kNoErr)
      err = POVMSMsg_SetDestinationAddress(&msg, FRONTEND_ADDRESS);

   if(err == kNoErr)
      err = POVMS_Send(POVMS_Render_Context, &msg, NULL, kPOVMSSendMode_NoReply);

   if(err != 0)
      (void)POVMS_ASSERT_OUTPUT("Sending InitInfo failed!", "povmsend.cpp", 0);
}