void SeqerWindow_newMidiFile(SeqerWindow_t window) { if (PointerArray_getSize(window->document->windows) == 1) { MidiFile_free(window->document->midi_file); String_clear(window->document->filename); } else { int window_number; for (window_number = PointerArray_getSize(window->document->windows) - 1; window_number >= 0; window_number--) { if ((SeqerWindow_t)(PointerArray_get(window->document->windows, window_number)) == window) { PointerArray_remove(window->document->windows, window_number); break; } } window->document = (SeqerDocument_t)(malloc(sizeof (struct SeqerDocument))); window->document->windows = PointerArray_new(8); window->document->filename = String_new(32); PointerArray_add(window->document->windows, window); } window->document->midi_file = MidiFile_new(1, window->application->preferred_midi_file_division_type, window->application->preferred_midi_file_resolution); window->document->modified = 0; window->horizontal_scroll_offset = 0; (*(window->application->redraw_callback))(window); (*(window->application->configure_horizontal_scrollbar_callback))(window, 0, 0, window->width, window->horizontal_scroll_offset); (*(window->application->configure_vertical_scrollbar_callback))(window, 128 * 5, 5, window->height, window->vertical_scroll_offset); (*(window->application->filename_change_callback))(window); }
Token LexParser_next(LexParser *self) { char ch; char ch2; while ((ch = BuffFile_get(&(self->input))) != EOF) { if (!isspace(ch)) switch (ch) { case ';': return t_scolon; case '-': return t_minus; case '+': return t_plus; case '*': return t_asterisk; case '/': return t_slash; case ',': return t_comma; case '=': return t_eqv; case '(': return t_lParenthessis; case ')': return t_rParenthessis; case '{': LexParser_readComment(self); break; case '\'': String_clear(&self->str); LexParser_readString(self); String_append(&self->str, 0); return t_str_val; case '.': ch2 = BuffFile_get(&(self->input)); BuffFile_pushBack(&(self->input), ch2); if (isdigit(ch2)) { return LexParser_parseNum(self, ch); } return t_period; case ':': return LexParser_colonOrAssigment(self); case '<': return LexParser_lessFound(self); case '>': return LexParser_greaterFound(self); default: if (isdigit(ch)) { return LexParser_parseNum(self, ch); } if (isalpha(ch) || ch == '_') return LexParser_readIdOrKeyword(self, ch); else Lex_throwError(self, "Can't resolve token from string"); } } return t_eof; }
Token LexParser_readIdOrKeyword(LexParser *self, char ch) { Token found; String_clear(&self->str); String_append(&self->str, tolower(ch)); ch = tolower(BuffFile_get(&(self->input))); while ( isalnum(ch) || ch == '_') { String_append(&self->str, tolower(ch)); ch = BuffFile_get(&(self->input)); } BuffFile_pushBack(&self->input, ch); found = LexParser_keywordCheck(&self->str); if (found == t_id) LexParser_syncLastVar(self); return found; }
void command_play_qam(JsmnContext * jc) { localptr(String, player_cmd) = String_value_none(); localptr(String, mux_cmd) = String_value_none(); localptr(String, azap_cmd) = String_value_none(); localptr(String, channel) = String_value_none(); localptr(String, clientid) = String_value_none(); clientid = jsmn_lookup_string(jc, "clientid"); if (String_is_none(clientid)) { fprintf(stderr, "%s: missing clientid\n", __func__); return; } channel = jsmn_lookup_string(jc, "channel"); if (String_is_none(channel)) { fprintf(stderr, "%s: missing channel\n", __func__); return; } /* Verify valid channel. */ if (!Regex_match(s(channel), "^[0-9]+[.][0-9]+$")) { fprintf(stderr, "%s: invalid channel\n", __func__); return; } set_client(clientid); stop_playback_programs(STOP_ALL); /* Start azap. */ azap_cmd = String_sprintf("/platform/rpi/bin/azap.jsg -j azap.json -c azap.conf -q -r %s", s(channel)); bgstart(s(azap_cmd), &playbackState.azap_pid); /* Start muxer. */ mux_cmd = String_sprintf("/platform/rpi/bin/streammux"); bgstart(s(mux_cmd), &playbackState.mux_pid); /* Start player. */ unlink("/tmp/pb.in"); unlink("/tmp/pb.out"); player_cmd = String_sprintf("empty -p empty_omxplayer.pid " "-i /tmp/pb.in -o /tmp/pb.out " "-f /usr/bin/omxplayer tcp://localhost:5102 --layer 1 --lavfdopts probesize:250000"); bgstart(s(player_cmd), &playbackState.player_pid); String_clear(&playbackState.title); playbackState.title = String_dup(channel); playbackState.playing = 1; playbackState.paused = 0; playbackState.recording = 0; }
void command_play_url(JsmnContext * jc) { localptr(String, player_cmd) = String_value_none(); localptr(String, clientid) = String_value_none(); localptr(String, url) = String_value_none(); clientid = jsmn_lookup_string(jc, "clientid"); if (String_is_none(clientid)) { fprintf(stderr, "%s: missing clientid\n", __func__); return; } url = jsmn_lookup_string(jc, "url"); if (String_is_none(url)) { fprintf(stderr, "%s: missing url\n", __func__); return; } /* Verify valid url */ //if (!Regex_match((channel), "^...$")) { //fprintf(stderr, "%s: invalid channel\n", __func__); //goto out; //} set_client(clientid); stop_playback_programs(STOP_ALL); /* Start player. */ unlink("/tmp/pb.in"); unlink("/tmp/pb.out"); player_cmd = String_sprintf("empty -p empty_omxplayer.pid" " -i /tmp/pb.in -o /tmp/pb.out" " -f livestreamer -np '/usr/bin/omxplayer --layer 1 --lavfdopts probesize:250000'" " '%s'" " best" , s(url)); // -i /tmp/pb.in -o /tmp/pb.out bgstart(s(player_cmd), &playbackState.player_pid); String_clear(&playbackState.title); playbackState.title = String_dup(url); /* FIXME: Potential XSS vector here when it gets passed back in config? */ playbackState.playing = 1; playbackState.paused = 0; playbackState.recording = 0; }
String File_getFileBaseName(String baseName, const String fileName) { long lastPathSeparatorIndex; assert(fileName != NULL); assert(baseName != NULL); /* find last path separator */ lastPathSeparatorIndex = String_findLastChar(fileName,STRING_END,FILES_PATHNAME_SEPARATOR_CHAR); /* get path */ if (lastPathSeparatorIndex >= 0) { String_sub(baseName,fileName,lastPathSeparatorIndex+1,STRING_END); } else { String_clear(baseName); } return baseName; }
LOCAL String getDestinationFileName(String destinationFileName, String fileName, const String directory, uint directoryStripCount ) { String pathName,baseName,name; StringTokenizer fileNameTokenizer; int z; assert(destinationFileName != NULL); assert(fileName != NULL); if (directory != NULL) { File_setFileName(destinationFileName,directory); } else { String_clear(destinationFileName); } File_splitFileName(fileName,&pathName,&baseName); File_initSplitFileName(&fileNameTokenizer,pathName); z = 0; while ((z< directoryStripCount) && File_getNextSplitFileName(&fileNameTokenizer,&name)) { z++; } while (File_getNextSplitFileName(&fileNameTokenizer,&name)) { File_appendFileName(destinationFileName,name); } File_doneSplitFileName(&fileNameTokenizer); File_appendFileName(destinationFileName,baseName); String_delete(pathName); String_delete(baseName); return destinationFileName; }
Errors File_readLine(FileHandle *fileHandle, String line ) { int ch; assert(fileHandle != NULL); assert(fileHandle->file != NULL); assert(line != NULL); String_clear(line); do { ch = getc(fileHandle->file); if (ch >= 0) fileHandle->index += 1; if (ch < 0) { return ERRORX(IO_ERROR,errno,String_cString(fileHandle->name)); } if (((char)ch != '\n') && ((char)ch != '\r')) { String_appendChar(line,ch); } } while (((char)ch != '\r') && ((char)ch != '\n')); if ((char)ch == '\r') { ch = getc(fileHandle->file); if (ch >= 0) fileHandle->index += 1; if (ch != '\n') { fileHandle->index -= 1; ungetc(ch,fileHandle->file); } } return ERROR_NONE; }
/*---------------------------------------------------------------------*/ void StringList_init(StringList *stringList) { assert(stringList != NULL); List_init(stringList); } void StringList_done(StringList *stringList) { assert(stringList != NULL); List_done(stringList,(ListNodeFreeFunction)freeStringNode,NULL); } StringList *StringList_new(void) { return (StringList*)List_new(); } StringList *StringList_duplicate(const StringList *stringList) { StringList *newStringList; assert(stringList != NULL); newStringList = StringList_new(); if (newStringList == NULL) { return NULL; } StringList_copy(newStringList,stringList); return newStringList; } void StringList_copy(StringList *stringList, const StringList *fromStringList) { StringNode *stringNode; assert(stringList != NULL); assert(fromStringList != NULL); stringNode = fromStringList->head; while (stringNode != NULL) { StringList_append(stringList,stringNode->string); stringNode = stringNode->next; } } void StringList_delete(StringList *stringList) { assert(stringList != NULL); List_delete(stringList,(ListNodeFreeFunction)freeStringNode,NULL); } void StringList_clear(StringList *stringList) { assert(stringList != NULL); List_clear(stringList,(ListNodeFreeFunction)freeStringNode,NULL); } void StringList_move(StringList *fromStringList, StringList *toStringList) { assert(fromStringList != NULL); assert(toStringList != NULL); List_move(fromStringList,toStringList,NULL,NULL,NULL); } #ifdef NDEBUG void StringList_insert(StringList *stringList, const String string, StringNode *nextStringNode) #else /* not NDEBUG */ void __StringList_insert(const char *__fileName__, ulong __lineNb__, StringList *stringList, const String string, StringNode *nextStringNode) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_duplicate(string),nextStringNode); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_duplicate(__fileName__,__lineNb__,string),nextStringNode); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_insertCString(StringList *stringList, const char *s, StringNode *nextStringNode) #else /* not NDEBUG */ void __StringList_insertCString(const char *__fileName__, ulong __lineNb__, StringList *stringList, const char *s, StringNode *nextStringNode) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newCString(s),nextStringNode); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newCString(__fileName__,__lineNb__,s),nextStringNode); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_insertChar(StringList *stringList, char ch, StringNode *nextStringNode) #else /* not NDEBUG */ void __StringList_insertChar(const char *__fileName__, ulong __lineNb__, StringList *stringList, char ch, StringNode *nextStringNode) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newChar(ch),nextStringNode); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newChar(__fileName__,__lineNb__,ch),nextStringNode); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_insertBuffer(StringList *stringList, char *buffer, ulong bufferLength, StringNode *nextStringNode) #else /* not NDEBUG */ void __StringList_insertBuffer(const char *__fileName__, ulong __lineNb__, StringList *stringList, char *buffer, ulong bufferLength, StringNode *nextStringNode) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newBuffer(buffer,bufferLength),nextStringNode); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newBuffer(__fileName__,__lineNb__,buffer,bufferLength),nextStringNode); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_append(StringList *stringList, const String string) #else /* not NDEBUG */ void __StringList_append(const char *__fileName__, ulong __lineNb__, StringList *stringList, const String string) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_duplicate(string),NULL); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_duplicate(__fileName__,__lineNb__,string),NULL); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_appendCString(StringList *stringList, const char *s) #else /* not NDEBUG */ void __StringList_appendCString(const char *__fileName__, ulong __lineNb__, StringList *stringList, const char *s) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newCString(s),NULL); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newCString(__fileName__,__lineNb__,s),NULL); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_appendChar(StringList *stringList, char ch) #else /* not NDEBUG */ void __StringList_appendChar(const char *__fileName__, ulong __lineNb__, StringList *stringList, char ch) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newChar(ch),NULL); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newChar(__fileName__,__lineNb__,ch),NULL); #endif /* NDEBUG */ } #ifdef NDEBUG void StringList_appendBuffer(StringList *stringList, char *buffer, ulong bufferLength) #else /* not NDEBUG */ void __StringList_appendBuffer(const char *__fileName__, ulong __lineNb__, StringList *stringList, char *buffer, ulong bufferLength) #endif /* NDEBUG */ { #ifdef NDEBUG insertString(stringList,String_newBuffer(buffer,bufferLength),NULL); #else /* not NDEBUG */ insertString(__fileName__,__lineNb__,stringList,__String_newBuffer(__fileName__,__lineNb__,buffer,bufferLength),NULL); #endif /* NDEBUG */ } #ifdef NDEBUG StringNode *StringList_remove(StringList *stringList, StringNode *stringNode) #else /* not NDEBUG */ StringNode *__StringList_remove(const char *__fileName__, ulong __lineNb__, StringList *stringList, StringNode *stringNode) #endif /* NDEBUG */ { StringNode *nextStringNode; assert(stringList != NULL); assert(stringNode != NULL); nextStringNode = (StringNode*)List_remove(stringList,stringNode); String_delete(stringNode->string); #ifdef NDEBUG stringNode = (StringNode*)LIST_DELETE_NODE(stringNode); #else /* not NDEBUG */ stringNode = (StringNode*)__LIST_DELETE_NODE(__fileName__,__lineNb__,stringNode); #endif /* NDEBUG */ return nextStringNode; } #ifdef NDEBUG String StringList_getFirst(StringList *stringList, String string) #else /* not NDEBUG */ String __StringList_getFirst(const char *fileName, ulong lineNb, StringList *stringList, String string) #endif /* NDEBUG */ { StringNode *stringNode; assert(stringList != NULL); stringNode = (StringNode*)List_getFirst(stringList); if (stringNode != NULL) { if (string != NULL) { String_set(string,stringNode->string); String_delete(stringNode->string); } else { string = stringNode->string; } #ifdef NDEBUG LIST_DELETE_NODE(stringNode); #else /* not NDEBUG */ __LIST_DELETE_NODE(fileName,lineNb,stringNode); #endif /* NDEBUG */ return string; } else { if (string != NULL) { String_clear(string); } return NULL; } } #ifdef NDEBUG String StringList_getLast(StringList *stringList, String string) #else /* not NDEBUG */ String __StringList_getLast(const char *fileName, ulong lineNb, StringList *stringList, String string) #endif /* NDEBUG */ { StringNode *stringNode; assert(stringList != NULL); stringNode = (StringNode*)List_getLast(stringList); if (stringNode != NULL) { if (string != NULL) { String_set(string,stringNode->string); String_delete(stringNode->string); } else { string = stringNode->string; } #ifdef NDEBUG LIST_DELETE_NODE(stringNode); #else /* not NDEBUG */ __LIST_DELETE_NODE(fileName,lineNb,stringNode); #endif /* NDEBUG */ return string; } else { if (string != NULL) { String_clear(string); } return NULL; } }
static void set_client(String * clientstr) { String_clear(&playbackState.clientid); playbackState.clientid = String_dup(clientstr); }
Errors Misc_executeCommand(const char *commandTemplate, const TextMacro macros[], uint macroCount, ExecuteIOFunction stdoutExecuteIOFunction, ExecuteIOFunction stderrExecuteIOFunction, void *executeIOUserData ) { Errors error; String commandLine; StringTokenizer stringTokenizer; String token; String command; StringList argumentList; const char *path; String fileName; bool foundFlag; char const **arguments; int pipeStdin[2],pipeStdout[2],pipeStderr[2]; int pid; StringNode *stringNode; uint n,z; int status; bool sleepFlag; String stdoutLine,stderrLine; int exitcode; int terminateSignal; error = ERROR_NONE; if (commandTemplate != NULL) { commandLine = String_new(); command = File_newFileName(); StringList_init(&argumentList); // expand command line Misc_expandMacros(commandLine,commandTemplate,macros,macroCount); printInfo(3,"Execute command '%s'...",String_cString(commandLine)); // parse command String_initTokenizer(&stringTokenizer,commandLine,STRING_BEGIN,STRING_WHITE_SPACES,STRING_QUOTES,FALSE); if (!String_getNextToken(&stringTokenizer,&token,NULL)) { String_doneTokenizer(&stringTokenizer); StringList_done(&argumentList); String_delete(command); String_delete(commandLine); return ERRORX_(PARSE_COMMAND,0,String_cString(commandLine)); } File_setFileName(command,token); // parse arguments while (String_getNextToken(&stringTokenizer,&token,NULL)) { StringList_append(&argumentList,token); } String_doneTokenizer(&stringTokenizer); // find command in PATH path = getenv("PATH"); if (path != NULL) { fileName = File_newFileName(); foundFlag = FALSE; String_initTokenizerCString(&stringTokenizer,path,":","",FALSE); while (String_getNextToken(&stringTokenizer,&token,NULL) && !foundFlag) { File_setFileName(fileName,token); File_appendFileName(fileName,command); if (File_exists(fileName)) { File_setFileName(command,fileName); foundFlag = TRUE; } } String_doneTokenizer(&stringTokenizer); File_deleteFileName(fileName); } #if 0 fprintf(stderr,"%s,%d: command %s\n",__FILE__,__LINE__,String_cString(command)); stringNode = argumentList.head; while (stringNode != NULL) { fprintf(stderr,"%s,%d: argument %s\n",__FILE__,__LINE__,String_cString(stringNode->string)); stringNode = stringNode->next; } #endif /* 0 */ #if defined(HAVE_PIPE) && defined(HAVE_FORK) && defined(HAVE_WAITPID) #if 1 // create i/o pipes if (pipe(pipeStdin) != 0) { error = ERRORX_(IO_REDIRECT_FAIL,errno,String_cString(commandLine)); StringList_done(&argumentList); String_delete(command); String_delete(commandLine); return error; } if (pipe(pipeStdout) != 0) { error = ERRORX_(IO_REDIRECT_FAIL,errno,String_cString(commandLine)); close(pipeStdin[0]); close(pipeStdin[1]); StringList_done(&argumentList); String_delete(command); String_delete(commandLine); return error; } if (pipe(pipeStderr) != 0) { error = ERRORX_(IO_REDIRECT_FAIL,errno,String_cString(commandLine)); close(pipeStdout[0]); close(pipeStdout[1]); close(pipeStdin[0]); close(pipeStdin[1]); StringList_done(&argumentList); String_delete(command); String_delete(commandLine); return error; } // do fork to start separated process pid = fork(); if (pid == 0) { // close stdin, stdout, and stderr and reassign them to the pipes close(STDERR_FILENO); close(STDOUT_FILENO); close(STDIN_FILENO); // redirect stdin/stdout/stderr to pipe dup2(pipeStdin[0],STDIN_FILENO); dup2(pipeStdout[1],STDOUT_FILENO); dup2(pipeStderr[1],STDERR_FILENO); /* close unused pipe handles (the pipes are duplicated by fork(), thus there are two open ends of the pipes) */ close(pipeStderr[0]); close(pipeStdout[0]); close(pipeStdin[1]); // execute of external program n = 1+StringList_count(&argumentList)+1; arguments = (char const**)malloc(n*sizeof(char*)); if (arguments == NULL) { HALT_INSUFFICIENT_MEMORY(); } z = 0; arguments[z] = String_cString(command); z++; stringNode = argumentList.head; while (stringNode != NULL) { assert(z < n); arguments[z] = String_cString(stringNode->string); z++; stringNode = stringNode->next; } assert(z < n); arguments[z] = NULL; z++; execvp(String_cString(command),(char**)arguments); // in case exec() fail, return a default exitcode HALT_INTERNAL_ERROR("execvp() returned"); } else if (pid < 0) { error = ERRORX_(EXEC_FAIL,errno,String_cString(commandLine)); printInfo(3,"FAIL!\n"); close(pipeStderr[0]); close(pipeStderr[1]); close(pipeStdout[0]); close(pipeStdout[1]); close(pipeStdin[0]); close(pipeStdin[1]); StringList_done(&argumentList); String_delete(command); String_delete(commandLine); return error; } // close unused pipe handles (the pipe is duplicated by fork(), thus there are two open ends of the pipe) close(pipeStderr[1]); close(pipeStdout[1]); close(pipeStdin[0]); #else /* 0 */ error = ERROR_NONE; #endif /* 0 */ // wait until process terminate and read stdout/stderr stdoutLine = String_new(); stderrLine = String_new(); status = 0; while ((waitpid(pid,&status,WNOHANG) == 0) || (!WIFEXITED(status) && !WIFSIGNALED(status))) { sleepFlag = TRUE; if (readProcessIO(pipeStdout[0],stdoutLine)) { if (stdoutExecuteIOFunction != NULL) stdoutExecuteIOFunction(executeIOUserData,stdoutLine); String_clear(stdoutLine); sleepFlag = FALSE; } if (readProcessIO(pipeStderr[0],stderrLine)) { if (stderrExecuteIOFunction != NULL) stderrExecuteIOFunction(executeIOUserData,stderrLine); String_clear(stderrLine); sleepFlag = FALSE; } if (sleepFlag) { Misc_udelay(500LL*1000LL); } } while (readProcessIO(pipeStdout[0],stdoutLine)) { if (stdoutExecuteIOFunction != NULL) stdoutExecuteIOFunction(executeIOUserData,stdoutLine); String_clear(stdoutLine); } while (readProcessIO(pipeStderr[0],stderrLine)) { if (stderrExecuteIOFunction != NULL) stderrExecuteIOFunction(executeIOUserData,stderrLine); String_clear(stderrLine); } String_delete(stderrLine); String_delete(stdoutLine); // close i/o close(pipeStderr[0]); close(pipeStdout[0]); close(pipeStdin[1]); // check exit code exitcode = -1; if (WIFEXITED(status)) { exitcode = WEXITSTATUS(status); printInfo(3,"ok (exitcode %d)\n",exitcode); if (exitcode != 0) { error = ERRORX_(EXEC_FAIL,exitcode,String_cString(commandLine)); StringList_done(&argumentList); String_delete(command); String_delete(commandLine); return error; } } else if (WIFSIGNALED(status)) { terminateSignal = WTERMSIG(status); error = ERRORX_(EXEC_FAIL,terminateSignal,String_cString(commandLine)); printInfo(3,"FAIL (signal %d)\n",terminateSignal); StringList_done(&argumentList); String_delete(command); String_delete(commandLine); return error; } else { printInfo(3,"ok (unknown exit)\n"); } #elif defined(WIN32) #if 0 HANDLE hOutputReadTmp,hOutputRead,hOutputWrite; HANDLE hInputWriteTmp,hInputRead,hInputWrite; HANDLE hErrorWrite; HANDLE hThread; DWORD ThreadId; SECURITY_ATTRIBUTES sa; // Set up the security attributes struct. sa.nLength= sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; // Create the child output pipe. if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0)) DisplayError("CreatePipe"); // Create a duplicate of the output write handle for the std error // write handle. This is necessary in case the child application // closes one of its std output handles. if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite, GetCurrentProcess(),&hErrorWrite,0, TRUE,DUPLICATE_SAME_ACCESS)) DisplayError("DuplicateHandle"); // Create the child input pipe. if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0)) DisplayError("CreatePipe"); // Create new output read handle and the input write handles. Set // the Properties to FALSE. Otherwise, the child inherits the // properties and, as a result, non-closeable handles to the pipes // are created. if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp, GetCurrentProcess(), &hOutputRead, // Address of new handle. 0,FALSE, // Make it uninheritable. DUPLICATE_SAME_ACCESS)) DisplayError("DupliateHandle"); if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp, GetCurrentProcess(), &hInputWrite, // Address of new handle. 0,FALSE, // Make it uninheritable. DUPLICATE_SAME_ACCESS)) DisplayError("DupliateHandle"); // Close inheritable copies of the handles you do not want to be // inherited. if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle"); if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle"); // Get std input handle so you can close it and force the ReadFile to // fail when you want the input thread to exit. if ( (hStdIn = GetStdHandle(STD_INPUT_HANDLE)) == INVALID_HANDLE_VALUE ) DisplayError("GetStdHandle"); PrepAndLaunchRedirectedChild(hOutputWrite,hInputRead,hErrorWrite); // Close pipe handles (do not continue to modify the parent). // You need to make sure that no handles to the write end of the // output pipe are maintained in this process or else the pipe will // not close when the child process exits and the ReadFile will hang. if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle"); if (!CloseHandle(hInputRead )) DisplayError("CloseHandle"); if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle"); // Launch the thread that gets the input and sends it to the child. hThread = CreateThread(NULL,0,GetAndSendInputThread, (LPVOID)hInputWrite,0,&ThreadId); if (hThread == NULL) DisplayError("CreateThread"); // Read the child's output. ReadAndHandleOutput(hOutputRead); // Redirection is complete // Force the read on the input to return by closing the stdin handle. if (!CloseHandle(hStdIn)) DisplayError("CloseHandle"); // Tell the thread to exit and wait for thread to die. bRunThread = FALSE; if (WaitForSingleObject(hThread,INFINITE) == WAIT_FAILED) DisplayError("WaitForSingleObject"); if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle"); if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle"); #endif #else /* not defined(HAVE_PIPE) && defined(HAVE_FORK) && defined(HAVE_WAITPID) || WIN32 */ #error pipe()/fork()/waitpid() not available nor Win32 system! #endif /* defined(HAVE_PIPE) && defined(HAVE_FORK) && defined(HAVE_WAITPID) || WIN32 */ // free resources StringList_done(&argumentList); String_delete(command); String_delete(commandLine); } return error; }
String Misc_expandMacros(String string, const char *macroTemplate, const TextMacro macros[], uint macroCount ) { #define APPEND_CHAR(string,index,ch) \ do \ { \ if ((index) < sizeof(string)-1) \ { \ (string)[index] = ch; \ (index)++; \ } \ } \ while (0) #define SKIP_SPACES(string,i) \ do \ { \ while ( ((string)[i] != '\0') \ && isspace((string)[i]) \ ) \ { \ (i)++; \ } \ } \ while (0) bool macroFlag; ulong i; uint j; char name[128]; char format[128]; assert(macroTemplate != NULL); assert((macroCount == 0) || (macros != NULL)); String_clear(string); i = 0; do { // add prefix string macroFlag = FALSE; while ((macroTemplate[i] != '\0') && !macroFlag) { if (macroTemplate[i] == '%') { if ((macroTemplate[i+1] == '%')) { String_appendChar(string,'%'); i+=2; } else { macroFlag = TRUE; i++; } } else { String_appendChar(string,macroTemplate[i]); i++; } } if (macroFlag) { // skip spaces SKIP_SPACES(macroTemplate,i); // get macro name j = 0; if ( (macroTemplate[i] != '\0') && isalpha(macroTemplate[i]) ) { APPEND_CHAR(name,j,'%'); do { APPEND_CHAR(name,j,macroTemplate[i]); i++; } while ( (macroTemplate[i] != '\0') && isalnum(macroTemplate[i]) ); } name[j] = '\0'; // get format data (if any) j = 0; if (macroTemplate[i] == ':') { // skip ':' i++; // skip spaces SKIP_SPACES(macroTemplate,i); // get format string APPEND_CHAR(format,j,'%'); while ( (macroTemplate[i] != '\0') && ( isdigit(macroTemplate[i]) || (macroTemplate[i] == '-') || (macroTemplate[i] == '.') ) ) { APPEND_CHAR(format,j,macroTemplate[i]); i++; } while ( (macroTemplate[i] != '\0') && (strchr("l",macroTemplate[i]) != NULL) ) { APPEND_CHAR(format,j,macroTemplate[i]); i++; } if ( (macroTemplate[i] != '\0') && (strchr("duxfsS",macroTemplate[i]) != NULL) ) { APPEND_CHAR(format,j,macroTemplate[i]); i++; } } format[j] = '\0'; // find macro if (strlen(name) > 0) { // find macro j = 0; while ( (j < macroCount) && (strcmp(name,macros[j].name) != 0) ) { j++; } if (j < macroCount) { // get default format if no format given if (strlen(format) == 0) { switch (macros[j].type) { case TEXT_MACRO_TYPE_INTEGER: strcpy(format,"%d"); break; case TEXT_MACRO_TYPE_INTEGER64: strcpy(format,"%lld"); break; case TEXT_MACRO_TYPE_DOUBLE: strcpy(format,"%lf"); break; case TEXT_MACRO_TYPE_CSTRING: strcpy(format,"%s"); break; case TEXT_MACRO_TYPE_STRING: strcpy(format,"%S"); break; #ifndef NDEBUG default: HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE(); break; /* not reached */ #endif /* NDEBUG */ } } // expand macro switch (macros[j].type) { case TEXT_MACRO_TYPE_INTEGER: String_format(string,format,macros[j].value.i); break; case TEXT_MACRO_TYPE_INTEGER64: String_format(string,format,macros[j].value.l); break; case TEXT_MACRO_TYPE_DOUBLE: String_format(string,format,macros[j].value.d); break; case TEXT_MACRO_TYPE_CSTRING: String_format(string,format,macros[j].value.s); break; case TEXT_MACRO_TYPE_STRING: String_format(string,format,macros[j].value.string); break; #ifndef NDEBUG default: HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE(); break; /* not reached */ #endif /* NDEBUG */ } } else { // keep unknown macro String_appendCString(string,name); } } else { // empty macro: add empty string String_format(string,format,""); } } } while (macroFlag); return string; #undef SKIP_SPACES #undef APPEND_CHAR }
Token LexParser_parseNum(LexParser * self, char ch) { NumParsingState st; if (ch == '.') st = np_needAfterDot; else st = np_int; String_clear(&self->str); String_append(&self->str, ch); while (true) { ch = BuffFile_get(&self->input); switch (st) { case np_int: if (isdigit(ch)) { break; } else if (ch == '.') { st = np_needAfterDot; } else if (ch == 'e' || ch == 'E') { ch = 'e'; st = np_needExponent; } else { BuffFile_pushBack(&self->input, ch); return t_num_int; } break; case np_needAfterDot: if (isdigit(ch)) st = np_real; else Lex_throwError(self, "expected number after dot"); break; case np_needExponent: if (isdigit(ch)) st = np_expReal; else if (ch == '-' || ch == '+') { st = np_needExponent_gotSign; } else Lex_throwError(self, "expected number as exponent"); break; case np_needExponent_gotSign: if (isdigit(ch)) st = np_expReal; else Lex_throwError(self, "expected number as exponent"); break; break; case np_real: if (isdigit(ch)) { } else if (ch == 'e' || ch == 'E') { ch = 'e'; st = np_needExponent; } else { BuffFile_pushBack(&self->input, ch); return t_num_real; } break; case np_expReal: if (ch == '.') st = np_expReal_needAfterDot; else if (isdigit(ch)) { break; } else { BuffFile_pushBack(&self->input, ch); return t_num_real; } break; case np_expReal_needAfterDot: if (isdigit(ch)) st = np_expReal_realExp; else Lex_throwError(self, "expected number after dot in exponent"); break; case np_expReal_realExp: if (!isdigit(ch)) { BuffFile_pushBack(&self->input, ch); return t_num_real; } } String_append(&self->str, ch); } Lex_throwError(self, "Lex parser is unable to parse number"); return t_invalid; }
Errors Device_readDeviceList(DeviceListHandle *deviceListHandle, String deviceName ) { uint i,j; char buffer[256]; assert(deviceListHandle != NULL); assert(deviceListHandle->file != NULL); assert(deviceName != NULL); // read entry iff not read while ( !deviceListHandle->readFlag && (fgets(deviceListHandle->line,sizeof(deviceListHandle->line),deviceListHandle->file) != NULL) ) { // skip leading spaces i = 0; while ((i < sizeof(deviceListHandle->line)) && isspace(deviceListHandle->line[i])) { i++; } j = 0; while ((i < sizeof(deviceListHandle->line)) && (deviceListHandle->line[i] != '\0')) { deviceListHandle->line[j] = deviceListHandle->line[i]; i++; j++; } // skip trailing spaces while ((j > 0) && isspace(deviceListHandle->line[j-1])) { j--; } deviceListHandle->line[j] = '\0'; // if line is not empty set read flag if (j > 0) deviceListHandle->readFlag = TRUE; } if (deviceListHandle->readFlag) { // parse and get device name if (!String_scanCString(deviceListHandle->line,"%* %* %* %256s %*",buffer)) { return ERRORX_(IO_ERROR,0,"invalid format"); } String_setCString(deviceName,"/dev"); File_appendFileNameCString(deviceName,buffer); // mark entry read deviceListHandle->readFlag = FALSE; } else { String_clear(deviceName); } return ERROR_NONE; }