Ejemplo n.º 1
0
Archivo: parser.c Proyecto: WCP52/gpha
/**
 * Parse boolean parameter as described in the spec SCPI-99 7.3 Boolean Program Data
 * @param context
 * @param value
 * @param mandatory
 * @return 
 */
scpi_bool_t SCPI_ParamBool(scpi_t * context, scpi_bool_t * value, scpi_bool_t mandatory) {
    const char * param;
    size_t param_len;
    size_t num_len;
    int32_t i;

    if (!value) {
        return FALSE;
    }

    if (!SCPI_ParamString(context, &param, &param_len, mandatory)) {
        return FALSE;
    }

    if (matchPattern("ON", 2, param, param_len)) {
        *value = TRUE;
    } else if (matchPattern("OFF", 3, param, param_len)) {
        *value = FALSE;
    } else {
        num_len = strToLong(param, &i);

        if (num_len != param_len) {
            SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
            return FALSE;
        }

        *value = i ? TRUE : FALSE;
    }

    return TRUE;
}
Ejemplo n.º 2
0
/**
 * Compare two strings, one be longer but may contains only numbers in that section
 * @param str1
 * @param len1
 * @param str2
 * @param len2
 * @return TRUE if strings match
 */
scpi_bool_t compareStrAndNum(const char * str1, size_t len1, const char * str2, size_t len2, int32_t * num) {
    scpi_bool_t result = FALSE;
    size_t i;

    if (len2 < len1) {
        return FALSE;
    }

    if (SCPIDEFINE_strncasecmp(str1, str2, len1) == 0) {
        result = TRUE;

        if (num) {
            if (len1 == len2) {
                *num = 1;
            } else {
                int32_t tmpNum;
                i = len1 + strToLong(str2 + len1, &tmpNum, 10);
                if (i != len2) {
                    result = FALSE;
                } else {
                    *num = tmpNum;
                }
            }
        } else {
            for (i = len1; i<len2; i++) {
                if (!isdigit((int) str2[i])) {
                    result = FALSE;
                    break;
                }
            }
        }
    }

    return result;
}
Ejemplo n.º 3
0
//cli arg defines upper bound for sum of even fib numbers below upper bound
//for 4000000, should be 4613732
int main(int argc, char *argv[]){
    int upperBound;
    if(argc > 1){
        upperBound = strToLong(argv[1], -1);
        if(upperBound == -1){
            printf("Enter a real number!\n");
            return -1;
        }
    }else{
        printf("Requires 1 cli arg!\n");
        return 1;
    }
    
    int *fibs = genFibb(upperBound);
    int i, sum=0;

    for(i=0; i< *(fibs-1); i++){
        if(fibs[i] % 2 == 0)
            sum+=fibs[i];   
    }
    fibs--;

    printf("Sum of even fibb numbers below %i: %i\n", upperBound, sum);
    free(fibs);
    return 0;
}
Ejemplo n.º 4
0
extern boolean strToInt(const char *const str, int base, int *value)
{
	long long_value;

	if(!strToLong(str, base, &long_value) || long_value > INT_MAX || long_value < INT_MIN)
		return false;

	*value = (int) long_value;
	return true;
}
Ejemplo n.º 5
0
Archivo: misc.c Proyecto: bioboy/ebbnc2
bool strToInt(const char* s, int* i)
{
    long value;
    bool result = strToLong(s, &value);
    if (result) {
        *i = (int) value;
        return true;
    }
    return false;
}
Ejemplo n.º 6
0
/**
 * Convert parameter to integer
 * @param context
 * @param parameter
 * @param value result
 * @return TRUE if succesful
 */
scpi_bool_t SCPI_ParamToInt(scpi_t * context, scpi_parameter_t * parameter, int32_t * value) {

    if (!value) {
        SCPI_ErrorPush(context, SCPI_ERROR_SYSTEM_ERROR);
        return FALSE;
    }

    switch (parameter->type) {
        case SCPI_TOKEN_HEXNUM:
            return strToLong(parameter->ptr, value, 16) > 0 ? TRUE : FALSE;
        case SCPI_TOKEN_OCTNUM:
            return strToLong(parameter->ptr, value, 8) > 0 ? TRUE : FALSE;
        case SCPI_TOKEN_BINNUM:
            return strToLong(parameter->ptr, value, 2) > 0 ? TRUE : FALSE;
        case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA:
        case SCPI_TOKEN_DECIMAL_NUMERIC_PROGRAM_DATA_WITH_SUFFIX:
            return strToLong(parameter->ptr, value, 10) > 0 ? TRUE : FALSE;
    }
    return FALSE;
}
Ejemplo n.º 7
0
Archivo: parser.c Proyecto: WCP52/gpha
/**
 * Parse integer parameter
 * @param context
 * @param value
 * @param mandatory
 * @return 
 */
scpi_bool_t SCPI_ParamInt(scpi_t * context, int32_t * value, scpi_bool_t mandatory) {
    const char * param;
    size_t param_len;
    size_t num_len;

    if (!value) {
        return FALSE;
    }

    if (!SCPI_ParamString(context, &param, &param_len, mandatory)) {
        return FALSE;
    }

    num_len = strToLong(param, value);

    if (num_len != param_len) {
        SCPI_ErrorPush(context, SCPI_ERROR_SUFFIX_NOT_ALLOWED);
        return FALSE;
    }

    return TRUE;
}
Ejemplo n.º 8
0
static json_t* escapeFieldValue (const tagEntryInfo * tag, fieldType ftype, bool returnEmptyStringAsNoValue)
{
	const char *str = renderFieldEscaped (jsonWriter.type, ftype, tag, NO_PARSER_FIELD, NULL);
	if (str)
	{
		unsigned int dt = getFieldDataType(ftype);
		if (dt & FIELDTYPE_STRING)
		{
			if (dt & FIELDTYPE_BOOL && str[0] == '\0')
				return json_false();
			else
				return json_string (str);
		}
		else if (dt & FIELDTYPE_INTEGER)
		{
			long tmp;

			if (strToLong (str, 10, &tmp))
				return json_integer (tmp);
			else
				return NULL;
		}
		else if (dt & FIELDTYPE_BOOL)
		{
			/* TODO: This must be fixed when new boolean field is added.
			   Currently only `file:' field use this. */
			return json_boolean (strcmp ("-", str)); /* "-" -> false */
		}
		AssertNotReached ();
		return NULL;
	}
	else if (returnEmptyStringAsNoValue)
		return json_false();
	else
		return NULL;
}
Ejemplo n.º 9
0
int loadConfigFile(void) {
	int ret, handle;
	char *name, *value;
	char buffer[READ_LENGTH+1];
	int attempt, goodPass;
	const int MAX_RETRIES = 3;

	ret = 0;	
	buffer[READ_LENGTH] = '\0'; //prevents readLine from searching for \n past buffer
	
	for (attempt = 0,goodPass = 0;attempt < MAX_RETRIES && !goodPass;attempt++) {
		goodPass = 1;
		LOG_FILE = 0; //default in case no logging location in config file (turns logging off)
		MACRO_FILE = 0; // default case if no MACRO_FILE listed
		handle = tbOpen((unsigned long)(CONFIG_FILE),O_RDONLY);
		if (handle == -1) {
			ret = -1;
			logString((char *)"CONFIG_FILE NOT FOUND",BUFFER); //NOTE:can't be logged if log file comes from config file
		}
		getLine(-1,0);  // reset in case at end from prior use
		while (goodPass && nextNameValuePair(handle, buffer, ':', &name, &value)) {
			if (!value)
				continue;
			// test there is a new line and that it isn't a comment (starting with "//")
			if (*name == '/' && *(name+1) == '/')
				continue; // move to next line
			if (!goodString(name,0) || !goodString(value,0)) { 
				goodPass = 0;
				logException(14,0,0);
				break; //out of while,but continue with for loop
			}
			if (!strcmp(name,(char *)"KEY_PLAY")) KEY_PLAY=strToInt(value);
				else if (!strcmp(name,(char *)"KEY_LEFT")) KEY_LEFT=strToInt(value);
				else if (!strcmp(name,(char *)"KEY_RIGHT")) KEY_RIGHT=strToInt(value);
				else if (!strcmp(name,(char *)"KEY_UP")) KEY_UP=strToInt(value);
				else if (!strcmp(name,(char *)"KEY_DOWN")) KEY_DOWN=strToInt(value);
				else if (!strcmp(name,(char *)"KEY_SELECT")) KEY_SELECT=strToInt(value);
				else if (!strcmp(name,(char *)"KEY_STAR")) KEY_STAR=strToInt(value);
				else if (!strcmp(name,(char *)"KEY_HOME")) KEY_HOME=strToInt(value);
				else if (!strcmp(name,(char *)"KEY_PLUS")) KEY_PLUS=strToInt(value);
				else if (!strcmp(name,(char *)"KEY_MINUS")) KEY_MINUS=strToInt(value);			
				else if (!strcmp(name,(char *)"LED_GREEN")) LED_GREEN=strToInt(value);
				else if (!strcmp(name,(char *)"LED_RED")) LED_RED=strToInt(value);
				else if (!strcmp(name,(char *)"MAX_SPEED")) MAX_SPEED=strToInt(value);
				else if (!strcmp(name,(char *)"NORMAL_SPEED")) NORMAL_SPEED=strToInt(value);
				else if (!strcmp(name,(char *)"MAX_VOLUME")) MAX_VOLUME=strToInt(value);
				else if (!strcmp(name,(char *)"NORMAL_VOLUME")) NORMAL_VOLUME=strToInt(value);
				else if (!strcmp(name,(char *)"SPEED_INCREMENT")) SPEED_INCREMENT=strToInt(value);
				else if (!strcmp(name,(char *)"VOLUME_INCREMENT")) VOLUME_INCREMENT=strToInt(value);
				else if (!strcmp(name,(char *)"BOOT_PACKAGE")) BOOT_PACKAGE=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"SYSTEM_PATH")) SYSTEM_PATH=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"USER_PATH")) USER_PATH=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"LIST_PATH")) LIST_PATH=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"INBOX_PATH")) INBOX_PATH=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"OUTBOX_PATH")) OUTBOX_PATH=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"NEW_PKG_SUBDIR")) NEW_PKG_SUBDIR=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"SYS_UPDATE_SUBDIR")) SYS_UPDATE_SUBDIR=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"LOG_FILE")) LOG_FILE=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"LIST_MASTER")) LIST_MASTER=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"MAX_PWR_CYCLES_IN_LOG")) MAX_PWR_CYCLES_IN_LOG=strToInt(value);
				else if (!strcmp(name,(char *)"SYSTEM_VARIABLE_FILE")) SYSTEM_VARIABLE_FILE=addTextToSystemHeap(value);
				// can we make the following prefixes be single-byte chars? 
				// it would make it easier to check list items starts with CUSTOM_PKG_PREFIX
				else if (!strcmp(name,(char *)"PKG_NUM_PREFIX")) PKG_NUM_PREFIX=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"LIST_NUM_PREFIX")) LIST_NUM_PREFIX=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"CUSTOM_PKG_PREFIX")) CUSTOM_PKG_PREFIX=addTextToSystemHeap(value);				
				else if (!strcmp(name,(char *)"AUDIO_FILE_EXT")) AUDIO_FILE_EXT=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"DEFAULT_TIME_PRECISION")) DEFAULT_TIME_PRECISION=strToInt(value);
				else if (!strcmp(name,(char *)"DEFAULT_REWIND")) DEFAULT_REWIND=strToInt(value);
				else if (!strcmp(name,(char *)"INSERT_SOUND_REWIND_MS")) INSERT_SOUND_REWIND_MS=strToInt(value);
				else if (!strcmp(name,(char *)"SPEAK_SOUND_FILE_IDX")) SPEAK_SOUND_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"REC_PAUSED_FILE_IDX")) REC_PAUSED_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"POST_REC_FILE_IDX")) POST_REC_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"INACTIVITY_SOUND_FILE_IDX")) INACTIVITY_SOUND_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"ERROR_SOUND_FILE_IDX")) ERROR_SOUND_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"EMPTY_LIST_FILE_IDX")) EMPTY_LIST_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"DELETED_FILE_IDX")) DELETED_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"PRE_COPY_FILE_IDX")) PRE_COPY_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"POST_COPY_FILE_IDX")) POST_COPY_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"POST_PLAY_FILE_IDX")) POST_PLAY_FILE_IDX=strToInt(value);				
				else if (!strcmp(name,(char *)"HYPERLINK_SOUND_FILE_IDX")) HYPERLINK_SOUND_FILE_IDX=strToInt(value);
				else if (!strcmp(name,(char *)"BLOCK_START_LEADER")) BLOCK_START_LEADER=strToInt(value);
				else if (!strcmp(name,(char *)"BLOCK_END_LEADER")) BLOCK_END_LEADER=strToInt(value);
				else if (!strcmp(name,(char *)"BIT_RATE")) BIT_RATE=strToLong(value);
				else if (!strcmp(name,(char *)"GREEN_LED_WHEN_PLAYING")) GREEN_LED_WHEN_PLAYING=strToInt(value);
				else if (!strcmp(name,(char *)"INACTIVITY_SECONDS")) INACTIVITY_SECONDS=strToInt(value);
				else if (!strcmp(name,(char *)"MIC_GAIN_NORMAL")) MIC_GAIN_NORMAL=strToInt(value);
				else if (!strcmp(name,(char *)"MIC_GAIN_HEADPHONE")) MIC_GAIN_HEADPHONE=strToInt(value);
				else if (!strcmp(name,(char *)"CONTROL_TEMPLATE")) CONTROL_TEMPLATE=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"MACRO_FILE")) MACRO_FILE=addTextToSystemHeap(value);
				else if (!strcmp(name,(char *)"VOLTAGE_SAMPLE_FREQ_SEC")) VOLTAGE_SAMPLE_FREQ_SEC=strToInt(value);
				else if (!strcmp(name,(char *)"USB_CLIENT_POLL_INTERVAL")) USB_CLIENT_POLL_INTERVAL=strToInt(value);
				else if (!strcmp(name,(char *)"LOG_WARNINGS")) LOG_WARNINGS=strToInt(value);
				else if (!strcmp(name,(char *)"LOG_KEYS")) LOG_KEYS=strToInt(value);
				else if (!strcmp(name,(char *)"CLOCK_RATE")) CLOCK_RATE = strToInt(value);
		}
	}
	if (!goodPass) {
		ret = -1;
		logString((char *)"CONFIG_FILE NOT READ CORRECTLY",BUFFER);	  //logException(14,0,USB_MODE); 		
	}
	close(handle);
	LED_ALL = LED_GREEN | LED_RED;
	if (*(LOG_FILE+1) != ':')
		LOG_FILE = 0; // should be == "a://....." otherwise, logging is turned off
	return ret;
}
Ejemplo n.º 10
0
long getValueNumForName(char* name, struct NameValuePair* pair, long defaultValue){
 // Searches the list of name/value pairs for the value that corresponds to the specified name, and converts it to an integer
    char* valueTxt = getValueForName(name, pair, NULL);
    return strToLong(valueTxt, defaultValue);
}
Ejemplo n.º 11
0
void processIntToken( char* inStr, struct argsInfo info ){
    long intToken;
    int i;
    
    ptrError = EINVAL;
    
    // Convert string to long
    intToken = strToLong(inStr, info.inputBase);
    
    /* Check for non-integer errors */
    if (errno == ptrError) {
        (void) fprintf(stderr, STR_INT_ENDPTR_ERR, inStr,\
                       info.inputBase);
        return;
    }
    
    /* Check for conversion errors */
    if (errno) {
        perror(inStr);
        return;
    }
    
    /* Print English mode */
    if (info.mode & E_FLAG) {
        
        /* Check for negative numbers */
        if (intToken < 0) {
            (void) printf(STR_MINUS);   // Print out minus sign
        }
        printEnglish(abs(intToken));
        (void) printf(STR_NEWLINE);
    }
    
    /* Print out the numbers in the given bases*/
    for (i = MIN_BASE; i <= MAX_BASE; i++) {
        
        // Get the actual base value based on the given flags
        int realBase = getRealBase(BASE_MASK(i) & info.outputBases);
        
        switch (realBase) {
            case 0:
                break;
                
            /* Print in binary representation*/
            case 2:
                printIntBinary(intToken);
                break;
            
            /* Print out prefix 0 and number in base 8 */
            case 8:
                
                /* Print out negative sign if negative number */
                if (intToken < 0) {
                    (void) printf(STR_NEG_PREFIX);
                }
                (void) printf(STR_OCT_PREFIX);
                printBase(abs(intToken), realBase);
                (void) printf(STR_NEWLINE);
                break;
            
            /* Print out prefix 0x and number in base 16 */
            case 16:
                
                /* Print out negative sign if negative number */
                if (intToken < 0) {
                    (void) printf(STR_NEG_PREFIX);
                }
                (void) printf(STR_HEX_PREFIX);
                printBase(abs(intToken), realBase);
                (void) printf(STR_NEWLINE);
                break;
            
            /* Print out number in given bases without prefixes */
            default:
                if (intToken < 0) {
                    (void) printf(STR_NEG_PREFIX);
                }
                printBase(abs(intToken), realBase);
                (void) printf(STR_NEWLINE);
                break;
        }
    }
}
Ejemplo n.º 12
0
/*
* Function name: main()
* Function prototype: int main ( int argc, char *argv[] );
* Description: C main driver which calls C and SPARC assembly routines to print two
*              squares within each other made of two different characters
* Parameters:
*       arg 1: int argc -- integer count for the number of arguments in argv
*       arg 2: char *argv[] -- array of string inputs
* Side Effects: Outputs two squares within each other made of different chars.
* Error Conditions: None
* Return Value: 0
*/
int main (int argc, char *argv[])
{   
    if(argc != 5)
    {
        (void) printf("Usage: pa1 outer_sq_sz inner_sq_sz outer_sq_ch inner_sq_ch\n");
        (void) printf("     outer_sq_sz (must be within the range of [%d - %d]\n"
                      , OUTER_SQUARE_MIN, OUTER_SQUARE_MAX );
        (void) printf("     inner_sq_sz (must be within the range of [%d - %d]\n"
                      , INNER_SQUARE_MIN, INNER_SQUARE_MIN );
        (void) printf("                 (must be smaller than outer_sq_sz)\n" );
        (void) printf("                 (must be odd if outer_sq_sz is odd)\n" );
        (void) printf("                 (must be even if outer_sq_sz is even)\n" );
        (void) printf("     outer_sq_ch (must be an ASCII value within the range [%d - %d]\n"
                      , ASCII_MIN, ASCII_MAX );
        (void) printf("     inner_sq_ch (must be an ASCII value within the range [%d - %d]\n"
                      , ASCII_MIN, ASCII_MAX );
        (void) printf("                 (must be different than outer_sq_ch)\n" );        
    }/*END IF to check if user knows how to use or not */
    else
    {
        int noError = 0; /* Holds if all data is correct values and in the ranges allowed. */
        long num1 = strToLong(argv[1], BASE); /*Holds the outer square size*/
        if(checkRange(num1, OUTER_SQUARE_MIN, OUTER_SQUARE_MAX) != 1 && errno == 0)
        {
            (void) printf("\n       outer_sq_sz(%ld) must be within the range of [%d - %d]\n",
                           num1, OUTER_SQUARE_MIN, OUTER_SQUARE_MAX );
            noError = 1;
        }/*END IF to check that integer is within the range*/    
        long num2 = strToLong(argv[2], BASE); /*Holds the inner square size*/
        if(checkRange(num2, INNER_SQUARE_MIN, INNER_SQUARE_MAX) != 1 && errno == 0)
        {
            (void) printf("\n       inner_sq_sz(%ld) must be within the range of [%d - %d]\n",
                           num2, INNER_SQUARE_MIN, INNER_SQUARE_MAX );
            noError = 1;
        }/*END IF to check that integer is within the range*/
        if( num2 >= num1 && (num1 != -1 && num2 != -1))
        {
            (void) printf("\n       inner_sq_sz(%ld) must be less than outer_sq_sz(%ld)\n", num2, num1);
            noError = 1;
        }/*end if to check that the second integer passed in is less than the first integer*/
        if(isOdd(num2) != isOdd(num1) && (num1 != -1 && num2 != -1))
        {
            (void) printf("\n       both outer_sq_sz(%ld) and inner_sq_sz(%ld) must be either odd or even\n", num1, num2);
            noError = 1;
        }/*end if to check that both integers are either odd or even*/
        long num3 = strToLong(argv[3], BASE); /*Holds the outer square character*/
        if(checkRange(num3, ASCII_MIN, ASCII_MAX) != 1 && errno == 0)
        {
            (void) printf("\n       outer_sq_ch(%ld) must be an ASCII code in the range [%d - %d]\n",
                           num3, ASCII_MIN, ASCII_MAX );
            noError = 1;
        }/*END IF to check that ASCII code is in the range*/
        long num4 = strToLong(argv[4], BASE); /*Holds the inner square character*/
        if(checkRange(num4, ASCII_MIN, ASCII_MAX) != 1 && errno == 0)
        {
            (void) printf("\n       inner_sq_ch(%ld) must be an ASCII code in the range [%d - %d]\n",
                           num4, ASCII_MIN, ASCII_MAX );
            noError = 1;
        }/*END IF to check that ASCII code is in the range*/
        if(num4 == num3)
        {
            (void) printf("\n       outer_sq_ch(%ld) and inner_sq_ch(%ld) must be different\n", num3, num4);
            noError = 1;
        }/*END IF to check that ASCII code is different*/
        if(noError == 0)
        { 
            displaySquare(num1, num2, num3, num4);
        }/*END IF to check if data is correct to be printed*/
    }/*END ELSE to check that 5 arguments have been sent in from command line */
	return 0;
}/*END main*/
Ejemplo n.º 13
0
void parseControlFile (char * filePath, CtnrPackage *pkg) {
	//symbolMap array size allows for avg symbol length of 10 plus room for an int index to block index
	char *pSymbolMap;
	int currentBlock, currentList, actionCount, currentOrderBlock; 
	int ret; // reused return value check
	int fileHandle;
	BOOL firstBuffer;
	BOOL needPkgActions;
	char *line;
	char *charCursor;
	char *charCursor2;
	OrderBlock *latestStart, *latestEnd;
	char currentContainerType; // P = package; F = file; B = block; L = List (of lists or packages); T = Translation List
	int lineCount;
	ListItem *list;
	TranslationList *transList;
	OrderBlock orderBlocks[MAX_BLOCKS*2];
	char buffer[READ_LENGTH+1];
	char tempBuffer[50];
	char symbolMap[MAX_BLOCKS * AVG_SYMBOL_LENGTH]; 
	int attempt, goodPass;
	//int tempListNum;
	const int MAX_ATTEMPTS = 3;
	
	buffer[READ_LENGTH] = '\0'; //prevents readLine from searching for \n past buffer
	
	for (attempt = 0, goodPass = 0; attempt < MAX_ATTEMPTS && !goodPass; attempt++) {
		// loop to deal with error #8 when no pkg->countFiles == 0
		// it appears that this might be due to a bad read, so we'll retry

		if (attempt) // more than one attempt
			logException(26,0,0);

		goodPass = 1;
		lineCount = -1;  // to make it 0-based
		currentBlock = -1; // haven't started with 0 yet
		actionCount = -1;
		pSymbolMap = symbolMap; //tracks top of heap
		firstBuffer = TRUE;
		latestStart = NULL;
		latestEnd = NULL;
		currentContainerType = 0;	
		pkg->idxLanguageCode = -1;
	
		fileHandle = tbOpen((LPSTR)(filePath),O_RDONLY);
		if (fileHandle == -1) {
			goodPass = 0;
			break; // tbOpen already retries before returning, so give up and handle as if retried
		} else {
			getLine(-1,0); // resets fct to beginning of file
			while ((line = getLine(fileHandle,buffer))) {
				if (!goodString(line,0)) {
					goodPass = 0;
					continue;
				}
				lineCount++;
				if (!currentContainerType) {
					// haven't entered into package container yet
					// check for preface settings
					charCursor = strstr(line,"TIME-PRECISION"); //TODO: move to case-insensitive fct
					if (!charCursor)
					    charCursor = strstr(line,"time-precision"); 
					if (charCursor) {
						charCursor = strchr(line,DELIMITER);
						if (charCursor) {
							pkg->timePrecision = getBitShift((int)strToLong(++charCursor));
							continue;
						}
					}
					charCursor = strstr(line,"APP"); //TODO: handle all this in a const array of application strings
					if (!charCursor)
					    charCursor = strstr(line,"app"); 
					if (charCursor) {
						if ((charCursor = strchr(line,DELIMITER))) {
							charCursor++;
							if (strstr(line,APP_QUIZ_PLAY_STR)) 
								pkg->app_type = APP_QUIZ_PLAY;
							else if (strstr(line,APP_QUIZ_REC_STR)) 
								pkg->app_type = APP_QUIZ_REC;
							else
								pkg->app_type = APP_CUSTOM;
						}
					}
				}
				// parse line if ended with \n or if last line of last buffer	
				switch (*line) {
					case 'P':
						currentContainerType = 'P';
						// if time precision was not specified (see above), use default
						if (!pkg->timePrecision)
							pkg->timePrecision = getBitShift(DEFAULT_TIME_PRECISION);
						// Setting package idxName with list's package name, not the package name in the control track
/*						charCursor = strchr(line,DELIMITER) + 1;
						if (*charCursor != 0) {
							ret = addTextToPkgHeap (charCursor,pkg);
							if (ret > -1) {
								pkg->idxName = ret;											
							}
						}
*/						break;
					case 'L':
						charCursor = strchr(line,DELIMITER) + 1;
						if (*charCursor == 'T') {
							currentContainerType = 'T';
							transList = &context.package->transList;
							transList->idxFirstAction = -1;
							transList->currFileIdx = -1;
							transList->mode = '0';
							
						}
						else {
							currentContainerType = 'L';
							pkg->countLists++;
							if (pkg->countLists > MAX_LISTS) {
								close(fileHandle);
								strcpy(tempBuffer,"ListItem#");
								longToDecimalString((long)pkg->countLists,tempBuffer+strlen(tempBuffer),2);
								logException(2,tempBuffer,(context.package == &pkgSystem)?USB_MODE:RESET); // todo: too many files, blocks, or lists
							}

							// now prep new ListItem container
							list = &pkg->lists[pkg->countLists-1];
							list->idxFirstAction = -1;
							list->currentFilePosition =  -1;
						}
						// first wrap up last File container, if any
						if (pkg->countFiles && latestStart) 
							setBlockOrder(pkg,latestStart,latestEnd);
						//charCursor = strchr(line,DELIMITER) + 1;
						if (*charCursor == 'L') {
							list->listType = LIST_OF_LISTS;
							pkg->idxMasterList = pkg->countLists-1;	
						}
						else if (*charCursor == 'P')
							list->listType = LIST_OF_PACKAGES;
						else if (*charCursor != 'T') {
							close(fileHandle);
							logException(8,line,(context.package == &pkgSystem)?USB_MODE:RESET);//syntax error
						}
						charCursor++;
						if (*charCursor != '[') 
							charCursor++; // skip any single char delimiter before list name, unless already at label
						while (*charCursor && isspace(*charCursor))
							charCursor++;
						if (*charCursor != 0) {
							if (currentContainerType == 'L' && *charCursor == '{') {
								charCursor++;
								ret = getIndexFromLine(charCursor,symbolMap);
	 							if (ret != -1) {	
									list->idxListWithFilename = ret;
									list->filename[0] = 0;
	 							}
								else {
									logException(6,charCursor,(context.package == &pkgSystem)?USB_MODE:RESET);  // todo:invalid internal reference in control track file 
								}
	 							charCursor = strchr(charCursor,'}');
	 							charCursor = strchr(charCursor,'[') + 1;
							}
							else {
								charCursor2 = strchr(charCursor,'[');
								if (charCursor2 == NULL) {
									close(fileHandle);
									strcpy(tempBuffer,"ListItem#");
									longToDecimalString((long)pkg->countLists,tempBuffer+strlen(tempBuffer),2);
								    logException(8,tempBuffer,(context.package == &pkgSystem)?USB_MODE:RESET); //todo: syntax error in control track
								} else if (charCursor == charCursor2){
									// '[' immediate follows list type -- no list filename
									//if (list->listType == LIST_OF_LISTS) { // no list filename needed for Lists of Lists (they use config master list)
									if (currentContainerType == 'L' && list->listType == LIST_OF_LISTS) { // no list filename needed for Lists of Lists (they use config master list)
										strcpy(list->filename,LIST_MASTER);
										charCursor++; //advance cursor from '[' to first character of list label
									}
									else if(currentContainerType == 'T') {
										charCursor++; //advance cursor from '[' to first character of list label
									}
									else {
										// Lists of Packages must have list filename
										strcpy(tempBuffer,"No list name");
										longToDecimalString((long)pkg->countLists,tempBuffer+strlen(tempBuffer),2);
									    logException(8,tempBuffer,(context.package == &pkgSystem)?USB_MODE:RESET); //todo: syntax error in control track
									}
								} else if (currentContainerType == 'L') {
									while (isspace(*(charCursor2-1)) && charCursor2 >= charCursor)
										charCursor2--;							
									*charCursor2++ = 0; // set null mark and move back to space or [
									strcpy(list->filename,charCursor);
									charCursor = charCursor2;  
									for (;isspace(*charCursor);charCursor++); // move cursor back to '['
									charCursor++; // move to first character of label
								}
							}
							charCursor2 = strchr(charCursor,']');
							if (charCursor2 != NULL)
								*charCursor2 = 0;
							else  {
								close(fileHandle);
								logException(8,charCursor,(context.package == &pkgSystem)?USB_MODE:RESET); //todo: syntax error in control track
							}
							//todo: separate list and block namespaces?
							charCursor = strcpy(pSymbolMap,charCursor);
							charCursor = strchr(charCursor,'\0');
							if(currentContainerType == 'T') {
								*(charCursor + 1) = MAX_LISTS;
								//*(charCursor + 1) = 2;
								//tempListNum = *(charCursor + 1);
								//strcpy(tempBuffer,"TranslationList#");
								//longToDecimalString((long)tempListNum,tempBuffer+strlen(tempBuffer),2);
								//logException(99,tempBuffer,(context.package == &pkgSystem)?USB_MODE:RESET); // todo: too many files, blocks, or lists
							}
							else 
								*(charCursor + 1) = pkg->countLists-1;
							pSymbolMap = charCursor + 2;
							if ((pSymbolMap - symbolMap) > (MAX_BLOCKS * AVG_SYMBOL_LENGTH)) {
								close(fileHandle);
								logException(7,0,(context.package == &pkgSystem)?USB_MODE:RESET); // todo: internal symbol heap is full							
							}
						}
						break;
					case 'F':
						currentContainerType = 'F';
						// first wrap up last File container, if any
						if (pkg->countFiles && latestStart) 
							setBlockOrder(pkg,latestStart,latestEnd);
									
						// now prep new File container
						charCursor = strchr(line,DELIMITER) + 1;
						if (*charCursor != 0) {
							if (*charCursor == '{') {
								if (*++charCursor == '$' && *++charCursor == 'L')
									pkg->files[pkg->countFiles++].idxFilename = -1; // signal of lastFileRecorded;
							} else { 
								latestStart = NULL;
								latestEnd = NULL;
								ret = addTextToPkgHeap (charCursor,pkg);
								if (ret != -1) {
									pkg->files[pkg->countFiles++].idxFilename = ret;
									currentOrderBlock = -1;
									if (pkg->countFiles > MAX_FILES) {
										close(fileHandle);
										strcpy(tempBuffer,"File#");
										longToDecimalString((long)pkg->countFiles,tempBuffer+strlen(tempBuffer),3);
										logException(2,tempBuffer,(context.package == &pkgSystem)?USB_MODE:RESET); // todo: too many files, blocks, or lists
									}
								}
								else
									logException(4,0,(context.package == &pkgSystem)?USB_MODE:RESET); //todo: text heap is full
							}
						}
						break;
					case 'B':
						currentBlock++;
						if (currentBlock > MAX_BLOCKS) {
							strcpy(tempBuffer,"Block#");
							longToDecimalString((long)currentBlock,tempBuffer+strlen(tempBuffer),3);							
							logException(2,tempBuffer,(context.package == &pkgSystem)?USB_MODE:RESET); // todo: too many actions, files, blocks, or lists
						}
						// check if first block in file
						if (currentContainerType == 'F') 
							pkg->files[pkg->countFiles-1].idxFirstBlockInFile = currentBlock;
						currentContainerType = 'B';
						if (parseCreateBlock(line,&pkg->blocks[currentBlock],&pSymbolMap,currentBlock)) {
							if ((pSymbolMap - symbolMap) > (MAX_BLOCKS * AVG_SYMBOL_LENGTH))
								logException(7,0,(context.package == &pkgSystem)?USB_MODE:RESET); // todo: internal symbol heap is full
							// prepare new orderBlock, but don't know where to link it yet
							orderBlocks[++currentOrderBlock].idxBlock = currentBlock;
							insertOrderBlock (&orderBlocks[currentOrderBlock], &latestStart, pkg->blocks[currentBlock].startTime, STARTING);
							orderBlocks[++currentOrderBlock].idxBlock = currentBlock;
							insertOrderBlock (&orderBlocks[currentOrderBlock], &latestEnd, pkg->blocks[currentBlock].endTime, ENDING);								
						}
						else
							currentBlock--; //back parse, so ignore line and back up counter
						break;
					case 'A':
							// the line below does not handle package actions
							// file actions might not be necessary right now
							if (currentContainerType == 'B' && pkg->blocks[currentBlock].idxFirstAction == -1) {
								//temporarily store file line number to find first action during second pass (below)
								pkg->blocks[currentBlock].idxFirstAction = lineCount; 
							} 
							else if (currentContainerType == 'P' && !pkg->countPackageActions)
								pkg->countPackageActions = lineCount;
							else if (currentContainerType == 'L' && list->idxFirstAction == -1) {
								//temporarily store file line number to find first action during second pass (below)
								list->idxFirstAction = lineCount; 
							} 
							else if (currentContainerType == 'T' && transList->idxFirstAction == -1) {
								//temporarily store file line number to find first action during second pass (below)
								transList->idxFirstAction = lineCount; 
							} 
							break;
				} // switch
			} // while (line);
			// block order for prev file is set when a new file is declared, 
			// but this catches the last file
	
			setBlockOrder(pkg,latestStart,latestEnd);
			
			pkg->countBlocks = currentBlock + 1;  //0-based
			getLine(fileHandle,0); // resets fct to beginning of file
			lineCount = -1;
			actionCount = -1;
			currentBlock = 0;			
			// Get Package Actions
			if (pkg->countPackageActions > 0) {
				do {
					if ((line = getLine(fileHandle,buffer)))
						lineCount++;
					if (!goodString(line,0)) 
						goodPass = 0;
				} while (line && lineCount < pkg->countPackageActions);
				if (!goodPass)
					continue;
				while (line && *line == 'A') {
					ret = parseCreateAction(line, (Action *) &pkg->actions, &actionCount, (char *)&symbolMap, NULL, NULL, NULL);
					if (!ret) {
						goodPass = 0;
						logException(8,0,0); 
					}
					if (actionCount > MAX_ACTIONS) {
						close(fileHandle);
						strcpy(tempBuffer,"Action#");
						longToDecimalString((long)actionCount,tempBuffer+strlen(tempBuffer),3);
						logException(2,tempBuffer,(context.package == &pkgSystem)?USB_MODE:RESET); // todo: too many actions, files, blocks, or lists
					}
					if ((line = getLine(fileHandle,buffer)))
						lineCount++;
					if (!goodString(line,0)) {
						goodPass = 0;
						continue;
					}
				} 
				setEndOfActions(&pkg->actions[actionCount],TRUE);
				pkg->countPackageActions = actionCount + 1;
				needPkgActions = FALSE;
			}  // if (pkg->countPackageActions > 0) 
			do {
				while (pkg->blocks[currentBlock].idxFirstAction == -1 && currentBlock < pkg->countBlocks)
					currentBlock++;
				do {
					if ((line = getLine(fileHandle,buffer)))
						lineCount++;
				} while (line && lineCount < pkg->blocks[currentBlock].idxFirstAction);
				// parse line if ended with \n or if last line of last buffer	
				if (line && *line == 'A') {
					//actionCount is updated within parseCreateAction
					pkg->blocks[currentBlock].idxFirstAction = actionCount + 1;
					do {
						ret = parseCreateAction(line, (Action *)&pkg->actions, &actionCount, (char *)&symbolMap, &pkg->blocks[currentBlock], NULL, NULL);
						if (ret == -1) {
							goodPass = 0;
							break;
						}
						if ((line = getLine(fileHandle,buffer)))
							lineCount++;
						if (!goodString(line,0)) {
							goodPass = 0;
							continue;
						}			
					} while (line && *line == 'A');
					setEndOfActions(&pkg->actions[actionCount],TRUE);
				}	
				currentBlock++;
			} while (line && currentBlock <= pkg->countBlocks);
			//Begin parsing for lists
			currentList = 0;		
			getLine(fileHandle,0); // resets fct to beginning of file
			line = getLine(fileHandle,buffer); // read first line
			if (!goodString(line,0)) {
				goodPass = 0;
				continue;
			}
			lineCount = 0;
			do {
				while (pkg->lists[currentList].idxFirstAction == -1 && currentList < pkg->countLists)
					currentList++;
				while (line && lineCount < pkg->lists[currentList].idxFirstAction) {
					if ((line = getLine(fileHandle,buffer)))
						lineCount++;
					if (!goodString(line,0)) {
						goodPass = 0;
						continue;
					}
				}
				// parse line if ended with \n or if last line of last buffer	
				if (line && *line == 'A') {
					//actionCount is updated within parseCreateAction
					pkg->lists[currentList].idxFirstAction = actionCount + 1;
					do {
						ret = parseCreateAction(line, (Action *)&pkg->actions, &actionCount, (char *)&symbolMap, NULL, &pkg->lists[currentList], NULL);
						//todo: handle ret = -1 or FALSE or 0 or whatever
						if ((line = getLine(fileHandle,buffer)))
							lineCount++;
						if (!goodString(line,0))
							goodPass = 0;
					} while (line && *line == 'A');	
					setEndOfActions(&pkg->actions[actionCount],TRUE);
				}	
				currentList++;
			} while (line && currentList <= pkg->countLists);
			
			//Begin parsing for Translation Lists
			getLine(fileHandle,0); // resets fct to beginning of file
			line = getLine(fileHandle,buffer); // read first line
			if (!goodString(line,0)) {
				goodPass = 0;
				continue;
			}
			lineCount = 0;
			while (line && lineCount < context.package->transList.idxFirstAction) {
				if ((line = getLine(fileHandle,buffer)))
					lineCount++;
				if (!goodString(line,0)) {
					goodPass = 0;
					continue;
				}
			}
			// parse line if ended with \n or if last line of last buffer	
			if (line && *line == 'A') {
				//actionCount is updated within parseCreateAction
				context.package->transList.idxFirstAction = actionCount + 1;
				do {
					ret = parseCreateAction(line, (Action *)&pkg->actions, &actionCount, (char *)&symbolMap, NULL, NULL, &context.package->transList);
					//todo: handle ret = -1 or FALSE or 0 or whatever
					if ((line = getLine(fileHandle,buffer)))
						lineCount++;
					if (!goodString(line,0))
						goodPass = 0;
				} while (line && *line == 'A');	
				setEndOfActions(&pkg->actions[actionCount],TRUE);
			}	
			
			close(fileHandle);
		} // if fileHandle >= 0 
		if (pkg->countFiles == 0)
			goodPass = 0;
	}
	if (!goodPass) 
		logException(8,filePath,(context.package == &pkgSystem)?USB_MODE:RESET); // not able to get a good read after MAX_ATTEMPTS trials
//	else {
//		logString((char *)"parsed ",BUFFER);
//		logString(filePath,ASAP);
//	}
}
Ejemplo n.º 14
0
static BOOL parseCreateBlock (char *line, CtnrBlock *block, char **freeSymbolMap, int idxBlock) {

	int ret;
	char *cursor;
 	unsigned long lStartTime, lEndTime;
	EnumAction blockAction;
	BOOL inLabel;
	
	ret = TRUE;  // TODO: set ret = 0 if there's not even a single time or no '-'  
	
	block->idxFirstAction = -1;
	block->idxNextStart = MASK_IDX_NEXT_START;
	block->idxNextEnd = -1;

	cursor = strchr(line,DELIMITER);
	cursor++; //either number or whitespace immediately following DELIMITER
	
	while (*cursor && isspace(*cursor))
		cursor++;
	
	//check for block-start action (of type EnumAction)
	//todo: don't get tricked into seeing digits in [labels]
	while (*cursor && !isdigit(*cursor) && *cursor != '-') {
		if (!isspace(*cursor)) {
			blockAction = getActionEnumFromChar(cursor);
			if (blockAction >= 0)
				setStartCode(&block->actionStartEnd,blockAction);
			//todo:else exception and log
		}
		cursor++;
	}

	if (*cursor == '-')	
		lStartTime = 0; //nothing before '-' means block begins at beginning of file
	else
		lStartTime = strToLong(cursor);
	//reduce the precision to convert long to int ans space space
	block->startTime = compressTime(lStartTime, context.package->timePrecision);
		
	cursor = strchr(cursor,'-');
	do //either number or whitespace immediately following '-'
		cursor++; 
	while (*cursor && isspace(*cursor));
	
	if (isdigit(*cursor))
		lEndTime = strToLong(cursor);
	else 
		lEndTime = 0xFFFFFFFF; // nothing after '-' means block runs to end of file
	//reduce the precision to convert long to int ans space space
	block->endTime = compressTime(lEndTime, context.package->timePrecision);

	if (block->startTime > block->endTime)
		ret = FALSE; //todo:log this problem
	
	while (*cursor && (isspace(*cursor) || isdigit(*cursor)))
		cursor++;
	
	//check for block-end action (of type EnumAction)
	while (*cursor && *cursor != '[' && *cursor != '/') {
		if (!isspace(*cursor)) {
			blockAction = getActionEnumFromChar(cursor);
			if (blockAction != -1)
				setEndCode(&block->actionStartEnd,blockAction);
		}
		cursor++;
	}
	
	// check if block is hyperlinked
	inLabel = FALSE;
	for (cursor=line;*cursor;cursor++) {
		if (*cursor == '[')
			inLabel = TRUE;
		else if (*cursor == ']')
			inLabel = FALSE;
		if (!inLabel && *cursor == '?') {
			setBlockHyperlinked(block);
			break;
		}
	}					

	// check if block has enter/exit events
	cursor = strchr(line,'/');
	if (cursor != NULL) {
		// go backwards to beginning of legit enter/exit codes
		do {
			cursor--;
			if (*cursor != '+' && *cursor != '-')
				blockAction = getEnterExitEnumFromChar(cursor); 
		} while (blockAction != -1 || *cursor == '+' || *cursor == '-' || *cursor == 'N');
		//read in enter codes
		for (cursor++;*cursor != '/';cursor++) {
			if (*cursor != '-' && *cursor != '+' && *cursor != 'N') {
				blockAction = getEnterExitEnumFromChar(cursor);
				setEnterCode(block,blockAction);
			}
		}
		// must be back to '/'; now read in exit codes
		do {
			cursor++;
			if (*cursor && *cursor != '-' && *cursor != '+' && *cursor != 'N') {
				blockAction = getEnterExitEnumFromChar(cursor);
				if (blockAction != -1)
					setExitCode(block,blockAction);
			}
		} while (*cursor && (blockAction != -1 || *cursor == '+' || *cursor == '-' || *cursor == 'N'));
	}
			
	cursor = strchr(line,']');
	// a block does not need a symbol if nothing refers to it
	if (cursor != NULL) {
		//set null marker before ] but also before any whitespace
		while (isspace(*(cursor-1)))
			cursor--;
		*cursor = '\0';
		cursor = strchr(line,'[');
		// todo: error if there is a ] but no [
		do
			cursor++;
		while (isspace(*cursor));
		cursor = strcpy(*freeSymbolMap,cursor);
		cursor = strchr(cursor,'\0');
		*(cursor + 1) = idxBlock;
		*freeSymbolMap = cursor + 2;
	}
	return ret;
}
Ejemplo n.º 15
0
static BOOL parseCreateAction (char *line, Action *action, int *actionCount, char *symbolMapStart, CtnrBlock *block, ListItem *list, TranslationList *transList) {	
	//TODO:
	//    Add code to parse speed changes in actions (already incorporated into Action, but nowhere else yet)
	//
	//block is NULL when parsing package actions; otherwise it is used to set block startEndAction
	int ret = TRUE; //todo: add exception handling
	char *strEvents, *delimeter, *strAction, *cursor;
	long l;
	int eventCode, actionCode, index;
	BOOL inLabel, whenPaused, whenHeld;
		
	(*actionCount)++;
	strEvents = line + 1; // move past the 'A'
	delimeter = strchr(strEvents,DELIMITER);
	strAction = delimeter + 1;
	while (*strAction && isspace(*strAction))
		strAction++;

	eventCode = getEventEnumFromChar(strEvents);

	// skip whitespace
	for (strEvents++;*strEvents && isspace(*strEvents);strEvents++);

	// check for onlyWhenPaused marker
	if (strEvents < delimeter) {
		whenPaused = (*strEvents == '|') ||  (*(strEvents+1) == '|') ;
		whenHeld = (*strEvents == '_') ||  (*(strEvents+1) == '_');
	} else 
		whenPaused = whenHeld = FALSE;
	setEventCodes(action + *actionCount, eventCode, whenPaused, whenHeld);

	// skip whitespace
	for (strEvents++;*strEvents && isspace(*strEvents);strEvents++);
	
	//work on action
	//but first check if there's a sound insert
	actionCode = getActionEnumFromChar(strAction);
	if (actionCode == INSERT_SOUND) {
		int *pStartEndCode;
		//process block to be sound-inserted before action is processed
		index = getIndexFromLine(++strAction,symbolMapStart);
		action[*actionCount].aux = index;  // as long as the index < 2^11-1, a CALL action's rewind bits won't overwrite (see below)
		setSoundInsert(&action[*actionCount], TRUE);
		if (list)
			pStartEndCode = &list->actionStartEnd;
		else if (transList)
			pStartEndCode = &transList->actionStartEnd;
		else
			pStartEndCode = &block->actionStartEnd;
		if (eventCode == START)
			setStartCode(pStartEndCode,INSERT_SOUND);
		if (eventCode == END)
			setEndCode(pStartEndCode,INSERT_SOUND);
		actionCode = -1; // reset so that we can check if we have a new action
 		//move strAction to be ready for action Code
		for (;*strAction && *strAction != ']';strAction++);
		if (*strAction) //move just past the ']' and skip whitespace
			for (strAction++;*strAction && isspace(*strAction);strAction++);
		if (*strAction)
			actionCode = getActionEnumFromChar(strAction);
/* 		CODE BELOW IS BAD BECAUSE IT OVERWRITES BLOCK START/END ACTIONS SET ON BLOCK LINE AND NO LONGER NECESSARY.
		if ((!*strAction || actionCode == -1) 
				&& (eventCode1 == START || eventCode1 == END) && (eventCode2 == START || eventCode2 == END)) {
			actionCode = INSERT_SOUND;
			setActionCode(action + *actionCount, actionCode);
		}  
		else
	  		ret = FALSE; */
	} 
	if (actionCode != -1) {
		setActionCode(action + *actionCount,actionCode);
		// actions like STOP, PAUSE, RETURN, FWD, BACK don't require parameters
		if (actionCode == JUMP_TIME || actionCode == CALL_BLOCK) {
			// get to numbers, but skip numbers inside any label
			inLabel = FALSE;
			for (cursor=strAction;*cursor;cursor++) {
				if (*cursor == '[')
					inLabel = TRUE;
				else if (*cursor == ']')
					inLabel = FALSE;
				if (!inLabel && (isdigit(*cursor) || *cursor == '-' || *cursor == '+'))
					break;
			}					
			if (*cursor) {
				l = strToLong(cursor);
				switch (actionCode) {
					case JUMP_TIME:
						action[*actionCount].destination = compressTime(l, context.package->timePrecision);
						break;
					case CALL_BLOCK:
						setRewind(&action[*actionCount].aux,(int)l);
						break;
					default:  /// not used now; was originally used for VOLUME and SPEED
						action[*actionCount].destination = (int)l;
						break;
				}
			} else if (actionCode == CALL_BLOCK)
				// no specified rewind time, so use default
				setRewind(&action[*actionCount].aux,-DEFAULT_REWIND);
		}					
		if (actionCode == DELETE || actionCode == DELETE_MESSAGES || actionCode == COPY || actionCode == TRIM || 
				actionCode == SURVEY_TAKEN || actionCode == SURVEY_APPLY || actionCode == SURVEY_USELESS || 
				actionCode == POSITION_TO_TOP || actionCode == MAKE_FAVORITE || actionCode == RECORD_FEEDBACK) {
			strAction++;
			if (actionCode == SURVEY_TAKEN || actionCode == SURVEY_APPLY || 
				actionCode == SURVEY_USELESS || actionCode == DELETE_MESSAGES || actionCode == RECORD_FEEDBACK)
				strAction++; // skip the 't', 'a', or 'u' or 'm'
			while (isspace(*strAction)) strAction++;
			if (*strAction == '{') { // variable-based package
				cursor = strchr(strAction,'}');
				if (cursor)
					*cursor = 0;			
				else {
						logException(8,strAction,0);  // syntax error in control track
						ret = FALSE;
				}
				strAction++;
				index = getIndexFromLine(strAction,symbolMapStart);
				if (index != -1) {
					action[*actionCount].destination = index; 
				}
				else {
					ret = FALSE;
					logException(6,strAction,0);  // todo:invalid internal reference in control track file
				}
			}
			else if (actionCode == POSITION_TO_TOP) // otherwise no parameter is legit for pushing language to top
				action[*actionCount].destination = -1;
			else  { 
				ret = FALSE;
				logException(8,strAction,0);  // syntax error in control track
			}
			if (actionCode != TRIM) {
				// TRIM doesn't use aux
				cursor++;
				index = getIndexFromLine(cursor,symbolMapStart);
				if (index != -1)
					action[*actionCount].aux = index; 		
			}	
		}
		if (actionCode == JUMP_BLOCK || actionCode == CALL_BLOCK || actionCode == CLONE || actionCode == COPY_LANGUAGE ||
			actionCode == RECORD_TITLE || actionCode == RECORD_MSG || actionCode == PACKAGE_RECORDING || 
			actionCode == USB_DEVICE_ON || actionCode == USB_HOST_ON) {
			if (actionCode == RECORD_TITLE || actionCode == RECORD_MSG) {
				// check if recording from headphone port instead of a microphone
				if (*(strAction+2) == '-') {  // moves past 'E' and 't'/'m'
					action[*actionCount].aux = 1;
					strAction += 3;
				} else
					action[*actionCount].aux = 0;	
			}
			index = getIndexFromLine(strAction,symbolMapStart);
			if (index != -1)
				action[*actionCount].destination = index; 
			//else {
			//	ret = FALSE;
			//	logException(6,strAction,0);  // todo:invalid internal reference in control track file
			//}
// TODO:If (index==-1), there was no destination ("[]"), which is ok for now -- and ret=FALSE was ignored anyway   
//			else
//				ret = FALSE;
		}
		if (actionCode == JUMP_PACKAGE) {
			strAction++;
			if (*strAction == '{') { // variable-based package
				cursor = strchr(strAction,'}');
				if (cursor)
					*cursor = 0;			
				strAction++;
				index = getIndexFromLine(strAction,symbolMapStart);
				if (index != -1) {
					action[*actionCount].destination = index; 
					action[*actionCount].aux = PKG_VARIABLE;
				}
				else {
					ret = FALSE;
					logException(6,strAction,0);  // todo:invalid internal reference in control track file
				}
			} else { // explicit name
				if (*strAction == SYS_PKG_CHAR) {
					action[*actionCount].aux = PKG_SYS;
					strAction++;
				} else if (*strAction == APP_PKG_CHAR) {
					action[*actionCount].aux = PKG_APP;
					strAction++;
				} else
					action[*actionCount].aux = PKG_MSG;
				cursor = strchr(strAction,'>');
				if (cursor == strAction) // "<%>" indicates current system package
					action[*actionCount].destination = SAME_SYSTEM;
				else {
					if (*strAction == '+')
						action[*actionCount].destination = NEXT_SYSTEM;
					else if (*strAction == '-')
						action[*actionCount].destination = PREV_SYSTEM;
					else
						logException(8,strAction-2,USB_MODE);
				}
			}
		}
		if (actionCode == JUMP_LIST) {
			strAction++;
			switch (*strAction) {
				case '+':
					setListRotation(&action[*actionCount].aux, 1);
					strAction++;
					break;
				case '-':
					setListRotation(&action[*actionCount].aux, -1);
					strAction++;
					break;
				default:
					action[*actionCount].aux = 0;	
			}
			index = getIndexFromLine(strAction,symbolMapStart);
			if (index != -1)	
				action[*actionCount].destination = index; 
			else {
				ret = FALSE;
				logException(6,strAction,0);  // todo:invalid internal reference in control track file 
			}
		}
		if (actionCode == DELETE_TRANSLATION || actionCode == WRAP_TRANSLATION) {
			//strAction = strAction+3;
			index = getIndexFromLine(strAction,symbolMapStart);
			if (index != -1)	
				action[*actionCount].destination = index; 
			else {
				ret = FALSE;
				logException(6,strAction,0);  // todo:invalid internal reference in control track file 
			}
		}
		if (actionCode == TRANSLATE_NEW){
			//Get first block and store in destination
			//Move past 'c' (c for create)
			strAction=strAction+2;
			while (*strAction && isspace(*strAction))
				strAction++;
			
			if (*strAction == '[') { 
				cursor = strchr(strAction,']');
				index = getIndexFromLine(strAction,symbolMapStart);
				if (index != -1) {
					action[*actionCount].destination = index; 
					strAction = cursor+1;
				}
				else {
					ret = FALSE;
					logException(6,strAction,0);  // todo:invalid internal reference in control track file
				}
			}
			else {
				ret = FALSE;
				logException(8,strAction,0);  // syntax error in control track
			}
		}
		if (actionCode == TRANSLATE_OVERWRITE) {
			//Get first block and store in destination
			//Move past '!'
			strAction=strAction+2;
			while (*strAction && isspace(*strAction))
				strAction++;
			
			if (*strAction == '[') { 
				cursor = strchr(strAction,']');
				index = getIndexFromLine(strAction,symbolMapStart);
				if (index != -1) {
					action[*actionCount].destination = index; 
					strAction = cursor+1;
				}
				else {
					ret = FALSE;
					logException(6,strAction,0);  // todo:invalid internal reference in control track file
				}
			}
			else {
				ret = FALSE;
				logException(8,strAction,0);  // syntax error in control track
			}
		}
		if (actionCode == TRANSLATE_DELETE_FINISH) {
			//Get first block and store in destination
			//Move past ?
			strAction=strAction+2;
			while (*strAction && isspace(*strAction))
				strAction++;
			
			if (*strAction == '[') { 
				cursor = strchr(strAction,']');
				//if (cursor)
				//	*cursor = 0;			
				//else {
				//	logException(8,strAction,0);  // syntax error in control track
				//	ret = FALSE;
				//}
				//strAction++;
				index = getIndexFromLine(strAction,symbolMapStart);
				if (index != -1) {
					action[*actionCount].destination = index; 
					strAction = cursor+1;
				}
				else {
					ret = FALSE;
					logException(6,(char *)"here1",0);  // todo:invalid internal reference in control track file
				}
			}
			else {
				ret = FALSE;
				logException(8,strAction,0);  // syntax error in control track
			}
			// Store second block name in aux
			while (*strAction && isspace(*strAction))
				strAction++;
			
			if (*strAction == '[') { 
				//cursor = strchr(strAction,']');
				//if (cursor)
				//	*cursor = 0;			
				//else {
				//	logException(8,strAction,0);  // syntax error in control track
				//	ret = FALSE;
				//}
				//strAction++;
				index = getIndexFromLine(strAction,symbolMapStart);
				if (index != -1) {
					action[*actionCount].aux = index; 
				}
				else {
					ret = FALSE;
					logException(6,(char *)"here1",0);  // todo:invalid internal reference in control track file
				}
			}
			else {
				ret = FALSE;
				logException(8,strAction,0);  // syntax error in control track
			}	
		
			/////////
		}
	}		
	if ((block || list || transList) && actionCode != -1) {
		int *pStartEndCode;
		if (list)
			pStartEndCode = &list->actionStartEnd;
		else if (transList)
			pStartEndCode = &transList->actionStartEnd;
		else
			pStartEndCode = &block->actionStartEnd;	
		if (eventCode == START)
			setStartCode(pStartEndCode,actionCode);
		if (eventCode == END)
			setEndCode(pStartEndCode,actionCode);
	}
	return ret;
}