Esempio n. 1
0
epicsShareFunc int epicsShareAPI eltc(int yesno)
{
    errlogInit(0);
    errlogFlush();
    pvtData.toConsole = yesno;
    return 0;
}
Esempio n. 2
0
static void testPrefixLogandCompare( const char* logmessage ) {
    struct timeval timeout;
    timeout.tv_sec = 5; /* in seconds */
    timeout.tv_usec = 0;

    errlogPrintfNoConsole("%s", logmessage);
    errlogFlush();
    iocLogFlush();
    fdmgr_pend_event(pfdctx, &timeout);
}
static void daeCASThread(void* arg)
{
    exServer    *pCAS;
    unsigned    debugLevel = 0u;
    double      executionTime = 0.0;
    double      asyncDelay = 0.1;
    const char*        pvPrefix;
    unsigned    aliasCount = 1u;
    unsigned    scanOn = true;
    unsigned    syncScan = true;
    unsigned    maxSimultAsyncIO = 1000u;
	isisdaeInterface* iface = static_cast<isisdaeInterface*>(arg);
    printf("starting cas server\n");
	pvPrefix = macEnvExpand("$(MYPVPREFIX)DAE:");
    try {
        pCAS = new exServer ( pvPrefix, aliasCount, 
            scanOn != 0, syncScan == 0, asyncDelay,
            maxSimultAsyncIO, iface );
    }
    catch ( ... ) {
        errlogSevPrintf (errlogMajor, "Server initialization error\n" );
        errlogFlush ();
        return;
    }
    
    pCAS->setDebugLevel(debugLevel);
    try
    {
        while (true) 
        {
            fileDescriptorManager.process(1000.0);
        }
    }
    catch(const std::exception& ex)
    {
        std::cerr << ex.what() << std::endl;
    }
    //pCAS->show(2u);
    delete pCAS;
    errlogFlush ();
}
Esempio n. 4
0
epicsShareFunc void * mallocMustSucceed(size_t size, const char *msg)
{
    void * mem = NULL;
    if (size > 0) {
        while ((mem = malloc(size)) == NULL) {
            errlogPrintf("%s: mallocMustSucceed(%lu) - malloc failed\n",
                msg, (unsigned long)size);
            errlogPrintf("Thread %s (%p) suspending.\n",
                    epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf());
            errlogFlush();
            epicsThreadSuspendSelf();
        }
    }
    return mem;
}
Esempio n. 5
0
epicsShareFunc void cantProceed(const char *msg, ...)
{
    va_list pvar;
    va_start(pvar, msg);
    if (msg)
        errlogVprintf(msg, pvar);
    va_end(pvar);
    
    errlogPrintf("Thread %s (%p) can't proceed, suspending.\n",
            epicsThreadGetNameSelf(), (void *)epicsThreadGetIdSelf());
    errlogFlush();
    
    epicsThreadSleep(1.0);
    while (1)
        epicsThreadSuspendSelf();
}
Esempio n. 6
0
int main(int argc,char **argv)
{
    int         argn = 1;
    char	*sub = NULL;
    int		subLength = 0;
    char	**pstr;
    char	*psep;
    int		*len;
    long	status = 0;
    static char *subSep = ",";

    /* Look for -Smacro=value options */
    while (argc>argn && (strncmp(argv[argn], "-S", 2)==0)) {
	pstr = &sub;
	psep = subSep;
	len = &subLength;
	if (strlen(argv[argn])==2) {
	    dbCatString(pstr, len, argv[++argn], psep);
	} else {
	    dbCatString(pstr, len, argv[argn]+2, psep);
	}
	argn++;
    }
    if (argc == argn) {
	status = asInitFP(stdin, sub);
	if(status) errlogPrintf("ascheck: Access Security File failed.\n");
    } else if (argc == argn+1) {
	status = asInitFile(argv[argn], sub);
	if(status) errlogPrintf("ascheck: Access Security File failed.\n");
    } else {
	printf("usage: ascheck [-Smac=sub ...] [<] file\n");
	status = -1;
    }
    errlogFlush();
    return status;
}
Esempio n. 7
0
cac::~cac ()
{
    // this blocks until the UDP thread exits so that
    // it will not sneak in any new clients
    //
    // lock intentionally not held here so that we dont deadlock 
    // waiting for the UDP thread to exit while it is waiting to 
    // get the lock.
    {
        epicsGuard < epicsMutex > cbGuard ( this->cbMutex );
        epicsGuard < epicsMutex > guard ( this->mutex );
        if ( this->pudpiiu ) {
            this->pudpiiu->shutdown ( cbGuard, guard );

            // make sure no new tcp circuits are created
            this->cacShutdownInProgress = true;

            //
            // shutdown all tcp circuits
            //
            tsDLIter < tcpiiu > iter = this->circuitList.firstIter ();
            while ( iter.valid() ) {
                // this causes a clean shutdown to occur
                iter->unlinkAllChannels ( cbGuard, guard );
                iter++;
            }
        }
    }
    
    //
    // wait for all tcp threads to exit
    //
    // this will block for oustanding sends to go out so dont 
    // hold a lock while waiting
    //
    {
        epicsGuard < epicsMutex > guard ( this->mutex );
        while ( this->iiuExistenceCount > 0 ) {
            epicsGuardRelease < epicsMutex > unguard ( guard );
            this->iiuUninstall.wait ();
        }
    }

    if ( this->pudpiiu ) {
        delete this->pudpiiu;
    }

    freeListCleanup ( this->tcpSmallRecvBufFreeList );
    freeListCleanup ( this->tcpLargeRecvBufFreeList );

    delete [] this->pUserName;

    tsSLList < bhe > tmpBeaconList;
    this->beaconTable.removeAll ( tmpBeaconList ); 
    while ( bhe * pBHE = tmpBeaconList.get() ) {
        pBHE->~bhe ();
        this->bheFreeList.release ( pBHE );
    }

    this->timerQueue.release ();

    this->ipToAEngine.release ();

    // clean-up the list of un-notified msg objects
    while ( msgForMultiplyDefinedPV * msg = this->msgMultiPVList.get() ) {
        msg->~msgForMultiplyDefinedPV ();
        this->mdpvFreeList.release ( msg );
    }

    errlogFlush ();

    osiSockRelease ();

    // its ok for channels and subscriptions to still
    // exist at this point. The user created them and 
    // its his responsibility to clean them up.
}
int main(int argc,char **argv)
{
	int		i;
	char	*outFilename;
	char	*pext;
	FILE	*outFile;
	dbMenu	*pdbMenu;
	dbRecordType	*pdbRecordType;
	dbFldDes	*pdbFldDes;
	char	*plastSlash;
	int		strip;
	char	*path = NULL;
	char	*sub = NULL;
	int		pathLength = 0;
	int		subLength = 0;
	char	**pstr;
	char	*psep;
	int		*len;
	long	status;
	static char *pathSep = OSI_PATH_LIST_SEPARATOR;
	static char *subSep = ",";

	/*Look for options*/
	if(argc<2) {
		fprintf(stderr,"usage: dbToDoxygen -Idir -Idir file.dbd [outfile]\n");
		exit(0);
	}
	while((strncmp(argv[1],"-I",2)==0)||(strncmp(argv[1],"-S",2)==0)) {
		if(strncmp(argv[1],"-I",2)==0) {
			pstr = &path;
			psep = pathSep;
			len = &pathLength;
		} else {
			pstr = &sub;
			psep = subSep;
			len = &subLength;
		}
		if(strlen(argv[1])==2) {
			dbCatString(pstr,len,argv[2],psep);
			strip = 2;
		} else {
			dbCatString(pstr,len,argv[1]+2,psep);
			strip = 1;
		}
		argc -= strip;
		for(i=1; i<argc; i++) argv[i] = argv[i + strip];
	}
	if(argc<2 || (strncmp(argv[1],"-",1)==0)) {
		fprintf(stderr,"usage: dbToRecordtypeH -Idir -Idir file.dbd [outfile]\n");
		exit(0);
	}
	if(argc==2){
		/*remove path so that outFile is created where program is executed*/
		plastSlash = strrchr(argv[1],'/');
		if(!plastSlash)  plastSlash = strrchr(argv[1],'\\');
		plastSlash = (plastSlash ? plastSlash+1 : argv[1]);
		outFilename = (char*)dbCalloc(1,strlen(plastSlash)+1);
		strcpy(outFilename,plastSlash);
		pext = strstr(outFilename,".dbd");
		if(!pext) {
			fprintf(stderr,"Input file MUST have .dbd extension\n");
			exit(-1);
		}
		strcpy(pext,".h");
	}else {
		outFilename = (char*)dbCalloc(1,strlen(argv[2])+1);
		strcpy(outFilename,argv[2]);
	}
	pdbbase = dbAllocBase();
	pdbbase->ignoreMissingMenus = TRUE;
	pdbbase->loadCdefs = TRUE;
	status = dbReadDatabase(&pdbbase,argv[1],path,sub);
	if(status)  {
		errlogFlush();
		fprintf(stderr, "dbToMenuH: Input errors, no output generated\n");
		exit(1);
	}
	outFile = fopen(outFilename,"wt");
	if(!outFile) {
		epicsPrintf("Error creating output file \"%s\"\n", outFilename);
		exit(1);
	}
	fprintf(outFile,"/// @file\n/// EPICS DB record definitions\n\n");

	pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList);
	while(pdbMenu) {
		fprintf(outFile,"/// %s EPICS DB menu\n",pdbMenu->name);
		fprintf(outFile,"enum %s\n{\n", pdbMenu->name);
		for(i=0; i<pdbMenu->nChoice; i++) {
			fprintf(outFile,"\t%s",pdbMenu->papChoiceName[i]);
			if(i < (pdbMenu->nChoice - 1)) fprintf(outFile,",");
			fprintf(outFile,"\t///< %s", pdbMenu->papChoiceValue[i]);
			fprintf(outFile,"\n");
		}
		fprintf(outFile,"};\n\n");
		pdbMenu = (dbMenu *)ellNext(&pdbMenu->node);
	}
	pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList);
	while(pdbRecordType) {
		fprintf(outFile,"/// %s EPICS DB record\n",pdbRecordType->name);
		fprintf(outFile,"struct %s\n{\n",pdbRecordType->name);
		for(i=0; i<pdbRecordType->no_fields; i++) {
			char	name[256];
			int		j;

			pdbFldDes = pdbRecordType->papFldDes[i];
			for(j=0; j< (int)strlen(pdbFldDes->name); j++)
				name[j] = pdbFldDes->name[j];
			name[strlen(pdbFldDes->name)] = 0;
			switch(pdbFldDes->field_type) {
			case DBF_STRING :
				fprintf(outFile, "\tchar\t\t%s[%d];\t///< %s\n",
					name, pdbFldDes->size, pdbFldDes->prompt);
				break;
			case DBF_CHAR :
				fprintf(outFile, "\tepicsInt8\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_UCHAR :
				fprintf(outFile, "\tepicsUInt8\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_SHORT :
				fprintf(outFile, "\tepicsInt16\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_USHORT :
				fprintf(outFile, "\tepicsUInt16\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_LONG :
				fprintf(outFile, "\tepicsInt32\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_ULONG :
				fprintf(outFile, "\tepicsUInt32\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_FLOAT :
				fprintf(outFile, "\tepicsFloat32\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_DOUBLE :
				fprintf(outFile, "\tepicsFloat64\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_MENU :
				pdbMenu = (dbMenu*)pdbFldDes->ftPvt;
				if (pdbMenu != NULL)
				{
				    fprintf(outFile, "\t%s\t%s;\t///< %s\n",
					      pdbMenu->name, name, pdbFldDes->prompt);
				}
				else
				{
					fprintf(outFile, "\tepicsEnum16\t%s;\t///< %s\n",
						name, pdbFldDes->prompt);
				}
				break;
			case DBF_ENUM :
			case DBF_DEVICE :
				fprintf(outFile, "\tepicsEnum16\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_INLINK :
			case DBF_OUTLINK :
			case DBF_FWDLINK :
				fprintf(outFile, "\tDBLINK\t\t%s;\t///< %s\n",
					name, pdbFldDes->prompt);
				break;
			case DBF_NOACCESS:
				break;
			default:
				fprintf(outFile,"ILLEGAL FIELD TYPE\n");
			}
		}
		fprintf(outFile,"};\n");
		pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node);
		if(pdbRecordType) fprintf(outFile,"\n");
	}
	fclose(outFile);
	free((void *)outFilename);
	return(0);
}
Esempio n. 9
0
int main(int argc,char **argv)
{
    dbMenu	*pdbMenu;
    char	*outFilename;
    char	*pext;
    FILE	*outFile;
    char	*plastSlash;
    int		i;
    int		strip;
    char	*path = NULL;
    char	*sub = NULL;
    int		pathLength = 0;
    int		subLength = 0;
    char	**pstr;
    char	*psep;
    int		*len;
    long	status;
    static char *pathSep = OSI_PATH_LIST_SEPARATOR;
    static char *subSep = ",";

    /*Look for options*/
    if(argc<2) {
	fprintf(stderr,"usage: dbToMenu -Idir -Idir file.dbd [outfile]\n");
	exit(0);
    }
    while((strncmp(argv[1],"-I",2)==0)||(strncmp(argv[1],"-S",2)==0)) {
	if(strncmp(argv[1],"-I",2)==0) {
	    pstr = &path;
	    psep = pathSep;
	    len = &pathLength;
	} else {
	    pstr = &sub;
	    psep = subSep;
	    len = &subLength;
	}
	if(strlen(argv[1])==2) {
	    dbCatString(pstr,len,argv[2],psep);
	    strip = 2;
	} else {
	    dbCatString(pstr,len,argv[1]+2,psep);
	    strip = 1;
	}
	argc -= strip;
	for(i=1; i<argc; i++) argv[i] = argv[i + strip];
    }
    if(argc<2 || (strncmp(argv[1],"-",1)==0)) {
	fprintf(stderr,"usage: dbToMenu -Idir -Idir file.dbd [outfile]\n");
	exit(0);
    }
    if (argc==2) {
        /*remove path so that outFile is created where program is executed*/
        plastSlash = strrchr(argv[1],'/');
        if(!plastSlash)  plastSlash = strrchr(argv[1],'\\');
        plastSlash = (plastSlash ? plastSlash+1 : argv[1]);
        outFilename = dbCalloc(1,strlen(plastSlash)+1);
        strcpy(outFilename,plastSlash);
        pext = strstr(outFilename,".dbd");
        if (!pext) {
            fprintf(stderr,"Input file MUST have .dbd extension\n");
            exit(-1);
        }
        strcpy(pext,".h");
    } else {
        outFilename = dbCalloc(1,strlen(argv[2])+1);
        strcpy(outFilename,argv[2]);
    }
    pdbbase = dbAllocBase();
    pdbbase->ignoreMissingMenus = TRUE;
    status = dbReadDatabase(&pdbbase,argv[1],path,sub);
    if (status) {
        errlogFlush();
        fprintf(stderr, "dbToMenuH: Input errors, no output generated\n");
        exit(1);
    }
    outFile = fopen(outFilename, "w");
    if (!outFile) {
        epicsPrintf("Error creating output file \"%s\"\n", outFilename);
        exit(1);
    }
    pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList);
    while(pdbMenu) {
	fprintf(outFile,"#ifndef INC%sH\n",pdbMenu->name);
	fprintf(outFile,"#define INC%sH\n",pdbMenu->name);
	fprintf(outFile,"typedef enum {\n");
	for(i=0; i<pdbMenu->nChoice; i++) {
	    fprintf(outFile,"\t%s",pdbMenu->papChoiceName[i]);
	    if(i < (pdbMenu->nChoice - 1)) fprintf(outFile,",");
	    fprintf(outFile,"\n");
	}
	fprintf(outFile,"}%s;\n",pdbMenu->name);
	fprintf(outFile,"#endif /*INC%sH*/\n",pdbMenu->name);
	pdbMenu = (dbMenu *)ellNext(&pdbMenu->node);
    }
    fclose(outFile);
    free((void *)outFilename);
    return(0);
}
Esempio n. 10
0
/*
 * The body of the command interpreter
 */
static int
iocshBody (const char *pathname, const char *commandLine)
{
    FILE *fp = NULL;
    const char *filename = NULL;
    int icin, icout;
    char c;
    int quote, inword, backslash;
    const char *raw = NULL;;
    char *line = NULL;
    int lineno = 0;
    int argc;
    char **argv = NULL;
    int argvCapacity = 0;
    struct iocshRedirect *redirects = NULL;
    struct iocshRedirect *redirect = NULL;
    int sep;
    const char *prompt = NULL;
    const char *ifs = " \t(),\r";
    iocshArgBuf *argBuf = NULL;
    int argBufCapacity = 0;
    struct iocshCommand *found;
    void *readlineContext = NULL;
    int wasOkToBlock;
    
    /*
     * See if command interpreter is interactive
     */
    if (commandLine == NULL) {
        if ((pathname == NULL) || (strcmp (pathname, "<telnet>") == 0)) {
            if ((prompt = envGetConfigParamPtr(&IOCSH_PS1)) == NULL)
                prompt = "epics> ";
        }
        else {
            fp = fopen (pathname, "r");
            if (fp == NULL) {
                fprintf(epicsGetStderr(), "Can't open %s: %s\n", pathname,
                    strerror (errno));
                return -1;
            }
            if ((filename = strrchr (pathname, '/')) == NULL)
                filename = pathname;
            else
                filename++;
            prompt = NULL;
        }

        /*
         * Create a command-line input context
         */
        if ((readlineContext = epicsReadlineBegin(fp)) == NULL) {
            fprintf(epicsGetStderr(), "Can't allocate command-line object.\n");
            if (fp)
                fclose(fp);
            return -1;
        }
    }

    /*
     * Set up redirection
     */
    redirects = (struct iocshRedirect *)calloc(NREDIRECTS, sizeof *redirects);
    if (redirects == NULL) {
        fprintf(epicsGetStderr(), "Out of memory!\n");
        return -1;
    }

    /*
     * Read commands till EOF or exit
     */
    argc = 0;
    wasOkToBlock = epicsThreadIsOkToBlock();
    epicsThreadSetOkToBlock(1);
    for (;;) {
        /*
         * Read a line
         */
        if (commandLine) {
            if (raw != NULL)
                break;
            raw = commandLine;
        }
        else {
            if ((raw = epicsReadline(prompt, readlineContext)) == NULL)
                break;
        }
        lineno++;

        /*
         * Skip leading white-space
         */
        icin = 0;
        while ((c = raw[icin]) && isspace(c)) {
            icin++;
        }

        /*
         * Ignore comment lines other than to echo
         * them if they came from a script.  This
         * avoids macLib errors from comments.
         */
        if (c == '#') {
            if ((prompt == NULL) && (commandLine == NULL))
                puts(raw);
            continue;
        }

        /*
         * Expand macros
         */
        free(line);
        if ((line = macEnvExpand(raw)) == NULL)
            continue;

        /*
         * Skip leading white-space coming from a macro
         */
        while ((c = line[icin]) && isspace(c)) {
            icin++;
        }

        /*
         * Echo non-empty lines read from a script
         */
        if ((prompt == NULL) && *line && (commandLine == NULL))
            puts(line);

        /*
         * Ignore lines that became a comment or empty after macro expansion
         */
        if (!c || c == '#')
            continue;

        /*
         * Break line into words
         */
        icout = 0;
        inword = 0;
        argc = 0;
        quote = EOF;
        backslash = 0;
        redirect = NULL;
        for (;;) {
            if (argc >= argvCapacity) {
                char **av;
                argvCapacity += 50;
                av = (char **)realloc (argv, argvCapacity * sizeof *argv);
                if (av == NULL) {
                    fprintf (epicsGetStderr(), "Out of memory!\n");
                    argc = -1;
                    break;
                }
                argv = av;
            }
            c = line[icin++];
            if (c == '\0')
                break;
            if ((quote == EOF) && !backslash && (strchr (ifs, c)))
                sep = 1;
            else
                sep = 0;
            if ((quote == EOF) && !backslash) {
                int redirectFd = 1;
                if (c == '\\') {
                    backslash = 1;
                    continue;
                }
                if (c == '<') {
                    if (redirect != NULL) {
                        break;
                    }
                    redirect = &redirects[0];
                    sep = 1;
                    redirect->mode = "r";
                }
                if ((c >= '1') && (c <= '9') && (line[icin] == '>')) {
                    redirectFd = c - '0';
                    c = '>';
                    icin++;
                }
                if (c == '>') {
                    if (redirect != NULL)
                        break;
                    if (redirectFd >= NREDIRECTS) {
                        redirect = &redirects[1];
                        break;
                    }
                    redirect = &redirects[redirectFd];
                    sep = 1;
                    if (line[icin] == '>') {
                        icin++;
                        redirect->mode = "a";
                    }
                    else {
                        redirect->mode = "w";
                    }
                }
            }
            if (inword) {
                if (c == quote) {
                    quote = EOF;
                }
                else {
                    if ((quote == EOF) && !backslash) {
                        if (sep) {
                            inword = 0;
                            line[icout++] = '\0';
                        }
                        else if ((c == '"') || (c == '\'')) {
                            quote = c;
                        }
                        else {
                            line[icout++] = c;
                        }
                    }
                    else {
                        line[icout++] = c;
                    }
                }
            }
            else {
                if (!sep) {
                    if (((c == '"') || (c == '\'')) && !backslash)
                        quote = c;
                    if (redirect != NULL) {
                        if (redirect->name != NULL) {
                            argc = -1;
                            break;
                        }
                        redirect->name = line + icout;
                        redirect = NULL;
                    }
                    else {
                        argv[argc++] = line + icout;
                    }
                    if (quote == EOF)
                        line[icout++] = c;
                    inword = 1;
                }
            }
            backslash = 0;
        }
        if (redirect != NULL) {
            showError(filename, lineno, "Illegal redirection.");
            continue;
        }
        if (argc < 0)
            break;
        if (quote != EOF) {
            showError(filename, lineno, "Unbalanced quote.");
            continue;
        }
        if (backslash) {
            showError(filename, lineno, "Trailing backslash.");
            continue;
        }
        if (inword)
            line[icout++] = '\0';
        argv[argc] = NULL;

        /*
         * Special case -- Redirected input but no command
         * Treat as if 'iocsh filename'.
         */
        if ((argc == 0) && (redirects[0].name != NULL)) {
            const char *commandFile = redirects[0].name;
            redirects[0].name = NULL;
            if (openRedirect(filename, lineno, redirects) < 0)
                continue;
            startRedirect(filename, lineno, redirects);
            iocshBody(commandFile, NULL);
            stopRedirect(filename, lineno, redirects);
            continue;
        }

        /*
         * Special command?
         */
        if ((argc > 0) && (strcmp(argv[0], "exit") == 0))
            break;

        /*
         * Set up redirection
         */
        if ((openRedirect(filename, lineno, redirects) == 0) && (argc > 0)) {
            /*
             * Look up command
             */
            found = (iocshCommand *)registryFind (iocshCmdID, argv[0]);
            if (found) {
                /*
                 * Process arguments and call function
                 */
                struct iocshFuncDef const *piocshFuncDef = found->pFuncDef;
                for (int iarg = 0 ; ; ) {
                    if (iarg == piocshFuncDef->nargs) {
                        startRedirect(filename, lineno, redirects);
                        (*found->func)(argBuf);
                        break;
                    }
                    if (iarg >= argBufCapacity) {
                        void *np;

                        argBufCapacity += 20;
                        np = realloc (argBuf, argBufCapacity * sizeof *argBuf);
                        if (np == NULL) {
                            fprintf (epicsGetStderr(), "Out of memory!\n");
                            argBufCapacity -= 20;
                            break;
                        }
                        argBuf = (iocshArgBuf *)np;
                    }
                    if (piocshFuncDef->arg[iarg]->type == iocshArgArgv) {
                        argBuf[iarg].aval.ac = argc-iarg;
                        argBuf[iarg].aval.av = argv+iarg;
                        iarg = piocshFuncDef->nargs;
                    }
                    else {
                        if (!cvtArg (filename, lineno,
                                ((iarg < argc) ? argv[iarg+1] : NULL),
                                &argBuf[iarg], piocshFuncDef->arg[iarg]))
                            break;
                        iarg++;
                    }
                }
                if ((prompt != NULL) && (strcmp(argv[0], "epicsEnvSet") == 0)) {
                    const char *newPrompt;
                    if ((newPrompt = envGetConfigParamPtr(&IOCSH_PS1)) != NULL)
                        prompt = newPrompt;
                }
            }
            else {
                showError(filename, lineno, "Command %s not found.", argv[0]);
            }
        }
        stopRedirect(filename, lineno, redirects);
    }
    if (fp && (fp != stdin))
        fclose (fp);
    if (redirects != NULL) {
        stopRedirect(filename, lineno, redirects);
        free (redirects);
    }
    free(line);
    free (argv);
    free (argBuf);
    errlogFlush();
    if (readlineContext)
        epicsReadlineEnd(readlineContext);
    epicsThreadSetOkToBlock( wasOkToBlock);
    return 0;
}
Esempio n. 11
0
/*
 * Tests the log prefix code
 * The prefix is only applied to log messages as they go out to the socket,
 * so we need to create a server listening on a port, accept connections etc.
 * This code is a reduced version of the code in iocLogServer.
 */
static void testLogPrefix(void) {
    struct sockaddr_in serverAddr;
    int status;
    struct timeval timeout;
    struct sockaddr_in actualServerAddr;
    osiSocklen_t actualServerAddrSize;
    char portstring[16];


    testDiag("Testing iocLogPrefix");

    timeout.tv_sec = 5; /* in seconds */
    timeout.tv_usec = 0;

    memset((void*)prefixmsgbuffer, 0, sizeof prefixmsgbuffer);

    /* Clear "errlog: <n> messages were discarded" status */
    errlogPrintfNoConsole(".");
    errlogFlush();

    sock = epicsSocketCreate(AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
        testAbort("epicsSocketCreate failed.");
    }

    /* We listen on a an available port. */
    memset((void *)&serverAddr, 0, sizeof serverAddr);
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(0);

    status = bind (sock, (struct sockaddr *)&serverAddr,
                   sizeof (serverAddr) );
    if (status < 0) {
        testAbort("bind failed; all ports in use?");
    }

    status = listen(sock, 10);
    if (status < 0) {
        testAbort("listen failed!");
    }

    /* Determine the port that the OS chose */
    actualServerAddrSize = sizeof actualServerAddr;
    memset((void *)&actualServerAddr, 0, sizeof serverAddr);
    status = getsockname(sock, (struct sockaddr *) &actualServerAddr,
         &actualServerAddrSize);
    if (status < 0) {
        testAbort("Can't find port number!");
    }

    sprintf(portstring, "%d", ntohs(actualServerAddr.sin_port));
    testDiag("Listening on port %s", portstring);

    /* Set the EPICS environment variables for logging. */
    epicsEnvSet ( "EPICS_IOC_LOG_INET", "localhost" );
    epicsEnvSet ( "EPICS_IOC_LOG_PORT", portstring );

    pfdctx = (void *) fdmgr_init();
    if (status < 0) {
        testAbort("fdmgr_init failed!");
    }

    status = fdmgr_add_callback(pfdctx, sock, fdi_read,
        acceptNewClient, &serverAddr);

    if (status < 0) {
        testAbort("fdmgr_add_callback failed!");
    }

    testOk1(iocLogInit() == 0);
    fdmgr_pend_event(pfdctx, &timeout);

    testPrefixLogandCompare(prefixactualmsg[0]);

    iocLogPrefix(prefixstring);
    testPrefixLogandCompare(prefixactualmsg[1]);
    testPrefixLogandCompare(prefixactualmsg[2]);
    epicsSocketDestroy(sock);
}
Esempio n. 12
0
epicsStatus
mrmEvgSetupPCI (
        const char* id,         // Card Identifier
        int b,       			// Bus number
        int d, 					// Device number
        int f,   				// Function number
        bool ignoreVersion)     // Ignore errors due to kernel module and firmware version checks
{
    deviceInfoT deviceInfo;

    deviceInfo.bus.busType = busType_pci;
    deviceInfo.bus.pci.bus = b;
    deviceInfo.bus.pci.device = d;
    deviceInfo.bus.pci.function = f;
    deviceInfo.series = series_unknown;

    try {
        if (mrf::Object::getObject(id)) {
            errlogPrintf("ID %s already in use\n", id);
            return -1;
        }

        if(checkUIOVersion(1) > 0) {    // check if kernel version is successfully read and is as expected or higher, and if it can be read at all.
            if(ignoreVersion){
                epicsPrintf("Ignoring kernel module error.\n");
            }
            else{
                return -1;
            }
        }

        /* Find PCI device from devLib2 */
        const epicsPCIDevice *cur = 0;
        if (devPCIFindBDF(mrmevgs, b, d, f, &cur, 0)) {
            errlogPrintf("PCI Device not found on %x:%x.%x\n", b, d, f);
            return -1;
        }

        epicsPrintf("Device %s  %x:%x.%x\n", id, cur->bus, cur->device, cur->function);
        epicsPrintf("Using IRQ %u\n", cur->irq);


        /* MMap BAR0(plx) and BAR2(EVG)*/
        volatile epicsUInt8 *BAR_plx, *BAR_evg; // base addressed for plx/evg bars

        if (devPCIToLocalAddr(cur, 0, (volatile void**) (void *) &BAR_plx, 0)
                || devPCIToLocalAddr(cur, 2, (volatile void**) (void *) &BAR_evg, 0)) {
            errlogPrintf("Failed to map BARs 0 and 2\n");
            return -1;
        }

        if (!BAR_plx || !BAR_evg) {
            errlogPrintf("BARs mapped to zero? (%08lx,%08lx)\n",
                    (unsigned long) BAR_plx, (unsigned long) BAR_evg);
            return -1;
        }

        //Set LE mode on PLX bridge
        //TODO: this limits cPCI EVG device support to LE architectures
        //			At this point in time we do not have any BE PCI systems at hand so this is left as
        //			unsported until we HW to test it on...

        epicsUInt32 plxCtrl = LE_READ32(BAR_plx,LAS0BRD);
        plxCtrl = plxCtrl & ~LAS0BRD_ENDIAN;
        LE_WRITE32(BAR_plx,LAS0BRD,plxCtrl);


        epicsUInt32 version = checkVersion(BAR_evg, 0x3);
        epicsPrintf("Firmware version: %08x\n", version);

        if(version == 0) {
            if(ignoreVersion) {
                epicsPrintf("Ignoring version error.\n");
            }
            else {
                return -1;
            }
        }

        evgMrm* evg = new evgMrm(id, deviceInfo, BAR_evg, 0, cur);

        evg->getSeqRamMgr()->getSeqRam(0)->disable();
        evg->getSeqRamMgr()->getSeqRam(1)->disable();


        /*Disable the interrupts and enable them at the end of iocInit via initHooks*/
        WRITE32(BAR_evg, IrqFlag, READ32(BAR_evg, IrqFlag));
        WRITE32(BAR_evg, IrqEnable, 0);

        /*
         * Enable active high interrupt1 through the PLX to the PCI bus.
         */
//		LE_WRITE16(BAR_plx, INTCSR,	INTCSR_INT1_Enable| INTCSR_INT1_Polarity| INTCSR_PCI_Enable);
        if(ignoreVersion){
            epicsPrintf("Not enabling interrupts.\n");
        }
        else {
            if(devPCIEnableInterrupt(cur)) {
                errlogPrintf("Failed to enable interrupt\n");
                return -1;
            }
        }

#ifdef __linux__
        evg->isrLinuxPvt = (void*) cur;
#endif

        /*Connect Interrupt handler to isr thread*/
        if(ignoreVersion){
            epicsPrintf("Not connecting interrupts.\n");
        }
        else {
            if (devPCIConnectInterrupt(cur, &evgMrm::isr_pci, (void*) evg, 0)) {//devConnectInterruptVME(irqVector & 0xff, &evgMrm::isr, evg)){
                errlogPrintf("ERROR:Failed to connect PCI interrupt\n");
                delete evg;
                return -1;
            } else {
                epicsPrintf("PCI interrupt connected!\n");
            }
        }
    } catch (std::exception& e) {
        errlogPrintf("Error: %s\n", e.what());
        errlogFlush();
        return -1;
    }

    return 0;
} //mrmEvgSetupPCI
Esempio n. 13
0
epicsStatus
mrmEvgSetupVME (
    const char* id,         // Card Identifier
    epicsInt32  slot,       // VME slot
    epicsUInt32 vmeAddress, // Desired VME address in A24 space
    epicsInt32  irqLevel,   // Desired interrupt level
    epicsInt32  irqVector,  // Desired interrupt vector number
    bool ignoreVersion)     // Ignore errors due to firmware checks
{
    volatile epicsUInt8* regCpuAddr = 0;
    volatile epicsUInt8* regCpuAddr2 = 0; //function 2 of regmap (fanout/concentrator specifics)
    struct VMECSRID info;
    deviceInfoT deviceInfo;

    info.board = 0; info.revision = 0; info.vendor = 0;

    deviceInfo.bus.busType = busType_vme;
    deviceInfo.bus.vme.slot = slot;
    deviceInfo.bus.vme.address = vmeAddress;
    deviceInfo.bus.vme.irqLevel = irqLevel;
    deviceInfo.bus.vme.irqVector = irqVector;
    deviceInfo.series = series_unknown;


    int status; // a variable to hold function return statuses

    try {
        if(mrf::Object::getObject(id)){
            errlogPrintf("ID %s already in use\n",id);
            return -1;
        }

        volatile unsigned char* csrCpuAddr; // csrCpuAddr is VME-CSR space CPU address for the board
        csrCpuAddr = //devCSRProbeSlot(slot);
                     devCSRTestSlot(vmeEvgIDs,slot,&info); //FIXME: add support for EVM id

        if(!csrCpuAddr) {
            errlogPrintf("No EVG in slot %d\n",slot);
            return -1;
        }

        epicsPrintf("##### Setting up MRF EVG in VME Slot %d #####\n",slot);
        epicsPrintf("Found Vendor: %08x\nBoard: %08x\nRevision: %08x\n",
                info.vendor, info.board, info.revision);

        epicsUInt32 xxx = CSRRead32(csrCpuAddr + CSR_FN_ADER(1));
        if(xxx)
            epicsPrintf("Warning: EVG not in power on state! (%08x)\n", xxx);

        /*Setting the base address of Register Map on VME Board (EVG)*/
        CSRSetBase(csrCpuAddr, 1, vmeAddress, VME_AM_STD_SUP_DATA);

        {
            epicsUInt32 temp=CSRRead32((csrCpuAddr) + CSR_FN_ADER(1));

            if(temp != CSRADER((epicsUInt32)vmeAddress,VME_AM_STD_SUP_DATA)) {
                errlogPrintf("Failed to set CSR Base address in ADER1.  Check VME bus and card firmware version.\n");
                return -1;
            }
        }

        /* Create a static string for the card description (needed by vxWorks) */
        char *Description = allocSNPrintf(40, "EVG-%d '%s' slot %d",
                                          info.board & MRF_BID_SERIES_MASK,
                                          id, slot);

        /*Register VME address and get corresponding CPU address */
        status = devRegisterAddress (
            Description,                           // Event Generator card description
            atVMEA24,                              // A24 Address space
            vmeAddress,                            // Physical address of register space
            EVG_REGMAP_SIZE,                       // Size of card's register space
            (volatile void **)(void *)&regCpuAddr  // Local address of card's register map
        );


        if(status) {
            errlogPrintf("Failed to map VME address %08x\n", vmeAddress);
            return -1;
        }


        epicsUInt32 version = checkVersion(regCpuAddr, 0x3);
        epicsPrintf("Firmware version: %08x\n", version);

        if(version == 0){
            if(ignoreVersion) {
                epicsPrintf("Ignoring version error.\n");
            }
            else {
                return -1;
            }
        }


        /* Set the base address of Register Map for function 2, if we have the right firmware version  */
        if(version >= EVG_FCT_MIN_FIRMWARE) {
            deviceInfo.series = series_300;
            CSRSetBase(csrCpuAddr, 2, vmeAddress+EVG_REGMAP_SIZE, VME_AM_STD_SUP_DATA);
            {
                epicsUInt32 temp=CSRRead32((csrCpuAddr) + CSR_FN_ADER(2));

                if(temp != CSRADER((epicsUInt32)vmeAddress+EVG_REGMAP_SIZE,VME_AM_STD_SUP_DATA)) {
                    epicsPrintf("Failed to set CSR Base address in ADER2 for FCT register mapping.  Check VME bus and card firmware version.\n");
                    return -1;
                }
            }

            /* Create a static string for the card description (needed by vxWorks) */
            char *Description = allocSNPrintf(40, "EVG-%d FOUT'%s' slot %d",
                                              info.board & MRF_BID_SERIES_MASK,
                                              id, slot);

             status = devRegisterAddress (
                Description,                           // Event Generator card description
                atVMEA24,                              // A24 Address space
                vmeAddress+EVG_REGMAP_SIZE,            // Physical address of register space
                EVG_REGMAP_SIZE*2,                     // Size of card's register space
                (volatile void **)(void *)&regCpuAddr2 // Local address of card's register map
            );

            if(status) {
                errlogPrintf("Failed to map VME address %08x for FCT mapping\n", vmeAddress);
                return -1;
            }
        }
        else {
            deviceInfo.series = series_230;
        }

        evgMrm* evg = new evgMrm(id, deviceInfo, regCpuAddr, regCpuAddr2, NULL);

        if(irqLevel > 0 && irqVector >= 0) {
            /*Configure the Interrupt level and vector on the EVG board*/
            CSRWrite8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_LEVEL, irqLevel&0x7);
            CSRWrite8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_VECTOR, irqVector&0xff);

            epicsPrintf("IRQ Level: %d\nIRQ Vector: %d\n",
                CSRRead8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_LEVEL),
                CSRRead8(csrCpuAddr + UCSR_DEFAULT_OFFSET + UCSR_IRQ_VECTOR)
            );


            epicsPrintf("csrCpuAddr : %p\nregCpuAddr : %p\nreCpuAddr2 : %p\n",csrCpuAddr, regCpuAddr, regCpuAddr2);

            /*Disable the interrupts and enable them at the end of iocInit via initHooks*/
            WRITE32(regCpuAddr, IrqFlag, READ32(regCpuAddr, IrqFlag));
            WRITE32(regCpuAddr, IrqEnable, 0);

            // VME IRQ level will be enabled later during iocInit()
            vme_level_mask |= 1 << ((irqLevel&0x7)-1);

            /*Connect Interrupt handler to vector*/
            if(devConnectInterruptVME(irqVector & 0xff, &evgMrm::isr_vme, evg)){
                errlogPrintf("ERROR:Failed to connect VME IRQ vector %d\n"
                                                         ,irqVector&0xff);
                delete evg;
                return -1;
            }
        }
    } catch(std::exception& e) {
        errlogPrintf("Error: %s\n",e.what());
        errlogFlush();
        return -1;
    }
    errlogFlush();
    return 0;

} //mrmEvgSetupVME
Esempio n. 14
0
int main(int argc,char **argv)
{
    int		i;
    char	*outFilename;
    char	*pext;
    FILE	*outFile;
    dbMenu	*pdbMenu;
    dbRecordType	*pdbRecordType;
    dbFldDes	*pdbFldDes;
    dbText	*pdbCdef;
    int		isdbCommonRecord = FALSE;
    char	*plastSlash;
    int		strip;
    char	*path = NULL;
    char	*sub = NULL;
    int		pathLength = 0;
    int		subLength = 0;
    char	**pstr;
    char	*psep;
    int		*len;
    long	status;
    static char *pathSep = OSI_PATH_LIST_SEPARATOR;
    static char *subSep = ",";

    /*Look for options*/
    if(argc<2) {
	fprintf(stderr,"usage: dbToRecordtypeH -Idir -Idir file.dbd [outfile]\n");
	exit(0);
    }
    while((strncmp(argv[1],"-I",2)==0)||(strncmp(argv[1],"-S",2)==0)) {
	if(strncmp(argv[1],"-I",2)==0) {
	    pstr = &path;
	    psep = pathSep;
	    len = &pathLength;
	} else {
	    pstr = &sub;
	    psep = subSep;
	    len = &subLength;
	}
	if(strlen(argv[1])==2) {
	    dbCatString(pstr,len,argv[2],psep);
	    strip = 2;
	} else {
	    dbCatString(pstr,len,argv[1]+2,psep);
	    strip = 1;
	}
	argc -= strip;
	for(i=1; i<argc; i++) argv[i] = argv[i + strip];
    }
    if(argc<2 || (strncmp(argv[1],"-",1)==0)) {
	fprintf(stderr,"usage: dbToRecordtypeH -Idir -Idir file.dbd [outfile]\n");
	exit(0);
    }
    if(argc==2){
    /*remove path so that outFile is created where program is executed*/
    plastSlash = strrchr(argv[1],'/');
    if(!plastSlash)  plastSlash = strrchr(argv[1],'\\');
    plastSlash = (plastSlash ? plastSlash+1 : argv[1]);
    outFilename = dbCalloc(1,strlen(plastSlash)+1);
    strcpy(outFilename,plastSlash);
    pext = strstr(outFilename,".dbd");
    if(!pext) {
	fprintf(stderr,"Input file MUST have .dbd extension\n");
	exit(-1);
    }
    strcpy(pext,".h");
    if(strcmp(outFilename,"dbCommonRecord.h")==0) {
	strcpy(outFilename,"dbCommon.h");
	isdbCommonRecord = TRUE;
    }
    }else {
    outFilename = dbCalloc(1,strlen(argv[2])+1);
    strcpy(outFilename,argv[2]);
    if(strstr(outFilename,"dbCommon.h")!=0) {
	isdbCommonRecord = TRUE;
    }
    }
    pdbbase = dbAllocBase();
    pdbbase->ignoreMissingMenus = TRUE;
    pdbbase->loadCdefs = TRUE;
    status = dbReadDatabase(&pdbbase,argv[1],path,sub);
    if(status)  {
        errlogFlush();
        fprintf(stderr, "dbToMenuH: Input errors, no output generated\n");
        exit(1);
    }
    outFile = fopen(outFilename,"w");
    if(!outFile) {
        epicsPrintf("Error creating output file \"%s\"\n", outFilename);
        exit(1);
    }

    pdbMenu = (dbMenu *)ellFirst(&pdbbase->menuList);
    while(pdbMenu) {
	fprintf(outFile,"\n#ifndef INC%sH\n",pdbMenu->name);
	fprintf(outFile,"#define INC%sH\n",pdbMenu->name);
	fprintf(outFile,"typedef enum {\n");
	for(i=0; i<pdbMenu->nChoice; i++) {
            fprintf(outFile,"\t%s",pdbMenu->papChoiceName[i]);
            if(i < (pdbMenu->nChoice - 1)) fprintf(outFile,",");
            fprintf(outFile,"\n");
	}
	fprintf(outFile,"}%s;\n",pdbMenu->name);
	fprintf(outFile,"#endif /*INC%sH*/\n",pdbMenu->name);
	pdbMenu = (dbMenu *)ellNext(&pdbMenu->node);
    }
    pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList);
    while(pdbRecordType) {
        fprintf(outFile,"#ifndef INC%sH\n",pdbRecordType->name);
        fprintf(outFile,"#define INC%sH\n",pdbRecordType->name);
	pdbCdef = (dbText *)ellFirst(&pdbRecordType->cdefList);
	while (pdbCdef) {
	    fprintf(outFile,"%s\n",pdbCdef->text);
	    pdbCdef = (dbText *)ellNext(&pdbCdef->node);
	}
	fprintf(outFile,"typedef struct %s",pdbRecordType->name);
	if(!isdbCommonRecord) fprintf(outFile,"Record");
	fprintf(outFile," {\n");
	for(i=0; i<pdbRecordType->no_fields; i++) {
	    char	name[256];
	    int		j;

	    pdbFldDes = pdbRecordType->papFldDes[i];
	    for(j=0; j< (int)strlen(pdbFldDes->name); j++)
		name[j] = tolower(pdbFldDes->name[j]);
	    name[strlen(pdbFldDes->name)] = 0;
	    switch(pdbFldDes->field_type) {
		case DBF_STRING :
		    fprintf(outFile, "\tchar\t\t%s[%d];\t/* %s */\n",
			name, pdbFldDes->size, pdbFldDes->prompt);
		    break;
		case DBF_CHAR :
		    fprintf(outFile, "\tepicsInt8\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_UCHAR :
		    fprintf(outFile, "\tepicsUInt8\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_SHORT :
		    fprintf(outFile, "\tepicsInt16\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_USHORT :
		    fprintf(outFile, "\tepicsUInt16\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_LONG :
		    fprintf(outFile, "\tepicsInt32\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_ULONG :
		    fprintf(outFile, "\tepicsUInt32\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_FLOAT :
		    fprintf(outFile, "\tepicsFloat32\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_DOUBLE :
		    fprintf(outFile, "\tepicsFloat64\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_ENUM :
		case DBF_MENU :
		case DBF_DEVICE :
		    fprintf(outFile, "\tepicsEnum16\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_INLINK :
		case DBF_OUTLINK :
		case DBF_FWDLINK :
		    fprintf(outFile, "\tDBLINK\t\t%s;\t/* %s */\n",
			name, pdbFldDes->prompt);
		    break;
		case DBF_NOACCESS:
		    fprintf(outFile, "\t%s;\t/* %s */\n",
			pdbFldDes->extra, pdbFldDes->prompt);
		    break;
		default:
		    fprintf(outFile,"ILLEGAL FIELD TYPE\n");
	    }
	}
	fprintf(outFile,"} %s",pdbRecordType->name);
	if(!isdbCommonRecord) fprintf(outFile,"Record");
	fprintf(outFile,";\n");
	if(!isdbCommonRecord) {
	    for(i=0; i<pdbRecordType->no_fields; i++) {
		pdbFldDes = pdbRecordType->papFldDes[i];
		fprintf(outFile,"#define %sRecord%s\t%d\n",
		    pdbRecordType->name,pdbFldDes->name,pdbFldDes->indRecordType);
	    }
	}
	fprintf(outFile,"#endif /*INC%sH*/\n",pdbRecordType->name);
	pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node);
	if(pdbRecordType) fprintf(outFile,"\n");
    }
    if(!isdbCommonRecord) {
	fprintf(outFile,"#ifdef GEN_SIZE_OFFSET\n");
	fprintf(outFile,"#ifdef __cplusplus\n");
	fprintf(outFile,"extern \"C\" {\n");
	fprintf(outFile,"#endif\n");
        fprintf(outFile,"#include <epicsExport.h>\n");
	pdbRecordType = (dbRecordType *)ellFirst(&pdbbase->recordTypeList);
	while(pdbRecordType) {
		fprintf(outFile,"static int %sRecordSizeOffset(dbRecordType *pdbRecordType)\n{\n",
		pdbRecordType->name);
	    fprintf(outFile,"    %sRecord *prec = 0;\n",pdbRecordType->name);
	    for(i=0; i<pdbRecordType->no_fields; i++) {
		char	name[256];
		int		j;

		pdbFldDes = pdbRecordType->papFldDes[i];
		for(j=0; j< (int)strlen(pdbFldDes->name); j++)
		    name[j] = tolower(pdbFldDes->name[j]);
		name[strlen(pdbFldDes->name)] = 0;
		fprintf(outFile,
		"  pdbRecordType->papFldDes[%d]->size=sizeof(prec->%s);\n",
		    i,name);
		fprintf(outFile,"  pdbRecordType->papFldDes[%d]->offset=",i);
		fprintf(outFile,
		    "(short)((char *)&prec->%s - (char *)prec);\n",name);
	    }
	    fprintf(outFile,"    pdbRecordType->rec_size = sizeof(*prec);\n");
	    fprintf(outFile,"    return(0);\n");
	    fprintf(outFile,"}\n");
	    fprintf(outFile,"epicsExportRegistrar(%sRecordSizeOffset);\n",
		pdbRecordType->name);
	    pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node);
	}
	fprintf(outFile,"#ifdef __cplusplus\n");
	fprintf(outFile,"}\n");
	fprintf(outFile,"#endif\n");
	fprintf(outFile,"#endif /*GEN_SIZE_OFFSET*/\n");
    }
    fclose(outFile);
    free((void *)outFilename);
    return(0);
}