/// Load a db file multiple times substituting a specified macro according to a number range.
///
/// The \a dbFile and \a macros arguments are like the normal dbLoadRecords() however
/// it is possible to embed a macro within these whose value follows the range \a start to \a stop.
/// You can either load the same \a dbFile multiple times with different macros, or even load
/// different database files by using \a loopVar as part of the filename. If you want to use a list
/// of (non-numeric) substitutions rather than an integer range see dbLoadRecordsList()
///
/// The name of the macro to be used for substitution is contained in \a loopVar and needs to be
/// reference in an \\ escaped way to make sure EPICS does not try to substitute it too soon.
/// as well as the \a macros the \a dbFile is also passed the \a loopVar macro value
/// @code
///     dbLoadRecordsLoop("file\$(I).db", "P=1,Q=Hello\$(I)", "I", 1, 4)
/// @endcode 
///
/// @param[in] dbFile @copydoc dbLoadRecordsLoopInitArg0
/// @param[in] macros @copydoc dbLoadRecordsLoopInitArg1
/// @param[in] loopVar @copydoc dbLoadRecordsLoopInitArg2
/// @param[in] start @copydoc dbLoadRecordsLoopInitArg3
/// @param[in] stop @copydoc dbLoadRecordsLoopInitArg4
/// @param[in] step @copydoc dbLoadRecordsLoopInitArg5
epicsShareFunc void dbLoadRecordsLoop(const char* dbFile, const char* macros, const char* loopVar, int start, int stop, int step)
{
    char loopVal[32];
    if (loopVar == NULL)
    {
        dbLoadRecords(dbFile, macros);
        return;
    }
    if (step <= 0)
    {
        step = 1;
    }
    std::string macros_s, dbFile_s;
    subMacros(macros_s, macros, loopVar);
    subMacros(dbFile_s, dbFile, loopVar);
    MAC_HANDLE* mh = NULL;
	char macros_exp[1024], dbFile_exp[1024];
    macCreateHandle(&mh, NULL);
	loadMacEnviron(mh);
    for(int i = start; i <= stop; i += step)
    {
		macPushScope(mh);
        epicsSnprintf(loopVal, sizeof(loopVal), "%d", i);
        macPutValue(mh, loopVar, loopVal);   
        macExpandString(mh, macros_s.c_str(), macros_exp, sizeof(macros_exp));
        macExpandString(mh, dbFile_s.c_str(), dbFile_exp, sizeof(dbFile_exp));
        std::ostringstream new_macros;
        new_macros << macros_exp << (strlen(macros_exp) > 0 ? "," : "") << loopVar << "=" << i;
        std::cout << "--> (" << i << ") dbLoadRecords(\"" << dbFile_exp << "\",\"" << new_macros.str() << "\")" << std::endl;
        dbLoadRecords(dbFile_exp, new_macros.str().c_str());
		macPopScope(mh);
    }
	macDeleteHandle(mh);		
}
/// Load a db file multiple times according to a list of items separated by known separator(s).
///
/// The \a dbFile and \a macros arguments are like the normal dbLoadRecords() however
/// it is possible to embed a macro within these whose value takes a value from the \a list.
/// You can either load the same \a dbFile multiple times with different macros, or even load
/// different database files by using \a loopVar as part of the filename. If you want to use a 
/// pure numeric range see dbLoadRecordsLoop()
///
/// The name of the macro to be used for substitution is contained in \a loopVar and needs to be
/// reference in an \\ escaped way to make sure EPICS does not try to substitute it too soon.
/// as well as the \a macros the \a dbFile is also passed the \a loopVar macro value
/// @code
///     dbLoadRecordsList("file\$(S).db", "P=1,Q=Hello\$(S)", "S", "A;B;C", ";")
/// @endcode 
///
/// @param[in] dbFile @copydoc dbLoadRecordsListInitArg0
/// @param[in] macros @copydoc dbLoadRecordsListInitArg1
/// @param[in] loopVar @copydoc dbLoadRecordsListInitArg2
/// @param[in] list @copydoc dbLoadRecordsListInitArg3
/// @param[in] sep @copydoc dbLoadRecordsListInitArg4
epicsShareFunc void dbLoadRecordsList(const char* dbFile, const char* macros, const char* loopVar, const char* list, const char* sep)
{
    static const char* default_sep = ";";
    if (loopVar == NULL || list == NULL)
    {
        dbLoadRecords(dbFile, macros);
        return;
    }
	if (sep == NULL)
	{
		sep = default_sep;
	}
    std::string macros_s, dbFile_s;
    subMacros(macros_s, macros, loopVar);
    subMacros(dbFile_s, dbFile, loopVar);
    MAC_HANDLE* mh = NULL;
	char macros_exp[1024], dbFile_exp[1024];
    macCreateHandle(&mh, NULL);
	loadMacEnviron(mh);
    char* saveptr = NULL;
    char* list_tmp = strdup(list);
    char* list_item = epicsStrtok_r(list_tmp, sep, &saveptr);
    while(list_item != NULL)
    {
		macPushScope(mh);
        macPutValue(mh, loopVar, list_item);   
        macExpandString(mh, macros_s.c_str(), macros_exp, sizeof(macros_exp));
        macExpandString(mh, dbFile_s.c_str(), dbFile_exp, sizeof(dbFile_exp));
        std::ostringstream new_macros;
        new_macros << macros_exp << (strlen(macros_exp) > 0 ? "," : "") << loopVar << "=" << list_item;
        std::cout << "--> (" << list_item << ") dbLoadRecords(\"" << dbFile_exp << "\",\"" << new_macros.str() << "\")" << std::endl;
        dbLoadRecords(dbFile_exp, new_macros.str().c_str());
        list_item = epicsStrtok_r(NULL, sep, &saveptr);
		macPopScope(mh);
    }
    free(list_tmp);
	macDeleteHandle(mh);		
}
Exemplo n.º 3
0
Arquivo: main.c Projeto: jbl5088/psu
int main(int argc, char *const argv[])
{
	puts("");
	argF = 0;				// -f argument: file - use file as a makefile
	argK = 0;				// -k argument: keep going - Continue as much as possible after error
	argN = 0;				// -n argument: Just print - print the commands that would be executed, don't execute
	argQ = 0;				// -q argument: question - don't run commands
	hasChanged = 0;
	bool hasTarget = 0;		// whether or not a target is specified from command line	

	char *makeFile;			// filename for the makefile being used.
	char *target;			// target to be used

	FILE *myFile;			// file to be used for reading

	int c;					// used for getopt loop

	while((c = getopt(argc, argv, "f:knq")) != -1)			// Collect command arguments
	{
		if(c == 'k') argK = 1;								// set K
		
		if(c == 'f' && argF == 0)							// set F (only if it has not been set before)
		{
			argF = 1;				
			makeFile = (char*)calloc(1, strlen(optarg) + 1);	// extract filename
			strcpy(makeFile, optarg);
		}

		if(c == 'n') argN = 1;								// set N
		if(c == 'q') argQ = 1;								// set Q

	}
	
	if(!argF)
	{
		struct stat fileBuf;
	
		if(stat("GNUmakefile", &fileBuf) == 0)
			makeFile = "GNUmakefile";
		else if(stat("makefile", &fileBuf) == 0)
			makeFile = "makefile";
		else if(stat("Makefile", &fileBuf) == 0)
			makeFile = "Makefile";
		else
		{
			printf("Could not find a default makefile.  Program terminating...\n");
			exit(0);
		}
	}
												

	if(argc > optind)										// if there are still arguments after the command options,
	{														// extract the target command from the argument list
		hasTarget = 1;									
		target = calloc(1, strlen(argv[optind]) + 1);
		strcpy(target, argv[optind]);
		originalTarget = target;
	}
	
	myFile = fopen(makeFile, "r");
	
	char line[MACROSIZE];
	char *makeString[MACROSIZE];
	int counter = 0;

	if( myFile != NULL)
	{

		while(fgets (line, sizeof line, myFile) != NULL)
		{
			makeString[counter] = calloc(1, strlen(line) + 1);
			strcpy(makeString[counter], line);
//			puts(makeString[counter]);
			counter ++;
		}
		
		fclose(myFile);
	}
	


	macI *firstMacro = calloc(1, sizeof(macI));
	firstMacro = createList(firstMacro, makeString, counter);

	for(int i = 0; i < counter; i++)
	{
		char *temp = subMacros(makeString[i], firstMacro);
		makeString[i] = realloc(makeString[i], strlen(temp) + 1);
		strcpy(makeString[i], temp);
		RemoveNewLines(makeString[i]);
		makeString[i] = RemoveStartSpaces(makeString[i]);

	}




	
	tItem *firstTarget = calloc(1, sizeof(tItem));
	firstTarget = insertTarget(firstTarget, FIRSTTARGET);
	

	switch(evaluateTarget(makeString, target, counter, hasTarget, firstTarget))
	{
		case 3:
//			puts("1");
			return 1;
			break;
		case 4:
//			puts("0");
			return 0;
			break;
		default:
			break;
	}
	

// ****************************************** FREE MEMORY *************************************
// ****************************************** FREE MEMORY *************************************
// ****************************************** FREE MEMORY *************************************

	if(hasChanged == 0) printf("mymake: `%s' is up to date.\n", originalTarget);

	if(argF) free(makeFile);


	if(hasTarget) free(target);


	for(int i = 0; i < counter; i ++)
		free(makeString[counter]);

	
	freeTargets(firstTarget);


	freeMacros(firstMacro);


}