forked from epics_driver_modules/motorBase
Added time stamps to debugging messages
This commit is contained in:
@@ -19,6 +19,7 @@ program XPS_trajectoryScan("P=13BMC:,R=traj1,IPADDR=164.54.160.34,PORT=5001,"
|
||||
%% #include <string.h>
|
||||
%% #include <stdio.h>
|
||||
%% #include <math.h>
|
||||
%% #include <stdarg.h>
|
||||
%% #include "XPS_C8_drivers.h"
|
||||
%% #include "Socket.h"
|
||||
%% #include "xps_ftp.h"
|
||||
@@ -135,6 +136,7 @@ unsigned long startTime;
|
||||
%% static int getGroupStatus(SS_ID ssId, struct UserVar *pVar);
|
||||
%% static void readGathering(SS_ID ssId, struct UserVar *pVar);
|
||||
%% static int trajectoryAbort(SS_ID ssId, struct UserVar *pVar);
|
||||
%% static void printMessage(const char *pformat, ...);
|
||||
|
||||
|
||||
ss xpsTrajectoryScan {
|
||||
@@ -204,7 +206,7 @@ ss xpsTrajectoryScan {
|
||||
state monitor_inputs {
|
||||
entry {
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryScan: state monitor_inputs:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryScan: state monitor_inputs:"
|
||||
" entry\n");
|
||||
}
|
||||
}
|
||||
@@ -237,7 +239,7 @@ ss xpsTrajectoryScan {
|
||||
state build {
|
||||
entry {
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryScan: state build:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryScan: state build:"
|
||||
" entry\n");
|
||||
}
|
||||
}
|
||||
@@ -294,7 +296,7 @@ ss xpsTrajectoryScan {
|
||||
state execute {
|
||||
entry {
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryScan: state execute:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryScan: state execute:"
|
||||
" entry\n");
|
||||
}
|
||||
%%waitMotors(ssId, pVar);
|
||||
@@ -374,7 +376,7 @@ ss xpsTrajectoryScan {
|
||||
/* Clear execute command, post. This is a "busy" record, don't
|
||||
* want to do this until execution is complete. */
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryScan: state execute:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryScan: state execute:"
|
||||
" execStatus = STATUS_FAILURE\n");
|
||||
}
|
||||
execute=0;
|
||||
@@ -386,7 +388,7 @@ ss xpsTrajectoryScan {
|
||||
%%pVar->xpsStatus = getGroupStatus(ssId, pVar);
|
||||
/* Setting execState here will cause the xpsTrajectoryRun SS to wake up */
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryScan: state execute:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryScan: state execute:"
|
||||
" setting execState = EXECUTE_STATE_MOVE_START\n");
|
||||
}
|
||||
execState = EXECUTE_STATE_MOVE_START;
|
||||
@@ -428,13 +430,13 @@ ss xpsTrajectoryScan {
|
||||
state wait_execute {
|
||||
entry {
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryScan: state wait_execute:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryScan: state wait_execute:"
|
||||
" entry\n");
|
||||
}
|
||||
}
|
||||
when (execStatus == STATUS_ABORT) {
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryScan: state wait_execute:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryScan: state wait_execute:"
|
||||
" execStatus = STATUS_ABORT\n");
|
||||
}
|
||||
/* The trajectory_abort state set has detected an abort. It has
|
||||
@@ -482,7 +484,7 @@ ss xpsTrajectoryScan {
|
||||
|
||||
when (execState==EXECUTE_STATE_FLYBACK) {
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryScan: state wait_execute:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryScan: state wait_execute:"
|
||||
" execStatus = EXECUTE_STATE_FLYBACK\n");
|
||||
}
|
||||
/* Stop the detector */
|
||||
@@ -522,7 +524,7 @@ ss xpsTrajectoryScan {
|
||||
state readback {
|
||||
entry {
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryScan: state readback:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryScan: state readback:"
|
||||
" entry\n");
|
||||
}
|
||||
}
|
||||
@@ -578,7 +580,7 @@ ss xpsTrajectoryAbort {
|
||||
|
||||
execStatus = STATUS_ABORT;
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryAbort: state monitorAbort:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryAbort: state monitorAbort:"
|
||||
" setting execStatus = STATUS_ABORT\n");
|
||||
}
|
||||
pvPut(execStatus);
|
||||
@@ -603,7 +605,7 @@ ss xpsTrajectoryRun {
|
||||
when (efTestAndClear(execStateMon) && (execState == EXECUTE_STATE_MOVE_START)) {
|
||||
/*%%pVar->xpsStatus = getGroupStatus(ssId, pVar);*/
|
||||
if (debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: ss xpsTrajectoryRun: state asyncExecute:"
|
||||
printMessage("XPS_trajectoryScan: ss xpsTrajectoryRun: state asyncExecute:"
|
||||
" setting execState = EXECUTE_STATE_EXECUTING\n");
|
||||
}
|
||||
execState = EXECUTE_STATE_EXECUTING;
|
||||
@@ -657,7 +659,7 @@ static int getMotorPositions(SS_ID ssId, struct UserVar *pVar, double *pos)
|
||||
status = GroupPositionCurrentGet(pVar->positionSocket,
|
||||
pVar->groupName,pVar->numAxes,pos);
|
||||
if (status != 0)
|
||||
printf("Error performing GroupPositionCurrentGet%i\n", status);
|
||||
printMessage("Error performing GroupPositionCurrentGet%i\n", status);
|
||||
/* Convert from XPS units (which are EPICS motor dial units) to user units */
|
||||
for (j=0; j<pVar->numAxes; j++) {
|
||||
if (pVar->epicsMotorDir[j] == 0) dir=1; else dir=-1;
|
||||
@@ -679,7 +681,7 @@ static int getMotorMoving(SS_ID ssId, struct UserVar *pVar)
|
||||
|
||||
status = GroupStatusGet(pVar->pollSocket,pVar->groupName,&groupStatus);
|
||||
if (status != 0)
|
||||
printf("Error performing GroupStatusGet %i\n",status);
|
||||
printMessage("Error performing GroupStatusGet %i\n",status);
|
||||
|
||||
if (groupStatus > 42)
|
||||
moving = 1;
|
||||
@@ -752,7 +754,7 @@ static int getSocket(SS_ID ssId, struct UserVar *pVar, double timeout)
|
||||
|
||||
sock = TCP_ConnectToServer(pVar->xpsAddress, pVar->xpsPort, timeout);
|
||||
if (sock < 0)
|
||||
printf("Error TCP_ConnectToServer, status=%d\n",sock);
|
||||
printMessage("Error TCP_ConnectToServer, status=%d\n",sock);
|
||||
return (sock);
|
||||
}
|
||||
|
||||
@@ -766,19 +768,19 @@ static void trajectoryExecute(SS_ID ssId, struct UserVar *pVar)
|
||||
int eventId;
|
||||
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" entry\n");
|
||||
}
|
||||
/* Configure Gathering */
|
||||
/* Reset gathering.
|
||||
* This must be done because GatheringOneData just appends to in-memory list */
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" calling GatheringReset(%d)\n", pVar->pollSocket);
|
||||
}
|
||||
status = GatheringReset(pVar->pollSocket);
|
||||
if (status != 0) {
|
||||
printf("Error performing GatheringReset, status=%d\n",status);
|
||||
printMessage("Error performing GatheringReset, status=%d\n",status);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -795,14 +797,14 @@ static void trajectoryExecute(SS_ID ssId, struct UserVar *pVar)
|
||||
/* Define what is to be saved in the GatheringExternal.dat.
|
||||
* 3 pieces of information per axis. */
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" calling GatheringConfigurationSet(%d, %d, %s)\n",
|
||||
pVar->pollSocket, pVar->numAxes*NUM_GATHERING_ITEMS, buffer);
|
||||
}
|
||||
status = GatheringConfigurationSet(pVar->pollSocket,
|
||||
pVar->numAxes*NUM_GATHERING_ITEMS, buffer);
|
||||
if (status != 0)
|
||||
printf("Error performing GatheringConfigurationSet, status=%d, buffer=%p\n",
|
||||
printMessage("Error performing GatheringConfigurationSet, status=%d, buffer=%p\n",
|
||||
status, buffer);
|
||||
|
||||
/* Define trajectory output pulses.
|
||||
@@ -813,7 +815,7 @@ static void trajectoryExecute(SS_ID ssId, struct UserVar *pVar)
|
||||
* the decceleration endPulses is the element, which means adding another +1. */
|
||||
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" calling MultipleAxesPVTPulseOutputSet(%d, %s, %d, %d, %f)\n",
|
||||
pVar->pollSocket, pVar->groupName,
|
||||
pVar->startPulses+1,
|
||||
@@ -828,7 +830,7 @@ static void trajectoryExecute(SS_ID ssId, struct UserVar *pVar)
|
||||
/* Define trigger */
|
||||
sprintf(buffer, "Always;%s.PVT.TrajectoryPulse", pVar->groupName);
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" calling EventExtendedConfigurationTriggerSet(%d, %d, %s, %s, %s, %s, %s)\n",
|
||||
pVar->pollSocket, 2, buffer,
|
||||
"", "", "", "");
|
||||
@@ -836,14 +838,14 @@ static void trajectoryExecute(SS_ID ssId, struct UserVar *pVar)
|
||||
status = EventExtendedConfigurationTriggerSet(pVar->pollSocket, 2, buffer,
|
||||
"", "", "", "");
|
||||
if (status != 0) {
|
||||
printf("Error performing EventExtendedConfigurationTriggerSet, status=%d, buffer=%s\n",
|
||||
printMessage("Error performing EventExtendedConfigurationTriggerSet, status=%d, buffer=%s\n",
|
||||
status, buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Define action */
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" calling EventExtendedConfigurationActionSet(%d, %d, %s, %s, %s, %s, %s)\n",
|
||||
pVar->pollSocket, 1,
|
||||
"GatheringOneData",
|
||||
@@ -853,25 +855,25 @@ static void trajectoryExecute(SS_ID ssId, struct UserVar *pVar)
|
||||
"GatheringOneData",
|
||||
"", "", "", "");
|
||||
if (status != 0) {
|
||||
printf("Error performing EventExtendedConfigurationActionSet, status=%d\n",
|
||||
printMessage("Error performing EventExtendedConfigurationActionSet, status=%d\n",
|
||||
status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Start gathering */
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" calling EventExtendedStart(%d, %p)\n",
|
||||
pVar->pollSocket, &eventId);
|
||||
}
|
||||
status= EventExtendedStart(pVar->pollSocket, &eventId);
|
||||
if (status != 0) {
|
||||
printf("Error performing EventExtendedStart, status=%d\n",status);
|
||||
printMessage("Error performing EventExtendedStart, status=%d\n",status);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" calling MultipleAxesPVTExecution(%d, %s, %s, %d)\n",
|
||||
pVar->driveSocket, pVar->groupName,
|
||||
TRAJECTORY_FILE, 1);
|
||||
@@ -880,22 +882,22 @@ static void trajectoryExecute(SS_ID ssId, struct UserVar *pVar)
|
||||
TRAJECTORY_FILE, 1);
|
||||
/* status -27 means the trajectory was aborted */
|
||||
if ((status != 0) && (status != -27))
|
||||
printf("Error performing MultipleAxesPVTExecution, status=%d\n", status);
|
||||
printMessage("Error performing MultipleAxesPVTExecution, status=%d\n", status);
|
||||
|
||||
/* Remove the event */
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" calling EventExtendedRemove(%d, %d)\n", pVar->pollSocket, eventId);
|
||||
}
|
||||
status = EventExtendedRemove(pVar->pollSocket, eventId);
|
||||
if (status != 0) {
|
||||
printf("Error performing ExtendedEventRemove, status=%d\n",status);
|
||||
printMessage("Error performing ExtendedEventRemove, status=%d\n",status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Save the gathered data to a file */
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: trajectoryExecute:"
|
||||
printMessage("XPS_trajectoryScan: trajectoryExecute:"
|
||||
" calling GatheringStopAndSave(%d)\n", pVar->pollSocket);
|
||||
}
|
||||
status = GatheringStopAndSave(pVar->pollSocket);
|
||||
@@ -903,7 +905,7 @@ static void trajectoryExecute(SS_ID ssId, struct UserVar *pVar)
|
||||
/* status -30 means gathering not started i.e. aborted before the end of
|
||||
1 trajectory element */
|
||||
if ((status != 0) && (status != -30))
|
||||
printf("Error performing GatheringStopAndSave, status=%d\n", status);
|
||||
printMessage("Error performing GatheringStopAndSave, status=%d\n", status);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -928,7 +930,7 @@ static void buildAndVerify(SS_ID ssId, struct UserVar *pVar)
|
||||
int dir[MAX_AXES];
|
||||
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: buildAndVerify:"
|
||||
printMessage("XPS_trajectoryScan: buildAndVerify:"
|
||||
" entry\n");
|
||||
}
|
||||
/* We create trajectories with an extra element at the beginning and at the end.
|
||||
@@ -954,7 +956,7 @@ static void buildAndVerify(SS_ID ssId, struct UserVar *pVar)
|
||||
&maxVelocity[j], &maxAcceleration[j],
|
||||
&minJerkTime[j], &maxJerkTime[j]);
|
||||
if (status != 0) {
|
||||
printf("Error calling positionerSGammaParametersSet, status=%d\n",
|
||||
printMessage("Error calling positionerSGammaParametersSet, status=%d\n",
|
||||
status);
|
||||
}
|
||||
/* The calculation using maxAcceleration read from controller below
|
||||
@@ -1056,28 +1058,28 @@ static void buildAndVerify(SS_ID ssId, struct UserVar *pVar)
|
||||
/* FTP the trajectory file from the local directory to the XPS */
|
||||
status = ftpConnect(pVar->xpsAddress, pVar->userName, pVar->password, &ftpSocket);
|
||||
if (status != 0) {
|
||||
printf("Error calling ftpConnect, status=%d\n", status);
|
||||
printMessage("Error calling ftpConnect, status=%d\n", status);
|
||||
return;
|
||||
}
|
||||
status = ftpChangeDir(ftpSocket, TRAJECTORY_DIRECTORY);
|
||||
if (status != 0) {
|
||||
printf("Error calling ftpChangeDir, status=%d\n", status);
|
||||
printMessage("Error calling ftpChangeDir, status=%d\n", status);
|
||||
return;
|
||||
}
|
||||
status = ftpStoreFile(ftpSocket, TRAJECTORY_FILE);
|
||||
if (status != 0) {
|
||||
printf("Error calling ftpStoreFile, status=%d\n", status);
|
||||
printMessage("Error calling ftpStoreFile, status=%d\n", status);
|
||||
return;
|
||||
}
|
||||
status = ftpDisconnect(ftpSocket);
|
||||
if (status != 0) {
|
||||
printf("Error calling ftpDisconnect, status=%d\n", status);
|
||||
printMessage("Error calling ftpDisconnect, status=%d\n", status);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Verify trajectory */
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: buildAndVerify:"
|
||||
printMessage("XPS_trajectoryScan: buildAndVerify:"
|
||||
" calling MultipleAxesPVTVerification(%d, %s, %s)\n",
|
||||
pVar->pollSocket, pVar->groupName, TRAJECTORY_FILE);
|
||||
}
|
||||
@@ -1111,7 +1113,7 @@ static void buildAndVerify(SS_ID ssId, struct UserVar *pVar)
|
||||
pVar->axisName[j], fileName, &pVar->motorMinPos[j], &pVar->motorMaxPos[j],
|
||||
&pVar->motorMVA[j], &pVar->motorMAA[j]);
|
||||
if (status != 0) {
|
||||
printf("Error performing MultipleAxesPVTVerificationResultGet for axis %s, status=%d\n",
|
||||
printMessage("Error performing MultipleAxesPVTVerificationResultGet for axis %s, status=%d\n",
|
||||
pVar->axisName[j], status);
|
||||
}
|
||||
}
|
||||
@@ -1136,7 +1138,7 @@ static int currentElement(SS_ID ssId, struct UserVar *pVar)
|
||||
status = MultipleAxesPVTParametersGet(pVar->pollSocket,
|
||||
pVar->groupName, fileName, &number);
|
||||
if (status != 0)
|
||||
printf("Error performing MultipleAxesPVTParametersGet, status=%d\n",
|
||||
printMessage("Error performing MultipleAxesPVTParametersGet, status=%d\n",
|
||||
status);
|
||||
return (number);
|
||||
}
|
||||
@@ -1150,7 +1152,7 @@ static int getGroupStatus(SS_ID ssId, struct UserVar *pVar)
|
||||
|
||||
status = GroupStatusGet(pVar->pollSocket,pVar->groupName,&groupStatus);
|
||||
if (status != 0)
|
||||
printf("Error performing GroupStatusGet, status=%d\n", status);
|
||||
printMessage("Error performing GroupStatusGet, status=%d\n", status);
|
||||
return(groupStatus);
|
||||
}
|
||||
|
||||
@@ -1170,28 +1172,28 @@ static void readGathering(SS_ID ssId, struct UserVar *pVar)
|
||||
int dir;
|
||||
|
||||
if (pVar->debugLevel > 0) {
|
||||
printf("XPS_trajectoryScan: readGathering:"
|
||||
printMessage("XPS_trajectoryScan: readGathering:"
|
||||
" entry\n");
|
||||
}
|
||||
/* FTP the gathering file from the XPS to the local directory */
|
||||
status = ftpConnect(pVar->xpsAddress, pVar->userName, pVar->password, &ftpSocket);
|
||||
if (status != 0) {
|
||||
printf("Error calling ftpConnect, status=%d\n", status);
|
||||
printMessage("Error calling ftpConnect, status=%d\n", status);
|
||||
return;
|
||||
}
|
||||
status = ftpChangeDir(ftpSocket, GATHERING_DIRECTORY);
|
||||
if (status != 0) {
|
||||
printf("Error calling ftpChangeDir, status=%d\n", status);
|
||||
printMessage("Error calling ftpChangeDir, status=%d\n", status);
|
||||
return;
|
||||
}
|
||||
status = ftpRetrieveFile(ftpSocket, GATHERING_FILE);
|
||||
if (status != 0) {
|
||||
printf("Error calling ftpRetrieveFile, status=%d\n", status);
|
||||
printMessage("Error calling ftpRetrieveFile, status=%d\n", status);
|
||||
return;
|
||||
}
|
||||
status = ftpDisconnect(ftpSocket);
|
||||
if (status != 0) {
|
||||
printf("Error calling ftpDisconnect, status=%d\n", status);
|
||||
printMessage("Error calling ftpDisconnect, status=%d\n", status);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1218,7 +1220,7 @@ static void readGathering(SS_ID ssId, struct UserVar *pVar)
|
||||
nitems = fscanf(gatheringFile, "%lf %lf ",
|
||||
&setpointPosition, &actualPosition);
|
||||
if (nitems != NUM_GATHERING_ITEMS) {
|
||||
printf("Error reading Gathering.dat file, nitems=%d, should be %d\n",
|
||||
printMessage("Error reading Gathering.dat file, nitems=%d, should be %d\n",
|
||||
nitems, NUM_GATHERING_ITEMS);
|
||||
goto done;
|
||||
}
|
||||
@@ -1243,9 +1245,27 @@ static int trajectoryAbort(SS_ID ssId, struct UserVar *pVar)
|
||||
|
||||
status = GroupMoveAbort(pVar->abortSocket,pVar->groupName);
|
||||
if (status != 0)
|
||||
printf("Error performing GroupMoveAbort, status=%d\n", status);
|
||||
printMessage("Error performing GroupMoveAbort, status=%d\n", status);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void printMessage(const char *pformat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
FILE *fp = stdout;
|
||||
epicsTimeStamp now;
|
||||
char nowText[40];
|
||||
|
||||
epicsTimeGetCurrent(&now);
|
||||
nowText[0] = 0;
|
||||
epicsTimeToStrftime(nowText,sizeof(nowText),
|
||||
"%Y/%m/%d %H:%M:%S.%03f",&now);
|
||||
fprintf(fp,"%s ",nowText);
|
||||
va_start(pvar, pformat);
|
||||
vfprintf(fp,pformat,pvar);
|
||||
va_end(pvar);
|
||||
fflush(fp);
|
||||
}
|
||||
|
||||
}%
|
||||
|
||||
Reference in New Issue
Block a user