/** * 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, ¶m, ¶m_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; }
/** * 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; }
//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; }
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; }
bool strToInt(const char* s, int* i) { long value; bool result = strToLong(s, &value); if (result) { *i = (int) value; return true; } return false; }
/** * 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; }
/** * 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, ¶m, ¶m_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; }
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; }
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; }
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); }
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; } } }
/* * 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*/
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); // } }
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; }
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; }