├── LICENSE ├── Makefile ├── README.md ├── bin ├── Makefile ├── getOpt.c ├── gtk_cells.c ├── gtk_overlay.c ├── qsQt.h ├── qsQt_block.cpp ├── qsQt_block.h ├── qsQt_graph.cpp ├── qsQt_graph.h ├── qsQt_notebook.cpp ├── qsQt_notebook.h ├── qsQt_treeview.cpp ├── qsQt_treeview.h ├── qsQt_window.cpp ├── qsg_CreateTreeView.c ├── qsg_assignBlocksToThreadsWindow.c ├── qsg_block.c ├── qsg_blockConfigWindow.c ├── qsg_blockPopupMenu.c ├── qsg_buttonBar.c ├── qsg_connection.c ├── qsg_createThreadPoolsWindow.c ├── qsg_cssProvider.c ├── qsg_cursor.c ├── qsg_drawLines.c ├── qsg_layout.c ├── qsg_quickstream.c ├── qsg_tab.c ├── qsg_tabPopupMenu.c ├── qsg_terminal.c ├── qsg_terminalPopupMenu.c ├── qsg_treeView.c ├── qsg_treeView.h ├── qsg_treeViewPopupMenu.c ├── qsg_util.c ├── qsg_window.c ├── qt6_2app_test.cpp ├── qt6_DSO_test.cpp ├── qt6_DSO_test.h ├── qt6_module_test.cpp ├── qt6_treeview_test.cpp ├── quickstream.c ├── quickstream.h ├── quickstreamGUI.c ├── quickstreamGUI.h ├── quickstreamGUI_attach.c ├── quickstreamQt.cpp ├── quickstream_RunCommand.c ├── quickstream_RunInterpreter.c ├── quickstream_help.c ├── quickstream_interpreter.c ├── scribble.c ├── treeView.c ├── treeView_directoryTest.c ├── treeView_test.c └── treeView_test.h ├── bootstrap ├── config.make.example ├── configure ├── developmentNotes.md ├── gtk3.make ├── include ├── Makefile ├── block.h ├── builder.h ├── footer.h ├── header.h └── runner.h ├── lib ├── Dictionary.c ├── Dictionary.h ├── FindFullPath.c ├── FindFullPath.h ├── LoadDSOFromTmpFile.h ├── Makefile ├── SearchArray.h ├── block.c ├── block.h ├── block_threadPools.c ├── builtInBlocks.h ├── builtInBlocks.txt ├── config.c ├── config.h ├── dir.h ├── epoll.c ├── epoll.h ├── graph.c ├── graph.h ├── graphCommand.c ├── graphConnect.h ├── graphPrint.c ├── interBlockJob.c ├── job.c ├── job.h ├── lib_constructor.c ├── listBuiltInBlocks.bash ├── metaData.c ├── metaData.h ├── mmapRingBuffer.c ├── mmapRingBuffer.h ├── mprintf.h ├── name.c ├── name.h ├── parameter.c ├── parameter.h ├── parse.c ├── parseBool.h ├── pkgconfig │ ├── Makefile │ └── quickstream.pc.in ├── port.h ├── qsBlock.c ├── qsBlock_printPorts.c ├── qsGetMemory.c ├── qsGraph_connect.c ├── qsGraph_createBlock.c ├── qsGraph_disconnect.c ├── qsGraph_flatten.c ├── qsGraph_save.c ├── qsGraph_saveSuperBlock.c ├── qsGraph_start.c ├── qsGraph_stop.c ├── qsGtk_init-symbols.txt ├── qsGtk_init.c ├── qsGtk_init.h ├── qsOpenDLHandle.c ├── qsQtApp-symbols.txt ├── qsQtApp.cpp ├── qsQtApp.h ├── qsQtApp_test.cpp ├── quickstream │ ├── blocks │ │ ├── Makefile │ │ ├── Resamplers │ │ │ ├── Makefile │ │ │ └── Rational_Resampler.c │ │ ├── common.make │ │ ├── controlParameters │ │ │ ├── Makefile │ │ │ ├── bool_gate.c │ │ │ ├── f64_gate.c │ │ │ └── not.c │ │ ├── examples │ │ │ ├── 3sliders │ │ │ ├── 3sliders.c │ │ │ ├── Makefile │ │ │ ├── rtlsdr_GNUradioSink_0 │ │ │ ├── rtlsdr_GNUradioSink_0.c │ │ │ ├── urandomToHexdump │ │ │ ├── urandomToHexdump.c │ │ │ ├── urandom_to_GNUradioSink │ │ │ └── urandom_to_GNUradioSink.c │ │ ├── file │ │ │ ├── Epoll.c │ │ │ ├── FileIn.c │ │ │ ├── FileOut.c │ │ │ ├── Makefile │ │ │ ├── PipeIn.c │ │ │ ├── PipeOut.c │ │ │ └── qs_examples │ │ │ │ ├── FileIn.c │ │ │ │ └── Makefile │ │ ├── gnuradio-3.10.1 │ │ │ ├── Makefile │ │ │ ├── QT_GNUradio_sink.c │ │ │ ├── QT_GNUradio_test.c │ │ │ ├── QT_GUI_Sink │ │ │ ├── QT_GUI_Sink.grc │ │ │ ├── _U8tofloat.c │ │ │ ├── rtl-sdr_test │ │ │ └── urandom_test │ │ ├── gtk3 │ │ │ ├── Makefile │ │ │ ├── README │ │ │ ├── _run.c │ │ │ ├── all_common.h │ │ │ ├── base.c │ │ │ ├── block_common.h │ │ │ ├── button.c │ │ │ ├── slider.c │ │ │ └── text.c │ │ ├── misc │ │ │ ├── Makefile │ │ │ └── NullSink.c │ │ ├── parameter_type_converters │ │ │ ├── Makefile │ │ │ ├── boolSettersToGetter.c │ │ │ ├── f32ToF64.c │ │ │ ├── f32ToStderr.c │ │ │ ├── f64SettersToGetter.c │ │ │ ├── f64ToF32.c │ │ │ ├── f64ToStderr.c │ │ │ └── f64ToString32.c │ │ ├── rtl-sdr │ │ │ ├── Makefile │ │ │ ├── README │ │ │ ├── _RawToASCII.c │ │ │ ├── _run.c │ │ │ ├── common.h │ │ │ ├── head.h │ │ │ └── rtlsdr.c │ │ ├── runner │ │ │ ├── Makefile │ │ │ ├── destroy.c │ │ │ └── run.c │ │ ├── stream_type_converters │ │ │ ├── Makefile │ │ │ ├── asciiHexToU8.c │ │ │ ├── f32ToAscii.c │ │ │ ├── u8ToF32.c │ │ │ └── u8ToMatrix.c │ │ └── wsServer │ │ │ ├── Makefile │ │ │ ├── _run.c │ │ │ ├── websocketServer.c │ │ │ └── wsServer.h │ └── misc │ │ ├── Makefile │ │ ├── quickstreamHelp.c.in │ │ └── test_blocks │ │ ├── FOSDEM2024.c │ │ ├── Makefile │ │ ├── README │ │ ├── Sequence.c │ │ ├── Sequence.h │ │ ├── _interBlockJob_base.c │ │ ├── _run.c │ │ ├── add1.c │ │ ├── benchmark.c │ │ ├── declare.c │ │ ├── declareFail.c │ │ ├── declareFailUndeclare.c │ │ ├── destroy.c │ │ ├── destroyGraph.c │ │ ├── emptySuperBlock.c │ │ ├── fOSDEM2024 │ │ ├── interBlockJob.c │ │ ├── interBlockJob_base.h │ │ ├── lotsOfPorts.c │ │ ├── matrix.c │ │ ├── multAndAdd_float.c │ │ ├── nullSink.c │ │ ├── nullSource.c │ │ ├── passThrough.c │ │ ├── passThroughCount.c │ │ ├── qs_examples │ │ ├── Makefile │ │ └── sequenceGen.c │ │ ├── runFile.c │ │ ├── runFileNoCopy.c │ │ ├── sequenceCheck.c │ │ ├── sequenceGen.c │ │ ├── setter.c │ │ ├── setterPrintDouble.c │ │ ├── setterPrintUint64.c │ │ ├── sharedMem.c │ │ ├── signalThread.c │ │ ├── skipUndeclare.c │ │ ├── startFail.c │ │ ├── stdin.c │ │ ├── stdout.c │ │ ├── subDir_test │ │ ├── Makefile │ │ └── a │ │ │ ├── Makefile │ │ │ └── b │ │ │ └── Makefile │ │ ├── superBlock.c │ │ ├── superBlock2.c │ │ ├── superBlock_withMetaData.c │ │ └── superSuperBlock.c ├── retain-symbols.txt ├── signalThread.c ├── signalThread.h ├── stream.c ├── stream.h ├── streamWork.c ├── threadPool.c ├── threadPool.h └── threadPoolHalt.c ├── qt6.make ├── share ├── bash-completion │ └── completions │ │ ├── Makefile │ │ └── quickstream.IN └── doc │ └── quickstream │ └── Makefile └── tests ├── 010_skipTest.c ├── 021_debug.c ├── 040_qsGraph_create.c ├── 044_qsGraph_create_many.c ├── 047_qsGraph_noDestroy.c ├── 052_qsGraphExit.c ├── 053_qsGraph_waitCommand.c ├── 060_job.c ├── 065_job.c ├── 068_job_nt.c ├── 080_job_parallel.c ├── 083_job.c ├── 085_jobSharedPeers.c ├── 086_job_multiThreadPool.c ├── 090_job_multiThreadPool.c ├── 100_oneBlock.c ├── 104_varyMaxThreads.c ├── 111_blocksChangeThreadPool.c ├── 120_removeBlock.c ├── 127_removeJobs.c ├── 131_addMutexes.c ├── 300_qsVersion ├── 402_empty ├── 404_declare ├── 405_destroy ├── 406_declareFail ├── 407_declareFailUndelare ├── 409_skipUndeclare ├── 412_builtIn ├── 415_setter ├── 417_parameterConnections ├── 420_signalThread ├── 430_blockLoadFail ├── 435_parameterChangeThreadPool ├── 443_blockConfigure ├── 464_connectStream ├── 471_execBlock.c ├── 503_runStream ├── 505_startFail ├── 510_blockDestroyingGraph ├── 520_parameterAddLoops ├── 530_parameterConnect ├── 540_loops ├── 554_startStop ├── 566_interpreter ├── 567_interpreter2 ├── 604_FileOut ├── 607_FileIn ├── 612_PipeIn ├── 618_PipeOut ├── 630_runFile ├── 706_passThrough ├── 720_interBlockJob ├── 750_qsGetMemory ├── 780_largeStreamVaryThreads ├── 801_qs_dlopen.c ├── 840_streamAndSetterGetter ├── 850_loadSuperBlock ├── 852_loadSuperBlock ├── 854_emptySuperBlock ├── 860_saveSuperBlock ├── 865_saveAndRunSuperBlock ├── 870_superSuperLoad ├── 871_superSuperSaveLoad ├── 881_saveGraph ├── 883_renameBlock ├── 890_multiGraph ├── 896_metaData ├── 898_metaDataReload ├── 920_epoll ├── Makefile ├── README.md ├── SearchArray.c ├── _042_waitForever ├── _043_wait5 ├── _542_loops ├── _550_spewForever ├── _553_spewSleepStop ├── _554_spewFileForever ├── _603_printDot1 ├── _710_passThroughFail ├── _770_largeStream30Seconds ├── _772_largeStream30SecDisp ├── _781_largeStreamVaryThreads ├── _810_buttonStopStart ├── _812_buttons ├── _820_slider ├── _830_startStopButton ├── _906_GNUradio_urandom ├── _zerosInFile.c ├── atomic_test.c ├── c-rbtree_00.c ├── devel_test_quickstreamGUI ├── fail.c ├── getline.c ├── itimer_test.c ├── malloc_leak.c ├── mod.c ├── pthread_once.c ├── qt6_app_test.cpp ├── qt6_fileLeak_DSO.cpp ├── qt6_fileLeak_test.cpp ├── qt6_fileLeak_test.h ├── quickstreamQt_test ├── returnStatus.c ├── run_tests ├── setjmp.c ├── structAddressMadness.c ├── success.c ├── valgrind_run_tests └── valgrind_suppressions /Makefile: -------------------------------------------------------------------------------- 1 | # This file is for building and installing quickstream with quickbuild, 2 | # not GNU autotools. 3 | # 4 | # The make files with name 'makefile' are generated from 'makefile.am' 5 | # using GNU autotools, specifically GNU automake; and we used the make 6 | # file name 'Makefile' and sometimes 'GNUmakefile' for using quickbuild. 7 | 8 | SUBDIRS :=\ 9 | include\ 10 | lib\ 11 | lib/quickstream/blocks\ 12 | lib/quickstream/misc\ 13 | bin\ 14 | share/doc/quickstream\ 15 | share/bash-completion/completions 16 | 17 | 18 | ifneq ($(wildcard quickbuild.make),quickbuild.make) 19 | $(error "First run './bootstrap'") 20 | endif 21 | ifneq ($(wildcard config.make),config.make) 22 | $(error "Now run './configure'") 23 | endif 24 | 25 | 26 | 27 | ifeq ($(strip $(subst cleaner, clean, $(MAKECMDGOALS))),clean) 28 | SUBDIRS +=\ 29 | tests 30 | endif 31 | 32 | 33 | test: 34 | $(MAKE) && cd tests && $(MAKE) test 35 | 36 | 37 | include quickbuild.make 38 | -------------------------------------------------------------------------------- /bin/qsQt.h: -------------------------------------------------------------------------------- 1 | 2 | class Notebook; 3 | 4 | extern 5 | void CreateWindow(const char *blockPath=0); 6 | 7 | -------------------------------------------------------------------------------- /bin/qsQt_block.h: -------------------------------------------------------------------------------- 1 | 2 | extern void CreateBlock(struct QsGraph *qsGraph, 3 | QGraphicsView *graphicsView, const char *blockPath); 4 | 5 | -------------------------------------------------------------------------------- /bin/qsQt_graph.h: -------------------------------------------------------------------------------- 1 | 2 | extern QWidget *CreateGraph(const char *blockPath); 3 | 4 | -------------------------------------------------------------------------------- /bin/qsQt_notebook.cpp: -------------------------------------------------------------------------------- 1 | // Qt has a generic tab-bar QTabBar which has no notebook page like widget 2 | // associated with each tab. The pre-made tab-notebook thing is managed 3 | // with a QTabWidget object. Me, coming from a GTK widgets background, 4 | // the Qt tabs terminology seems a little off too me. 5 | 6 | 7 | // To add a tab is to add a graph. 8 | 9 | #include 10 | #include 11 | 12 | #include "../include/quickstream.h" 13 | 14 | #include "../lib/debug.h" 15 | 16 | #include "qsQt_notebook.h" 17 | #include "qsQt_graph.h" 18 | 19 | 20 | class Notebook : public QTabWidget 21 | { 22 | Q_OBJECT // MOC voodoo 23 | 24 | public: 25 | explicit Notebook(QWidget *window, QWidget *parent); 26 | ~Notebook(void); 27 | 28 | private slots: // MOC voodoo. 29 | void closeTab(const int& index); 30 | 31 | private: 32 | QWidget *window; // The main window that this notebook is in. 33 | }; 34 | 35 | 36 | void Notebook::closeTab(const int& index) { 37 | 38 | if(count() == 1) 39 | // This is the last tab left, that will be destroyed with the main 40 | // window which is a super (top) parent of these tabs. 41 | delete window; 42 | else 43 | delete widget(index); 44 | } 45 | 46 | 47 | Notebook::Notebook(QWidget *win, QWidget *parent) : 48 | QTabWidget(parent), window(win) { 49 | 50 | setTabsClosable(true); 51 | 52 | // MOC voodoo. This works with Qt6 v6.7.0 53 | connect(this, SIGNAL(tabCloseRequested(int)), 54 | this, SLOT(closeTab(int))); 55 | show(); 56 | } 57 | 58 | Notebook::~Notebook(void) { 59 | 60 | ERROR(); 61 | } 62 | 63 | // To hell with OOP (object oriented programming). 64 | 65 | // We did not want to expose any more Qt MOC code to the other code, 66 | // hence we just expose these two functions (symbols) to the other 67 | // source files: 68 | 69 | Notebook *CreateNotebook(QWidget *window, QWidget *parent) { 70 | DASSERT(window); 71 | DASSERT(parent); 72 | return new Notebook(window, parent); 73 | } 74 | 75 | void Notebook_AddTab(Notebook *notebook, const char *name/*tab label*/, 76 | const char *blockPath) { 77 | 78 | DASSERT(notebook); 79 | DASSERT(name); 80 | DASSERT(name[0]); 81 | 82 | notebook->addTab(CreateGraph(blockPath), Notebook::tr(name)); 83 | } 84 | -------------------------------------------------------------------------------- /bin/qsQt_notebook.h: -------------------------------------------------------------------------------- 1 | 2 | class Notebook; 3 | 4 | extern Notebook *CreateNotebook(QWidget *win, QWidget *parent); 5 | 6 | extern void Notebook_AddTab(Notebook *notebook, 7 | const char *name, const char *blockPath=0); 8 | 9 | -------------------------------------------------------------------------------- /bin/qsQt_treeview.h: -------------------------------------------------------------------------------- 1 | 2 | extern 3 | QTreeView *MakeTreeview(QWidget *parent = 0); 4 | 5 | -------------------------------------------------------------------------------- /bin/qsQt_window.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | 6 | #include "../lib/debug.h" 7 | #include "../include/quickstream.h" 8 | 9 | #include "qsQt_notebook.h" 10 | 11 | #include "qsQt.h" 12 | #include "qsQt_treeview.h" 13 | 14 | 15 | class Window : public QWidget { 16 | 17 | public: 18 | 19 | Window(const char *blockPath=0); 20 | 21 | private: 22 | 23 | ~Window(void); 24 | }; 25 | 26 | 27 | // This is the only exposed function from this file. 28 | void CreateWindow(const char *blockPath) { 29 | new Window(blockPath); 30 | // This Window will automatically have delete called on it. 31 | } 32 | 33 | #define W 1400 34 | #define H 700 35 | 36 | // https://doc.qt.io/qt-6/qtwidgets-tutorials-widgets-toplevel-example.html 37 | // Says: 38 | // it is up to the developer to keep track of the top-level widgets in an 39 | // application. 40 | // 41 | Window::Window(const char *blockPath_in): 42 | QWidget((QWidget *)0/*0 = top level window widget*/){ 43 | 44 | size_t w = W, h = H; 45 | 46 | QWidget *win = this; 47 | // This Window object will automatically have delete called on it. 48 | win->setAttribute(Qt::WA_DeleteOnClose, true); 49 | win->resize(w, h); 50 | win->show(); 51 | 52 | DSPEW("blockPath=\"%s\"", blockPath_in); 53 | 54 | win->setWindowTitle("quickstream"); 55 | //QApplication::translate("toplevel", "Top-level widget")); 56 | 57 | QVBoxLayout *layout = new QVBoxLayout(win); 58 | layout->setContentsMargins( 59 | /* adds a border around the edge of the window */ 60 | 0/*left*/, 0/*top*/, 0/*right*/, 0/*bottom*/); 61 | QSplitter *splitter = new QSplitter(Qt::Horizontal); 62 | layout->addWidget(splitter); 63 | 64 | Notebook *notebook = CreateNotebook(win, splitter); 65 | Notebook_AddTab(notebook, "TabName1"); 66 | Notebook_AddTab(notebook, "TabName2"); 67 | 68 | MakeTreeview(splitter); 69 | 70 | splitter->setHandleWidth(3); 71 | splitter->show(); 72 | // Reuse w, and h. 73 | h = w; 74 | if(w > 300) 75 | w = w - 300; 76 | else 77 | w /= 2; 78 | splitter->setSizes({(int) w, (int) (h - w)}); 79 | splitter->setChildrenCollapsible(true); 80 | } 81 | 82 | 83 | Window::~Window(void) { 84 | 85 | // TODO: cleanup anything else that may need cleaning up. 86 | 87 | DSPEW(); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /bin/qsg_cursor.c: -------------------------------------------------------------------------------- 1 | // 2 | // The easiest solution would be that the CSS that makes themes included 3 | // setting the cursor in it; but GTK3 does not support that. The CSS 4 | // widget theme stuff that GTK3 does support works pretty well; like for 5 | // example controlling the background-color and border of GTK widgets; and 6 | // so we can change that on the fly. 7 | // 8 | // Support for setting the cursor using CSS on web pages just fucking 9 | // works. 10 | // 11 | // The solution may be to see what a "good" working program like firefox 12 | // is doing to control the cursor. That's a big can of worms. 13 | // 14 | // from looking at /proc/$PID/maps I see a mapping with libgtk-3.so.0.2404.29 15 | // so maybe firefox uses GTK3 to make it's widgets on GNU/Linux. 16 | // 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "../lib/debug.h" 24 | #include "../lib/Dictionary.h" 25 | 26 | #include "quickstreamGUI.h" 27 | 28 | 29 | static 30 | struct QsDictionary *dict = 0; 31 | 32 | 33 | static void CleanupCursor(GdkCursor *cursor) { 34 | 35 | // TODO: WTF why 2? 36 | g_object_unref(cursor); 37 | g_object_unref(cursor); 38 | } 39 | 40 | 41 | void CleanUpCursors(void) { 42 | 43 | if(!dict) return; 44 | qsDictionaryDestroy(dict); 45 | dict = 0; 46 | } 47 | 48 | 49 | // file:///usr/share/gtk-doc/html/gdk3/gdk3-Cursors.html#gdk-cursor-new-from-name 50 | // 51 | // cursors we like are: "default", "pointer", "grabbing", "grab" 52 | // 53 | void SetWidgetCursor(GtkWidget *w, const char *name) { 54 | 55 | // First see if we have this cursor already in our dictionary. 56 | if(!dict) 57 | dict = qsDictionaryCreate(); 58 | 59 | GdkCursor *cursor = qsDictionaryFind(dict, name); 60 | 61 | if(!cursor) { 62 | cursor = gdk_cursor_new_from_name( 63 | gdk_display_get_default(), 64 | name); 65 | DASSERT(cursor); 66 | struct QsDictionary *idict; 67 | ASSERT(0 == qsDictionaryInsert(dict, name, cursor, &idict)); 68 | qsDictionarySetFreeValueOnDestroy(idict, 69 | (void (*)(void *)) CleanupCursor); 70 | } 71 | 72 | GdkWindow *win = gtk_widget_get_window(w); 73 | DASSERT(win); 74 | gdk_window_set_cursor(win, cursor); 75 | } 76 | -------------------------------------------------------------------------------- /bin/qsg_treeView.h: -------------------------------------------------------------------------------- 1 | // Stupid-ass GTK3 tree view widget wrapper/API. 2 | 3 | extern 4 | GtkWidget *treeViewCreate(void); 5 | 6 | extern 7 | bool treeViewAdd(GtkWidget *tree, 8 | const char *path, const char *name, GtkTreeIter *topIter, 9 | bool (*CheckFile)(int dirfd, const char *path), 10 | char *(*GetName)(int dirfd, const char *path)); 11 | 12 | extern 13 | bool treeViewAdd_usingStringArray( 14 | GtkWidget *tree, GtkTreeIter *parentIter, 15 | const char * const builtInBlocks[]); 16 | 17 | 18 | extern 19 | void treeViewShow(GtkWidget *tree, const char *header); 20 | 21 | 22 | extern 23 | void ShowTreeViewPopupMenu(GtkTreeView *treeView, 24 | char *newPath, char *dir); 25 | 26 | extern 27 | char *GetBlockSourcePath(GtkTreeView *treeView); 28 | 29 | 30 | extern 31 | GtkTreePath *GetTreePath(GtkTreeView *treeView); 32 | -------------------------------------------------------------------------------- /bin/qt6_2app_test.cpp: -------------------------------------------------------------------------------- 1 | // This test program shows the Qt is more robust than GTK. The main loop 2 | // thingy of Qt has a destructor and GTK does not. GTK can have only one 3 | // main loop object in a process; they never bothered to make a gtk_init() 4 | // a corresponding destructor. 5 | // 6 | // I wonder how thread-safe QApplication is: Can I make many threads, 7 | // each with a different QApplication in it? 8 | 9 | // From 10 | // https://doc.qt.io/qt-6/qtwidgets-tutorials-widgets-toplevel-example.html 11 | // and some changes. 12 | 13 | // We are not using gmake, Cmake, or whatever other build tools that Qt6 14 | // uses; so we do not have a standard header include like in the Qt 15 | // examples: 16 | #include 17 | 18 | #include "../lib/debug.h" 19 | 20 | 21 | static 22 | int RunWindow(QApplication *qa) { 23 | 24 | QWidget window; 25 | window.resize(620, 740); 26 | window.show(); 27 | window.setWindowTitle( 28 | QApplication::translate("toplevel", "Top-level widget")); 29 | return qa->exec(); 30 | } 31 | 32 | static 33 | void RunApp(int argc, char* argv[]) { 34 | 35 | // We tried making 2 QApplications and it just hangs the second 36 | // QApplication constructor. We'll need to make a wrapper of 37 | // QApplication, so that we can count them, and pretend to make many 38 | // of them. Far better than the bull shit we had to do to use GTK3 as 39 | // a module. 40 | //QApplication qa2(argc, argv); 41 | QApplication qa(argc, argv); 42 | 43 | ERROR(); 44 | ERROR("exec() returned %d", RunWindow(&qa)); 45 | ERROR("exec() returned %d", RunWindow(&qa)); 46 | } 47 | 48 | 49 | int main(int argc, char* argv[]) { 50 | 51 | // See if QApplication is robust under reuse. 52 | RunApp(argc, argv); 53 | 54 | RunApp(argc, argv); 55 | // If we did not crash before here than yes we can make create and 56 | // destroy a QApplication many times in one process. 57 | // 58 | // Who knows, QApplication may not even leak memory. 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /bin/qt6_DSO_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | #include "../lib/debug.h" 9 | 10 | #include "qt6_DSO_test.h" 11 | 12 | 13 | static 14 | int RunWindow(QApplication *qa) { 15 | 16 | QWidget window; 17 | window.resize(620, 740); 18 | window.show(); 19 | window.setWindowTitle( 20 | QApplication::translate("toplevel", "Top-level widget")); 21 | 22 | DSPEW(); 23 | 24 | Wait("About to call qa->exec()"); 25 | 26 | return qa->exec(); 27 | } 28 | 29 | 30 | void RunApp(int argc, char* argv[]) { 31 | 32 | // We tried making 2 QApplications and it just hangs the second 33 | // QApplication constructor. We'll need to make a wrapper of 34 | // QApplication, so that we can count them, and pretend to make 35 | // many of them. Far better than the bull shit we had to do to 36 | // use GTK3 as a module. 37 | //QApplication qa2(argc, argv); 38 | QApplication qa(argc, argv); 39 | 40 | ERROR(); 41 | ERROR("exec() returned %d", RunWindow(&qa)); 42 | ERROR("exec() returned %d", RunWindow(&qa)); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /bin/qt6_DSO_test.h: -------------------------------------------------------------------------------- 1 | 2 | #ifdef __cplusplus 3 | extern "C" { 4 | #endif 5 | void RunApp(int argc, char* argv[]); 6 | #ifdef __cplusplus 7 | } 8 | #endif 9 | 10 | 11 | static inline 12 | void Wait(const char *note = 0) { 13 | if(note) 14 | printf("\n%s\n\n", note); 15 | printf("Run: ls -thlF --color=auto /proc/%d/fd\n", getpid()); 16 | printf(" to continue\n"); 17 | getchar(); 18 | printf("\n"); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /bin/qt6_module_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "../lib/debug.h" 10 | 11 | #include "qt6_DSO_test.h" 12 | 13 | 14 | int main(int argc, char* argv[]) { 15 | 16 | const char *DSOPath = "./qt6_DSO_test.so"; 17 | 18 | Wait("About to dlopen Qt6 DSO wrapper"); 19 | 20 | void *dlh = dlopen(DSOPath, RTLD_LAZY); 21 | ASSERT(dlh, "dlopen(\"%s\", 0) failed", DSOPath); 22 | 23 | void (*RunApp)(int argc, char* argv[]) = 24 | (void (*)(int argc, char* argv[])) dlsym(dlh, "RunApp"); 25 | 26 | // See if QApplication is robust under reuse. 27 | RunApp(argc, argv); 28 | 29 | 30 | Wait("About to dclose() Qt6 DSO wrapper"); 31 | 32 | ASSERT(0 == dlclose(dlh)); 33 | ERROR("dlclose() was called"); 34 | 35 | Wait("About to dlopen Qt6 DSO wrapper"); 36 | 37 | 38 | dlh = dlopen(DSOPath, RTLD_LAZY); 39 | ASSERT(dlh, "dlopen(\"%s\", 0) failed", DSOPath); 40 | 41 | RunApp(argc, argv); 42 | // If we did not crash before here than yes we can make create and 43 | // destroy a QApplication many times in one process. 44 | // 45 | // Who knows, QApplication may not even leak memory. 46 | 47 | Wait("About to dclose() Qt6 DSO wrapper"); 48 | 49 | ASSERT(0 == dlclose(dlh)); 50 | ERROR("dlclose() was called"); 51 | 52 | Wait("About to exit main()"); 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /bin/qt6_treeview_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "../include/quickstream.h" 6 | #include "../lib/debug.h" 7 | #include "../lib/mprintf.h" 8 | 9 | #include "qsQt_treeview.h" 10 | 11 | 12 | 13 | int main(int argc, char *argv[]) { 14 | 15 | QApplication app(argc, argv); 16 | 17 | char *path = mprintf("%s/quickstream/misc/test_blocks", qsLibDir); 18 | //char *path = strdup("../lib/quickstream/misc/test_blocks"); 19 | 20 | // This will add more blocks to the treeview. 21 | setenv("QS_BLOCK_PATH", path, 1); 22 | memset(path, 0, strlen(path)); 23 | free(path); 24 | 25 | QTreeView *view = MakeTreeview(); 26 | 27 | const auto screenSize = view->screen()->availableSize(); 28 | view->resize({screenSize.width()/2, screenSize.height()/2}); 29 | view->show(); 30 | return QCoreApplication::exec(); 31 | } 32 | -------------------------------------------------------------------------------- /bin/quickstream.h: -------------------------------------------------------------------------------- 1 | 2 | // Needed for ../lib/quickstream/misc/qsOptions.h 3 | // 4 | struct opts { 5 | const char *longOpt; 6 | int shortOpt; // char code like 'c' 7 | }; 8 | 9 | 10 | extern 11 | int exitStatus; 12 | 13 | extern 14 | bool exitOnError; 15 | 16 | extern 17 | int spewLevel; 18 | 19 | 20 | // i is the current index 21 | // 22 | // i should be 1 first call to this 23 | // for common use main(argc, argv) 24 | // 25 | // argv must be null terminated 26 | // 27 | // returns the next short option char, or 0 if at the end, 28 | // or '*' 29 | // 30 | // command gets set to point to a static string that is the 31 | // long option like for example: "--help" or "*" if there 32 | // was none found. 33 | // 34 | extern int getOpt(int argc, const char * const *argv, int i, 35 | const struct opts *options/*array of options*/, 36 | const char **command); 37 | 38 | extern 39 | bool RunCommand(int c, int argc, const char *command, 40 | const char * const * argv); 41 | 42 | extern 43 | void help(int fd, const char *opt); 44 | 45 | 46 | extern 47 | int RunInterpreter(int numArgs, const char * const *arg); 48 | -------------------------------------------------------------------------------- /bin/quickstreamGUI.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../include/quickstream.h" 8 | 9 | #include "../lib/debug.h" 10 | #include "../lib/qsGtk_init.h" 11 | 12 | #include "quickstreamGUI.h" 13 | 14 | 15 | 16 | // Clean up some stuff in this program and maybe do somethings before 17 | // exiting. 18 | static inline void FinishUp(void) { 19 | 20 | DSPEW(); 21 | } 22 | 23 | 24 | static void 25 | Catcher(int sig) { 26 | 27 | ASSERT(0, "Caught signal %d\n", sig); 28 | } 29 | 30 | 31 | 32 | int main(int argc, char *argv[]) { 33 | 34 | ASSERT(signal(SIGSEGV, Catcher) != SIG_ERR); 35 | ASSERT(signal(SIGABRT, Catcher) != SIG_ERR); 36 | 37 | // TODO: Add --help support. 38 | 39 | // qsGtk_init() is a gtk_init() wrapper that helps us use the pthreads 40 | // API and not the glib gthread stuff. 41 | // 42 | qsGtk_init(&argc, &argv); 43 | 44 | AddCSS(); 45 | 46 | // Make one top level window to start with. 47 | // 48 | // We can make more as it runs. 49 | if(argc < 2 || !argv[1][0]) 50 | CreateWindow(0); 51 | else 52 | CreateWindow(argv[1]); 53 | 54 | gtk_main(); 55 | 56 | // TODO: Should this be called before the above loop? 57 | FinishUp(); 58 | 59 | // qsGtk_cleanup() is part of the qsGtk_init() hack. 60 | qsGtk_cleanup(); 61 | 62 | // At this point there will be some system resources not cleaned up by 63 | // GTK3. GTK3 is not robust that way. It's that way by design. 64 | // There is no corresponding destructor for gtk_init() and/or a 65 | // library destructor for the GTK3 libraries (crap-ton of 66 | // libraries). 67 | 68 | // The libquickstream.so resources are all cleaned up in it's library 69 | // destructor. We checked it with Valgrind. 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /bin/quickstreamGUI_attach.c: -------------------------------------------------------------------------------- 1 | 2 | #include "../include/quickstream.h" 3 | #include "../lib/debug.h" 4 | 5 | 6 | 7 | int main(int argc, const char * const *argv) { 8 | 9 | 10 | 11 | ERROR("This program is not finished and nor is" 12 | " it ready to use. It's just a place holder " 13 | "for future code."); 14 | 15 | 16 | return 1; // 1 error code 17 | } 18 | -------------------------------------------------------------------------------- /bin/quickstreamQt.cpp: -------------------------------------------------------------------------------- 1 | // This is like quickstreamGUI but with Qt 6 and not GTK3. 2 | 3 | #include 4 | #include 5 | //#include 6 | //#include 7 | //#include 8 | 9 | 10 | #include 11 | 12 | #include "../lib/qsQtApp.h" 13 | #include "../lib/debug.h" 14 | #include "../include/quickstream.h" 15 | 16 | #include "qsQt.h" 17 | 18 | 19 | static void 20 | Catcher(int sig) { 21 | 22 | ASSERT(0, "Caught signal %d\n", sig); 23 | } 24 | 25 | int main(int argc, const char * const *argv) { 26 | 27 | // Looks like some times errno starts in a random value. 28 | errno = 0; 29 | ASSERT(signal(SIGSEGV, Catcher) != SIG_ERR); 30 | ASSERT(signal(SIGABRT, Catcher) != SIG_ERR); 31 | 32 | // TODO: add command-line options argv parsing. 33 | 34 | // qsQtApp is a wrapper of QApplication. It is needed so that we can 35 | // have quickstream blocks that make Qt widgets without having to have 36 | // Qt libraries linked to ../lib/libquickstream.so without have to put 37 | // a lot of code here. 38 | qsQtApp_construct(); 39 | 40 | // Add block path argument if it's given in the command-line. 41 | CreateWindow(); 42 | //CreateWindow(); // Test that there can be more main windows. 43 | //CreateWindow(); 44 | 45 | qsQtApp_exec(); 46 | 47 | qsQtApp_destroy(); 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /bin/quickstream_interpreter.c: -------------------------------------------------------------------------------- 1 | // This program, quickstream_interpreter, is to get around the limitations 2 | // of GNU/Linux Shebang in some use cases; it's like the program 3 | // "quickstream" with this one C file changed. 4 | // 5 | // You see we need to provide a way for quickstream users to run a 6 | // quickstream graph via the common Shebang at the top of a file like: 7 | // 8 | // #!/usr/bin/env quickstream_interpreter 9 | // 10 | // because something like: 11 | // 12 | // #!/usr/bin/env quickstream --interpreter 13 | // 14 | // will not work because the 2 arguments "quickstream --interpreter" 15 | // end up being seen as 1 argument. The "quickstream --interpreter" 16 | // is not the program we wish to run, "quickstream" is. 17 | // Running: "quickstream_interpreter" is equivalent to running 18 | // "quickstream --interpreter", that is "quickstream" with the 19 | // "--interpreter" command-line option. 20 | // 21 | // 22 | // See: https://en.wikipedia.org/wiki/Shebang_(Unix) 23 | // 24 | // 25 | // It also gets around the limitations of the length of a bash command 26 | // line. The quickstream_interpreter file has no file size limit, where 27 | // as a single bash command line has a length limit where-by limiting the 28 | // number of quickstream commands that can be run by the "quickstream" 29 | // program, without this interpreter mode. 30 | // 31 | // 32 | // TODO: A little more studying of what this does is needed. 33 | // 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | #include "../lib/debug.h" 41 | 42 | #include "../include/quickstream.h" 43 | 44 | #include "./quickstream.h" 45 | 46 | // defines qsOptions[] and DEFAULT_SPEW_LEVEL 47 | #include "../lib/quickstream/misc/qsOptions.h" 48 | 49 | 50 | 51 | int exitStatus = 0; 52 | 53 | int spewLevel = DEFAULT_SPEW_LEVEL; 54 | 55 | bool exitOnError = false; 56 | 57 | 58 | 59 | static void gdb_catcher(int signum) { 60 | // The action of ASSERT() depends on how this is compiled. 61 | ASSERT(0, "Caught signal %d\n", signum); 62 | } 63 | 64 | 65 | int main(int argc, const char * const *argv) { 66 | 67 | setSpewLevel(spewLevel); 68 | 69 | // Hang the program for debugging, if we segfault. 70 | ASSERT(SIG_ERR != signal(SIGSEGV, gdb_catcher)); 71 | 72 | return RunInterpreter(argc-1, argv+1); 73 | } 74 | -------------------------------------------------------------------------------- /bin/treeView_test.h: -------------------------------------------------------------------------------- 1 | 2 | extern 3 | GtkWidget *treeViewCreate(void); 4 | 5 | extern 6 | GtkWidget *treeViewAdd(GtkWidget *tree, 7 | const char *path, const char *name, 8 | bool (*CheckFile)(int dirfd, const char *path), 9 | char *(*GetName)(int dirfd, const char *path)); 10 | 11 | extern 12 | void treeViewShow(GtkWidget *tree, const char *header); 13 | -------------------------------------------------------------------------------- /config.make.example: -------------------------------------------------------------------------------- 1 | # This file defines possible make "configuration" variables. 2 | # 3 | # This make file is used when building/installing using the quickbuild 4 | # build system to build/install quickstream. This file is ignored when 5 | # building/installing quickbuild with the GNU autotools build system, and 6 | # when building/installing with meson (TODO). 7 | # 8 | # We try to keep similar make variables in the GNU autotools build method. 9 | # 10 | # The optionally built files are automatically added based on running 11 | # programs like 'pkg-config' in the quickbuild makefiles (Makefile) to see 12 | # if dependences are available. 13 | 14 | 15 | # We really want there to be very little to configure in this file. 16 | # PREFIX is (or will be) a directory that contains all the files 17 | # that are installed for this software project. 18 | 19 | PREFIX = /usr/local/encap/quickstream 20 | 21 | 22 | # Set CPPFLAGS for debug build options: 23 | # 24 | # 25 | # SPEW_LEVEL_* controls macros in lib/debug.h 26 | # 27 | # The following may be defined; defining them turns on the following CPP 28 | # macro functions that are in debug.h which is a source file for 29 | # libquickstream.so and other binary files. 30 | # 31 | # CPP macro flag makes SPEW CPP macro functions 32 | #----------------- ------------------------------ 33 | # 34 | # DEBUG --> DASSERT() 35 | # 36 | # SPEW_LEVEL_DEBUG --> DSPEW() INFO() NOTICE() WARN() ERROR() 37 | # SPEW_LEVEL_INFO --> INFO() NOTICE() WARN() ERROR() 38 | # SPEW_LEVEL_NOTICE --> NOTICE() WARN() ERROR() 39 | # SPEW_LEVEL_WARN --> WARN() ERROR() 40 | # SPEW_LEVEL_ERROR --> ERROR() 41 | # 42 | # 43 | # If you really need to understand what these do look in 44 | # the file lib/debug.h 45 | # 46 | # always on is --> ASSERT() 47 | # 48 | 49 | 50 | # Examples: 51 | #CPPFLAGS := -DSPEW_LEVEL_NOTICE 52 | CPPFLAGS := -DDEBUG -DSPEW_LEVEL_DEBUG 53 | 54 | #CPPFLAGS := -DDEBUG -DSPEW_LEVEL_INFO 55 | 56 | 57 | # C compiler option flags 58 | CFLAGS := -g -Wall -Werror -fno-omit-frame-pointer 59 | 60 | # C++ compiler option flags 61 | CXXFLAGS := -g -Wall -Werror -fno-omit-frame-pointer 62 | -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This will get replaced by a GNU autotools autoconf input file named 4 | # configure.ac. For now quickBuild is 10 times faster so the lost in 5 | # development time is not worth the gain in standardization and user 6 | # acceptance which comes from using GNU autotools. Oh yes, CMake is a 7 | # bloat monster. quickstream will not use CMake. 8 | 9 | set -ex 10 | 11 | # Go to the directory where this script is. 12 | cd $(dirname ${BASH_SOURCE[0]}) 13 | 14 | # File config.make is not checked in and it may have user 15 | # configuration information in it, so we do not want to 16 | # check it in. 17 | if [ ! -e config.make ] ; then 18 | echo -e "# This is a generated file\n" > config.make 19 | cat config.make.example >> config.make 20 | fi 21 | 22 | 23 | if [ ! -e quickbuild.make ] ; then 24 | ./bootstrap 25 | fi 26 | 27 | 28 | set +x 29 | echo -e "\n$0 Success" 30 | -------------------------------------------------------------------------------- /gtk3.make: -------------------------------------------------------------------------------- 1 | 2 | # apt install libgtk-3-dev 3 | # 4 | # Get the GTK3 specific compiler options if we can. If GTK3 is 5 | # installed where we can find it this way: 6 | ifeq ($(WITHOUT_GTK3),) 7 | GTK3_LDFLAGS := $(shell pkg-config --libs gtk+-3.0) 8 | GTK3_CFLAGS := $(shell pkg-config --cflags gtk+-3.0) 9 | endif 10 | 11 | # Spew what GTK3 stuff we have found 12 | #$(warning GTK3_CFLAGS="$(GTK3_CFLAGS)" GTK3_LDFLAGS="$(GTK3_LDFLAGS)") 13 | 14 | -------------------------------------------------------------------------------- /include/Makefile: -------------------------------------------------------------------------------- 1 | # We broke the libquistream.so header file into a few smaller source files 2 | # and we build another version of it for running doxygen on. 3 | 4 | INSTALL_DIR = $(PREFIX)/include 5 | 6 | 7 | BUILD := quickstream.h quickstream_debug.h quickstream_mprintf.h 8 | BUILD_NO_INSTALL := quickstream_expanded.h 9 | 10 | 11 | quickstream_expanded.h: header.h block.h builder.h runner.h footer.h 12 | echo -e "// This is a generated file\n" > $@ 13 | cat $^ >> $@ 14 | 15 | # TODO: note this assumes we are using GCC 16 | quickstream.h: quickstream_expanded.h 17 | echo -e "// This is a generated file\n" > $@ 18 | $(CC) -Werror -Wall -fpreprocessed -dD -E -P $< >> $@ 19 | 20 | quickstream_debug.h: ../lib/debug.h 21 | cp $^ $@ 22 | 23 | quickstream_mprintf.h: ../lib/mprintf.h 24 | cp $^ $@ 25 | 26 | 27 | 28 | 29 | include ../quickbuild.make 30 | -------------------------------------------------------------------------------- /include/footer.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | } // extern "C" { 3 | #endif 4 | 5 | 6 | #endif // #ifndef __QUICKSTREAM_H__ 7 | -------------------------------------------------------------------------------- /lib/FindFullPath.h: -------------------------------------------------------------------------------- 1 | 2 | extern 3 | char *FindFullPath(const char *name, 4 | const char *prefix, 5 | const char *suffix, 6 | const char *envPath); 7 | -------------------------------------------------------------------------------- /lib/SearchArray.h: -------------------------------------------------------------------------------- 1 | // This could be extended to different types. 2 | 3 | 4 | // We assume that the array[] has elements in ascending order. 5 | // 6 | // O(log2 N) of operation bisection search 7 | // 8 | // It's a little complex, but not O(N^2) 9 | // 10 | static inline 11 | int FindNearestInArray(int x, int *array, int alen) { 12 | 13 | // Find the closest x. 14 | // 15 | // We assume that the array[] array has an ascending order. 16 | // 17 | // Let "inc" be the amount (increment er) we travel in the array as we 18 | // search. It can be positive or negative and it decreases in 19 | // magnitude as we search. 20 | int inc = alen/2; 21 | // Let i be the index into array[] that we are looking for. 22 | int i = inc; 23 | if(array[i] > x) 24 | inc *= -1; 25 | int prevX = array[i]; 26 | int imax = alen - 1; 27 | 28 | // O(log2 N) bisection search. 29 | // 30 | // I don't know why I did this. It's like a list of 30 values. 31 | // A simple linear search would have been fine, but why do something 32 | // easy when you can make it the hard way. 33 | // 34 | while((inc > 0 && array[i] < x) || (inc < 0 && array[i] > x)) { 35 | 36 | prevX = array[i]; 37 | 38 | if(inc > 1 || inc < -1) 39 | // Move less this time. 40 | inc /= 2; 41 | 42 | if((inc > 0 && i < imax) || (inc < 0 && i > 0)) 43 | // move in the chosen direction 44 | i += inc; 45 | else 46 | // We are at an edge in the array[] array. 47 | return array[i]; 48 | 49 | if(abs(inc) == 1) 50 | if((prevX > x && x > array[i]) || 51 | (prevX < x && x < array[i])) 52 | // We trapped the value between to ends. 53 | break; 54 | 55 | if((inc > 0 && array[i] > x) || (inc < 0 && array[i] < x)) { 56 | // change direction 57 | inc *= -1; 58 | } 59 | } 60 | 61 | if(abs(prevX - x) < abs(array[i] - x)) 62 | return prevX; 63 | 64 | return array[i]; 65 | } 66 | 67 | -------------------------------------------------------------------------------- /lib/builtInBlocks.h: -------------------------------------------------------------------------------- 1 | 2 | extern 3 | struct QsDictionary *builtInBlocksFunctions; 4 | 5 | // This function is auto-generated into listBuiltInBlocks.c 6 | // GatherBuiltInBlocksFunctions() puts all the built-in block callback 7 | // functions in the builtInBlocksFunctions dictionary. 8 | extern 9 | void GatherBuiltInBlocksFunctions(void); 10 | 11 | // This string of strings qsBuiltInBlocks is auto-generated into 12 | // builtInBlocks/listBuiltInBlocks.c 13 | extern 14 | const char * const qsBuiltInBlocks[]; 15 | -------------------------------------------------------------------------------- /lib/builtInBlocks.txt: -------------------------------------------------------------------------------- 1 | # These are the built in blocks. Their source is the directories with 2 | # the DSO (dynamic shared object) blocks. The function names of callbacks 3 | # in the built in blocks are a little different from the DSO blocks. 4 | 5 | file/Epoll 6 | file/FileIn 7 | file/FileOut 8 | file/PipeIn 9 | file/PipeOut 10 | misc/NullSink 11 | 12 | -------------------------------------------------------------------------------- /lib/config.h: -------------------------------------------------------------------------------- 1 | 2 | // A simple block or a super block may have any number to configure 3 | // callbacks that configure attributes. We keep a dictionary of 4 | // attributes in the simple and super blocks in the QsModule::attributes 5 | // dictionary. These so called attributes are created in the block's 6 | // declare() function with qsAddConfig(). 7 | // 8 | struct QsAttribute { 9 | 10 | // Unique name for this attribute, for the given block: 11 | char *name; 12 | 13 | // The block callback 14 | char *(*config)(int argc, const char * const *argv, void *userData); 15 | 16 | // description: 17 | char *desc; 18 | 19 | char *argSyntax; 20 | 21 | char *currentArgs; 22 | 23 | // If we keep a record of the last attribute config call by the 24 | // graph runner. 25 | // 26 | // If lastArgv == 0 then there is no record for this attribute. 27 | char **lastArgv; 28 | int lastArgc; 29 | 30 | // The last parent block (or graph) that configured this attribute. 31 | struct QsParentBlock *parentBlock; 32 | }; 33 | -------------------------------------------------------------------------------- /lib/dir.h: -------------------------------------------------------------------------------- 1 | // TODO: This is Linux specific. 2 | 3 | #define DIRSTR "/" 4 | #define DIRCHR '/' 5 | 6 | -------------------------------------------------------------------------------- /lib/epoll.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../include/quickstream.h" 10 | 11 | #include "debug.h" 12 | #include "Dictionary.h" 13 | 14 | #include "c-rbtree.h" 15 | #include "name.h" 16 | #include "threadPool.h" 17 | #include "block.h" 18 | #include "graph.h" 19 | #include "job.h" 20 | #include "port.h" 21 | #include "stream.h" 22 | #include "epoll.h" 23 | 24 | 25 | 26 | static inline struct QsStreamJob *Init(int fd, struct QsPort *port, 27 | struct QsSimpleBlock **b) { 28 | 29 | 30 | // The other non-stream port would be for a control parameter 31 | // setter. 32 | ASSERT(port == 0, "This code is not written for " 33 | "non-stream block callbacks yet."); 34 | 35 | struct QsStreamJob *sj = GetStreamJob(CB_DECLARE, b); 36 | 37 | int flags = fcntl(fd, F_GETFL, 0); 38 | ASSERT(flags != -1); 39 | ASSERT(-1 != fcntl(fd, F_SETFL, flags | O_NONBLOCK)); 40 | 41 | ERROR("Write more code here: sj=%p", sj); 42 | 43 | return sj; 44 | } 45 | 46 | 47 | 48 | void qsAddEpollReadJob(int fd, struct QsPort *port) { 49 | 50 | struct QsSimpleBlock *b; 51 | struct QsStreamJob *sj = Init(fd, port, &b); 52 | 53 | ERROR("Write more code here: sj=%p", sj); 54 | } 55 | 56 | void qsAddEpollWriteJob(int fd, struct QsPort *port) { 57 | 58 | struct QsSimpleBlock *b; 59 | struct QsStreamJob *sj = Init(fd, port, &b); 60 | 61 | ERROR("Write more code here: sj=%p", sj); 62 | } 63 | 64 | -------------------------------------------------------------------------------- /lib/epoll.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | struct EpollClient { 4 | 5 | bool isRead; 6 | 7 | int fd; 8 | 9 | // We use the port to get to the stream job or a control parameter 10 | // setter (job). 11 | struct QsPort *port; 12 | 13 | struct EpollClient *prev, *next; 14 | }; 15 | 16 | 17 | struct Epoll { 18 | 19 | struct EpollClient *clients; 20 | 21 | }; 22 | 23 | 24 | -------------------------------------------------------------------------------- /lib/metaData.h: -------------------------------------------------------------------------------- 1 | 2 | extern 3 | void qsGraph_createMetaDataDict(struct QsGraph *g, 4 | const struct QsBlock *block); 5 | 6 | extern 7 | void WriteMetaDataToSuperBlock(FILE *f, const struct QsGraph *g); 8 | -------------------------------------------------------------------------------- /lib/mmapRingBuffer.h: -------------------------------------------------------------------------------- 1 | 2 | extern 3 | void *makeRingBuffer(size_t *len, size_t *overhang); 4 | 5 | 6 | extern 7 | void freeRingBuffer(void *x, size_t len, size_t overhang); 8 | -------------------------------------------------------------------------------- /lib/name.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "debug.h" 7 | #include "Dictionary.h" 8 | #include "name.h" 9 | 10 | 11 | 12 | // The non-zero success return value must be freed by the user. 13 | // 14 | // If dict is 0 than the name will not be checked with a dictionary. 15 | // 16 | char *GetUniqueName(struct QsDictionary *dict, uint32_t count, 17 | const char *name, const char *prefix) { 18 | 19 | if(name && !name[0]) 20 | name = 0; 21 | 22 | // Get unique name. 23 | if(name) { 24 | 25 | if(!ValidNameString(name)) { 26 | ERROR("Name \"%s\" is invalid", name); 27 | return 0; 28 | } 29 | if(dict && qsDictionaryFind(dict, name)) { 30 | ERROR("Name \"%s\" already exists", name); 31 | return 0; 32 | } 33 | name = strdup(name); 34 | 35 | } else { 36 | // name == 0 so generate a name. 37 | const size_t Len = strlen(prefix) + 12; 38 | char nname[Len]; 39 | do 40 | snprintf(nname, Len, "%s%" PRIu32, prefix, count++); 41 | while(dict && qsDictionaryFind(dict, nname)); 42 | 43 | name = strdup(nname); 44 | } 45 | ASSERT(name, "strdup() failed"); 46 | return (char *) name; 47 | } 48 | -------------------------------------------------------------------------------- /lib/name.h: -------------------------------------------------------------------------------- 1 | 2 | extern 3 | char *GetUniqueName(struct QsDictionary *dict, uint32_t count, 4 | const char *name, const char *prefix); 5 | 6 | static inline bool ValidChar(char c) { 7 | 8 | if(c < ' ' || 9 | c > '~' || 10 | c == '\\' || 11 | c == '`' || 12 | // ':' is the special char that we use in as a sub-name 13 | // delimiter in full names for blocks that have parents. 14 | c == ':') 15 | return false; // not valid 16 | return true; // valid 17 | } 18 | 19 | 20 | static inline bool ValidNameString(const char *s) { 21 | 22 | while(*s && ValidChar(*(s++))); 23 | return !(*s); 24 | } 25 | -------------------------------------------------------------------------------- /lib/parseBool.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | static inline bool 4 | qsParseBool(const char *str) { 5 | 6 | if(!*str) return true; 7 | 8 | char c0 = str[0]; 9 | char c1 = str[1]; 10 | 11 | if(c0 == 'n' || c0 == 'N' || //no 12 | c0 == '0' || // 0 13 | c0 == 'f' || c0 == 'F' || // false 14 | ((c0 == 'o' || c0 == 'O') && 15 | (c1 == 'f' || c1 == 'F')) || // off 16 | c0 == 'u' || c0 == 'U') // unset 17 | return false; 18 | 19 | return true; 20 | } 21 | -------------------------------------------------------------------------------- /lib/pkgconfig/Makefile: -------------------------------------------------------------------------------- 1 | 2 | INSTALL_DIR = $(PREFIX)/lib/pkgconfig 3 | 4 | 5 | INSTALLED := quickstream.pc 6 | 7 | 8 | IN_VARS := PREFIX QUICKSTREAM_VERSION 9 | 10 | 11 | QUICKSTREAM_VERSION := $(shell ../../bin/quickstream -V) 12 | 13 | 14 | quickstream.pc: quickstream.pc.in 15 | 16 | 17 | 18 | include ../../quickbuild.make 19 | -------------------------------------------------------------------------------- /lib/pkgconfig/quickstream.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@PREFIX@ 2 | exec_prefix=${prefix} 3 | libdir=${prefix}/lib 4 | includedir=${prefix}/include 5 | 6 | 7 | Name: quickstream 8 | Description: quickstream, stream graph library 9 | Version: @QUICKSTREAM_VERSION@ 10 | Requires: 11 | Requires.private: 12 | Libs: -L${libdir} -lquickstream 13 | Cflags: -I${includedir} 14 | -------------------------------------------------------------------------------- /lib/port.h: -------------------------------------------------------------------------------- 1 | 2 | // A port is a job with the addition of connections between them and other 3 | // jobs. Ports can be connected to other ports; but there are connection 4 | // rules. 5 | // 6 | // The idea of connections between ports is seen by the highest end users; 7 | // where as the jobs in the ports provides the code that runs to transfer 8 | // data between the ports. The job objects are what the thread pool 9 | // worker threads see. 10 | // 11 | struct QsPort { 12 | 13 | enum QsPortType portType; 14 | 15 | struct QsBlock *block; 16 | 17 | // The "parentBlock" is a history (record) of the last super block (or 18 | // graph top block) that made (or un-made) a connection with this 19 | // port. 20 | // 21 | // We only need to use this "parentBlock" pointer for input and setter 22 | // ports. It's complicated. It's used in qsGraph_saveSuperBlock(). 23 | // 24 | // "parentBlock" is the graph or super block that made the last 25 | // connection with this port. 26 | // 27 | // We need this so we may find the connections made by a graph or 28 | // super block. 29 | // 30 | // Note: we need this for control parameters and stream inputs, but we 31 | // do not need it for stream outputs; because stream inputs only 32 | // connect to one stream output, so stream inputs alone can with keep 33 | // a full record all stream connections since an output can only 34 | // connect to an input. 35 | // 36 | // This value will change as more connections are made and un-made as 37 | // super blocks are loaded recursively, or a graph (top block) makes 38 | // connections. 39 | // 40 | // Think of this as the record of the "last parent block" that made or 41 | // unmade a connection to this port. The last one is all that is 42 | // needed for writing out a super block. The connections made by 43 | // child blocks are already done by the time we access this. 44 | // 45 | struct QsParentBlock *parentBlock; // graph or super block 46 | 47 | char *name; // port name. 48 | }; 49 | -------------------------------------------------------------------------------- /lib/qsGtk_init-symbols.txt: -------------------------------------------------------------------------------- 1 | qsGetGTKContext 2 | qsGtk_cleanup 3 | qsGtk_init 4 | qsReleaseGTKContext 5 | -------------------------------------------------------------------------------- /lib/qsGtk_init.h: -------------------------------------------------------------------------------- 1 | #ifndef __QSGTK_INIT_H__ 2 | #define __QSGTK_INIT_H__ 3 | 4 | 5 | #ifdef BUILD_LIB 6 | // BUILD_LIB is set when compiling qsGtk_init.so 7 | # define QSG_EXPORT __attribute__((visibility("default"))) extern 8 | #else 9 | // This "undef QSG_EXPORT" stops gcc from printing a warning when we run: 10 | // cc -fpreprocessed -dD -E -P quickstream_expanded.h >> quickstream.h 11 | # undef QSG_EXPORT 12 | # define QSG_EXPORT extern 13 | #endif 14 | 15 | 16 | // Users should use these two variables as read only: 17 | QSG_EXPORT 18 | atomic_uint qsGtk_finishedRunning; 19 | QSG_EXPORT 20 | atomic_uint qsGtk_didRun; // it may still be running. 21 | 22 | 23 | 24 | // Wrapper of gtk_init(). It actually creates a thread that runs 25 | // a "special gtk main loop". One that lets you call the GTK3 APIs 26 | // from other "unrelated threads" by using qsGetGTKContext() and 27 | // qsReleaseGTKContext(). 28 | QSG_EXPORT 29 | void qsGtk_init(int *argc, char ***argv); 30 | 31 | // There is no cleanup function for gtk_init() or should I say the cleanup 32 | // function for gtk_init() is exit(). We cleanup what we can of this 33 | // wrapper stuff. 34 | QSG_EXPORT 35 | void qsGtk_cleanup(void); 36 | 37 | 38 | // Use these as gate keepers for where you call functions in the GTK3 39 | // family of APIs. Yes qsGetGTKContext() is like an "enter GTK3" and 40 | // qsReleaseGTKContext() is like an "exit GTK3". 41 | QSG_EXPORT 42 | void qsGetGTKContext(void); 43 | 44 | QSG_EXPORT 45 | void qsReleaseGTKContext(void); 46 | 47 | 48 | #endif // #ifndef __QSGTK_INIT_H__ 49 | -------------------------------------------------------------------------------- /lib/qsQtApp-symbols.txt: -------------------------------------------------------------------------------- 1 | qsQtApp_construct 2 | qsQtApp_exec 3 | qsQtApp_destroy 4 | -------------------------------------------------------------------------------- /lib/qsQtApp.h: -------------------------------------------------------------------------------- 1 | 2 | extern "C" { 3 | 4 | // These are C functions that contain C++ code in them. 5 | 6 | void qsQtApp_construct(void); 7 | 8 | void qsQtApp_exec(void); 9 | 10 | void qsQtApp_destroy(void); 11 | } 12 | -------------------------------------------------------------------------------- /lib/qsQtApp_test.cpp: -------------------------------------------------------------------------------- 1 | // Testing qsQtApp.cpp (read comments there-in) and libqsQtApp.so. 2 | 3 | #include 4 | //#include 5 | //#include 6 | //#include 7 | 8 | #include 9 | #include "qsQtApp.h" 10 | 11 | #include "debug.h" 12 | 13 | 14 | static uint32_t count = 0; 15 | 16 | 17 | static 18 | void RunWindow(void) { 19 | 20 | ERROR(" window count=%" PRIu32, ++count); 21 | QWidget window; 22 | window.resize(320, 440); 23 | window.show(); 24 | qsQtApp_exec(); 25 | ERROR(); 26 | } 27 | 28 | 29 | static 30 | void RunApp(void) { 31 | 32 | qsQtApp_construct(); 33 | RunWindow(); 34 | RunWindow(); 35 | qsQtApp_destroy(); 36 | 37 | qsQtApp_construct(); 38 | RunWindow(); 39 | RunWindow(); 40 | qsQtApp_destroy(); 41 | } 42 | 43 | 44 | int main(void) { 45 | 46 | // See if QApplication is robust under reuse. 47 | RunApp(); 48 | RunApp(); 49 | // Who knows, QApplication may not even leak memory. 50 | // I don't think I'll hold my breath for that one. 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/Makefile: -------------------------------------------------------------------------------- 1 | # We make in all sub-directories in this directory, so long as there is a 2 | # Makefile in them: 3 | SUBDIRS := $(sort $(patsubst ./%/Makefile,%, $(dir $(wildcard ./*/Makefile)))) 4 | 5 | 6 | INSTALL_DIR = $(PREFIX)/lib/quickstream/blocks 7 | 8 | 9 | include ../../../quickbuild.make 10 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/Resamplers/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../.. 4 | 5 | # Now that root is defined we can use the generic block building make 6 | # rules from: 7 | include $(root)/lib/quickstream/blocks/common.make 8 | 9 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/Resamplers/Rational_Resampler.c: -------------------------------------------------------------------------------- 1 | 2 | #include "../../../../include/quickstream.h" 3 | #include "../../../debug.h" 4 | 5 | 6 | 7 | int declare(void) { 8 | 9 | ERROR("Write more code here!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); 10 | 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/controlParameters/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../.. 4 | 5 | # Now that root is defined we can use the generic block building make 6 | # rules from: 7 | include $(root)/lib/quickstream/blocks/common.make 8 | 9 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/controlParameters/bool_gate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../../../../include/quickstream.h" 5 | #include "../../../debug.h" 6 | 7 | 8 | static struct QsParameter *getter; 9 | 10 | // The gate is open (true) or not (false). 11 | static bool gate = false; 12 | static bool valueWaiting = false; 13 | static bool value = false; 14 | 15 | 16 | static 17 | int SetGate(const struct QsParameter *p, 18 | const bool *newGate, 19 | uint32_t readCount, uint32_t queueCount, 20 | void *userData) { 21 | 22 | if((gate = *newGate) && valueWaiting) { 23 | qsGetterPush(getter, &value); 24 | valueWaiting = false; 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | 31 | static 32 | int SetValue(const struct QsParameter *p, 33 | const bool *newValue, 34 | uint32_t readCount, uint32_t queueCount, 35 | void *userData) { 36 | 37 | // Save the value. 38 | value = (*newValue)?true:false; 39 | 40 | if(gate) 41 | // The gate is open so we push a value even if the value did not 42 | // change from the last time. 43 | qsGetterPush(getter, &value); 44 | else 45 | valueWaiting = true; 46 | 47 | return 0; 48 | } 49 | 50 | 51 | 52 | int declare(void) { 53 | 54 | qsCreateSetter("gate", 55 | sizeof(gate), QsValueType_bool, &gate, 56 | (int (*)(const struct QsParameter *, const void *, 57 | uint32_t readCount, uint32_t queueCount, 58 | void *)) SetGate); 59 | 60 | qsCreateSetter("in", 61 | sizeof(value), QsValueType_bool, 0, 62 | (int (*)(const struct QsParameter *, const void *, 63 | uint32_t readCount, uint32_t queueCount, 64 | void *)) SetValue); 65 | 66 | getter = qsCreateGetter("out", sizeof(value), 67 | QsValueType_bool, 0); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/controlParameters/f64_gate.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "../../../../include/quickstream.h" 5 | #include "../../../debug.h" 6 | 7 | 8 | static struct QsParameter *getter; 9 | 10 | // The gate is open (true) or not (false). 11 | static bool gate = false; 12 | static bool valueWaiting = false; 13 | static double value = NAN; 14 | 15 | 16 | static 17 | int SetGate(const struct QsParameter *p, 18 | const bool *newGate, 19 | uint32_t readCount, uint32_t queueCount, 20 | void *userData) { 21 | 22 | if((gate = *newGate) && valueWaiting) { 23 | qsGetterPush(getter, &value); 24 | valueWaiting = false; 25 | } 26 | 27 | return 0; 28 | } 29 | 30 | 31 | static 32 | int SetValue(const struct QsParameter *p, 33 | const double *newValue, 34 | uint32_t readCount, uint32_t queueCount, 35 | void *userData) { 36 | 37 | // Save the value. 38 | value = *newValue; 39 | 40 | if(isnormal(value)) { 41 | if(gate) 42 | // The gate is open so we push a value even if the 43 | // value did not change from the last time. 44 | qsGetterPush(getter, &value); 45 | else 46 | valueWaiting = true; 47 | } else 48 | valueWaiting = false; 49 | 50 | return 0; 51 | } 52 | 53 | 54 | 55 | int declare(void) { 56 | 57 | qsCreateSetter("gate", 58 | sizeof(gate), QsValueType_bool, &gate, 59 | (int (*)(const struct QsParameter *, const void *, 60 | uint32_t readCount, uint32_t queueCount, 61 | void *)) SetGate); 62 | 63 | qsCreateSetter("in", 64 | sizeof(value), QsValueType_double, 0, 65 | (int (*)(const struct QsParameter *, const void *, 66 | uint32_t readCount, uint32_t queueCount, 67 | void *)) SetValue); 68 | 69 | 70 | getter = qsCreateGetter("out", sizeof(value), 71 | QsValueType_double, 0); 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/controlParameters/not.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../debug.h" 5 | 6 | 7 | static struct QsParameter *getter; 8 | 9 | 10 | static 11 | int SetCallback(const struct QsParameter *p, 12 | const bool *value, 13 | uint32_t readCount, uint32_t queueCount, 14 | void *userData) { 15 | 16 | const bool valueOut = !(*value); 17 | 18 | qsGetterPush(getter, &valueOut); 19 | 20 | return 0; 21 | } 22 | 23 | 24 | int declare(void) { 25 | 26 | bool val = false; 27 | 28 | qsCreateSetter("in", 29 | sizeof(val), QsValueType_bool, &val, 30 | (int (*)(const struct QsParameter *, const void *, 31 | uint32_t readCount, uint32_t queueCount, 32 | void *)) SetCallback); 33 | 34 | val = !val; 35 | 36 | getter = qsCreateGetter("out", sizeof(val), 37 | QsValueType_bool, &val); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/examples/3sliders: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env quickstream_interpreter 2 | # 3 | # This is a generated file 4 | 5 | set-block-path ../lib/quickstream/misc/test_blocks 6 | graph g1 2 tp0 /home/lance/git/quickstream/lib/quickstream/blocks/examples/3sliders 7 | ############################################ 8 | # Create More Thread Pools 9 | ############################################ 10 | ############################################ 11 | # Assign Blocks to Thread Pools 12 | ############################################ 13 | threads-add tp0 slider 14 | threads-add tp0 slider_2 15 | threads-add tp0 slider_3 16 | threads-add tp0 f64SettersToGetter 17 | ############################################ 18 | start 19 | wait-for-stream 20 | 21 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/examples/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../.. 4 | 5 | # Now that root is defined we can use the generic block building make 6 | # rules from: 7 | include $(root)/lib/quickstream/blocks/common.make 8 | 9 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/examples/rtlsdr_GNUradioSink_0: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env quickstream_interpreter 2 | # 3 | # This is a generated file 4 | 5 | set-block-path ../lib/quickstream/misc/test_blocks 6 | graph g3 2 tp0 /home/lance/git/quickstream/lib/quickstream/blocks/examples/rtlsdr_GNUradioSink_0 7 | ############################################ 8 | # Create More Thread Pools 9 | ############################################ 10 | ############################################ 11 | # Assign Blocks to Thread Pools 12 | ############################################ 13 | threads-add tp0 rtlsdr 14 | threads-add tp0 QT_GNUradio_sink:PipeOut 15 | threads-add tp0 u8ToF32 16 | threads-add tp0 freq slider 17 | threads-add tp0 gain slider 18 | threads-add tp0 run button 19 | threads-add tp0 run 20 | threads-add tp0 gtk base 21 | threads-add tp0 f64ToString32 22 | threads-add tp0 freq text 23 | threads-add tp0 print gain 24 | threads-add tp0 print freq 25 | ############################################ 26 | start 27 | wait-for-stream 28 | 29 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/examples/urandomToHexdump: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env quickstream_interpreter 2 | # 3 | # This is a generated file 4 | 5 | set-block-path ../lib/quickstream/misc/test_blocks 6 | graph g6 2 tp0 /home/lance/git/quickstream/lib/quickstream/blocks/examples/urandomToHexdump 7 | ############################################ 8 | # Create More Thread Pools 9 | ############################################ 10 | ############################################ 11 | # Assign Blocks to Thread Pools 12 | ############################################ 13 | threads-add tp0 URandom 14 | threads-add tp0 Hexdump 15 | ############################################ 16 | start 17 | wait-for-stream 18 | 19 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/examples/urandom_to_GNUradioSink: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env quickstream_interpreter 2 | # 3 | # This is a generated file 4 | 5 | set-block-path ../lib/quickstream/misc/test_blocks 6 | graph g5 2 tp0 /home/lance/git/quickstream/lib/quickstream/blocks/examples/urandom_to_GNUradioSink 7 | ############################################ 8 | # Create More Thread Pools 9 | ############################################ 10 | ############################################ 11 | # Assign Blocks to Thread Pools 12 | ############################################ 13 | threads-add tp0 QT_GNUradio_sink:PipeOut 14 | threads-add tp0 u8ToF32 15 | threads-add tp0 URandom 16 | ############################################ 17 | start 18 | wait-for-stream 19 | 20 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/file/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../.. 4 | 5 | 6 | # Now that root is defined we can use the generic block building make 7 | # rules from: 8 | include $(root)/lib/quickstream/blocks/common.make 9 | 10 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/file/qs_examples/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../../.. 4 | 5 | # Now that root is defined we can use the generic block building make 6 | # rules from: 7 | include $(root)/lib/quickstream/blocks/common.make 8 | 9 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/gnuradio-3.10.1/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../.. 4 | 5 | # Additionally install 6 | INSTALLED := QT_GUI_Sink 7 | 8 | 9 | # Now that root is defined we can use the generic block building make 10 | # rules from: 11 | include $(root)/lib/quickstream/blocks/common.make 12 | 13 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/gnuradio-3.10.1/QT_GNUradio_sink.c: -------------------------------------------------------------------------------- 1 | // This was a generated file. 2 | // 3 | // This is the source to a quickstream Super Block module. 4 | 5 | #include 6 | 7 | #include "../../../../include/quickstream.h" 8 | #include "../../../debug.h" 9 | 10 | 11 | struct QsBlockOptions options = { .type = QsBlockType_super }; 12 | 13 | // ERROR() will print a line number which is a big help. 14 | #define FAIL() do { ERROR(); return -1; } while(0) 15 | 16 | 17 | 18 | int declare(void) { 19 | 20 | /////////////////////////////////////////////////////////////// 21 | // Load child blocks 22 | /////////////////////////////////////////////////////////////// 23 | 24 | if(!qsGraph_createBlock(0, 0, "PipeOut", "PipeOut", 0)) 25 | FAIL(); 26 | 27 | /////////////////////////////////////////////////////////////// 28 | // Setup Port Aliases to child block ports 29 | /////////////////////////////////////////////////////////////// 30 | 31 | if(qsBlock_makePortAlias(0, "PipeOut", "i", "0", "input")) 32 | FAIL(); 33 | 34 | /////////////////////////////////////////////////////////////// 35 | // Connect child blocks 36 | /////////////////////////////////////////////////////////////// 37 | 38 | /////////////////////////////////////////////////////////////// 39 | // Configure child blocks 40 | /////////////////////////////////////////////////////////////// 41 | 42 | if(qsBlock_configVByName(0/*graph*/, "PipeOut", 43 | "Program", "QT_GUI_Sink", 44 | 0/*null terminate*/)) 45 | FAIL(); 46 | 47 | if(qsBlock_configVByName(0/*graph*/, "PipeOut", 48 | "AtStart", "true", 49 | 0/*null terminate*/)) 50 | FAIL(); 51 | 52 | if(qsBlock_configVByName(0/*graph*/, "PipeOut", 53 | "RelativePath", "quickstream/blocks/gnuradio-3.10.1", 54 | 0/*null terminate*/)) 55 | FAIL(); 56 | 57 | /////////////////////////////////////////////////////////////// 58 | // Maybe add some qsAddConfig() calls below here 59 | /////////////////////////////////////////////////////////////// 60 | 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/gnuradio-3.10.1/_U8tofloat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int main(void) { 7 | 8 | uint8_t value[2]; 9 | 10 | while(fread(&value, 2, 1, stdin)) { 11 | float x[2]; 12 | x[0] = value[0]; 13 | x[1] = value[1]; 14 | 15 | x[0] -= 127.5; 16 | x[1] -= 127.5; 17 | 18 | x[0] /= 127.5; 19 | x[1] /= 127.5; 20 | 21 | if(!fwrite(x, sizeof(x), 1, stdout)) 22 | return 0; 23 | } 24 | 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/gnuradio-3.10.1/rtl-sdr_test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | set -x 5 | 6 | dir="$(dirname ${BASH_SOURCE[0]})" 7 | 8 | cd "$dir" 9 | 10 | if ! which rtl_sdr ; then 11 | echo "The program rtl_sdr was not found in your PATH" 12 | exit 1 13 | fi 14 | 15 | 16 | 17 | rtl_sdr - -S -g 100 -f 105300000 -s 2000000 |\ 18 | ./_U8tofloat |\ 19 | ./QT_GUI_Sink --samp_rate 2000000 20 | 21 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/gnuradio-3.10.1/urandom_test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | set -x 5 | 6 | dir="$(dirname ${BASH_SOURCE[0]})" 7 | 8 | cd "$dir" 9 | 10 | 11 | ./_U8tofloat < /dev/urandom | ./QT_GUI_Sink --samp_rate 2000000 12 | 13 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/gtk3/Makefile: -------------------------------------------------------------------------------- 1 | # Note: not much happens with the files in this directory if 2 | # GTK 3 is not found. 3 | 4 | root := ../../../.. 5 | 6 | 7 | # define GTK3_LDFLAGS and GTK3_CFLAGS, or not. 8 | include $(root)/gtk3.make 9 | 10 | 11 | # -------------------------------------------------------------------- 12 | ifeq ($(GTK3_LDFLAGS),) 13 | # -------------------------------------------------------------------- 14 | 15 | # GTK3 development libraries were not found so in this case we will 16 | # not be building or installing anything. 17 | $(warning NOTICE Not building GTK3 blocks from $(shell pwd)) 18 | 19 | # We still need the generic make targets: 20 | include $(root)/quickbuild.make 21 | 22 | # -------------------------------------------------------------------- 23 | else 24 | # -------------------------------------------------------------------- 25 | 26 | # Looks like every thing we compile (CPP) needs the GTK3_CFLAGS 27 | CPPFLAGS := $(GTK3_CFLAGS) 28 | 29 | _run.so_LDFLAGS :=\ 30 | $(GTK3_LDFLAGS)\ 31 | -L$(root)/lib -lqsGtk_init\ 32 | -Wl,-rpath=\$$ORIGIN/$(root)/lib 33 | 34 | Scribble_LDFLAGS := $(GTK3_LDFLAGS) 35 | 36 | 37 | # We now use the generic block building make rules from: 38 | include $(root)/lib/quickstream/blocks/common.make 39 | 40 | 41 | # -------------------------------------------------------------------- 42 | endif 43 | # -------------------------------------------------------------------- 44 | 45 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/gtk3/README: -------------------------------------------------------------------------------- 1 | We had to do some weird-ass shit to get the GTK main event loop to run in 2 | a separate thread (pthread and not GDK thread). We gave ourselves the 3 | requirement that the thread that is running the GTK main event loop not 4 | use any CPU when there are no events being processed. The same goes for 5 | all other threads. 6 | 7 | This is just a general trend, frameworks that have a main loop do a poor 8 | job of integrating with other frameworks that have a main loop. Both 9 | frameworks, GTK and quickstream, want to be the center-of-the-universe. 10 | In the case of this code quickstream is the center-of-the-universe and 11 | we force GTK to be a well behaved runtime optional module. We hog tired 12 | GTK. 13 | 14 | Adding GSource object to the GContext, to control the running of the 15 | thread, turned out to not work at all, totally soaked the CPU while doing 16 | nothing. There was no way to get the system poll(2) call in GTK to be a 17 | blocking call, once you added the GSource to the GContext. Yes, the GTK 18 | and GLib documentation says otherwise. It would appear that some of the 19 | "internal" GTK file descriptors when grouped with own "control" file 20 | descriptor caused the GTK main poll(2) call, with a total of 3 file 21 | descriptors, to be non-blocking. In my case I think that at least one of 22 | the file descriptors was the connection to the X11 server. I don't know 23 | what the 3rd file descriptor was. Use the strace utility. 24 | 25 | That's like 500 lines of C code that burned one month of my life. See 26 | _baseRun.c. A new slow coding record. I'd fire me, but I'm the only one 27 | working on this. 28 | 29 | The result that seemed to work was use pthread_kill() to signal from a 30 | requesting thread to the GTK main loop thread, and then use a mutex and 31 | condition variable to make the GTK main loop thread wait while the 32 | signaling thread finishes running GTK code. The signal would cause the 33 | g_main_context_iteration() to return and then we made it wait on a 34 | pthread_cond_wait(). Note: it's a mix of system signals and pthead 35 | condition signal. See _baseRun.c. 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/gtk3/text.c: -------------------------------------------------------------------------------- 1 | // This file is NOT linked with the GTK3 libraries. 2 | 3 | #define _GNU_SOURCE 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "../../../../include/quickstream.h" 12 | #include "../../../debug.h" 13 | #include "../../../mprintf.h" 14 | 15 | #include "all_common.h" 16 | #include "block_common.h" 17 | 18 | 19 | // This Text will be added into the struct Window in the widget list. 20 | // 21 | static struct Text text = { 22 | .widget.type = Text, 23 | .value = "" 24 | }; 25 | 26 | 27 | static 28 | int Value_setter(const struct QsParameter *p, char value[32], 29 | uint32_t readCount, uint32_t queueCount, 30 | void *userData) { 31 | 32 | //DSPEW("*value=\"%s\"", value); 33 | 34 | if(strcmp(value, text.value) == 0) 35 | goto finish; 36 | 37 | strncpy(text.value, value, 31); 38 | text.value[31] = '\0'; 39 | 40 | if(!text.setTextValue) 41 | goto finish; 42 | 43 | text.setTextValue(&text, value); 44 | 45 | finish: 46 | 47 | return 0; 48 | } 49 | 50 | 51 | 52 | int declare(void) { 53 | 54 | qsCreateSetter("value", 55 | 32, QsValueType_string32, 0/*0=no initial value*/, 56 | (int (*)(const struct QsParameter *, const void *, 57 | uint32_t readCount, uint32_t queueCount, 58 | void *)) Value_setter); 59 | 60 | ASSERT(CreateWidget(&text.widget)); 61 | 62 | DSPEW(); 63 | return 0; 64 | } 65 | 66 | 67 | int undeclare(void *userData) { 68 | 69 | DestroyWidget(&text.widget); 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/misc/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../.. 4 | 5 | # Now that root is defined we can use the generic block building make 6 | # rules from: 7 | include $(root)/lib/quickstream/blocks/common.make 8 | 9 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/misc/NullSink.c: -------------------------------------------------------------------------------- 1 | // This is the source code to a built-in block that is compiled into 2 | // lib/libquickstream.so 3 | 4 | #include "../../../debug.h" 5 | 6 | #include "../../../../include/quickstream.h" 7 | 8 | 9 | // This defines built-in block "NullSink" 10 | 11 | // We are in a C-like namespace of NullSink_ 12 | // 13 | // symbols that are shared outside this file are prefixed with "NullSink_" 14 | // 15 | // Anything else that is file scope must be static. 16 | 17 | #define MAX_INPUTS 5 18 | 19 | 20 | // Block callback declare() 21 | int NullSink_declare(void) { 22 | 23 | // This block is a sink with at least one input stream 24 | qsSetNumInputs(1, MAX_INPUTS); 25 | 26 | return 0; // success 27 | } 28 | 29 | 30 | // Block callback flow() 31 | int NullSink_flow(const void * const in[], const size_t inLens[], 32 | uint32_t numIn, 33 | void * const out[], const size_t outLens[], uint32_t numOut, 34 | void *userData) { 35 | 36 | DASSERT(numIn >= 1); 37 | DASSERT(numIn <= MAX_INPUTS); 38 | DASSERT(numOut == 0); 39 | 40 | for(uint32_t i = numIn - 1; i != -1; --i) 41 | if(inLens[i]) 42 | // Advance all input that we got. 43 | qsAdvanceInput(0, inLens[i]); 44 | 45 | return 0; // success 46 | } 47 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/parameter_type_converters/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../.. 4 | 5 | # Now that root is defined we can use the generic block building make 6 | # rules from: 7 | include $(root)/lib/quickstream/blocks/common.make 8 | 9 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/parameter_type_converters/boolSettersToGetter.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | static struct QsParameter *getter; 6 | 7 | 8 | static 9 | int Value_setter(const struct QsParameter *p, bool *value, 10 | uint32_t readCount, uint32_t queueCount, 11 | void *userData) { 12 | 13 | // We just push the latest value. 14 | if(readCount == queueCount) 15 | qsGetterPush(getter, value); 16 | 17 | return 0; 18 | } 19 | 20 | 21 | 22 | int declare(void) { 23 | 24 | // Make 5 setters that are the similar. 25 | const char *names[] = {"4", "3", "2", "1", "0", 0 }; 26 | for(const char * const *name = names; *name; ++name) 27 | qsCreateSetter(*name, 28 | sizeof(bool), QsValueType_bool, 0/*0=no initial value*/, 29 | (int (*)(const struct QsParameter *, const void *, 30 | uint32_t readCount, uint32_t queueCount, 31 | void *)) Value_setter); 32 | 33 | getter = qsCreateGetter("out", 34 | sizeof(bool), QsValueType_bool, 35 | 0/*0=no initial value*/); 36 | 37 | DSPEW(); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/parameter_type_converters/f32ToF64.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../debug.h" 5 | #include "../../../mprintf.h" 6 | 7 | 8 | static struct QsParameter *getter; 9 | 10 | static 11 | int Value_setter(const struct QsParameter *p, float *value, 12 | uint32_t readCount, uint32_t queueCount, 13 | void *userData) { 14 | 15 | double out = (* ((float *) value)); 16 | 17 | qsGetterPush(getter, &out); 18 | 19 | return 0; 20 | } 21 | 22 | 23 | int declare(void) { 24 | 25 | // control parameter input is a float 26 | qsCreateSetter("value", 27 | sizeof(float), QsValueType_float, 0/*0=no initial value*/, 28 | (int (*)(const struct QsParameter *, const void *, 29 | uint32_t readCount, uint32_t queueCount, 30 | void *)) Value_setter); 31 | 32 | // We will output a control parameter that is a double. 33 | getter = qsCreateGetter("value", 34 | sizeof(double), QsValueType_double, 35 | 0/*0=no initial value*/); 36 | 37 | DSPEW(); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/parameter_type_converters/f32ToStderr.c: -------------------------------------------------------------------------------- 1 | // TODO: Maybe make this a C++ template out of this so that there is 2 | // one source file for both this and f64ToStderr.so; or use CPP (C 3 | // preprocessor) code to macro-ize this (I'm not crazy about Large CPP 4 | // macros). 5 | 6 | #include 7 | 8 | #include "../../../../include/quickstream.h" 9 | #include "../../../debug.h" 10 | #include "../../../mprintf.h" 11 | 12 | 13 | #define DEFAULT_FMT "%g" 14 | #define FMT_LEN 40 15 | 16 | 17 | static char format[FMT_LEN]; 18 | 19 | static 20 | int Value_setter(const struct QsParameter *p, float *value, 21 | uint32_t readCount, uint32_t queueCount, 22 | void *userData) { 23 | 24 | fprintf(stderr, format, *value); 25 | fprintf(stderr, "\n"); 26 | 27 | return 0; 28 | } 29 | 30 | 31 | // TODO: Format_config() is the same in f64ToStderr.c 32 | static 33 | char *Format_config(int argc, const char * const *argv, 34 | void *userData) { 35 | 36 | if(argc < 2) 37 | return QS_CONFIG_FAIL; 38 | 39 | strncpy(format, argv[1], FMT_LEN-1); 40 | format[FMT_LEN-1] = '\0'; 41 | 42 | // mprintf() will malloc memory which libquickstream.so will own when 43 | // we return it to the function that called this callback. 44 | // 45 | // The string that we return will be in the command-line syntax for 46 | // the configure thingy with the current format value plugged into 47 | // it. 48 | return mprintf("format \"%s\"", format); 49 | } 50 | 51 | 52 | 53 | int declare(void) { 54 | 55 | qsCreateSetter("value", 56 | sizeof(float), QsValueType_float, 0/*0=no initial value*/, 57 | (int (*)(const struct QsParameter *, const void *, 58 | uint32_t readCount, uint32_t queueCount, 59 | void *)) Value_setter); 60 | 61 | // Initialize the format string. 62 | strncpy(format, DEFAULT_FMT, FMT_LEN); 63 | format[FMT_LEN - 1] = '\0'; 64 | 65 | qsAddConfig((char *(*)(int argc, const char * const *argv, 66 | void *userData)) Format_config, "format", 67 | "set printf type format string"/*desc*/, 68 | "format FMT", 69 | "format " DEFAULT_FMT); 70 | 71 | DSPEW(); 72 | return 0; 73 | } 74 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/parameter_type_converters/f64SettersToGetter.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | static struct QsParameter *getter; 6 | 7 | 8 | static 9 | int Value_setter(const struct QsParameter *p, double *value, 10 | uint32_t readCount, uint32_t queueCount, 11 | void *userData) { 12 | 13 | // We just push the latest value. 14 | if(readCount == queueCount) 15 | qsGetterPush(getter, value); 16 | 17 | return 0; 18 | } 19 | 20 | 21 | 22 | int declare(void) { 23 | 24 | // Make 5 setters that are just about the same. 25 | const char *names[] = {"4", "3", "2", "1", "0", 0 }; 26 | for(const char * const *name = names; *name; ++name) 27 | qsCreateSetter(*name, 28 | sizeof(double), QsValueType_double, 0/*0=no initial value*/, 29 | (int (*)(const struct QsParameter *, const void *, 30 | uint32_t readCount, uint32_t queueCount, 31 | void *)) Value_setter); 32 | 33 | getter = qsCreateGetter("out", 34 | sizeof(double), QsValueType_double, 35 | 0/*0=no initial value*/); 36 | 37 | DSPEW(); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/parameter_type_converters/f64ToF32.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../debug.h" 5 | #include "../../../mprintf.h" 6 | 7 | 8 | static struct QsParameter *getter; 9 | 10 | static 11 | int Value_setter(const struct QsParameter *p, double *value, 12 | uint32_t readCount, uint32_t queueCount, 13 | void *userData) { 14 | 15 | float out = (* ((double *) value)); 16 | 17 | qsGetterPush(getter, &out); 18 | 19 | return 0; 20 | } 21 | 22 | 23 | int declare(void) { 24 | 25 | // control parameter input is a double 26 | qsCreateSetter("value", 27 | sizeof(double), QsValueType_double, 0/*0=no initial value*/, 28 | (int (*)(const struct QsParameter *, const void *, 29 | uint32_t readCount, uint32_t queueCount, 30 | void *)) Value_setter); 31 | 32 | // We will output a control parameter that is a float. 33 | getter = qsCreateGetter("value", 34 | sizeof(float), QsValueType_float, 35 | 0/*0=no initial value*/); 36 | 37 | DSPEW(); 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/parameter_type_converters/f64ToStderr.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../debug.h" 5 | #include "../../../mprintf.h" 6 | 7 | 8 | #define DEFAULT_FMT "%lg" 9 | #define FMT_LEN 54 10 | 11 | 12 | static char format[FMT_LEN]; 13 | 14 | static 15 | int Value_setter(const struct QsParameter *p, double *value, 16 | uint32_t readCount, uint32_t queueCount, 17 | void *userData) { 18 | 19 | fprintf(stderr, format, *value); 20 | fprintf(stderr, "\n"); 21 | 22 | return 0; 23 | } 24 | 25 | 26 | // TODO: Format_config() is the same in f32ToStderr.c 27 | static 28 | char *Format_config(int argc, const char * const *argv, 29 | void *userData) { 30 | 31 | if(argc < 2) 32 | return QS_CONFIG_FAIL; 33 | 34 | strncpy(format, argv[1], FMT_LEN-1); 35 | format[FMT_LEN-1] = '\0'; 36 | 37 | // mprintf() will malloc memory which libquickstream.so will own when 38 | // we return it to the function that called this callback. 39 | // 40 | // The string that we return will be in the command-line syntax for 41 | // the configure thingy with the current format value plugged into 42 | // it. 43 | return mprintf("format \"%s\"", format); 44 | } 45 | 46 | 47 | 48 | int declare(void) { 49 | 50 | qsCreateSetter("value", 51 | sizeof(double), QsValueType_double, 0/*0=no initial value*/, 52 | (int (*)(const struct QsParameter *, const void *, 53 | uint32_t readCount, uint32_t queueCount, 54 | void *)) Value_setter); 55 | 56 | // Initialize the format string. 57 | strncpy(format, DEFAULT_FMT, FMT_LEN); 58 | format[FMT_LEN - 1] = '\0'; 59 | 60 | qsAddConfig((char *(*)(int argc, const char * const *argv, 61 | void *userData)) Format_config, "format", 62 | "set printf type format string"/*desc*/, 63 | "format FMT", 64 | "format " DEFAULT_FMT); 65 | 66 | DSPEW(); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/parameter_type_converters/f64ToString32.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../debug.h" 5 | #include "../../../mprintf.h" 6 | 7 | 8 | static struct QsParameter *getter; 9 | 10 | 11 | #define DEFAULT_FMT "%lg" 12 | #define FMT_LEN 32 13 | 14 | 15 | static char format[FMT_LEN]; 16 | 17 | static 18 | int Value_setter(const struct QsParameter *p, double *value, 19 | uint32_t readCount, uint32_t queueCount, 20 | void *userData) { 21 | 22 | //DSPEW("*value=%lg format=\"%s\"", *value, format); 23 | 24 | char out[32] = { 0 }; 25 | snprintf(out, 32, format, *value); 26 | 27 | //fprintf(stderr, "\"%s\"\n", out); 28 | 29 | qsGetterPush(getter, out); 30 | 31 | return 0; 32 | } 33 | 34 | 35 | static 36 | char *Format_config(int argc, const char * const *argv, 37 | void *userData) { 38 | 39 | if(argc < 2) 40 | return QS_CONFIG_FAIL; 41 | 42 | strncpy(format, argv[1], 31); 43 | format[31] = '\0'; 44 | 45 | return mprintf("format \"%s\"", format); 46 | } 47 | 48 | 49 | 50 | int declare(void) { 51 | 52 | qsCreateSetter("value", 53 | sizeof(double), QsValueType_double, 0/*0=no initial value*/, 54 | (int (*)(const struct QsParameter *, const void *, 55 | uint32_t readCount, uint32_t queueCount, 56 | void *)) Value_setter); 57 | 58 | // We will output a control parameter that is a 32 byte string. 59 | getter = qsCreateGetter("value", 60 | 32, QsValueType_string32, 61 | 0/*0=no initial value*/); 62 | 63 | // Initialize the format string. 64 | strncpy(format, DEFAULT_FMT, FMT_LEN); 65 | format[FMT_LEN - 1] = '\0'; 66 | 67 | qsAddConfig((char *(*)(int argc, const char * const *argv, 68 | void *userData)) Format_config, "format", 69 | "set printf type format string"/*desc*/, 70 | "format FMT", 71 | "format " DEFAULT_FMT); 72 | 73 | DSPEW(); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/rtl-sdr/Makefile: -------------------------------------------------------------------------------- 1 | # Note: not much happens with the files in this directory if 2 | # the software package librtlsdr is not found via pkg-config. 3 | # 4 | # https://github.com/librtlsdr/librtlsdr 5 | # 6 | # apt install librtlsdr-dev 7 | 8 | root := ../../../.. 9 | 10 | 11 | 12 | RTLSDR_CFLAGS := $(shell pkg-config --cflags librtlsdr) 13 | ifeq ($(WITHOUT_GTK3),) 14 | RTLSDR_LDFLAGS := $(shell pkg-config --libs librtlsdr) 15 | endif 16 | 17 | 18 | # -------------------------------------------------------------------- 19 | ifeq ($(RTLSDR_LDFLAGS),) 20 | # -------------------------------------------------------------------- 21 | 22 | # wsServer development libraries were not found so in this case we will 23 | # not be building or installing anything. 24 | $(warning NOTICE Not building wsServer blocks from $(shell pwd)") 25 | 26 | # We still need the generic make targets: 27 | include $(root)/quickbuild.make 28 | 29 | # -------------------------------------------------------------------- 30 | else 31 | # -------------------------------------------------------------------- 32 | 33 | # Looks like every thing we compile (CPP) needs the RTLSDR_CFLAGS 34 | CPPFLAGS := $(RTLSDR_CFLAGS) 35 | 36 | _run.so_LDFLAGS :=\ 37 | $(RTLSDR_LDFLAGS)\ 38 | -L../../.. -lqsGtk_init\ 39 | -Wl,-rpath=\$$ORIGIN/../../.. 40 | 41 | 42 | # We now use the generic block building make rules from: 43 | include $(root)/lib/quickstream/blocks/common.make 44 | 45 | 46 | # -------------------------------------------------------------------- 47 | endif 48 | # -------------------------------------------------------------------- 49 | 50 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/rtl-sdr/_RawToASCII.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | int main(void) { 7 | 8 | //uint64_t count = 0; 9 | uint8_t value[2]; 10 | 11 | while(fread(&value, 2, 1, stdin)) 12 | printf("%" PRIu8 " %" PRIu8 "\n", value[0], value[1]); 13 | 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/rtl-sdr/common.h: -------------------------------------------------------------------------------- 1 | 2 | struct Common { 3 | 4 | double freq, // center frequency in Hz 5 | rate, // sample rate 6 | gain; // gain in dB 7 | bool autoGain; 8 | 9 | size_t outputMax; 10 | 11 | 12 | uint32_t dev_index; 13 | 14 | 15 | 16 | // These get set in function construct() of _run.c 17 | // 18 | // These are shared between _run.c and rtlsdr.c. 19 | // 20 | // _run.so provides a wrapper API that rtlsdr.c uses so as to not directly 21 | // use the librtlsdr.so API. That makes it so that rtlsdr.c does not have 22 | // to link with librtlsdr.so at build-time. 23 | // 24 | // This totally looks like boilerplate code. Very repetitive shit. 25 | // 26 | void (*setFreq)(double freq); 27 | 28 | double (*getFreq)(void); 29 | 30 | void (*setRate)(double rate); 31 | 32 | double (*getRate)(void); 33 | 34 | void (*setGain)(double gain); 35 | 36 | double (*getGain)(void); 37 | 38 | void (*setAutoGain)(bool autoGain); 39 | 40 | double (*getAutoGain)(void); 41 | }; 42 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/rtl-sdr/head.h: -------------------------------------------------------------------------------- 1 | 2 | struct Common; 3 | 4 | #define QS_USER_DATA_TYPE struct Common * 5 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/runner/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../.. 4 | 5 | # Now that root is defined we can use the generic block building make 6 | # rules from: 7 | include $(root)/lib/quickstream/blocks/common.make 8 | 9 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/runner/destroy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../../../../include/quickstream.h" 6 | #include "../../../debug.h" 7 | 8 | 9 | static 10 | int SetCallback(const struct QsParameter *p, 11 | const bool *value, 12 | uint32_t readCount, uint32_t queueCount, 13 | void *userData) { 14 | 15 | // Feedback for testing. 16 | DSPEW("Block \"%s\" Setter \"destroy\" got value[%" PRIu32 "]= %d", 17 | qsBlockGetName(), queueCount, *value); 18 | 19 | if(*value) 20 | qsDestroy(0, 0); 21 | 22 | return 0; 23 | } 24 | 25 | 26 | int declare(void) { 27 | 28 | bool val = false; 29 | 30 | qsCreateSetter("destroy", 31 | sizeof(val), QsValueType_bool, &val, 32 | (int (*)(const struct QsParameter *, const void *, 33 | uint32_t readCount, uint32_t queueCount, 34 | void *)) SetCallback); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/runner/run.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../../../../include/quickstream.h" 6 | #include "../../../debug.h" 7 | 8 | 9 | 10 | static bool isRunning = 0; 11 | 12 | 13 | static 14 | int SetCallback(const struct QsParameter *p, 15 | const bool *value, 16 | uint32_t readCount, uint32_t queueCount, 17 | void *userData) { 18 | 19 | // Feedback for testing. 20 | DSPEW("Block \"%s\" Setter \"run\" got value[%" PRIu32 "]= %d", 21 | qsBlockGetName(), queueCount, *value); 22 | 23 | isRunning = (*value)?true:false; 24 | 25 | if(isRunning == qsIsRunning()) 26 | // Something other then this changed the state, 27 | // or this is getting the same value again. 28 | return 0; 29 | 30 | if(isRunning) 31 | qsStart(); 32 | else 33 | qsStop(); 34 | 35 | return 0; 36 | } 37 | 38 | 39 | int declare(void) { 40 | 41 | qsCreateSetter("run", 42 | sizeof(isRunning), QsValueType_bool, 0/*initial value*/, 43 | (int (*)(const struct QsParameter *, const void *, 44 | uint32_t readCount, uint32_t queueCount, 45 | void *)) SetCallback); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/stream_type_converters/Makefile: -------------------------------------------------------------------------------- 1 | 2 | # root is the top quickstream source directory relative to this directory 3 | root := ../../../.. 4 | 5 | # Now that root is defined we can use the generic block building make 6 | # rules from: 7 | include $(root)/lib/quickstream/blocks/common.make 8 | 9 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/wsServer/Makefile: -------------------------------------------------------------------------------- 1 | # Note: not much happens with the files in this directory if 2 | # wsServer is not found. 3 | # 4 | # https://github.com/Theldus/wsServer/ 5 | 6 | root := ../../../.. 7 | 8 | 9 | WSS_CFLAGS := $(shell pkg-config --cflags wsserver) 10 | ifeq ($(WITHOUT_WSS),) 11 | WSS_LDFLAGS := $(shell pkg-config --libs wsserver) 12 | endif 13 | 14 | 15 | # -------------------------------------------------------------------- 16 | ifeq ($(WSS_LDFLAGS),) 17 | # -------------------------------------------------------------------- 18 | 19 | # wsServer development libraries were not found so in this case we will 20 | # not be building or installing anything. 21 | $(warning NOTICE Not building wsServer blocks from $(shell pwd)") 22 | 23 | # We still need the generic make targets: 24 | include $(root)/quickbuild.make 25 | 26 | # -------------------------------------------------------------------- 27 | else 28 | # -------------------------------------------------------------------- 29 | 30 | # Looks like every thing we compile (CPP) needs the WSS_CFLAGS 31 | CPPFLAGS := $(WSS_CFLAGS) 32 | 33 | _run.so_LDFLAGS :=\ 34 | $(WSS_LDFLAGS)\ 35 | -L../../.. -lqsGtk_init\ 36 | -Wl,-rpath=\$$ORIGIN/../../.. 37 | 38 | 39 | # We now use the generic block building make rules from: 40 | include $(root)/lib/quickstream/blocks/common.make 41 | 42 | 43 | # -------------------------------------------------------------------- 44 | endif 45 | # -------------------------------------------------------------------- 46 | 47 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/wsServer/_run.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "wsServer.h" 4 | 5 | #include "../../../debug.h" 6 | #include "../../../../include/quickstream.h" 7 | 8 | // Note: currently the wsServer library is a static archive file, libws.a, 9 | // not a DSO (dynamic shared object) library (like libws.so); so this C 10 | // file builds a DSO object with the wsServer functions and other wsServer 11 | // symbols in it. This DSO gets loaded with dlopen(3) in wsServer.so 12 | // (source wsServer.c). 13 | 14 | 15 | // This DSO (from compiling this file) is not a quickstream block. It 16 | // is loaded by the block compiled from wsServer.c 17 | 18 | void remove_this_DUMMY_test_function(void) { 19 | 20 | // Force libws.a to provide a function to the linked DSO. 21 | ERROR("ws_sendframe=%p", ws_sendframe); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/wsServer/websocketServer.c: -------------------------------------------------------------------------------- 1 | // This file is NOT linked with the wsServer library. 2 | 3 | #define _GNU_SOURCE 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "wsServer.h" 10 | 11 | #include "../../../../include/quickstream.h" 12 | #include "../../../debug.h" 13 | #include "../../../mprintf.h" 14 | 15 | 16 | static struct QsParameter *launch_getter; 17 | 18 | static struct wsServer server; 19 | 20 | // local launch state 21 | static bool launch = false; // initial launch value 22 | 23 | 24 | // Setter to turn the server on/off. 25 | static 26 | int Launch_setter(const struct QsParameter *p, bool *value, 27 | uint32_t readCount, uint32_t queueCount, 28 | void *userData) { 29 | 30 | DSPEW("*value=%d", *value); 31 | 32 | return 0; 33 | } 34 | 35 | 36 | int declare(void) { 37 | 38 | qsCreateSetter("launch", 39 | sizeof(launch), QsValueType_bool, &launch/*initial value*/, 40 | (int (*)(const struct QsParameter *, const void *, 41 | uint32_t readCount, uint32_t queueCount, 42 | void *)) Launch_setter); 43 | 44 | launch_getter = qsCreateGetter("launch", sizeof(launch), 45 | QsValueType_bool, 0/*0=no initial value*/); 46 | 47 | // Remove compiler warning with &server being used here. 48 | ERROR("This block does nothing yet, we" 49 | " have not finished writing it yet. server=%p", &server); 50 | 51 | 52 | // MORE CODE HERE .... 53 | 54 | return 0; 55 | } 56 | 57 | 58 | int undeclare(void *userData) { 59 | 60 | // MORE CODE HERE .... 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /lib/quickstream/blocks/wsServer/wsServer.h: -------------------------------------------------------------------------------- 1 | // In this file data structures and other interfaces that are 2 | // shared between the wsServer.so block and _run.so. 3 | 4 | // We brake from our standard of not including include files in our 5 | // private include files, because we have a problem here with CPP (C 6 | // preprocessor) marco DEBUG getting redefined in the file ws.h. 7 | 8 | 9 | // We have a CPP macro name-space pollution problem here. 10 | // 11 | // Stupid ws.h defines DEBUG and so does this when compiled with compiler 12 | // option flag -DDEBUG. We can only hope that ws.h does not intend to use 13 | // the CPP macro DEBUG from outside of that file, like in a wsServer CPP 14 | // macro function that we may be using here in this file. We'll find out 15 | // if this is not okay when the wsServer functions fail to work. 16 | // 17 | // Exporting a CPP macro into a C API without a unique prefix is not 18 | // a good idea. This is what can happen... 19 | // 20 | // I think it is "bad form" for a C API to define a CPP macro that is such 21 | // a common name, DEBUG. Does quickstream do something so bad (in 22 | // quickstream.h)? I need to check that. I don't think it does... 23 | // 24 | // Here's the fix we choose: 25 | // 26 | // --- BEGIN FIX 27 | #ifdef DEBUG 28 | # define zzxxNEED_DEBUGg 29 | # undef DEBUG 30 | #endif 31 | // Now we can load ws.h without a CPP macro redefine compiler error. 32 | 33 | #include 34 | 35 | #ifdef zzxxNEED_DEBUGg 36 | // Because we got here we know that DEBUG was set by quickstream too. 37 | // Undo what we did a few lines above. 38 | // 39 | // We don't assume that ws.h set DEBUG so we check if it did. 40 | # ifdef DEBUG 41 | # undef DEBUG 42 | # endif 43 | # undef zzxxNEED_DEBUGg 44 | // Reset DEBUG to the empty value that quickstream uses: 45 | # define DEBUG 46 | #endif 47 | // It's amazing how complicated CPP conditionals get for something this 48 | // simple. 49 | // --- END FIX 50 | 51 | 52 | struct wsServer { 53 | 54 | struct ws_server server; 55 | 56 | // We could add a lot more server configuration stuff here: 57 | }; 58 | 59 | -------------------------------------------------------------------------------- /lib/quickstream/misc/Makefile: -------------------------------------------------------------------------------- 1 | 2 | topdir := ../../.. 3 | 4 | SUBDIRS := test_blocks 5 | 6 | INSTALL_DIR = $(PREFIX)/lib/quickstream/misc 7 | 8 | quickstreamHelp_SOURCES := quickstreamHelp.c 9 | 10 | 11 | IN_VARS := PACKAGE_URL 12 | 13 | BUILD_NO_INSTALL := qsOptions.h 14 | 15 | qsOptions.h: quickstreamHelp 16 | if ! ./$< -c > $@ ; then\ 17 | rm -f $@; exit 1; fi 18 | 19 | 20 | include $(topdir)/quickbuild.make 21 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/Makefile: -------------------------------------------------------------------------------- 1 | # 1. build all [a-z]*.c as a block module 2 | # 2. build all [a-z]*.cpp as a block module 3 | # 3. build all [A-Z]*.c as a uninstalled test 4 | 5 | root := ../../../.. 6 | 7 | SUBDIRS := subDir_test qs_examples 8 | 9 | ############################## 10 | # BUG FIX: temporary?? (not sure) 11 | # 12 | # The problem with wild-card make targets... 13 | # 14 | # fOSDEM.so_CFLAGS fixes building fOSDEM.so from fOSDEM.c 15 | # because it has #include in it that 16 | # was generated from quickstreamGUI. 17 | # 18 | # When quickstreamGUI compiles fOSDEM.so from fOSDEM.c is works 19 | # out fine, but this makefile needs to add this -I option. 20 | # 21 | # We could consider add CFLAGS := -I$(root)/include so 22 | # that all block C source files with "#include " 23 | # dumped in this directory can be built with this make file. 24 | # But that will pollute the compile commands that do not need 25 | # this fix. Pick one line to uncomment. 26 | # 27 | # uncomment to add cc option to all binaries built in this directory: 28 | CFLAGS := -I$(root)/include 29 | # 30 | # or uncomment (less intrusive): 31 | #fOSDEM.so_CFLAGS := -I$(root)/include 32 | ############################## 33 | 34 | 35 | INSTALL_DIR = $(PREFIX)/lib/quickstream/misc/test_blocks 36 | 37 | # skip Sequence 38 | c_plugins := $(filter-out Sequence,\ 39 | $(sort $(patsubst %.c, %, $(wildcard [a-z]*.c)\ 40 | $(wildcard _[a-z]*.c [A-Z]*.c)) empty)) 41 | 42 | cpp_plugins := $(patsubst %.cpp, %, $(wildcard [a-z]*.cpp)) 43 | 44 | 45 | define makeSOURCES 46 | $(1)$(2)_SOURCES := $(1)$(3) 47 | $(1)$(2)_CPPFLAGS := -I$(root)/include 48 | #We do not appear to need to do this next line: 49 | #$(1)$(2)_LDFLAGS := -L$(root)/lib -lquickstream -Wl,-rpath=\$$$$ORIGIN/$(root)/lib 50 | endef 51 | 52 | 53 | 54 | BUILD_NO_INSTALL := Sequence 55 | 56 | 57 | empty.c: 58 | touch $@ 59 | 60 | CLEANFILES := empty.c 61 | 62 | 63 | $(foreach targ,$(c_plugins),$(eval $(call makeSOURCES,$(targ),.so,.c))) 64 | $(foreach targ,$(cpp_plugins),$(eval $(call makeSOURCES,$(targ),.so,.cpp))) 65 | $(foreach targ,$(BUILD_NO_INSTALL),$(eval $(call makeSOURCES,$(targ),,.c))) 66 | 67 | 68 | Sequence_SOURCES += $(root)/lib/debug.c 69 | 70 | 71 | include $(root)/quickbuild.make 72 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/README: -------------------------------------------------------------------------------- 1 | 2 | 3 | CAUTION: 4 | 5 | It would not be a good idea to use blocks in this directory without 6 | reading and understanding the source code to them. Some of these blocks 7 | crash libquickstream.so on purpose in order to test failure modes in 8 | libquickstream.so. These bad blocks help keep quickstream from 9 | digressing as it is developed. Function and variable naming conventions 10 | in this C source files totally suck. These are not good examples. 11 | 12 | 13 | 14 | Most of the files in this directory make test block modules that are 15 | loaded as DSOs (dynamic shared objects). 16 | 17 | The quickstream software test programs in ../../../../tests/ are very 18 | dependent on these block DSOs; so if you make any changes to files in this 19 | directory you must run the test programs in ../../../../tests/ and test 20 | the changes. If you make changes to files in this directory, and the 21 | tests pass with those changes, there is still no guarantee that you did 22 | not just add a false positive to the tests and you just wrecked the 23 | code. 24 | 25 | Any changes to this code require that you understand previously existing 26 | tests that will continue to use this code. If you're not sure, it's 27 | better to just add a new test block module, then to edit an old test block 28 | module. 29 | 30 | 31 | 32 | REPEAT CAUTION: 33 | 34 | It would not be a good idea to use blocks in this directory without 35 | reading and understanding the source code to them. Some of these blocks 36 | crash libquickstream.so on purpose in order to test failure modes in 37 | libquickstream.so. These bad blocks help keep quickstream from 38 | digressing as it is developed. 39 | 40 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/Sequence.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "Sequence.h" 7 | 8 | static bool running = true; 9 | 10 | static void catch(int sig) { 11 | 12 | fprintf(stderr, "Caught signal %d ... exiting\n", sig); 13 | running = false; 14 | signal(SIGTERM, 0); 15 | signal(SIGINT, 0); 16 | } 17 | 18 | 19 | int main(void) { 20 | 21 | signal(SIGTERM, catch); 22 | signal(SIGINT, catch); 23 | 24 | struct RandomString r; 25 | randomString_init(&r, 0); 26 | 27 | const size_t LEN = 10; 28 | char str[LEN]; 29 | 30 | while(running) { 31 | printf("%10.10s", randomString_get(&r, LEN, str)); 32 | } 33 | 34 | fprintf(stderr, "done\n"); 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/_interBlockJob_base.c: -------------------------------------------------------------------------------- 1 | // This file adds shared functions and variables to any number of blocks 2 | // that are loaded, but are not shared unless the block load this file 3 | // via: qsOpenRelativeDLHandle(relpath) which is just a small wrapper of 4 | // dlopen(3). 5 | 6 | // TODO: this will not work with more than one graph. 7 | 8 | #include "string.h" 9 | #include "stdlib.h" 10 | #include "pthread.h" 11 | 12 | #include "../../../../include/quickstream.h" 13 | #include "../../../debug.h" 14 | 15 | #include "./interBlockJob_base.h" 16 | 17 | // The only thing not static is base. 18 | struct Base *base = 0; 19 | 20 | 21 | // Note: This is called in interBlockJob.so::declare() which will be 22 | // called each time when the interBlockJob.so block is loaded via 23 | // qsGraph_createBlock(). If it was called in block callbacks that run in 24 | // thread pool worker threads we'd have to make this thread-safe. 25 | static 26 | void AddJob(struct QsInterBlockJob *j) { 27 | 28 | ASSERT(j); 29 | ASSERT(base->numJobs < MAX_JOBS); 30 | 31 | base->jobs[base->numJobs++] = j; 32 | 33 | // This code is kind-of part of the block code libquickstream.so does 34 | // not know it's not block code; so qsBlockGetName() works okay. 35 | ERROR("Added job[%" PRIu32 "]=%p from block \"%s\"", 36 | base->numJobs-1, j, qsBlockGetName()); 37 | 38 | } 39 | 40 | static void __attribute__ ((constructor)) Construct(void); 41 | 42 | static void Construct(void) { 43 | 44 | DASSERT(!base); 45 | base = calloc(1, sizeof(*base)); 46 | ASSERT(base, "calloc(1,%zu) failed", sizeof(*base)); 47 | 48 | CHECK(pthread_mutex_init(&base->mutex, 0)); 49 | 50 | base->AddJob = AddJob; 51 | } 52 | 53 | 54 | static void __attribute__ ((destructor)) Destroy(void); 55 | 56 | static void Destroy(void) { 57 | 58 | DASSERT(base); 59 | 60 | CHECK(pthread_mutex_destroy(&base->mutex)); 61 | 62 | #ifdef DEBUG 63 | memset(base, 0, sizeof(*base)); 64 | #endif 65 | 66 | free(base); 67 | 68 | ERROR(); 69 | } 70 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/add1.c: -------------------------------------------------------------------------------- 1 | // Definitely just a test; so fucking wonky. 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../debug.h" 5 | 6 | 7 | static struct QsParameter *getter = 0; 8 | 9 | static uint64_t val = 0; 10 | 11 | static uint64_t check = 100; 12 | 13 | 14 | int Set(const struct QsParameter *p, uint64_t *value, 15 | uint32_t readCount, uint32_t queueCount, 16 | void *userData) { 17 | 18 | ++(*value); 19 | ASSERT(val < *value); 20 | ASSERT(*value < val + 6); 21 | val = *value; 22 | 23 | if((*value) >= check) { 24 | printf("%" PRIu64 "\n", *value); 25 | check += 3000; 26 | } 27 | 28 | // We just need a value much larger than the control parameter queue 29 | // length, which is like 10 (see ../../parameter.c to check). 30 | if(*value >= 23179) { 31 | printf("\n"); 32 | // qsStop() is an async function. 33 | qsStop(); 34 | // This is it. We are done running. 35 | // Well, at least after the async shit goes. 36 | WARN("Stopping stream"); 37 | return 0; 38 | } 39 | 40 | qsGetterPush(getter, value); 41 | 42 | return 0; 43 | } 44 | 45 | 46 | int declare(void) { 47 | 48 | DSPEW(); 49 | 50 | qsCreateSetter("add", sizeof(val), QsValueType_uint64, 51 | &val/*initValue*/, 52 | (int (*)(const struct QsParameter *p, const void *value, 53 | uint32_t readCount, uint32_t queueCount, 54 | void *userData)) Set); 55 | 56 | getter = qsCreateGetter("add", sizeof(val), 57 | QsValueType_uint64, 0); 58 | DASSERT(getter); 59 | 60 | 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/declare.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | int declare(void) { 6 | 7 | DSPEW(); 8 | 9 | return 0; 10 | } 11 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/declareFail.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | int declare(void) { 6 | 7 | DSPEW(); 8 | 9 | return 1; 10 | } 11 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/declareFailUndeclare.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | int declare(void) { 6 | 7 | DSPEW(); 8 | 9 | return 0; 10 | } 11 | 12 | int undeclare(void *userData) { 13 | 14 | DSPEW(); 15 | 16 | return -1; // less than 0 is a failure. 17 | } 18 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/destroy.c: -------------------------------------------------------------------------------- 1 | 2 | struct UserData; 3 | 4 | #define QS_USER_DATA_TYPE struct UserData * 5 | 6 | #include "../../../../include/quickstream.h" 7 | #include "../../../debug.h" 8 | 9 | 10 | struct UserData { 11 | 12 | int value; 13 | }; 14 | 15 | 16 | 17 | 18 | 19 | #define TEST_VALUE (0xFE3458E9) 20 | 21 | static 22 | struct UserData userData = { .value = TEST_VALUE }; 23 | 24 | 25 | 26 | 27 | int declare(void) { 28 | 29 | qsSetUserData(&userData); 30 | 31 | return 0; 32 | } 33 | 34 | 35 | 36 | int destroy(struct UserData *d) { 37 | 38 | // Just need to see some feedback: 39 | WARN("HELLO"); 40 | 41 | // It's nice to know that user data works. 42 | ASSERT(d->value == TEST_VALUE); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/destroyGraph.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | 6 | int Set(const struct QsParameter *p, bool *value, 7 | uint32_t readCount, uint32_t queueCount, 8 | void *userData) { 9 | 10 | if(*value) { 11 | INFO("Destroying graph"); 12 | qsDestroy(0, 12/*status*/); 13 | } 14 | 15 | return 0; 16 | } 17 | 18 | 19 | int declare(void) { 20 | 21 | DSPEW(); 22 | 23 | bool val = false; 24 | 25 | qsCreateSetter("destroy", sizeof(val), QsValueType_bool, 26 | &val/*initValue*/, 27 | (int (*)(const struct QsParameter *p, const void *value, 28 | uint32_t readCount, uint32_t queueCount, 29 | void *userData)) Set); 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/emptySuperBlock.c: -------------------------------------------------------------------------------- 1 | 2 | #include "../../../../include/quickstream.h" 3 | 4 | 5 | struct QsBlockOptions options = { .type = QsBlockType_super }; 6 | 7 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/fOSDEM2024: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env quickstream_interpreter 2 | # 3 | # This is a generated file 4 | 5 | set-block-path ../../misc/test_blocks 6 | graph g1 2 tp0 /home/lance/git/quickstream/lib/quickstream/misc/test_blocks/fOSDEM2024 7 | ############################################ 8 | # Create More Thread Pools 9 | ############################################ 10 | ############################################ 11 | # Assign Blocks to Thread Pools 12 | ############################################ 13 | threads-add tp0 sequenceCheck 14 | threads-add tp0 sequenceCheck_2 15 | threads-add tp0 sequenceCheck_3 16 | threads-add tp0 sequenceCheck_4 17 | threads-add tp0 sequenceGen 18 | threads-add tp0 FileOut 19 | threads-add tp0 button 20 | threads-add tp0 run 21 | threads-add tp0 empty 22 | ############################################ 23 | start 24 | wait-for-stream 25 | 26 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/interBlockJob_base.h: -------------------------------------------------------------------------------- 1 | #define MAX_JOBS 10 2 | 3 | 4 | struct Base { 5 | 6 | void (*AddJob)(struct QsInterBlockJob *j); 7 | 8 | uint32_t numJobs; 9 | struct QsInterBlockJob *jobs[MAX_JOBS]; 10 | 11 | pthread_mutex_t mutex; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/multAndAdd_float.c: -------------------------------------------------------------------------------- 1 | #ifndef _GNU_SOURCE 2 | # define _GNU_SOURCE 3 | #endif 4 | #include 5 | 6 | #include "../../../../include/quickstream.h" 7 | #include "../../../../lib/debug.h" 8 | 9 | 10 | // Same as maxRead. 11 | static size_t maxWrite = 1024; 12 | 13 | 14 | // Out = In * a + b 15 | 16 | static const float a = 3.182; 17 | static const float b = 6.132; 18 | 19 | static bool cpuSet; 20 | 21 | 22 | int declare(void) { 23 | 24 | qsSetNumInputs(1, 1); 25 | qsSetNumOutputs(1, 1); 26 | qsMakePassThroughBuffer(0, 0); 27 | return 0; // success 28 | } 29 | 30 | 31 | int start(uint32_t numInputs, uint32_t numOutputs, void *userData) { 32 | 33 | cpuSet = false; 34 | qsSetOutputMax(0, maxWrite); 35 | qsSetInputMax(0, maxWrite); 36 | 37 | return 0; // success 38 | } 39 | 40 | static inline void SetCPU(int cpu) { 41 | 42 | cpu_set_t set; 43 | CPU_ZERO(&set); 44 | CPU_SET(cpu, &set); 45 | ASSERT(0 == sched_setaffinity(0/*0=>this thread*/, sizeof(set), &set)); 46 | cpuSet = true; 47 | } 48 | 49 | 50 | int flow(const void * const in[], const size_t inLens[], uint32_t numIn, 51 | void * const out[], const size_t outLens[], uint32_t numOut, 52 | void *userData) { 53 | 54 | if(false && !cpuSet) SetCPU(6); 55 | 56 | size_t len = inLens[0]; 57 | if(len > outLens[0]) 58 | len = outLens[0]; 59 | if(len < sizeof(float)) 60 | return 0; 61 | 62 | len -= len % sizeof(float); 63 | 64 | uint32_t numFloats = len / sizeof(float); 65 | 66 | float *x = out[0]; 67 | float *end = x + numFloats; 68 | 69 | for(; x < end; ++x) { 70 | *x *= a; 71 | *x += b; 72 | } 73 | 74 | qsAdvanceInput(0, len); 75 | qsAdvanceOutput(0, len); 76 | 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/nullSink.c: -------------------------------------------------------------------------------- 1 | #ifndef _GNU_SOURCE 2 | # define _GNU_SOURCE 3 | #endif 4 | #include 5 | #include 6 | 7 | #include "../../../../include/quickstream.h" 8 | #include "../../../../lib/debug.h" 9 | 10 | 11 | static size_t maxRead = 1024; 12 | static bool cpuSet; 13 | static size_t count; 14 | struct timespec t0; 15 | 16 | int declare(void) { 17 | 18 | qsSetNumInputs(1, 1); 19 | qsSetNumOutputs(0, 0); 20 | return 0; // success 21 | } 22 | 23 | 24 | int start(uint32_t numInputs, uint32_t numOutputs, void *userData) { 25 | 26 | count = 0; 27 | cpuSet = false; 28 | ASSERT(0 == clock_gettime(CLOCK_REALTIME, &t0)); 29 | qsSetInputMax(0, maxRead); 30 | return 0; // success 31 | } 32 | 33 | 34 | static inline void SetCPU(int cpu) { 35 | 36 | cpu_set_t set; 37 | CPU_ZERO(&set); 38 | CPU_SET(cpu, &set); 39 | ASSERT(0 == sched_setaffinity(0/*0=>this thread*/, sizeof(set), &set)); 40 | cpuSet = true; 41 | } 42 | 43 | 44 | int flow(const void * const in[], const size_t inLens[], uint32_t numIn, 45 | void * const out[], const size_t outLens[], uint32_t numOut, 46 | void *userData) { 47 | 48 | if(false && !cpuSet) SetCPU(6); 49 | 50 | size_t len = inLens[0]; 51 | if(!len) return 0; 52 | count += len; 53 | qsAdvanceInput(0, len); 54 | return 0; 55 | } 56 | 57 | 58 | int stop(uint32_t numInputs, uint32_t numOutputs, void *userData) { 59 | 60 | struct timespec t1; 61 | ASSERT(0 == clock_gettime(CLOCK_REALTIME, &t1)); 62 | 63 | double time = (t1.tv_sec - t0.tv_sec) + 1.0e-9 *t1.tv_nsec - 1.0e-9 * t0.tv_nsec; 64 | 65 | fprintf(stderr, "Read %zu bytes = %zu floats -> %lg floats/second\n", 66 | count, count/sizeof(float), (count/sizeof(float))/time); 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/passThrough.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../../lib/debug.h" 3 | 4 | 5 | 6 | #define MAX_INPUTS (9) 7 | 8 | 9 | static const size_t maxWrite = 102; 10 | 11 | 12 | int declare(void) { 13 | 14 | qsSetNumInputs(0, MAX_INPUTS); 15 | qsSetNumOutputs(0, MAX_INPUTS); 16 | 17 | for(uint32_t i=0; i outLens[i]) 48 | len = outLens[i]; 49 | if(len == 0) 50 | continue; 51 | 52 | // Advance both the reader and the writer. 53 | // 54 | qsAdvanceInput(i, len); 55 | qsAdvanceOutput(i, len); 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/qs_examples/Makefile: -------------------------------------------------------------------------------- 1 | 2 | root := ../../../../.. 3 | 4 | 5 | 6 | include $(root)/lib/quickstream/blocks/common.make 7 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/qs_examples/sequenceGen.c: -------------------------------------------------------------------------------- 1 | // This is a generated file. 2 | // 3 | // This is the source to a quickstream Super Block module. 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | 11 | struct QsBlockOptions options = { .type = QsBlockType_super }; 12 | 13 | // ERROR() will print a line number which is a big help. 14 | #define FAIL() do { ERROR(); return -1; } while(0) 15 | 16 | 17 | /////////////////////////////////////////////////////////////////// 18 | // Block Meta Data 19 | /////////////////////////////////////////////////////////////////// 20 | const char *QS_quickstreamGUI = 21 | "c2VxdWVuY2VDaGVjawBzZXF1ZW5jZUdlbgAAAAAAAAAAAACqoEAAAAAAAHibQOQA" 22 | "AAAAAAAAAAAAAAD8nEAAAAAAADSbQOQAAAAAAAAA"; 23 | 24 | // A null terminated array of all metaData symbol suffixes above: 25 | const char *qsMetaDataKeys[] = { 26 | "quickstreamGUI", 27 | 0 /*0 null terminator*/ 28 | }; 29 | /////////////////////////////////////////////////////////////////// 30 | 31 | 32 | int declare(void) { 33 | 34 | /////////////////////////////////////////////////////////////// 35 | // Load child blocks 36 | /////////////////////////////////////////////////////////////// 37 | 38 | if(!qsGraph_createBlock(0, 0, "sequenceGen.so", "sequenceGen", 0)) 39 | FAIL(); 40 | 41 | if(!qsGraph_createBlock(0, 0, "sequenceCheck.so", "sequenceCheck", 0)) 42 | FAIL(); 43 | 44 | /////////////////////////////////////////////////////////////// 45 | // Setup Port Aliases to child block ports 46 | /////////////////////////////////////////////////////////////// 47 | 48 | /////////////////////////////////////////////////////////////// 49 | // Configure child blocks 50 | /////////////////////////////////////////////////////////////// 51 | 52 | /////////////////////////////////////////////////////////////// 53 | // Connect child blocks 54 | /////////////////////////////////////////////////////////////// 55 | 56 | if(qsGraph_connectByStrings(0, "sequenceGen", "o", "0", "sequenceCheck", "i", "0")) 57 | FAIL(); 58 | 59 | /////////////////////////////////////////////////////////////// 60 | // Maybe add some qsAddConfig() calls below here 61 | /////////////////////////////////////////////////////////////// 62 | 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/runFile.c: -------------------------------------------------------------------------------- 1 | // For test: ../../../../tests/630_runFile 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../../lib/debug.h" 5 | 6 | 7 | 8 | int loadCount = 0; 9 | 10 | 11 | // For this test we load "B0" than "B1" than "B2" 12 | // 13 | // This DSO is loaded with a copy of the DSO. 14 | 15 | 16 | int declare(void) { 17 | 18 | qsSetNumOutputs(1, 1); 19 | 20 | 21 | // We get our own copy of this loadCount variable. 22 | ASSERT(loadCount == 0); 23 | 24 | // Changing just in this instance of this block. 25 | ++loadCount; 26 | 27 | qsSetUserData(&loadCount); 28 | 29 | qsAddRunFile("_run.so", true); 30 | 31 | return 0; // success 32 | } 33 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/runFileNoCopy.c: -------------------------------------------------------------------------------- 1 | // For test: ../../../../tests/630_runFile 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../../lib/debug.h" 5 | #include "../../../../lib/parseBool.h" 6 | 7 | 8 | struct QsBlockOptions options = { 9 | .disableDSOLoadCopy = true 10 | }; 11 | 12 | 13 | int loadCount = 0; 14 | 15 | 16 | // For this test we load "b0" than "b1" than "b2" 17 | 18 | 19 | int declare(void) { 20 | 21 | qsSetNumOutputs(1, 1); 22 | 23 | const char *name = qsBlockGetName(); 24 | ASSERT(name && name[0] && name[1] && !name[2]); 25 | 26 | 27 | switch(name[1]) { 28 | 29 | case '0': // First time loaded in this graph 30 | ASSERT(loadCount == 0); 31 | break; 32 | case '1': // Second time loaded in this graph 33 | ASSERT(loadCount == 1); 34 | break; 35 | case '2': // Third time loaded in this graph 36 | ASSERT(loadCount == 2); 37 | break; 38 | default: 39 | ASSERT(0); 40 | break; 41 | } 42 | 43 | // Changing the value in all instances of this block from this DSO. 44 | ++loadCount; 45 | 46 | qsSetUserData(&loadCount); 47 | 48 | qsAddRunFile("_run.so", false/*do not load a copy*/); 49 | 50 | return 0; // success 51 | } 52 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/setter.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | int callback(const struct QsParameter *p, const void *value, 6 | uint32_t readCount, uint32_t queueCount, void *userData) { 7 | 8 | return 0; 9 | } 10 | 11 | int declare(void) { 12 | 13 | DSPEW(); 14 | 15 | qsCreateSetter("mySetter", sizeof(double), QsValueType_double, 16 | 0/*initValue*/, callback); 17 | 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/setterPrintDouble.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | int callback(const struct QsParameter *p, const double *value, 6 | uint32_t readCount, uint32_t queueCount, void *userData) { 7 | 8 | printf("%lg\n", *value); 9 | 10 | return 0; 11 | } 12 | 13 | int declare(void) { 14 | 15 | DSPEW(); 16 | 17 | qsCreateSetter("value", sizeof(double), QsValueType_double, 18 | 0/*initValue*/, 19 | (int (*)(const struct QsParameter *p, 20 | const void *value, uint32_t readCount, uint32_t queueCount, 21 | void *userData)) callback); 22 | 23 | return 0; 24 | } 25 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/setterPrintUint64.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | int callback(const struct QsParameter *p, const uint64_t *value, 6 | uint32_t readCount, uint32_t queueCount, void *userData) { 7 | 8 | printf("%" PRIu64 "\n", *value); 9 | 10 | return 0; 11 | } 12 | 13 | int declare(void) { 14 | 15 | DSPEW(); 16 | 17 | qsCreateSetter("value", sizeof(uint64_t), QsValueType_uint64, 18 | 0/*initValue*/, 19 | (int (*)(const struct QsParameter *p, 20 | const void *value, uint32_t readCount, 21 | uint32_t queueCount, 22 | void *userData)) callback); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/signalThread.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../debug.h" 5 | 6 | 7 | 8 | int callback(void *userData) { 9 | 10 | DSPEW(); 11 | 12 | return 0; 13 | } 14 | 15 | 16 | 17 | int declare(void) { 18 | 19 | DSPEW(); 20 | 21 | qsSignalJobCreate(SIGRTMIN+4, callback, 0); 22 | qsSignalJobCreate(SIGRTMIN+5, callback, 0); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/skipUndeclare.c: -------------------------------------------------------------------------------- 1 | #include "../../../../include/quickstream.h" 2 | #include "../../../debug.h" 3 | 4 | 5 | int declare(void) { 6 | 7 | DSPEW(); 8 | 9 | return -1; 10 | } 11 | 12 | int undeclare(void *userData) { 13 | 14 | DSPEW(); 15 | 16 | ASSERT(0, "This should not have been called"); 17 | 18 | return 1; 19 | } 20 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/startFail.c: -------------------------------------------------------------------------------- 1 | // Specifically for tests/505_startFail 2 | // 3 | 4 | #include "../../../../include/quickstream.h" 5 | #include "../../../../lib/debug.h" 6 | 7 | 8 | static 9 | int startCount = 0; 10 | 11 | static 12 | int stopCount = 0; 13 | 14 | 15 | int declare(void) { 16 | 17 | qsSetNumInputs(0, 0); 18 | qsSetNumOutputs(1, 2); 19 | 20 | return 0; // success 21 | } 22 | 23 | 24 | int start(uint32_t numInputs, uint32_t numOutputs, void *userData) { 25 | 26 | 27 | DSPEW("Block \"%s\" %" PRIu32 " outputs", 28 | qsBlockGetName(), numOutputs); 29 | 30 | ++startCount; 31 | 32 | if(startCount <= 2) 33 | return 1; // non-zero => fail and do call stop() 34 | 35 | return -2; // non-zero => fail and do not call stop() 36 | } 37 | 38 | 39 | int flow(const void * const in[], const size_t inLens[], uint32_t numIn, 40 | void * const out[], const size_t outLens[], uint32_t numOut, 41 | void *userData) { 42 | 43 | ASSERT(0, "We should never get here"); 44 | 45 | return 0; 46 | } 47 | 48 | 49 | int stop(uint32_t numInputs, uint32_t numOutputs, void *userData) { 50 | 51 | DSPEW(); 52 | 53 | ASSERT(startCount <= 2, "startCount=%d", startCount); 54 | 55 | ++stopCount; 56 | 57 | return 0; 58 | } 59 | 60 | 61 | int destroy(void *userData) { 62 | 63 | DSPEW(); 64 | //ASSERT(0, "This should not be called"); 65 | 66 | return 0; 67 | } 68 | 69 | 70 | int undeclare(void *userData) { 71 | 72 | DSPEW("startCount=%d stopCount=%d", startCount, stopCount); 73 | 74 | ASSERT(startCount == 3); 75 | ASSERT(stopCount == 2); 76 | 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/stdin.c: -------------------------------------------------------------------------------- 1 | // This is kind-of dumb, using buffered IO to feed a buffered quickstream 2 | // stream, but it is just a test so it's okay. A better method to read 3 | // stdin is to use unbuffered read. Then again, if you pick the wrong 4 | // buffer sizes this could end up faster than using unbuffered read. 5 | 6 | 7 | #include "../../../debug.h" 8 | #include "../../../../include/quickstream.h" 9 | 10 | 11 | static 12 | size_t maxWrite = 1045; 13 | 14 | 15 | int declare(void) { 16 | 17 | DSPEW(); 18 | 19 | qsSetNumInputs(0, 0); 20 | qsSetNumOutputs(1, 1); 21 | 22 | return 0; // success 23 | } 24 | 25 | int start(uint32_t numIn, uint32_t numOut, void *userData) { 26 | 27 | DASSERT(numOut == 1); 28 | DASSERT(numIn == 0); 29 | 30 | qsSetOutputMax(0, maxWrite); 31 | 32 | return 0; 33 | } 34 | 35 | 36 | int flow(const void * const in[], const size_t inLens[], uint32_t numIn, 37 | void * const out[], const size_t outLens[], uint32_t numOut, 38 | void *userData) { 39 | 40 | 41 | size_t len = outLens[0]; 42 | 43 | if(!len) return 0; 44 | 45 | // This would be an API code error. 46 | // This should not happen given we have an output threshold. 47 | ASSERT(len, "Block \"%s\" had 0 bytes output available", 48 | __BASE_FILE__); 49 | 50 | 51 | size_t rd = fread(out[0], 1, len, stdin); 52 | 53 | if(rd) 54 | qsAdvanceOutput(0, rd); 55 | 56 | if(rd < len) 57 | return 1; // stdin is done 58 | 59 | return 0; // success 60 | } 61 | 62 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/stdout.c: -------------------------------------------------------------------------------- 1 | // This is not such a dumb idea, a sink block that writes to a standard 2 | // buffered stream. It could be efficient if the block feeding it is 3 | // writing small chunks at a time. In any case this is just a test. 4 | // 5 | #include "../../../debug.h" 6 | #include "../../../../include/quickstream.h" 7 | 8 | 9 | int declare(void) { 10 | 11 | qsSetNumInputs(1, 1); 12 | qsSetNumOutputs(0, 0); 13 | 14 | return 0; // success 15 | } 16 | 17 | 18 | int flow(const void * const in[], const size_t inLens[], uint32_t numIn, 19 | void * const out[], const size_t outLens[], uint32_t numOut, 20 | void *userData) { 21 | 22 | if(!*inLens) return 0; 23 | 24 | ASSERT(*inLens, "inLens[0] == 0"); 25 | 26 | size_t ret = fwrite(in[0], 1, *inLens, stdout); 27 | 28 | if(ret) 29 | // Eat this much input from port 0 30 | qsAdvanceInput(0, ret); 31 | 32 | if(ret != *inLens) { 33 | ERROR("fwrite()=%zu != %zu failed", ret, *inLens); 34 | return -1; // error 35 | } 36 | 37 | return 0; // success 38 | } 39 | 40 | 41 | int stop(uint32_t numIn, uint32_t numOut, void *userData) { 42 | 43 | fflush(stdout); 44 | 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/subDir_test/Makefile: -------------------------------------------------------------------------------- 1 | # 1. build all [a-z]*.c as a block module 2 | # 2. build all [a-z]*.cpp as a block module 3 | # 3. build all [A-Z]*.c as a uninstalled test 4 | 5 | root := ../../../../.. 6 | 7 | SUBDIRS := a 8 | 9 | # add cc option to all binaries built in this directory: 10 | CFLAGS := -I$(root)/include 11 | 12 | 13 | INSTALL_DIR = $(PREFIX)/lib/quickstream/misc/test_blocks 14 | 15 | c_plugins := $(sort $(patsubst %.c, %, $(wildcard [a-z]*.c) $(wildcard _[a-z]*.c)) empty) 16 | 17 | cpp_plugins := $(patsubst %.cpp, %, $(wildcard [a-z]*.cpp)) 18 | 19 | 20 | define makeSOURCES 21 | $(1)$(2)_SOURCES := $(1)$(3) 22 | endef 23 | 24 | 25 | # If it turns out we need to link with libquickstream.so we'll have to 26 | # change the order in which make runs in subdirectories of lib/; that is 27 | # this directory need to make after ../../../../lib/. 28 | # 29 | define ADDlib 30 | $(1)_LDFLAGS := -L$(root)/lib -lquickstream -Wl,-rpath=\$$$$ORIGIN/$(root)/lib 31 | endef 32 | 33 | BUILD_NO_INSTALL := $(patsubst %.c, %, $(wildcard [A-Z]*.c)) 34 | 35 | 36 | empty.c: 37 | touch $@ 38 | 39 | CLEANFILES := empty.c 40 | 41 | 42 | $(foreach targ,$(c_plugins),$(eval $(call makeSOURCES,$(targ),.so,.c))) 43 | $(foreach targ,$(cpp_plugins),$(eval $(call makeSOURCES,$(targ),.so,.cpp))) 44 | $(foreach targ,$(BUILD_NO_INSTALL),$(eval $(call makeSOURCES,$(targ),,.c))) 45 | #$(foreach targ,$(BUILD_NO_INSTALL),$(eval $(call ADDlib,$(targ),))) 46 | 47 | 48 | 49 | include $(root)/quickbuild.make 50 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/subDir_test/a/Makefile: -------------------------------------------------------------------------------- 1 | # 1. build all [a-z]*.c as a block module 2 | # 2. build all [a-z]*.cpp as a block module 3 | # 3. build all [A-Z]*.c as a uninstalled test 4 | 5 | root := ../../../../../.. 6 | 7 | SUBDIRS := b 8 | 9 | # add cc option to all binaries built in this directory: 10 | CFLAGS := -I$(root)/include 11 | 12 | 13 | INSTALL_DIR = $(PREFIX)/lib/quickstream/misc/test_blocks 14 | 15 | c_plugins := $(sort $(patsubst %.c, %, $(wildcard [a-z]*.c) $(wildcard _[a-z]*.c)) empty) 16 | 17 | cpp_plugins := $(patsubst %.cpp, %, $(wildcard [a-z]*.cpp)) 18 | 19 | 20 | define makeSOURCES 21 | $(1)$(2)_SOURCES := $(1)$(3) 22 | endef 23 | 24 | 25 | # If it turns out we need to link with libquickstream.so we'll have to 26 | # change the order in which make runs in subdirectories of lib/; that is 27 | # this directory need to make after ../../../../lib/. 28 | # 29 | define ADDlib 30 | $(1)_LDFLAGS := -L$(root)/lib -lquickstream -Wl,-rpath=\$$$$ORIGIN/$(root)/lib 31 | endef 32 | 33 | BUILD_NO_INSTALL := $(patsubst %.c, %, $(wildcard [A-Z]*.c)) 34 | 35 | 36 | empty.c: 37 | touch $@ 38 | 39 | CLEANFILES := empty.c 40 | 41 | 42 | $(foreach targ,$(c_plugins),$(eval $(call makeSOURCES,$(targ),.so,.c))) 43 | $(foreach targ,$(cpp_plugins),$(eval $(call makeSOURCES,$(targ),.so,.cpp))) 44 | $(foreach targ,$(BUILD_NO_INSTALL),$(eval $(call makeSOURCES,$(targ),,.c))) 45 | #$(foreach targ,$(BUILD_NO_INSTALL),$(eval $(call ADDlib,$(targ),))) 46 | 47 | 48 | 49 | include $(root)/quickbuild.make 50 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/subDir_test/a/b/Makefile: -------------------------------------------------------------------------------- 1 | # 1. build all [a-z]*.c as a block module 2 | # 2. build all [a-z]*.cpp as a block module 3 | # 3. build all [A-Z]*.c as a uninstalled test 4 | 5 | root := ../../../../../../.. 6 | 7 | 8 | # add cc option to all binaries built in this directory: 9 | CFLAGS := -I$(root)/include 10 | 11 | 12 | INSTALL_DIR = $(PREFIX)/lib/quickstream/misc/test_blocks 13 | 14 | c_plugins := $(sort $(patsubst %.c, %, $(wildcard [a-z]*.c) $(wildcard _[a-z]*.c)) empty) 15 | 16 | cpp_plugins := $(patsubst %.cpp, %, $(wildcard [a-z]*.cpp)) 17 | 18 | 19 | define makeSOURCES 20 | $(1)$(2)_SOURCES := $(1)$(3) 21 | endef 22 | 23 | 24 | # If it turns out we need to link with libquickstream.so we'll have to 25 | # change the order in which make runs in subdirectories of lib/; that is 26 | # this directory need to make after ../../../../lib/. 27 | # 28 | define ADDlib 29 | $(1)_LDFLAGS := -L$(root)/lib -lquickstream -Wl,-rpath=\$$$$ORIGIN/$(root)/lib 30 | endef 31 | 32 | BUILD_NO_INSTALL := $(patsubst %.c, %, $(wildcard [A-Z]*.c)) 33 | 34 | 35 | empty.c: 36 | touch $@ 37 | 38 | CLEANFILES := empty.c 39 | 40 | 41 | $(foreach targ,$(c_plugins),$(eval $(call makeSOURCES,$(targ),.so,.c))) 42 | $(foreach targ,$(cpp_plugins),$(eval $(call makeSOURCES,$(targ),.so,.cpp))) 43 | $(foreach targ,$(BUILD_NO_INSTALL),$(eval $(call makeSOURCES,$(targ),,.c))) 44 | #$(foreach targ,$(BUILD_NO_INSTALL),$(eval $(call ADDlib,$(targ),))) 45 | 46 | 47 | 48 | include $(root)/quickbuild.make 49 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/superBlock.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "../../../../include/quickstream.h" 4 | #include "../../../../include/quickstream_debug.h" 5 | 6 | 7 | 8 | // ERROR() will print a line number which is a big help. 9 | #define FAIL() do { ERROR(); return -1; } while(0) 10 | 11 | 12 | const struct QsBlockOptions options = { .type = QsBlockType_super }; 13 | 14 | 15 | 16 | int declare(void) { 17 | 18 | DSPEW(); 19 | 20 | struct QsBlock *gen = qsGraph_createBlock(0, 0, "sequenceGen", "gen", 0); 21 | if(!gen) 22 | FAIL(); 23 | 24 | struct QsBlock *check = qsGraph_createBlock(0, 0, "sequenceCheck", "check", 0); 25 | if(!check) 26 | FAIL(); 27 | 28 | if(qsGraph_connectByBlock(0, gen, "o", "0", check, "i", "0")) 29 | FAIL(); 30 | 31 | return 0; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/superBlock_withMetaData.c: -------------------------------------------------------------------------------- 1 | // This was a generated file, but we made some edits. 2 | // 3 | // This is the source to a quickstream Super Block module. 4 | 5 | #include "../../../../include/quickstream.h" 6 | #include "../../../../include/quickstream_debug.h" 7 | 8 | 9 | struct QsBlockOptions options = { .type = QsBlockType_super }; 10 | 11 | // ERROR() will print a line number which is a big help. 12 | #define FAIL() do { ERROR(); return -1; } while(0) 13 | 14 | 15 | /////////////////////////////////////////////////////////////////// 16 | // Block Meta Data 17 | /////////////////////////////////////////////////////////////////// 18 | const char *QS_key0 = 19 | "MTIzNAB0aGlzAGlzAG1ldGFkYXRhADEyMzQAAA=="; 20 | const char *QS_key1 = 21 | "NDMyMQB0aGlzAGlzAG1vcmUAbWV0YWRhdGEANDMyMQAA"; 22 | 23 | // A null terminated array of all metaData symbol suffixes above: 24 | const char *qsMetaDataKeys[] = { 25 | "key0", 26 | "key1", 27 | 0 /*0 null terminator*/ 28 | }; 29 | /////////////////////////////////////////////////////////////////// 30 | 31 | 32 | int declare(void) { 33 | 34 | /////////////////////////////////////////////////////////////// 35 | // Load blocks 36 | /////////////////////////////////////////////////////////////// 37 | 38 | if(!qsGraph_createBlock(0, 0, "sequenceGen", "b0", 0)) 39 | FAIL(); 40 | 41 | if(!qsGraph_createBlock(0, 0, "sequenceCheck", "b1", 0)) 42 | FAIL(); 43 | 44 | /////////////////////////////////////////////////////////////// 45 | // Setup Port Aliases 46 | /////////////////////////////////////////////////////////////// 47 | 48 | /////////////////////////////////////////////////////////////// 49 | // Connect blocks 50 | /////////////////////////////////////////////////////////////// 51 | 52 | if(qsGraph_connectByStrings(0, "b0", "o", "0", "b1", "i", "0")) 53 | FAIL(); 54 | 55 | /////////////////////////////////////////////////////////////// 56 | // Configure blocks 57 | /////////////////////////////////////////////////////////////// 58 | 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /lib/quickstream/misc/test_blocks/superSuperBlock.c: -------------------------------------------------------------------------------- 1 | 2 | #ifndef SPEW_LEVEL_DEBUG 3 | # define SPEW_LEVEL_DEBUG 4 | #endif 5 | 6 | #include "../../../../include/quickstream.h" 7 | #include "../../../../include/quickstream_debug.h" 8 | 9 | 10 | struct QsBlockOptions options = { .type = QsBlockType_super }; 11 | 12 | 13 | // ERROR() will print a line number which is a big help. 14 | #define FAIL() do { ERROR(); return -1; } while(0) 15 | 16 | 17 | int declare(void) { 18 | 19 | 20 | if(!qsGraph_createBlock(0, 0, "superBlock2", "b0", 0)) 21 | FAIL(); 22 | 23 | if(!qsGraph_createBlock(0, 0, "superBlock2", "b1", 0)) 24 | FAIL(); 25 | 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /lib/retain-symbols.txt: -------------------------------------------------------------------------------- 1 | qsAddConfig 2 | qsAddEpollReadJob 3 | qsAddEpollWriteJob 4 | qsAddInterBlockJob 5 | qsAddRunFile 6 | qsAdvanceInput 7 | qsAdvanceOutput 8 | qsBlock_config 9 | qsBlock_configV 10 | qsBlock_configVByName 11 | qsBlock_destroy 12 | qsBlockDir 13 | qsBlock_getGetter 14 | qsBlock_getName 15 | qsBlockGetName 16 | qsBlock_getPort 17 | qsBlock_getSetter 18 | qsBlock_makePortAlias 19 | qsBlock_printPorts 20 | qsBlock_rename 21 | qsBuiltInBlocks 22 | qsCloseDLHandle 23 | qsCreateGetter 24 | qsCreateSetter 25 | qsDestroy 26 | qsFreeMemory 27 | qsGetDLSymbol 28 | qs_getGraph 29 | qsGetMemory 30 | getLibSpewLevel 31 | qsGetterPush 32 | qsGraph_clearMetaData 33 | qsGraph_connect 34 | qsGraph_connectByBlock 35 | qsGraph_connectByStrings 36 | qsGraph_create 37 | qsGraph_createBlock 38 | qsGraph_createThreadPool 39 | qsGraph_destroy 40 | qsGraph_disconnect 41 | qsGraph_disconnectByStrings 42 | qsGraph_getBlock 43 | qsGraph_getMetaData 44 | qsGraph_getName 45 | qsGraph_getNumThreadPools 46 | qsGraph_getThreadPool 47 | qsGraph_halt 48 | qsGraph_launchRunner 49 | qsGraph_lock 50 | qsGraph_printDot 51 | qsGraph_printDotDisplay 52 | qsGraph_removePortAlias 53 | qsGraph_removeConfigAttribute 54 | qsGraph_save 55 | qsGraph_saveConfig 56 | qsGraph_saveSuperBlock 57 | qsGraph_setDefaultThreadPool 58 | qsGraph_setMetaData 59 | qsGraph_setName 60 | qsGraph_start 61 | qsGraph_stop 62 | qsGraph_unhalt 63 | qsGraph_unlock 64 | qsGraph_wait 65 | qsGraph_waitForDestroy 66 | qsGraph_waitForStream 67 | qsIsRunning 68 | qsLibDir 69 | qsMakePassThroughBuffer 70 | qsOpenRelativeDLHandle 71 | qsOutputDone 72 | qsParameter_disconnect 73 | qsParameter_getSize 74 | qsParameter_getValue 75 | qsParameter_getValueType 76 | qsParameterIsConnected 77 | qsParameter_isGetterGroup 78 | qsParameter_setValue 79 | qsParameter_setValueByString 80 | qsParseAdvance 81 | qsParseBoolArray 82 | qsParseDouble 83 | qsParseDoubleArray 84 | qsParseInt32t 85 | qsParseSizet 86 | qsParseSizetArray 87 | qsParseUint32tArray 88 | qsParseUint64tArray 89 | qsQueueInterBlockJob 90 | qsSetInputMax 91 | qsSetNumInputs 92 | qsSetNumOutputs 93 | qsSetOutputMax 94 | setSpewLevel 95 | qsSetUserData 96 | qsSignalJobCreate 97 | qsSignalJobDestroy 98 | spew 99 | qsStart 100 | qsStop 101 | qsThreadPool_addBlock 102 | qsThreadPool_destroy 103 | qsThreadPool_getName 104 | qsThreadPool_setMaxThreads 105 | qsThreadPool_setName 106 | qsUnmakePassThroughBuffer 107 | -------------------------------------------------------------------------------- /lib/signalThread.h: -------------------------------------------------------------------------------- 1 | // It seems that signals do not mix easily with other events. 2 | // 3 | // This injects events/jobs from a "signal thread" into the worker thread 4 | // pools events/jobs. It's just a single very sleepy thread that feeds 5 | // the "regular" quickstream thread pool worker threads. 6 | // 7 | // Since signals are a process wide thing; we make this signal thread 8 | // thing function across all blocks in all graphs. Putting this kind of 9 | // thing in the thread pool worker threads would at least double the 10 | // complexity of the thread pool worker threads main loop. We are not 11 | // seeing great demand for this, so we are keeping it more separate from 12 | // the general thread pool worker threads. We envision that this code is 13 | // robust and as simple as we could make it. 14 | // 15 | 16 | #define _QS_WAKEUP_SIG (SIGCONT) 17 | 18 | 19 | 20 | struct QsSignalJob { 21 | 22 | // inherit job. 23 | struct QsJob job; 24 | 25 | int (*callback)(void *userData); 26 | 27 | void *userData; 28 | 29 | // Points back to the struct QsSignal. 30 | struct QsSignal *signal; 31 | }; 32 | 33 | 34 | // a container for an array of jobs: 35 | // 36 | struct QsSignal { 37 | 38 | // We keep an array of signal job pointers. There can be any number 39 | // of blocks using a given signal number. 40 | // 41 | struct QsSignalJob **signalJobs; 42 | // 43 | // Length of array of signal jobs. 44 | // 45 | uint32_t numSignalJobs; 46 | 47 | // See signal number from running "kill -L" 48 | // 49 | int sigNum; // signal number like for example: SIGUSR2 50 | 51 | // For the list of jobs in the signal thread thingy. 52 | CRBNode node; 53 | }; 54 | 55 | 56 | 57 | // The signal thread will not exist unless it is needed. We let it handle 58 | // any number of signals. We remove it if it is not needed after being 59 | // used. Instead of making a static singleton object we make it (malloc 60 | // it) dynamically when it is needed saving memory when it is not 61 | // needed. 62 | // 63 | struct QsSignalThread { 64 | 65 | pthread_t pthread; 66 | 67 | pthread_barrier_t *barrier; 68 | 69 | sigset_t sigset; 70 | 71 | // This red black tree list is keyed by signal number. 72 | // 73 | CRBTree signals; 74 | 75 | // Flag that says the signal thread is finished. 76 | atomic_uint done; 77 | }; 78 | -------------------------------------------------------------------------------- /share/bash-completion/completions/Makefile: -------------------------------------------------------------------------------- 1 | 2 | topdir := ../../.. 3 | 4 | 5 | INSTALL_DIR = $(PREFIX)/share/bash-completion/completions 6 | 7 | BUILD := quickstream 8 | 9 | 10 | builtIns := $(sort $(shell cat $(topdir)/lib/builtInBlocks.txt | grep -ve '^\#')) 11 | 12 | #$(warning builtIns=$(builtIns)) 13 | 14 | 15 | helper := $(topdir)/lib/quickstream/misc/quickstreamHelp 16 | 17 | 18 | quickstream: quickstream.IN $(helper) $(topdir)/lib/builtInBlocks.txt 19 | opts="$$($(helper) -O)" &&\ 20 | opts_noarg="$$($(helper) -w)" &&\ 21 | sed $<\ 22 | -e "s/@GEN_FILE@/\# This is a generated file from the quickstream package/g"\ 23 | -e "s/@OPTS@/$$opts/g"\ 24 | -e "s/@OPTS_NOARG@/$$opts_noarg/g"\ 25 | -e "s!@builtInBlocks@!$(builtIns)!g" > $@ 26 | 27 | 28 | include $(topdir)/quickbuild.make 29 | -------------------------------------------------------------------------------- /share/doc/quickstream/Makefile: -------------------------------------------------------------------------------- 1 | topdir := ../../.. 2 | 3 | # More here later. 4 | 5 | include $(topdir)/quickbuild.make 6 | -------------------------------------------------------------------------------- /tests/010_skipTest.c: -------------------------------------------------------------------------------- 1 | 2 | int main(void) { 3 | return 123; 4 | } 5 | -------------------------------------------------------------------------------- /tests/021_debug.c: -------------------------------------------------------------------------------- 1 | #include "../lib/debug.h" 2 | 3 | 4 | int main(void) { 5 | 6 | WARN("It worked %d", 1); 7 | 8 | return 0; // success 9 | } 10 | -------------------------------------------------------------------------------- /tests/040_qsGraph_create.c: -------------------------------------------------------------------------------- 1 | 2 | #include "../include/quickstream.h" 3 | 4 | 5 | int main(void) { 6 | 7 | struct QsGraph *g = qsGraph_create(0, 3/*maxThreads*/, 8 | "graph 1", "tp 1", 0); 9 | 10 | qsGraph_destroy(g); 11 | 12 | return 0; // success 13 | } 14 | -------------------------------------------------------------------------------- /tests/044_qsGraph_create_many.c: -------------------------------------------------------------------------------- 1 | 2 | #include "../include/quickstream.h" 3 | 4 | 5 | int main(void) { 6 | 7 | struct QsGraph *g0 = qsGraph_create(0, 3/*maxThreads*/, 8 | "graph 0", "", 0); 9 | 10 | struct QsGraph *g1 = qsGraph_create(0, 1/*maxThreads*/, 11 | "graph 1", 0, QS_GRAPH_IS_MASTER); 12 | 13 | struct QsGraph *g2 = qsGraph_create(0, 7/*maxThreads*/, 14 | "graph 2", "tp 2", QS_GRAPH_IS_MASTER); 15 | 16 | qsGraph_destroy(g0); 17 | qsGraph_destroy(g1); 18 | qsGraph_destroy(g2); 19 | 20 | return 0; // success 21 | } 22 | -------------------------------------------------------------------------------- /tests/047_qsGraph_noDestroy.c: -------------------------------------------------------------------------------- 1 | 2 | #include "../include/quickstream.h" 3 | 4 | 5 | int main(void) { 6 | 7 | 8 | struct QsGraph *g0 = qsGraph_create(0, 3/*maxThreads*/, 9 | "graph 0", "", 0); 10 | 11 | qsGraph_create(0, 1/*maxThreads*/, "graph 1", 0, 0); 12 | 13 | qsGraph_create(0, 7/*maxThreads*/, "graph 2", "tp 2", 0); 14 | 15 | qsGraph_destroy(g0); 16 | 17 | return 0; // success 18 | } 19 | -------------------------------------------------------------------------------- /tests/052_qsGraphExit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | #include "../include/quickstream.h" 6 | #include "../lib/debug.h" 7 | 8 | 9 | // Will using this mutex leak resources that valgrind will complain 10 | // about? 11 | // 12 | // If that changes I really need to know, hence this test exists. 13 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 14 | 15 | 16 | int main(void) { 17 | 18 | 19 | qsGraph_create(0, 3/*maxThreads*/, "graph 0", "", QS_GRAPH_IS_MASTER); 20 | 21 | CHECK(pthread_mutex_lock(&mutex)); 22 | 23 | // We are assuming that no other thread is calling exit() so in that 24 | // case exit() is thread-safe. Well anyway we have a mutex lock to 25 | // test for resource leaks, but in this case, not for making making 26 | // exit() thread-safe. Ya, this is testing that we understand shit. 27 | // 28 | // The libquickstream destructor will be called to cleanup the 29 | // quickstream graph; so we hope. 30 | // 31 | exit(0); 32 | 33 | // We never get here: 34 | return 0; // success 35 | } 36 | -------------------------------------------------------------------------------- /tests/053_qsGraph_waitCommand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "../include/quickstream.h" 12 | 13 | #include "../lib/debug.h" 14 | #include "../lib/Dictionary.h" 15 | #include "../lib/name.h" 16 | 17 | #include "../lib/c-rbtree.h" 18 | #include "../lib/threadPool.h" 19 | #include "../lib/block.h" 20 | #include "../lib/graph.h" 21 | #include "../lib/job.h" 22 | 23 | 24 | void catcher(int signum) { 25 | ASSERT(0, "Catch signal %d", signum); 26 | } 27 | 28 | 29 | 30 | int main(void) { 31 | 32 | ASSERT(0 == signal(SIGSEGV, catcher)); 33 | ASSERT(0 == signal(SIGABRT, catcher)); 34 | 35 | struct QsGraph *g = qsGraph_create(0, 3/*maxThreads*/, "graph 0", "", 0); 36 | ASSERT(g); 37 | 38 | // Do not wait very long. Test that it does not hang forever. 39 | qsGraph_wait(g, 0.0001/*seconds*/); 40 | 41 | return 0; // success 42 | } 43 | -------------------------------------------------------------------------------- /tests/060_job.c: -------------------------------------------------------------------------------- 1 | // Testing making a block and a job. 2 | // 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "../include/quickstream.h" 11 | 12 | #include "../lib/debug.h" 13 | #include "../lib/Dictionary.h" 14 | 15 | #include "../lib/c-rbtree.h" 16 | #include "../lib/name.h" 17 | #include "../lib/threadPool.h" 18 | #include "../lib/block.h" 19 | #include "../lib/graph.h" 20 | #include "../lib/job.h" 21 | 22 | 23 | static 24 | bool Work(struct QsJob *j) { 25 | 26 | DSPEW(); 27 | 28 | return false; 29 | } 30 | 31 | void Catcher(int sig) { 32 | ERROR("Caught signal %d", sig); 33 | ASSERT(0); 34 | } 35 | 36 | 37 | int main(void) { 38 | 39 | signal(SIGSEGV, Catcher); 40 | signal(SIGABRT, Catcher); 41 | 42 | 43 | struct QsGraph *g = qsGraph_create(0, 3, 0, 0, 0); 44 | 45 | struct QsJobsBlock b; 46 | 47 | qsBlock_init(g, &b.block, 48 | 0/*parent block*/, 49 | 0/*thread pool*/, 50 | QsBlockType_jobs, 0/*name*/, 0); 51 | 52 | struct QsJob j; 53 | 54 | qsJob_init(&j, &b, Work, 0, 0); 55 | 56 | qsJob_cleanup(&j); 57 | 58 | qsBlock_cleanup(&b.block); 59 | 60 | qsGraph_destroy(g); 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /tests/300_qsVersion: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -xe 4 | 5 | ../bin/quickstream -V 6 | 7 | -------------------------------------------------------------------------------- /tests/402_empty: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block empty 13 | 14 | 15 | ../bin/quickstream\ 16 | --exit-on-error\ 17 | -v 5\ 18 | --block empty dum 19 | 20 | 21 | # Repeating the same block name should fail. 22 | if ../bin/quickstream\ 23 | --exit-on-error\ 24 | -v 5\ 25 | --block empty dum\ 26 | --block empty dum ; then 27 | exit 1 28 | fi 29 | 30 | 31 | # Repeating the same block name 32 | # without --exit-on-error will not return error status. 33 | ../bin/quickstream\ 34 | -v 5\ 35 | --block empty dum\ 36 | --block empty dum 37 | 38 | 39 | # Without --exit-on-error but with last command succeeding 40 | ../bin/quickstream\ 41 | -v 5\ 42 | --block empty dum\ 43 | --block empty dum\ 44 | --block empty 45 | 46 | 47 | 48 | ../bin/quickstream\ 49 | --exit-on-error\ 50 | -v 5\ 51 | --block empty dum\ 52 | --block empty dum2\ 53 | --block empty\ 54 | --block empty\ 55 | --block empty\ 56 | --block empty 57 | 58 | 59 | ../bin/quickstream\ 60 | --exit-on-error\ 61 | -v 5\ 62 | --block empty empty_2\ 63 | --block empty empty\ 64 | --block empty empty_4\ 65 | --block empty\ 66 | --block empty\ 67 | --block empty 68 | 69 | -------------------------------------------------------------------------------- /tests/404_declare: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block "declare" 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/405_destroy: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block destroy 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/406_declareFail: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block "declare" 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/407_declareFailUndelare: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block declareFailUndeclare b0 13 | 14 | 15 | 16 | if ../bin/quickstream\ 17 | --exit-on-error\ 18 | -v 5\ 19 | --block declareFailUndeclare b0\ 20 | --block-unload b0 ; then 21 | exit 1 22 | fi 23 | 24 | -------------------------------------------------------------------------------- /tests/409_skipUndeclare: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | if ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block skipUndeclare b0\ 13 | --block-unload b0 ; then 14 | exit 1 15 | fi 16 | 17 | if ../bin/quickstream\ 18 | --exit-on-error\ 19 | -v 5\ 20 | --block skipUndeclare b0 ; then 21 | exit 1 22 | fi 23 | 24 | -------------------------------------------------------------------------------- /tests/412_builtIn: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block FileIn b0\ 13 | --block-unload b0 14 | 15 | ../bin/quickstream\ 16 | --exit-on-error\ 17 | -v 5\ 18 | --block FileIn 19 | 20 | -------------------------------------------------------------------------------- /tests/415_setter: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block setter b0 13 | -------------------------------------------------------------------------------- /tests/417_parameterConnections: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block lotsOfPorts b0\ 13 | --block lotsOfPorts b1\ 14 | --block lotsOfPorts b2\ 15 | --connect b0 s freq1 b1 s freq1\ 16 | --connect b1 s freq1 b2 s freq1 17 | 18 | 19 | # Control Parameters b2:freq1 and b0:freq1 are already connected: 20 | if ../bin/quickstream\ 21 | --exit-on-error\ 22 | -v 5\ 23 | --block lotsOfPorts b0\ 24 | --block lotsOfPorts b1\ 25 | --block lotsOfPorts b2\ 26 | --connect b0 s freq1 b1 s freq1\ 27 | --connect b1 s freq1 b2 s freq1\ 28 | --connect b2 s freq1 b0 s freq1 ; then 29 | exit 1 30 | fi 31 | 32 | 33 | # connecting different control parameter types: 34 | if ../bin/quickstream\ 35 | --exit-on-error\ 36 | -v 5\ 37 | --block lotsOfPorts b0\ 38 | --block lotsOfPorts b1\ 39 | --connect b0 s gain1 b1 s freq1 ; then 40 | exit 1 41 | fi 42 | 43 | 44 | ../bin/quickstream\ 45 | --exit-on-error\ 46 | -v 5\ 47 | --block lotsOfPorts b0\ 48 | --block lotsOfPorts b1\ 49 | --block lotsOfPorts b2\ 50 | --connect b0 s freq1 b1 s freq1\ 51 | --connect b1 s freq1 b2 s freq1\ 52 | --connect b0 g gain b1 s gain\ 53 | --connect b0 G gain b2 S gain 54 | 55 | 56 | ../bin/quickstream\ 57 | --exit-on-error\ 58 | -v 5\ 59 | --block lotsOfPorts b0\ 60 | --block lotsOfPorts b1\ 61 | --block lotsOfPorts b2\ 62 | --connect b0 s freq1 b1 s freq1\ 63 | --connect b1 s freq1 b2 s freq1\ 64 | --connect b0 g gain b1 s gain\ 65 | --disconnect b0 G gain\ 66 | --disconnect b0 s freq1\ 67 | --disconnect b1 s freq1 68 | 69 | -------------------------------------------------------------------------------- /tests/420_signalThread: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block signalThread b0 13 | -------------------------------------------------------------------------------- /tests/430_blockLoadFail: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | # I have a bug where failing to load a block caused the program to hang. 7 | # This will catch such a bug and hang the test. Trying a few forms of 8 | # it. 9 | 10 | 11 | if ../bin/quickstream\ 12 | --exit-on-error\ 13 | -v 5\ 14 | --block non_eXistenT_block b\ 15 | --wait ; then 16 | exit 1 17 | fi 18 | 19 | 20 | if ../bin/quickstream\ 21 | --exit-on-error\ 22 | -v 5\ 23 | --block non_eXistenT_block b ; then 24 | exit 1 25 | fi 26 | 27 | ../bin/quickstream\ 28 | -v 5\ 29 | --block non_eXistenT_block b\ 30 | -v 5 31 | 32 | 33 | ../bin/quickstream\ 34 | -v 5\ 35 | --block non_eXistenT_block b 36 | -------------------------------------------------------------------------------- /tests/435_parameterChangeThreadPool: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | # This makes the block change thread pools by deleting a thread pool. 9 | # There was a bug assertion from this test. The parameters handle lists 10 | # of peer jobs differently than stream peer jobs. 11 | 12 | 13 | ../bin/quickstream\ 14 | --exit-on-error\ 15 | -v 5\ 16 | --threads 1 tp1\ 17 | --block lotsOfPorts b0\ 18 | --block lotsOfPorts b1\ 19 | --block lotsOfPorts b2\ 20 | --connect b0 s freq1 b1 s freq1\ 21 | --connect b1 s freq1 b2 s freq1\ 22 | --threads 1 tp2\ 23 | --threads-destroy tp1 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /tests/443_blockConfigure: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block lotsOfPorts b0\ 13 | --block lotsOfPorts b1\ 14 | --configure-mk MK b0 config1 MK\ 15 | --configure-mk MK b0 config1 foo bar baz MK 16 | 17 | 18 | # Configure a non-existent attribute named myAss 19 | if ../bin/quickstream\ 20 | --exit-on-error\ 21 | -v 5\ 22 | --block lotsOfPorts b1\ 23 | --configure-mk M b1 myAss foo bar M ; then 24 | exit 1 25 | fi 26 | 27 | 28 | # This has a race to see the printing to stderr from 29 | # the block, but that does not make it fail. We 30 | # do not want this program to wait a time longer than 31 | # one thousandth of a second. Quick tests must be quick. 32 | ../bin/quickstream\ 33 | --exit-on-error\ 34 | -v 5\ 35 | --block lotsOfPorts b0\ 36 | --block lotsOfPorts b1\ 37 | --configure-mk MK b0 config1 MK\ 38 | --configure-mk MK b0 config1 foo bar baz MK\ 39 | --parameter-set-mk MK b0 freq1 1000 MK\ 40 | --parameter-set-mk MK b1 gain -3000.5 10 24.789 MK\ 41 | --parameter-set-mk MK b1 gain 2.789 MK\ 42 | --parameter-set-mk MK b1 gain MK\ 43 | --parameter-set-mk MK b1 on True MK\ 44 | --configure-mk MK b0 config1 1 2 3 4.8 5.123 MK\ 45 | --configure-mk MK b0 config1 1 2 3 MK\ 46 | --wait 0.0001 47 | -------------------------------------------------------------------------------- /tests/464_connectStream: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block lotsOfPorts b0\ 13 | --connect b0 output 0 b0 input 0 14 | 15 | 16 | 17 | # connecting at input twice. 18 | # 19 | # block "b0" input port 0 already connected 20 | if ../bin/quickstream\ 21 | --exit-on-error\ 22 | -v 5\ 23 | --block lotsOfPorts b0\ 24 | --connect b0 output 0 b0 input 0\ 25 | --connect b0 output 1 b0 input 0 ; then 26 | exit 1 27 | fi 28 | 29 | 30 | 31 | ../bin/quickstream\ 32 | --exit-on-error\ 33 | -v 5\ 34 | --block lotsOfPorts b0\ 35 | --block lotsOfPorts b1\ 36 | --connect b0 output 0 b1 input 0\ 37 | --connect b1 output 0 b0 input 0\ 38 | --connect b0 output 1 b1 input 1\ 39 | --connect b1 output 1 b0 input 1\ 40 | --disconnect b1 output 0\ 41 | --disconnect b0 output 0\ 42 | --connect b1 output 0 b0 input 0 43 | 44 | 45 | # Block "b0" stream input port 1 gap not connected 46 | if ../bin/quickstream\ 47 | --exit-on-error\ 48 | -v 5\ 49 | --block lotsOfPorts b0\ 50 | --block lotsOfPorts b1\ 51 | --connect b0 output 0 b1 input 0\ 52 | --connect b1 output 2 b0 input 2\ 53 | --start ; then 54 | exit 1 55 | fi 56 | 57 | 58 | # No such port: "b0:input:2" 59 | if ../bin/quickstream\ 60 | --exit-on-error\ 61 | -v 5\ 62 | --block sequenceGen b0\ 63 | --block sequenceCheck b1\ 64 | --connect b1 output 2 b0 input 2\ 65 | --start ; then 66 | exit 1 67 | fi 68 | 69 | 70 | # Block "b0" stream output port 0 not connected 71 | if ../bin/quickstream\ 72 | --exit-on-error\ 73 | -v 5\ 74 | --block sequenceGen b0\ 75 | --start ; then 76 | exit 1 77 | fi 78 | 79 | 80 | # unsetting exit-on-error 81 | # 82 | ../bin/quickstream\ 83 | --exit-on-error\ 84 | -v 5\ 85 | --block lotsOfPorts b0\ 86 | --block lotsOfPorts b1\ 87 | --connect b1 output 1 b0 input 1\ 88 | --disconnect b1 output 0\ 89 | --disconnect b0 output 0\ 90 | --connect b1 output 0 b0 input 0\ 91 | --exit-on-error False\ 92 | --connect b1 output 1 b0 input 1 93 | 94 | 95 | # Graph has no stream ports connected, 96 | # but we let it try to run the stream 97 | if ../bin/quickstream\ 98 | --exit-on-error\ 99 | -v 5\ 100 | --block sequenceCheck b0\ 101 | --block sequenceCheck b1\ 102 | --start\ 103 | --wait ; then 104 | exit 1 105 | fi 106 | 107 | 108 | -------------------------------------------------------------------------------- /tests/471_execBlock.c: -------------------------------------------------------------------------------- 1 | // This is compiled into a DSO (dynamic shared object) that is 2 | // loadable with dlopen(3) and is executable. 3 | // 4 | // Executing the binary made from this file executes ../bin/quickstream 5 | // which loads the DSO from this file as a block module. 6 | // 7 | // So using this trick ... I should be able to make DSO (dynamic shared 8 | // object) quickstream super blocks that can run themselves. 9 | 10 | 11 | // TODO: This is, so very much, not portable code. 12 | 13 | 14 | //https://stackoverflow.com/questions/1449987/building-a-so-that-is-also-an-executable 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | #include "../lib/debug.h" 21 | #include "../include/quickstream.h" // for QS_DL_LOADER 22 | 23 | /* 24 | In a bash shell you can run: 25 | 26 | /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 --help 27 | */ 28 | 29 | const char service_interp[] __attribute__((section(".interp"))) = QS_DL_LOADER; 30 | 31 | // may be needed on i386 computers: 32 | //__attribute__((force_align_arg_pointer)) 33 | int main(int argc, char **argv) { 34 | 35 | printf("hello\n"); 36 | 37 | ASSERT(setenv("QS_BLOCK_PATH", ".", 1) == 0); 38 | 39 | execl("../bin/quickstream", 40 | "quickstream", "--exit-on-error", 41 | "--block", "471_execBlock.so", NULL); 42 | ERROR("execl() failed"); 43 | return 1; 44 | } 45 | 46 | 47 | int declare(void) { 48 | 49 | DSPEW(); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /tests/505_startFail: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This test is vary particularly paired with the test block 4 | # ../lib/quickstream/misc/test_blocks/startFail.so 5 | # 6 | # It tests a block that fails to start() and how it gets 7 | # stop() called, depending on what value start() returns. 8 | 9 | 10 | set -ex 11 | 12 | 13 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 14 | 15 | 16 | ../bin/quickstream\ 17 | --exit-on-error\ 18 | -v 5\ 19 | --block startFail b0\ 20 | --block stdout b1\ 21 | --connect b0 output 0 b1 input 0\ 22 | --exit-on-error False\ 23 | --start\ 24 | --exit-on-error\ 25 | --wait-for-stream\ 26 | --exit-on-error False\ 27 | --start\ 28 | --exit-on-error\ 29 | --wait-for-stream\ 30 | --exit-on-error False\ 31 | --start\ 32 | --exit-on-error\ 33 | --wait-for-stream 34 | 35 | -------------------------------------------------------------------------------- /tests/510_blockDestroyingGraph: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block destroyGraph 13 | 14 | 15 | 16 | ../bin/quickstream\ 17 | --exit-on-error\ 18 | -v 5\ 19 | --graph\ 20 | --wait 0.001 21 | 22 | 23 | # This will never get the requested qsDestroy() command to run because the 24 | # qsGraph_wait() is never called to run it. But it does not matter. 25 | # The queued command is destroyed with the graph. That is the next 26 | # thing after setter setting the command is to destroy the graph. 27 | # 28 | ../bin/quickstream\ 29 | --exit-on-error\ 30 | -v 5\ 31 | --block destroyGraph b\ 32 | --parameter-set-mk MK b destroy True MK 33 | 34 | 35 | # This gets to destroy the graph using the block's setter callback. 36 | # This will try to wait forever but the destroy command requested 37 | # by the blocks setter callback will interrupt the wait. 38 | ../bin/quickstream\ 39 | --exit-on-error\ 40 | -v 5\ 41 | --block destroyGraph b\ 42 | --parameter-set-mk MK b destroy True MK\ 43 | --wait 44 | 45 | 46 | 47 | # This gets to destroy the graph using the block's setter callback. 48 | # The wait 100 will be interrupted by the destroy command requested 49 | # by the blocks setter callback. 50 | ../bin/quickstream\ 51 | --exit-on-error\ 52 | -v 5\ 53 | --block destroyGraph b\ 54 | --parameter-set-mk MK b destroy True MK\ 55 | --wait 100 56 | 57 | 58 | # This gets to destroy the graph using the block's setter callback. 59 | ../bin/quickstream\ 60 | --exit-on-error\ 61 | -v 5\ 62 | --block destroyGraph b\ 63 | --parameter-set-mk MK b destroy 1 MK\ 64 | --wait 0.01 65 | 66 | -------------------------------------------------------------------------------- /tests/520_parameterAddLoops: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | # --connect BLOCK_A TYPE_A PORT_A BLOCK_B TYPE_B PORT_B 9 | 10 | 11 | ../bin/quickstream\ 12 | --exit-on-error\ 13 | -v 5\ 14 | --block add1 add 15 | 16 | 17 | ../bin/quickstream\ 18 | --exit-on-error\ 19 | -v 5\ 20 | --block add1 a1\ 21 | --wait 0.0001 22 | 23 | 24 | ../bin/quickstream\ 25 | --exit-on-error\ 26 | -v 5\ 27 | --block add1 a1\ 28 | --connect a1 g add a1 s add\ 29 | --wait 30 | 31 | 32 | ../bin/quickstream\ 33 | --exit-on-error\ 34 | -v 5\ 35 | --block add1 a1\ 36 | --block add1 a2\ 37 | --connect a1 g add a2 s add\ 38 | --connect a2 g add a1 s add\ 39 | --wait 40 | 41 | 42 | ../bin/quickstream\ 43 | --exit-on-error\ 44 | -v 5\ 45 | --block add1 a1\ 46 | --block add1 a2\ 47 | --block add1 a3\ 48 | --connect a1 g add a2 s add\ 49 | --connect a2 g add a3 s add\ 50 | --connect a3 g add a1 s add\ 51 | --wait 52 | 53 | 54 | ../bin/quickstream\ 55 | --exit-on-error\ 56 | -v 5\ 57 | --graph\ 58 | --halt\ 59 | --block add1 a1\ 60 | --block add1 a2\ 61 | --block add1 a3\ 62 | --connect a1 g add a2 s add\ 63 | --connect a2 g add a3 s add\ 64 | --connect a3 g add a1 s add\ 65 | --unhalt\ 66 | --wait 67 | 68 | 69 | ../bin/quickstream\ 70 | --exit-on-error\ 71 | -v 5\ 72 | --block add1 a1\ 73 | --block add1 a2\ 74 | --block add1 a3\ 75 | --block add1 a4\ 76 | --connect a1 g add a2 s add\ 77 | --connect a2 g add a3 s add\ 78 | --connect a3 g add a4 s add\ 79 | --connect a4 g add a1 s add\ 80 | --wait 81 | 82 | -------------------------------------------------------------------------------- /tests/530_parameterConnect: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | # This hit a bug I came upon. The last command 9 | # --connect b2 setter freq1 b2 setter freq2 FAILED 10 | # 11 | # DO NOT CHANGE THIS NEXT COMMAND. 12 | # 13 | ../bin/quickstream\ 14 | --exit-on-error\ 15 | --block lotsOfPorts b1\ 16 | --block lotsOfPorts b2\ 17 | --connect b1 setter freq1 b2 setter freq1\ 18 | --connect b1 setter freq2 b2 setter freq2\ 19 | --connect b2 setter freq1 b2 setter freq2 20 | 21 | 22 | 23 | ../bin/quickstream\ 24 | --exit-on-error\ 25 | --block lotsOfPorts b1\ 26 | --block lotsOfPorts b2\ 27 | --connect b1 setter freq1 b2 setter freq1\ 28 | --connect b2 setter freq2 b1 setter freq2\ 29 | --connect b2 setter freq1 b2 setter freq2\ 30 | --disconnect b2 setter freq2\ 31 | --connect b1 setter freq1 b2 setter freq2 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/540_loops: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | ../bin/quickstream\ 9 | --exit-on-error\ 10 | -v 5\ 11 | --graph g0 1\ 12 | --block sequenceGen b0\ 13 | --block sequenceCheck b1\ 14 | --configure-mk MK b0 Seeds 22 MK\ 15 | --configure-mk MK b1 Seeds 22 MK\ 16 | --connect b0 output 0 b1 input 0\ 17 | --connect b1 output 0 b1 input 1\ 18 | --start\ 19 | --wait 20 | 21 | 22 | ../bin/quickstream\ 23 | --exit-on-error\ 24 | -v 5\ 25 | --graph g0 1\ 26 | --block sequenceGen b0\ 27 | --block sequenceCheck b1\ 28 | --block sequenceCheck b2\ 29 | --configure-mk MK b0 Seeds 22 MK\ 30 | --configure-mk MK b1 Seeds 22 MK\ 31 | --configure-mk MK b2 Seeds 22 MK\ 32 | --connect b0 output 0 b1 input 0\ 33 | --connect b1 output 0 b2 input 0\ 34 | --connect b2 output 0 b1 input 1\ 35 | --start\ 36 | --wait 37 | 38 | 39 | 40 | ../bin/quickstream\ 41 | --exit-on-error\ 42 | -v 5\ 43 | --graph g0 1\ 44 | --block sequenceGen b0\ 45 | --block sequenceCheck b1\ 46 | --block sequenceCheck b3\ 47 | --configure-mk MK b0 Seeds 22 MK\ 48 | --configure-mk MK b1 Seeds 22 MK\ 49 | --configure-mk MK b3 Seeds 22 MK\ 50 | --connect b0 output 0 b1 input 0\ 51 | --connect b1 output 0 b1 input 1\ 52 | --connect b1 output 1 b1 input 2\ 53 | --connect b1 output 2 b1 input 3\ 54 | --connect b1 output 3 b3 input 0\ 55 | --connect b3 output 0 b1 input 4\ 56 | --connect b3 output 0 b1 input 5\ 57 | --start\ 58 | --wait 59 | 60 | -------------------------------------------------------------------------------- /tests/566_interpreter: -------------------------------------------------------------------------------- 1 | #!../bin/quickstream_interpreter 2 | 3 | 4 | v 5 5 | 6 | exit-on-error 7 | 8 | graph 9 | # this is a comment 10 | 11 | # Set the environment variable QS_BLOCK_PATH 12 | set-block-path ../lib/quickstream/misc/test_blocks:../lib/quickstream 13 | block sequenceGen b0 14 | # testing using a weird path with the weird QS_BLOCK_PATH 15 | block misc/test_blocks/sequenceCheck b1 16 | connect b0 output 0 b1 input 0 17 | start 18 | wait-for-stream 19 | 20 | -------------------------------------------------------------------------------- /tests/567_interpreter2: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This tests the quickstream interpreter running from 4 | # the program "quickstream". 5 | 6 | 7 | 8 | set -ex 9 | 10 | thisFile="${BASH_SOURCE[0]}" 11 | 12 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 13 | 14 | ../bin/quickstream\ 15 | --exit-on-error\ 16 | -v 5\ 17 | --interpreter "$thisFile" 23 18 | 19 | # Tell the shell to exit, so it does not run below what was meant for the 20 | # quickstream interpreter and not for bash. 21 | exit 22 | 23 | 24 | block sequenceGen b0 25 | block sequenceCheck b1 26 | connect b0 output 0 b1 input 0 27 | # jump to this file line 30 28 | interpreter 567_interpreter2 30 29 | 30 | 31 | 32 | start 33 | wait-for-stream 34 | 35 | -------------------------------------------------------------------------------- /tests/612_PipeIn: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | 7 | inFile="data_$(basename $0)_in.tmp" 8 | outFile="data_$(basename $0)_out.tmp" 9 | compFile="data_$(basename $0)_comp.tmp" 10 | 11 | 12 | dd if=/dev/urandom count=21 of=$inFile 13 | 14 | 15 | ../bin/quickstream\ 16 | --exit-on-error\ 17 | -v 5\ 18 | --threads 1\ 19 | --block file/PipeIn in0\ 20 | --block file/FileOut out\ 21 | --configure-mk MK in0 Program cat $inFile MK\ 22 | --connect in0 output 0 out input 0\ 23 | --start\ 24 | --wait-for-stream > $outFile 25 | 26 | 27 | diff -q $inFile $outFile 28 | 29 | 30 | 31 | ../bin/quickstream\ 32 | --exit-on-error\ 33 | -v 5\ 34 | --threads 2\ 35 | --block file/PipeIn in0\ 36 | --block file/FileOut out\ 37 | --configure-mk MK in0 Program cat $inFile MK\ 38 | --connect in0 output 0 out input 0\ 39 | --start\ 40 | --wait-for-stream > $outFile 41 | 42 | 43 | diff -q $inFile $outFile 44 | 45 | 46 | 47 | # Run it twice with the same input. 48 | ../bin/quickstream\ 49 | --exit-on-error\ 50 | -v 5\ 51 | --threads 2\ 52 | --block file/PipeIn in0\ 53 | --block file/FileOut out\ 54 | --configure-mk MK in0 Program cat $inFile MK\ 55 | --configure-mk MK in0 AtStart True MK\ 56 | --connect in0 output 0 out input 0\ 57 | --start\ 58 | --wait-for-stream\ 59 | --start\ 60 | --wait-for-stream > $outFile 61 | 62 | 63 | # The input is doubled. 64 | cat $inFile $inFile > $compFile 65 | diff -q $compFile $outFile 66 | 67 | 68 | # cleanup 69 | rm $inFile $outFile $compFile 70 | 71 | -------------------------------------------------------------------------------- /tests/618_PipeOut: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | inFile="data_$(basename $0)_in.tmp" 7 | outFile="data_$(basename $0)_out.tmp" 8 | 9 | 10 | dd if=/dev/urandom count=19 of=$inFile 11 | 12 | 13 | ../bin/quickstream\ 14 | --exit-on-error\ 15 | -v 5\ 16 | --threads 1\ 17 | --block file/FileIn in0\ 18 | --block file/PipeOut out\ 19 | --configure-mk MK out Program cat - MK\ 20 | --configure-mk MK out SignalNum 0 MK\ 21 | --connect in0 output 0 out input 0\ 22 | --start\ 23 | --wait-for-stream < $inFile > $outFile 24 | 25 | 26 | diff $inFile $outFile 27 | 28 | rm $inFile $outFile 29 | -------------------------------------------------------------------------------- /tests/630_runFile: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | # block runFile has a qsAddRunFile("_run.so") in it. 9 | # and _run.so is in the same directory as runFile.so. 10 | 11 | # This tests a lot more than you would think, at first glance. 12 | 13 | ../bin/quickstream\ 14 | --exit-on-error\ 15 | -v 5\ 16 | --threads 2\ 17 | --block runFile B0\ 18 | --block runFile B1\ 19 | --block runFile B2\ 20 | --block misc/NullSink out\ 21 | --connect B0 output 0 out input 0\ 22 | --connect B1 output 0 out input 1\ 23 | --connect B2 output 0 out input 2\ 24 | --start\ 25 | --wait-for-stream\ 26 | --start\ 27 | --wait-for-stream 28 | 29 | 30 | 31 | ../bin/quickstream\ 32 | --exit-on-error\ 33 | -v 5\ 34 | --threads 2\ 35 | --block runFileNoCopy b0\ 36 | --block runFileNoCopy b1\ 37 | --block runFileNoCopy b2\ 38 | --block misc/NullSink out\ 39 | --connect b0 output 0 out input 0\ 40 | --connect b1 output 0 out input 1\ 41 | --connect b2 output 0 out input 2\ 42 | --start\ 43 | --wait-for-stream\ 44 | --start\ 45 | --wait-for-stream 46 | -------------------------------------------------------------------------------- /tests/720_interBlockJob: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | # Good to check with ValGrind and make sure memory of the 10 | # interBlock callback thingy is cleaned up when the graph 11 | # is automatically cleaned up; without doing anything but 12 | # creating it. 13 | 14 | 15 | ../bin/quickstream\ 16 | --exit-on-error\ 17 | -v 5\ 18 | --block interBlockJob 19 | 20 | 21 | ../bin/quickstream\ 22 | --exit-on-error\ 23 | -v 5\ 24 | --block interBlockJob b0\ 25 | --block interBlockJob b1\ 26 | --wait 0.001 27 | 28 | 29 | # halt the worker threads until all the blocks are loaded. 30 | # That way all the blocks can participate in the game 31 | # of pass in a circle from b0 to b5 to b4 to b3 to b2 to b1 and 32 | # back to b0 to b5 to ... on until a counter gets above some 33 | # value. 34 | # 35 | ../bin/quickstream\ 36 | --exit-on-error\ 37 | -v 5\ 38 | --threads 3\ 39 | --halt\ 40 | --block interBlockJob b0\ 41 | --block interBlockJob b1\ 42 | --block interBlockJob b2\ 43 | --block interBlockJob b3\ 44 | --block interBlockJob b4\ 45 | --block interBlockJob b5\ 46 | --unhalt\ 47 | --wait 0.001 48 | 49 | -------------------------------------------------------------------------------- /tests/750_qsGetMemory: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | 10 | ../bin/quickstream\ 11 | --exit-on-error\ 12 | -v 5\ 13 | --block sharedMem b0\ 14 | --block sharedMem\ 15 | --block sharedMem\ 16 | --block sharedMem\ 17 | --block sharedMem\ 18 | --block sharedMem\ 19 | --block sharedMem\ 20 | --block sharedMem\ 21 | --block sharedMem 22 | 23 | -------------------------------------------------------------------------------- /tests/780_largeStreamVaryThreads: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | set -ex 5 | 6 | 7 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 8 | 9 | 10 | if [ -n "${VaLGRIND_RuN}" ] ; then 11 | # skip testing with valgrind 12 | exit 123 13 | fi 14 | 15 | 16 | bytes=0 17 | 18 | 19 | ../bin/quickstream\ 20 | --exit-on-error\ 21 | -v 5\ 22 | --threads 10 tp1\ 23 | --threads 1 tp0\ 24 | --block sequenceGen i\ 25 | --block sequenceCheck o\ 26 | --block passThrough p1\ 27 | --block passThrough p2\ 28 | --block sequenceCheck p3\ 29 | --block passThrough p4\ 30 | --block passThrough p5\ 31 | --configure-mk MK i TotalOutputBytes $bytes MK\ 32 | --configure-mk MK o TotalOutputBytes $bytes MK\ 33 | --configure-mk MK p3 TotalOutputBytes $bytes MK\ 34 | --configure-mk MK p3 PassThrough 0 MK\ 35 | --configure-mk MK i Seeds 1 2 3 4 MK\ 36 | --configure-mk MK o Seeds 1 2 3 4 MK\ 37 | --configure-mk MK p3 Seeds 1 2 4 MK\ 38 | --connect p3 output 2 p3 input 3\ 39 | --connect p3 output 3 p3 input 4\ 40 | --connect i output 3 p3 input 2\ 41 | --connect i output 2 o input 2\ 42 | --connect i output 0 p1 input 0\ 43 | --connect p1 output 0 p2 input 0\ 44 | --connect p2 output 0 p3 input 0\ 45 | --connect p3 output 0 p4 input 0\ 46 | --connect p3 output 1 p1 input 1\ 47 | --connect p4 output 0 p5 input 0\ 48 | --connect p5 output 0 o input 0\ 49 | --connect p1 output 1 p1 input 2\ 50 | --connect p1 output 2 p1 input 3\ 51 | --connect p1 output 3 o input 1\ 52 | --connect i output 1 p3 input 1\ 53 | --start\ 54 | --wait 0.003\ 55 | --threads 5 tp0\ 56 | --wait 0.002\ 57 | --threads 1 tp0\ 58 | --threads-add tp1 i o p1 p2 p3 p4\ 59 | --wait 0.004 60 | 61 | -------------------------------------------------------------------------------- /tests/840_streamAndSetterGetter: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --threads 1\ 13 | --block sequenceGen b0\ 14 | --block passThroughCount b1\ 15 | --block sequenceCheck b2\ 16 | --block setterPrintUint64 p\ 17 | --connect b0 output 0 b1 input 0\ 18 | --connect b1 output 0 b2 input 0\ 19 | --connect p setter value b1 getter trigger\ 20 | --configure-mk MK b0 TotalOutputBytes 0 MK\ 21 | --configure-mk MK b1 triggerCount 1000 MK\ 22 | --configure-mk MK b1 quitCount 80000 MK\ 23 | --configure-mk MK b2 TotalOutputBytes 0 MK\ 24 | --start\ 25 | --wait-for-stream 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /tests/850_loadSuperBlock: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | 10 | ../bin/quickstream\ 11 | --exit-on-error\ 12 | -v 5\ 13 | --threads 1\ 14 | --block superBlock b0\ 15 | --start\ 16 | --wait-for-stream 17 | 18 | 19 | ../bin/quickstream\ 20 | --exit-on-error\ 21 | -v 5\ 22 | --threads 1\ 23 | --block superBlock b0\ 24 | --block superBlock b1\ 25 | --start\ 26 | --wait-for-stream\ 27 | --start\ 28 | --wait-for-stream 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/852_loadSuperBlock: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | set -ex 5 | 6 | # Holy shit, this actually works with valgrind. 7 | 8 | 9 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 10 | 11 | 12 | ../bin/quickstream\ 13 | --exit-on-error\ 14 | --graph g0 1 tp0 superBlock2\ 15 | --start\ 16 | --wait-for-stream 17 | 18 | -------------------------------------------------------------------------------- /tests/854_emptySuperBlock: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | 10 | ../bin/quickstream\ 11 | --exit-on-error\ 12 | -v 5\ 13 | --threads 1\ 14 | --block emptySuperBlock 15 | 16 | 17 | ../bin/quickstream\ 18 | --exit-on-error\ 19 | -v 5\ 20 | --graph g0 2 tp emptySuperBlock 21 | 22 | -------------------------------------------------------------------------------- /tests/860_saveSuperBlock: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [ -n "${VaLGRIND_RuN}" ] ; then 6 | # skip testing with valgrind 7 | exit 123 8 | fi 9 | 10 | 11 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 12 | 13 | # Write this test file 14 | superBlockName="data_$(basename $0).tmp" 15 | 16 | rm -f ${superBlockName}.c ${superBlockName}.so 17 | 18 | 19 | ../bin/quickstream\ 20 | --exit-on-error\ 21 | -v 5\ 22 | --threads 1\ 23 | --block sequenceGen b0\ 24 | --block passThroughCount b1\ 25 | --block sequenceCheck b2\ 26 | --block setterPrintUint64 p\ 27 | --connect b0 output 0 b1 input 0\ 28 | --connect b1 output 0 b2 input 0\ 29 | --connect p setter value b1 getter trigger\ 30 | --configure-mk MK b0 TotalOutputBytes 0 MK\ 31 | --configure-mk MK b1 triggerCount 1000 MK\ 32 | --configure-mk MK b1 quitCount 80000 MK\ 33 | --configure-mk MK b2 TotalOutputBytes 0 MK\ 34 | --save-block ${superBlockName} 35 | 36 | 37 | rm ${superBlockName}.c ${superBlockName}.so 38 | 39 | -------------------------------------------------------------------------------- /tests/865_saveAndRunSuperBlock: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Save super blocks and than load them. 4 | # 5 | # This test takes a longer time to run than most. 6 | 7 | 8 | set -ex 9 | 10 | if [ -n "${VaLGRIND_RuN}" ] ; then 11 | # skip testing with valgrind 12 | exit 123 13 | fi 14 | 15 | 16 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 17 | 18 | # Write this test file 19 | superBlockName="data_$(basename $0).tmp" 20 | 21 | rm -f\ 22 | ${superBlockName}.c\ 23 | ${superBlockName}.so\ 24 | ${superBlockName}2.c\ 25 | ${superBlockName}2.so 26 | 27 | 28 | ../bin/quickstream\ 29 | --exit-on-error\ 30 | -v 5\ 31 | --graph g0 1\ 32 | --save-config\ 33 | --block sequenceGen b0\ 34 | --block passThroughCount b1\ 35 | --block sequenceCheck b2\ 36 | --block setterPrintUint64 p\ 37 | --make-port-alias b2 output 0 out\ 38 | --make-port-alias b2 input 0 in0\ 39 | --connect b0 output 0 b1 input 0\ 40 | --connect b1 output 0 g0 input in0\ 41 | --connect p setter value b1 getter trigger\ 42 | --configure-mk MK b0 TotalOutputBytes 0 MK\ 43 | --configure-mk MK b1 triggerCount 100 MK\ 44 | --configure-mk MK b1 quitCount 8100 MK\ 45 | --configure-mk MK b2 TotalOutputBytes 0 MK\ 46 | --save-block ${superBlockName} 47 | 48 | 49 | ../bin/quickstream\ 50 | --exit-on-error\ 51 | --block ${superBlockName}\ 52 | --save-block ${superBlockName}2 53 | 54 | 55 | ../bin/quickstream\ 56 | --exit-on-error\ 57 | --block ${superBlockName}2\ 58 | --start\ 59 | --wait-for-stream 60 | 61 | 62 | rm ${superBlockName}.c\ 63 | ${superBlockName}.so\ 64 | ${superBlockName}2.c\ 65 | ${superBlockName}2.so 66 | 67 | -------------------------------------------------------------------------------- /tests/870_superSuperLoad: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | set -ex 5 | 6 | 7 | # NOTE: with --graph g0 1 changed to --graph g0 3 8 | # this test fails when running with valgrind. 9 | # 10 | # like; 11 | # 12 | # ./valgrind_run_tests 870_superSuperLoad 13 | # 14 | 15 | 16 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 17 | 18 | 19 | ../bin/quickstream\ 20 | --exit-on-error\ 21 | -v 5\ 22 | --graph g0 1\ 23 | --save-config\ 24 | --block superSuperBlock b0\ 25 | --start\ 26 | --wait-for-stream 27 | 28 | 29 | ../bin/quickstream\ 30 | --exit-on-error\ 31 | --graph g0 1 tp0 superSuperBlock\ 32 | --start\ 33 | --wait-for-stream 34 | 35 | -------------------------------------------------------------------------------- /tests/871_superSuperSaveLoad: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Save super blocks and than load them. 4 | # 5 | # This test takes a longer time to run than most. 6 | 7 | 8 | set -ex 9 | 10 | if [ -n "${VaLGRIND_RuN}" ] ; then 11 | # skip testing with valgrind 12 | exit 123 13 | fi 14 | 15 | 16 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 17 | 18 | # Write this test file 19 | superBlockName="data_$(basename $0).tmp" 20 | 21 | rm -f\ 22 | ${superBlockName}.c\ 23 | ${superBlockName}.so 24 | 25 | 26 | ../bin/quickstream\ 27 | --exit-on-error\ 28 | -v 5\ 29 | --graph g0 1\ 30 | --save-config\ 31 | --block superSuperBlock b0\ 32 | --save-block ${superBlockName} 33 | 34 | 35 | ../bin/quickstream\ 36 | --exit-on-error\ 37 | --block ${superBlockName}\ 38 | --start\ 39 | --wait-for-stream 40 | 41 | 42 | ../bin/quickstream\ 43 | --exit-on-error\ 44 | --graph g0 1 tp0 ${superBlockName}\ 45 | --start\ 46 | --wait-for-stream 47 | 48 | 49 | 50 | rm ${superBlockName}.c\ 51 | ${superBlockName}.so 52 | 53 | -------------------------------------------------------------------------------- /tests/881_saveGraph: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | set -ex 5 | 6 | if [ -n "${VaLGRIND_RuN}" ] ; then 7 | # Skip running with ValGrind. 8 | exit 123 9 | fi 10 | 11 | 12 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 13 | 14 | # Write this test file 15 | F="data_$(basename $0).tmp" 16 | 17 | rm -f $F $F.c $F.so 18 | 19 | 20 | ../bin/quickstream\ 21 | --exit-on-error\ 22 | -v 5\ 23 | --threads 1\ 24 | --block sequenceGen b0\ 25 | --block passThrough b1\ 26 | --threads 3 tp3\ 27 | --block passThroughCount b2\ 28 | --block sequenceCheck b3\ 29 | --block setterPrintUint64 p\ 30 | --connect b0 output 0 b1 input 0\ 31 | --connect b1 output 0 b2 input 0\ 32 | --connect b2 output 0 b3 input 0\ 33 | --connect p setter value b2 getter trigger\ 34 | --configure-mk MK b0 TotalOutputBytes 0 MK\ 35 | --configure-mk MK b2 triggerCount 1000 MK\ 36 | --configure-mk MK b2 quitCount 80000 MK\ 37 | --configure-mk MK b3 TotalOutputBytes 0 MK\ 38 | --save ${F} 39 | 40 | export PATH="${PATH}:../bin" 41 | 42 | ./$F 43 | 44 | 45 | rm $F $F.c $F.so 46 | 47 | 48 | 49 | ../bin/quickstream\ 50 | --exit-on-error\ 51 | -v 5\ 52 | --graph g 2 tp superBlock2\ 53 | --save ${F}\ 54 | --start\ 55 | --wait-for-stream 56 | 57 | 58 | rm $F $F.c $F.so 59 | 60 | -------------------------------------------------------------------------------- /tests/883_renameBlock: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | set -ex 5 | 6 | 7 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 8 | 9 | 10 | ../bin/quickstream\ 11 | --exit-on-error\ 12 | -v 5\ 13 | --graph g0 1\ 14 | --save-config\ 15 | --block superSuperBlock b0\ 16 | --rename-block b0 b123\ 17 | --start\ 18 | --wait-for-stream 19 | 20 | exit 21 | 22 | # This is the version of this test that shows more, 23 | # but is not a quick and non-interactive test. 24 | 25 | ../bin/quickstream\ 26 | --exit-on-error\ 27 | -v 5\ 28 | --graph g0 1\ 29 | --save-config\ 30 | --block superSuperBlock b0\ 31 | --display\ 32 | --rename-block b0 b123\ 33 | --display\ 34 | --start\ 35 | --wait-for-stream 36 | 37 | -------------------------------------------------------------------------------- /tests/890_multiGraph: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | # Note: superBlock2 destroys its graph after it runs the stream. 10 | 11 | 12 | ../bin/quickstream\ 13 | --exit-on-error\ 14 | -v 5\ 15 | --graph g0 1 tp0\ 16 | --block superBlock b0\ 17 | --graph g1 1 tp1 superBlock2\ 18 | --graph g0\ 19 | --start\ 20 | --graph g1\ 21 | --start\ 22 | --wait-for-stream\ 23 | --graph g0\ 24 | --wait-for-stream 25 | 26 | -------------------------------------------------------------------------------- /tests/896_metaData: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --threads 1\ 13 | --block sequenceGen b0\ 14 | --block sequenceCheck b1\ 15 | --connect b0 output 0 b1 input 0\ 16 | --add-metadata-mk MK key 1234 this is metadata 1234 MK\ 17 | --print-metadata key 18 | 19 | 20 | # stupid test block with meta data in it that is base64 encoded in the 21 | # super block DSO file. 22 | 23 | ../bin/quickstream\ 24 | --exit-on-error\ 25 | -v 5\ 26 | --graph g0 1 tp0 superBlock_withMetaData\ 27 | --print-metadata key0\ 28 | --print-metadata key1 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/898_metaDataReload: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [ -n "${VaLGRIND_RuN}" ] ; then 6 | # skip testing with valgrind 7 | exit 123 8 | fi 9 | 10 | 11 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 12 | 13 | # Write this test file 14 | superBlockName="data_$(basename $0).tmp" 15 | 16 | rm -f ${superBlockName}.c ${superBlockName}.so 17 | 18 | 19 | ../bin/quickstream\ 20 | --exit-on-error\ 21 | -v 5\ 22 | --threads 1\ 23 | --block sequenceGen b0\ 24 | --block sequenceCheck b1\ 25 | --connect b0 output 0 b1 input 0\ 26 | --add-metadata-mk MK key0 1234 this is metadata 1234 MK\ 27 | --add-metadata-mk MK key1 4321 this is more metadata 4321 MK\ 28 | --print-metadata key0\ 29 | --save-block ${superBlockName} 30 | 31 | 32 | ../bin/quickstream\ 33 | --exit-on-error\ 34 | --graph g0 1 tp0 ${superBlockName}\ 35 | --print-metadata key0\ 36 | --print-metadata key1 37 | 38 | 39 | rm ${superBlockName}.c ${superBlockName}.so 40 | 41 | 42 | -------------------------------------------------------------------------------- /tests/920_epoll: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | # For now, we have not finished writing the code yet so: 6 | if ! ../bin/quickstream\ 7 | --exit-on-error\ 8 | -v 5\ 9 | --block Epoll epoll ; then 10 | echo "Success" 11 | exit 0 12 | fi 13 | 14 | exit 1 # fail 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/SearchArray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "../lib/SearchArray.h" 6 | 7 | 8 | int main(void) { 9 | 10 | 11 | #define NX 25 12 | #define NY 22 13 | 14 | int x[NX] = 15 | { -23, -7, 0, 0, 2, 16 | 2, 6, 6, 7, 8, 17 | 8, 9, 9, 12, 12, 18 | 12, 12, 23, 34, 40, 19 | 41, 42, 43, 50, 56 20 | }; 21 | 22 | int y[NY] = { 23 | -283, -24, -23, -22, -7, 24 | -6, 0, 6, 7, 8, 25 | 8, 9, 9, 12, 33, 26 | 34, 50, 54, 55, 56, 27 | 57, 1000 28 | }; 29 | 30 | printf(" Searching in:"); 31 | for(int i = 0; i < NX; ++i) 32 | printf(" %d", x[i]); 33 | printf("\n"); 34 | 35 | printf("Searching for:"); 36 | for(int i = 0; i < NY; ++i) 37 | printf(" %d", y[i]); 38 | printf("\n"); 39 | 40 | printf("\n"); 41 | for(int i = 0; i < NY; ++i) 42 | printf(" %d => %d\n", y[i], FindNearestInArray(y[i], x, NX)); 43 | printf("\n"); 44 | 45 | return 0; 46 | } 47 | 48 | -------------------------------------------------------------------------------- /tests/_042_waitForever: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | echo -e "\nThis test should hang forever\n\n" 10 | 11 | 12 | ../bin/quickstream\ 13 | --exit-on-error\ 14 | -v 5\ 15 | --graph\ 16 | --wait 17 | -------------------------------------------------------------------------------- /tests/_043_wait5: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | function Wait() { 10 | 11 | set +x 12 | echo -e "\nWait $1\n" 13 | set -x 14 | 15 | ../bin/quickstream\ 16 | --exit-on-error\ 17 | -v 5\ 18 | --graph\ 19 | --wait $1 20 | } 21 | 22 | 23 | Wait 0.01 24 | Wait 0.01 25 | Wait 0.999 26 | Wait 5 27 | -------------------------------------------------------------------------------- /tests/_542_loops: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | 10 | ../bin/quickstream\ 11 | --exit-on-error\ 12 | -v 5\ 13 | --graph g0 1\ 14 | --block sequenceGen b0\ 15 | --block sequenceCheck b1\ 16 | --block sequenceCheck b2\ 17 | --configure-mk MK b0 Seeds 22 MK\ 18 | --configure-mk MK b1 Seeds 22 MK\ 19 | --configure-mk MK b2 Seeds 22 MK\ 20 | --configure-mk MK b0 TotalOutputBytes 0 MK\ 21 | --configure-mk MK b1 TotalOutputBytes 0 MK\ 22 | --configure-mk MK b2 TotalOutputBytes 0 MK\ 23 | --connect b0 output 0 b1 input 0\ 24 | --connect b1 output 0 b1 input 1\ 25 | --connect b1 output 1 b1 input 2\ 26 | --connect b1 output 2 b1 input 3\ 27 | --connect b1 output 3 b2 input 0\ 28 | --connect b2 output 0 b1 input 4\ 29 | --connect b2 output 0 b1 input 5\ 30 | --connect b2 output 0 b2 input 1\ 31 | --start\ 32 | --catch-sig\ 33 | --sleep 4\ 34 | --stop\ 35 | --start\ 36 | --catch-sig\ 37 | --sleep 4 38 | 39 | -------------------------------------------------------------------------------- /tests/_550_spewForever: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block sequenceGen b0\ 13 | --block sequenceCheck b1\ 14 | --block stdout out\ 15 | --connect b0 output 0 b1 input 0\ 16 | --connect b1 output 0 out input 0\ 17 | --configure-mk MK b0 TotalOutputBytes 0 MK\ 18 | --configure-mk MK b1 TotalOutputBytes 0 MK\ 19 | --start\ 20 | --catch-sig 2\ 21 | --sleep 22 | 23 | -------------------------------------------------------------------------------- /tests/_553_spewSleepStop: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block sequenceGen b0\ 13 | --block sequenceCheck b1\ 14 | --block stdout out\ 15 | --connect b0 output 0 b1 input 0\ 16 | --connect b1 output 0 out input 0\ 17 | --configure-mk MK b0 TotalOutputBytes 0 MK\ 18 | --configure-mk MK b1 TotalOutputBytes 0 MK\ 19 | --start\ 20 | --sleep 1\ 21 | --stop\ 22 | --sleep 1\ 23 | --start\ 24 | --sleep 1 25 | 26 | 27 | -------------------------------------------------------------------------------- /tests/_554_spewFileForever: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | ../bin/quickstream\ 10 | --exit-on-error\ 11 | -v 5\ 12 | --block stdin In\ 13 | --block stdout out\ 14 | --connect In output 0 out input 0\ 15 | --start\ 16 | --catch-sig 2\ 17 | --sleep < /dev/urandom | hexdump -v 18 | 19 | -------------------------------------------------------------------------------- /tests/_603_printDot1: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | # 2 graphs 10 | 11 | ../bin/quickstream\ 12 | --exit-on-error\ 13 | -v 5\ 14 | --block lotsOfPorts b1\ 15 | --block lotsOfPorts b2\ 16 | --connect b1 getter freq1 b2 setter freq1\ 17 | --connect b1 getter freq1 b2 setter freq2\ 18 | --connect b1 getter freq1 b2 setter freq3\ 19 | --connect b2 getter gain b2 setter gain\ 20 | --connect b1 setter gain b2 setter gain\ 21 | --connect b1 input 0 b2 output 0\ 22 | --connect b1 input 1 b2 output 0\ 23 | --connect b1 input 2 b2 output 0\ 24 | --connect b1 input 3 b2 output 0\ 25 | --connect b2 input 0 b1 output 0\ 26 | --connect b2 input 1 b1 output 0\ 27 | --connect b2 input 2 b1 output 0\ 28 | --connect b2 input 3 b1 output 0\ 29 | --disconnect b2 input 2\ 30 | --graph\ 31 | --block add1 add\ 32 | --display 33 | 34 | exit 0 35 | 36 | 37 | ../bin/quickstream\ 38 | --exit-on-error\ 39 | -v 5\ 40 | --block add1 b1\ 41 | --block add1 b2\ 42 | --connect b1 getter add b2 setter add\ 43 | --display 44 | 45 | exit 0 46 | 47 | 48 | 49 | 50 | # no graphs 51 | 52 | ../bin/quickstream\ 53 | --exit-on-error\ 54 | -v 5\ 55 | --display 56 | 57 | exit 0 58 | 59 | 60 | -------------------------------------------------------------------------------- /tests/_710_passThroughFail: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 7 | 8 | 9 | if [ -n "${VaLGRIND_RuN}" ] ; then 10 | # skip testing with valgrind 11 | exit 123 12 | fi 13 | 14 | 15 | # this fails with ASSERT 16 | # 17 | # TODO: We need to add more failure modes to the quickstream API 18 | # so that this fails at the "--configure-mk MK p1 PassThrough t MK\" 19 | ../bin/quickstream\ 20 | --exit-on-error\ 21 | -v 5\ 22 | --block sequenceGen b0\ 23 | --block sequenceCheck p1\ 24 | --block sequenceCheck b2\ 25 | --configure-mk MK b0 Seeds 4 MK\ 26 | --configure-mk MK p1 Seeds 4 MK\ 27 | --configure-mk MK b2 Seeds 4 MK\ 28 | --connect b0 output 0 p1 input 0\ 29 | --connect b0 output 0 p1 input 1\ 30 | --connect p1 output 0 b2 input 0\ 31 | --connect p1 output 1 b2 input 1\ 32 | --configure-mk MK p1 PassThrough t MK\ 33 | --start\ 34 | --wait\ 35 | --start\ 36 | --wait 37 | 38 | 39 | 40 | # this fails with ASSERT 41 | # 42 | # TODO: We need to add more failure modes to the quickstream API 43 | # so that this fails at the "--connect in0 output 0 p1 input 1" 44 | # or "--connect p1 output 1 b2 input 1" 45 | ../bin/quickstream\ 46 | --exit-on-error\ 47 | -v 5\ 48 | --block sequenceGen in0\ 49 | --block passThrough p1\ 50 | --block sequenceCheck b2\ 51 | --connect in0 output 0 p1 input 0\ 52 | --connect in0 output 0 p1 input 1\ 53 | --connect p1 output 0 b2 input 0\ 54 | --connect p1 output 1 b2 input 1\ 55 | --start\ 56 | --wait\ 57 | --start\ 58 | --wait 59 | 60 | 61 | 62 | # this passes 63 | ../bin/quickstream\ 64 | --exit-on-error\ 65 | -v 5\ 66 | --block sequenceGen in0\ 67 | --block passThrough p1\ 68 | --block sequenceCheck b2\ 69 | --connect in0 output 0 p1 input 0\ 70 | --connect in0 output 1 p1 input 1\ 71 | --connect p1 output 0 b2 input 0\ 72 | --connect p1 output 1 b2 input 1\ 73 | --start\ 74 | --wait\ 75 | --start\ 76 | --wait 77 | 78 | -------------------------------------------------------------------------------- /tests/_770_largeStream30Seconds: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This takes 30 seconds to run on my computer: 4 | # Fri Apr 14 10:57:25 AM EDT 2023 5 | # It's a relatively bad ass machine from that period 6 | # AMD Ryzen 7 2700X (16) @ 3.700GHz 7 | # Memory: 32049MiB 8 | 9 | set -ex 10 | 11 | 12 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 13 | 14 | 15 | if [ -n "${VaLGRIND_RuN}" ] ; then 16 | # skip testing with valgrind 17 | exit 123 18 | fi 19 | 20 | 21 | # measured run time of about 30 seconds 22 | bytes=20100100 23 | 24 | 25 | ../bin/quickstream\ 26 | --exit-on-error\ 27 | -v 5\ 28 | --threads 3 foo3\ 29 | --block sequenceGen i\ 30 | --block sequenceCheck o\ 31 | --block passThrough p1\ 32 | --block passThrough p2\ 33 | --block sequenceCheck p3\ 34 | --block passThrough p4\ 35 | --block passThrough p5\ 36 | --configure-mk MK i TotalOutputBytes $bytes MK\ 37 | --configure-mk MK o TotalOutputBytes $bytes MK\ 38 | --configure-mk MK p3 TotalOutputBytes $bytes MK\ 39 | --configure-mk MK p3 PassThrough 0 MK\ 40 | --configure-mk MK i Seeds 1 2 3 4 MK\ 41 | --configure-mk MK o Seeds 1 2 3 4 MK\ 42 | --configure-mk MK p3 Seeds 1 2 4 MK\ 43 | --connect p3 output 2 p3 input 3\ 44 | --connect p3 output 3 p3 input 4\ 45 | --connect i output 3 p3 input 2\ 46 | --connect i output 2 o input 2\ 47 | --connect i output 0 p1 input 0\ 48 | --connect p1 output 0 p2 input 0\ 49 | --connect p2 output 0 p3 input 0\ 50 | --connect p3 output 0 p4 input 0\ 51 | --connect p3 output 1 p1 input 1\ 52 | --connect p4 output 0 p5 input 0\ 53 | --connect p5 output 0 o input 0\ 54 | --connect p1 output 1 p1 input 2\ 55 | --connect p1 output 2 p1 input 3\ 56 | --connect p1 output 3 o input 1\ 57 | --connect i output 1 p3 input 1\ 58 | --start\ 59 | --wait\ 60 | --start\ 61 | --wait 62 | 63 | -------------------------------------------------------------------------------- /tests/_772_largeStream30SecDisp: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This takes 30 seconds to run on my computer: 4 | # Fri Apr 14 10:57:25 AM EDT 2023 5 | # It's a relatively bad ass machine from that period 6 | # AMD Ryzen 7 2700X (16) @ 3.700GHz 7 | # Memory: 32049MiB 8 | 9 | set -ex 10 | 11 | 12 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 13 | 14 | 15 | if [ -n "${VaLGRIND_RuN}" ] ; then 16 | # skip testing with valgrind 17 | exit 123 18 | fi 19 | 20 | 21 | bytes=20100100 22 | 23 | 24 | ../bin/quickstream\ 25 | --exit-on-error\ 26 | -v 5\ 27 | --threads 3 foo3\ 28 | --block sequenceGen i\ 29 | --block sequenceCheck o\ 30 | --block passThrough p1\ 31 | --block passThrough p2\ 32 | --block sequenceCheck p3\ 33 | --block passThrough p4\ 34 | --block passThrough p5\ 35 | --configure-mk MK i TotalOutputBytes $bytes MK\ 36 | --configure-mk MK o TotalOutputBytes $bytes MK\ 37 | --configure-mk MK p3 TotalOutputBytes $bytes MK\ 38 | --configure-mk MK p3 PassThrough 0 MK\ 39 | --configure-mk MK i Seeds 1 2 3 4 MK\ 40 | --configure-mk MK o Seeds 1 2 3 4 MK\ 41 | --configure-mk MK p3 Seeds 1 2 4 MK\ 42 | --connect p3 output 2 p3 input 3\ 43 | --connect p3 output 3 p3 input 4\ 44 | --connect i output 3 p3 input 2\ 45 | --connect i output 2 o input 2\ 46 | --connect i output 0 p1 input 0\ 47 | --connect p1 output 0 p2 input 0\ 48 | --connect p2 output 0 p3 input 0\ 49 | --connect p3 output 0 p4 input 0\ 50 | --connect p3 output 1 p1 input 1\ 51 | --connect p4 output 0 p5 input 0\ 52 | --connect p5 output 0 o input 0\ 53 | --connect p1 output 1 p1 input 2\ 54 | --connect p1 output 2 p1 input 3\ 55 | --connect p1 output 3 o input 1\ 56 | --connect i output 1 p3 input 1\ 57 | --display\ 58 | --start\ 59 | --wait\ 60 | --start\ 61 | --wait 62 | 63 | -------------------------------------------------------------------------------- /tests/_781_largeStreamVaryThreads: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # run "htop" and see the number of threads change while the 4 | # stream runs continuously. 5 | 6 | 7 | set -ex 8 | 9 | 10 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 11 | 12 | 13 | if [ -n "${VaLGRIND_RuN}" ] ; then 14 | # skip testing with valgrind 15 | exit 123 16 | fi 17 | 18 | 19 | bytes=0 20 | 21 | 22 | ../bin/quickstream\ 23 | --exit-on-error\ 24 | -v 5\ 25 | --threads 10 tp1\ 26 | --threads 1 tp0\ 27 | --block sequenceGen i\ 28 | --block sequenceCheck o\ 29 | --block passThrough p1\ 30 | --block passThrough p2\ 31 | --block sequenceCheck p3\ 32 | --block passThrough p4\ 33 | --block passThrough p5\ 34 | --configure-mk MK i TotalOutputBytes $bytes MK\ 35 | --configure-mk MK o TotalOutputBytes $bytes MK\ 36 | --configure-mk MK p3 TotalOutputBytes $bytes MK\ 37 | --configure-mk MK p3 PassThrough 0 MK\ 38 | --configure-mk MK i Seeds 1 2 3 4 MK\ 39 | --configure-mk MK o Seeds 1 2 3 4 MK\ 40 | --configure-mk MK p3 Seeds 1 2 4 MK\ 41 | --connect p3 output 2 p3 input 3\ 42 | --connect p3 output 3 p3 input 4\ 43 | --connect i output 3 p3 input 2\ 44 | --connect i output 2 o input 2\ 45 | --connect i output 0 p1 input 0\ 46 | --connect p1 output 0 p2 input 0\ 47 | --connect p2 output 0 p3 input 0\ 48 | --connect p3 output 0 p4 input 0\ 49 | --connect p3 output 1 p1 input 1\ 50 | --connect p4 output 0 p5 input 0\ 51 | --connect p5 output 0 o input 0\ 52 | --connect p1 output 1 p1 input 2\ 53 | --connect p1 output 2 p1 input 3\ 54 | --connect p1 output 3 o input 1\ 55 | --connect i output 1 p3 input 1\ 56 | --display\ 57 | --start\ 58 | --wait 7\ 59 | --threads 5 tp0\ 60 | --wait 7\ 61 | --threads 1 tp0\ 62 | --wait 7\ 63 | --threads-add tp1 i o p1 p2 p3 p4\ 64 | --wait 7\ 65 | --threads-destroy tp1\ 66 | --wait 10 67 | 68 | -------------------------------------------------------------------------------- /tests/_810_buttonStopStart: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | if [ ! -x ../lib/quickstream/blocks/gtk3/button.so ] ; then 7 | # We skip this test if a module is not built. 8 | set +x 9 | echo "skipping: ${BASH_SOURCE[0]}" 10 | exit 123 11 | fi 12 | 13 | 14 | export QS_BLOCK_PATH=../lib/quickstream/misc 15 | 16 | 17 | ../bin/quickstream\ 18 | --exit-on-error\ 19 | -v 5\ 20 | --threads 1\ 21 | --block gtk3/base gtk\ 22 | --block gtk3/button button\ 23 | --block test_blocks/sequenceGen gen\ 24 | --block test_blocks/stdout out\ 25 | --block test_blocks/destroyGraph destroy\ 26 | --block runner/run run\ 27 | --configure-mk MK gen TotalOutputBytes 0 MK\ 28 | --connect gen output 0 out input 0\ 29 | --configure-mk MK button label "Run" MK\ 30 | --connect destroy setter destroy gtk getter destroy\ 31 | --connect button getter value run setter run\ 32 | --display\ 33 | --parameter-set-mk MK button show True MK\ 34 | --wait-for-destroy 35 | 36 | -------------------------------------------------------------------------------- /tests/_812_buttons: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | if [ ! -x ../lib/quickstream/blocks/gtk3/base.so ] ; then 7 | # We skip this test if a module is not built. 8 | set +x 9 | echo "skipping ${BASH_SOURCE[0]}: missing build requirement" 10 | exit 123 11 | fi 12 | 13 | 14 | export QS_BLOCK_PATH=../lib/quickstream/misc 15 | 16 | 17 | ../bin/quickstream\ 18 | --exit-on-error\ 19 | -v 5\ 20 | --threads 1\ 21 | --block test_blocks/empty empty\ 22 | --block gtk3/base gtk\ 23 | --block gtk3/button runButton\ 24 | --block gtk3/button exitButton\ 25 | --block gtk3/button extraButton\ 26 | --block test_blocks/sequenceGen gen\ 27 | --block test_blocks/stdout out\ 28 | --configure-mk MK gen TotalOutputBytes 0 MK\ 29 | --connect gen output 0 out input 0\ 30 | --configure-mk MK runButton label "Run" MK\ 31 | --configure-mk MK exitButton label "Quit" MK\ 32 | --configure-mk MK extraButton label "Launch Nukes" MK\ 33 | --block runner/run run\ 34 | --block runner/destroy destroy\ 35 | --connect runButton getter value run setter run\ 36 | --connect exitButton getter value destroy setter destroy\ 37 | --parameter-set-mk MK gtk show True MK\ 38 | --parameter-set-mk MK gtk show False MK 39 | 40 | -------------------------------------------------------------------------------- /tests/_820_slider: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | if [ ! -x ../lib/quickstream/blocks/gtk3/base.so ] ; then 7 | # We skip this test if a module is not built. 8 | set +x 9 | echo "skipping ${BASH_SOURCE[0]}: missing build requirement" 10 | exit 123 11 | fi 12 | 13 | 14 | export QS_BLOCK_PATH=../lib/quickstream/misc 15 | 16 | 17 | ../bin/quickstream\ 18 | --exit-on-error\ 19 | -v 5\ 20 | --threads 1\ 21 | --block gtk3/base gtk\ 22 | --block gtk3/slider slider\ 23 | --block test_blocks/setterPrintDouble pd\ 24 | --configure-mk MK slider label "${USER}-ness" MK\ 25 | --configure-mk MK slider attributes -2.0 -1.9 1.9 2.0 1000000.0 41 11 "%1.1lf MHz" MK\ 26 | --configure-mk MK gtk title "The Big $USER Slider" MK\ 27 | --parameter-set-mk MK slider value 0.5 MK\ 28 | --connect pd setter value slider getter value\ 29 | --display\ 30 | --sleep 0.5\ 31 | --parameter-set-mk MK slider show True MK\ 32 | --wait-for-destroy 33 | 34 | -------------------------------------------------------------------------------- /tests/_830_startStopButton: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | 6 | if [ ! -x ../lib/quickstream/blocks/gtk3/base.so ] ; then 7 | # We skip this test if a module is not built. 8 | set +x 9 | echo "skipping: ${BASH_SOURCE[0]}" 10 | exit 123 11 | fi 12 | 13 | 14 | export QS_BLOCK_PATH=../lib/quickstream/misc/test_blocks 15 | 16 | # This builds a window and then removes and than recreates it. 17 | 18 | ../bin/quickstream\ 19 | --exit-on-error\ 20 | -v 5\ 21 | --threads 1\ 22 | --block gtk3/base gtk\ 23 | --block gtk3/button button\ 24 | --block sequenceGen gen\ 25 | --block stdout out\ 26 | --block runner/run run\ 27 | --block destroyGraph destroy\ 28 | --configure-mk MK gen TotalOutputBytes 0 MK\ 29 | --configure-mk MK button label "Run" MK\ 30 | --configure-mk MK gtk title "Start and Stop" MK\ 31 | --connect gen output 0 out input 0\ 32 | --connect button g value run s run\ 33 | --parameter-set-mk MK gtk show True MK\ 34 | --wait-for-destroy 5\ 35 | --block-unload button\ 36 | --block-unload gtk\ 37 | --sleep 4\ 38 | --block gtk3/base gtk\ 39 | --block gtk3/button button\ 40 | --connect button g value run s run\ 41 | --connect gtk getter destroy destroy setter destroy\ 42 | --parameter-set-mk MK gtk show True MK\ 43 | --wait-for-destroy 44 | 45 | -------------------------------------------------------------------------------- /tests/_906_GNUradio_urandom: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | if [ -n "${VaLGRIND_RuN}" ] ; then 6 | # skip testing with valgrind 7 | exit 123 8 | fi 9 | 10 | 11 | ../bin/quickstream\ 12 | --exit-on-error\ 13 | -v 5\ 14 | --block gnuradio-3.10.1/QT_GNUradio_test b0\ 15 | --start\ 16 | --wait-for-stream\ 17 | --start\ 18 | --wait-for-stream 19 | 20 | -------------------------------------------------------------------------------- /tests/_zerosInFile.c: -------------------------------------------------------------------------------- 1 | // Check every C file in this directory with: 2 | // 3 | // cat *.c | ./_zerosInFile 4 | // 5 | 6 | #include 7 | #include 8 | 9 | 10 | int main(void) { 11 | 12 | char c; 13 | uint64_t len = 0; 14 | uint64_t count = 0; 15 | 16 | // prompt the user what the hell we are doing. 17 | fprintf(stderr, "Reading stdin\n"); 18 | 19 | while((c = getchar()) != EOF) { 20 | ++len; 21 | if(!c) { 22 | ++count; 23 | fprintf(stderr, "The file we read (%" 24 | PRIu64 ") zero " 25 | "in it at character number %" 26 | PRIu64 "\n", count, len); 27 | } 28 | } 29 | 30 | if(!count) 31 | fprintf(stderr, "\nNo zeros found in " 32 | "this file from stdin, file length %" 33 | PRIu64 " bytes\n\n", len); 34 | else 35 | fprintf(stderr, "\nFound %" PRIu64 36 | " zeros from reading stdin\n\n", 37 | count); 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /tests/atomic_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../lib/debug.h" 8 | 9 | 10 | pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 11 | 12 | 13 | //https://www.gnu.org/software/libc/manual/html_node/Atomic-Types.html 14 | // Not a good multi-threaded counter. 15 | //volatile sig_atomic_t iCount = 0; 16 | int iCount = 0; 17 | 18 | 19 | int mCount = 0; 20 | 21 | // This one works. 22 | atomic_uint goodCount = 0; 23 | 24 | 25 | 26 | const int maxCount = 1000000; 27 | 28 | 29 | void *CountUp(void *data) { 30 | 31 | int count = 0; 32 | for(;count 7 | #include 8 | 9 | int main(int argc, char *argv[]) { 10 | 11 | FILE *stream; 12 | char *line = NULL; 13 | size_t len = 0; 14 | ssize_t nread; 15 | 16 | if (argc != 2) { 17 | fprintf(stderr, "Usage: %s \n", argv[0]); 18 | return EXIT_FAILURE; 19 | } 20 | 21 | stream = fopen(argv[1], "r"); 22 | if (stream == NULL) { 23 | perror("fopen"); 24 | return EXIT_FAILURE; 25 | } 26 | 27 | while((nread = getline(&line, &len, stream)) != -1) { 28 | printf("Retrieved line of length %zu:\n", nread); 29 | fwrite(line, nread, 1, stdout); 30 | } 31 | 32 | free(line); 33 | fclose(stream); 34 | return EXIT_SUCCESS; 35 | } 36 | -------------------------------------------------------------------------------- /tests/itimer_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "../lib/debug.h" 7 | 8 | static 9 | int count = 0; 10 | 11 | static 12 | void sighandler(int sig) { 13 | 14 | WARN("caught signal %d count=%d", sig, ++count); 15 | } 16 | 17 | 18 | 19 | int main(void) { 20 | 21 | ASSERT(signal(SIGALRM, sighandler) == 0); 22 | // This is to fix a GCC compiler bug: 23 | // itimer_test.c:9:5: error: ‘count’ defined but not used [-Werror=unused-variable] 24 | // But you can clearly see it is used above. 25 | count = 0; 26 | 27 | #if 0 28 | errno = 0; 29 | struct itimerval it = { { 1/*seconds*/, 0/*microseconds*/ }, { 1,0 }}; 30 | if(setitimer(ITIMER_REAL, &it, 0)) { 31 | ERROR("setitimer(ITIMER_REAL,,) failed"); 32 | return -1; // fail 33 | } 34 | #else 35 | errno = 0; 36 | struct itimerval it = { 37 | { 0/*seconds*/, 100000/*microseconds*/ }, { 0,100000 }}; 38 | if(setitimer(ITIMER_REAL, &it, 0)) { 39 | ERROR("setitimer(ITIMER_REAL,,) failed"); 40 | return -1; // fail 41 | } 42 | #endif 43 | 44 | while(1) { 45 | errno = 0; 46 | pause(); 47 | //ERROR(); 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /tests/malloc_leak.c: -------------------------------------------------------------------------------- 1 | // Testing that valrind can find the memory lead by running this 2 | // with valgrind. 3 | // 4 | // Try running: 5 | // 6 | // ./valgrid_run_tests malloc_leak 7 | 8 | 9 | #include 10 | 11 | int main(void) { 12 | 13 | void *p = malloc(1); 14 | 15 | if(!p) 16 | return 1; 17 | 18 | // We needed a test to test that valgrind is working. 19 | 20 | // No free(ptr) should cause valgrind to fail. 21 | 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /tests/mod.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main(void) { 5 | 6 | uint64_t x = 5; 7 | uint32_t y = 3; 8 | 9 | printf("%" PRIu64 "%c%" PRIu32 "=%" PRIu64 "\n", 10 | x, '%', y, x%y); 11 | 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /tests/pthread_once.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "../lib/debug.h" 8 | 9 | 10 | static pthread_once_t key_once = PTHREAD_ONCE_INIT; 11 | 12 | 13 | // Will this get called twice? 14 | static void make_key(void) { 15 | 16 | ERROR(); 17 | } 18 | 19 | 20 | 21 | int main(void) { 22 | 23 | CHECK(pthread_once(&key_once, make_key)); 24 | CHECK(pthread_once(&key_once, make_key)); 25 | CHECK(pthread_once(&key_once, make_key)); 26 | CHECK(pthread_once(&key_once, make_key)); 27 | CHECK(pthread_once(&key_once, make_key)); 28 | CHECK(pthread_once(&key_once, make_key)); 29 | CHECK(pthread_once(&key_once, make_key)); 30 | 31 | 32 | key_once = PTHREAD_ONCE_INIT; 33 | CHECK(pthread_once(&key_once, make_key)); 34 | CHECK(pthread_once(&key_once, make_key)); 35 | CHECK(pthread_once(&key_once, make_key)); 36 | CHECK(pthread_once(&key_once, make_key)); 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /tests/qt6_fileLeak_test.cpp: -------------------------------------------------------------------------------- 1 | // Ref: https://bugreports.qt.io/browse/QTBUG-122948 2 | // 3 | // This is just a test. We are not looking to optimise this code. 4 | // 5 | // This test has 3 source files required: qt6_fileLeak_test.cpp (this 6 | // file), qt6_fileLeak_DSO.cpp, and qt6_fileLeak_test.h 7 | // 8 | 9 | /* Compile with (in a bash shell): 10 | 11 | g++ -g -Wall -Werror qt6_fileLeak_test.cpp -o qt6_fileLeak_test 12 | 13 | # Check it linked well without Qt6 libraries: 14 | ldd qt6_fileLeak_test 15 | 16 | # I get the following output: 17 | # 18 | # linux-vdso.so.1 (0x00007ffd7d7dc000) 19 | # libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f498e49d000) 20 | # /lib64/ld-linux-x86-64.so.2 (0x00007f498e6a5000) 21 | # 22 | 23 | 24 | */ 25 | 26 | // TODO: Add counting the number of files leaked in a given run. 27 | // 28 | // I've counted 12 every time I've run the loop. 29 | 30 | 31 | 32 | #include 33 | 34 | #include "qt6_fileLeak_test.h" 35 | 36 | 37 | static inline void Run(int argc, char* argv[]) { 38 | 39 | // Run "ls" to list all open files for the process now: 40 | RunLsOnProcFd("Before loading QApplication DSO"); 41 | 42 | const char *dsoFilename = "./qt6_fileLeak_DSO.so"; 43 | 44 | dlerror(); 45 | void *hdl = dlopen(dsoFilename, RTLD_NOW); 46 | if(!hdl) FAIL("dlopen(\"%s\",)-- %s --", dsoFilename, dlerror()); 47 | 48 | RunLsOnProcFd("After loading QApplication DSO and before creating QApplication"); 49 | 50 | void (*RunApp)(int argc, char* argv[]) = 51 | (void (*)(int argc, char* argv[])) dlsym(hdl, "RunApp"); 52 | 53 | if(!RunApp) FAIL("dlsym(,RunApp)"); 54 | 55 | RunApp(argc, argv); 56 | 57 | if(dlclose(hdl) != 0) FAIL("dlclose(%p)", hdl); 58 | 59 | RunLsOnProcFd("After unloading QApplication DSO"); 60 | 61 | printf( 62 | "NOTE: there appears to be 12 files left open that were created\n" 63 | " by creating a QApplication object (you need to count yourself).\n\n"); 64 | } 65 | 66 | 67 | int main(int argc, char* argv[]) { 68 | 69 | const int NUM_LOOPS = 2; 70 | 71 | for(int i=0; i < NUM_LOOPS;) { 72 | Run(argc, argv); 73 | if(++i < NUM_LOOPS) { 74 | printf(" to run again\n"); 75 | getchar(); 76 | } 77 | } 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /tests/qt6_fileLeak_test.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #define FAIL(fmt, ...)\ 11 | do {\ 12 | fprintf(stderr,"\n" fmt " FAILED errno=%d\n\n", ##__VA_ARGS__, errno);\ 13 | exit(1);\ 14 | } while(0) 15 | 16 | 17 | static inline 18 | void RunLsOnProcFd(const char *label) { 19 | 20 | pid_t parentPid = getpid(); 21 | 22 | pid_t pid = fork(); 23 | if(pid == -1) 24 | FAIL("fork()"); 25 | 26 | if(pid) { 27 | // I'm the parent and I'll wait for the child 28 | // to run "ls". 29 | if(pid != waitpid(pid, 0, 0)) 30 | FAIL("waitpid()"); 31 | printf("\n"); 32 | return; 33 | } 34 | 35 | // I'm the child that will run "ls" 36 | 37 | // PID numbers are only so long. 38 | // 39 | char *dir = strdup("/proc/PARENT_PID_AAAAAAAAAAAA/fd/"); 40 | if(!dir) 41 | FAIL("strdup()"); 42 | 43 | size_t len = strlen(dir); 44 | snprintf(dir, len, "/proc/%d/fd/", parentPid); 45 | 46 | printf("\n----- %s: list of open files from %s --------------\n", 47 | label, dir); 48 | 49 | execlp("ls", "-lt", "--color=auto", "--file-type", "--full-time", 50 | dir, NULL); 51 | 52 | FAIL("execlp()"); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /tests/quickstreamQt_test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | cd "$(dirname ${BASH_SOURCE[0]})" 6 | 7 | echo "PWD=${PWD}" 8 | 9 | 10 | testBlockDir=../lib/quickstream/misc/test_blocks 11 | 12 | if [ -n "$QS_BLOCK_PATH" ] ; then 13 | export QS_BLOCK_PATH="$testBlockDir:$QS_BLOCK_PATH" 14 | else 15 | export QS_BLOCK_PATH="$testBlockDir" 16 | fi 17 | 18 | echo "QS_BLOCK_PATH=$QS_BLOCK_PATH" 19 | 20 | exec ../bin/quickstreamQt $* 21 | 22 | -------------------------------------------------------------------------------- /tests/returnStatus.c: -------------------------------------------------------------------------------- 1 | // Run: 2 | // 3 | // make ; ./returnStatus ; echo $? 4 | // 5 | 6 | int main(void) { 7 | 8 | return 257; // 257 -> 1 for first 8 bits. 9 | } 10 | -------------------------------------------------------------------------------- /tests/setjmp.c: -------------------------------------------------------------------------------- 1 | // Testing what system calls are made from sigsetjmp() and setjmp() and so 2 | // on. 3 | // 4 | // example: 5 | // 6 | // make 7 | // strace ./setjmp 8 | // 9 | // 10 | // Results: 11 | // 12 | // sigsetjmp() 13 | // calls system call rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 14 | // 15 | // and 16 | // 17 | // setjmp() 18 | // makes no system calls 19 | // 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "../lib/debug.h" 26 | 27 | 28 | int main(void) { 29 | 30 | //int count = 0; 31 | 32 | jmp_buf jmpEnv; 33 | 34 | 35 | for(int i=0; i<10000; ++i) 36 | if(setjmp(jmpEnv)) { 37 | //if(sigsetjmp(jmpEnv, 1)) { 38 | 39 | // We jumped into this point in the code. 40 | 41 | //++count; 42 | 43 | //DSPEW("count=%d", count); 44 | } 45 | 46 | //if(count < 10000) 47 | //siglongjmp(jmpEnv, 1); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /tests/structAddressMadness.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct Foo { 8 | 9 | int x; 10 | }; 11 | 12 | 13 | struct Bar { 14 | 15 | int x; 16 | char y; 17 | struct Foo foo; 18 | }; 19 | 20 | 21 | 22 | void printx(struct Foo *f) { 23 | 24 | struct Bar *b = 0; 25 | 26 | uint32_t diff = (uint32_t) ((uintptr_t) (((void *) &b->foo) - 27 | (uintptr_t) ((void *) b))); 28 | 29 | b = (struct Bar *) (((void *)f) - diff); 30 | 31 | printf("diff Address=%" PRIu32 "\n", diff); 32 | 33 | printf("x=%d\n", b->x); 34 | 35 | // Now I get it: 36 | b = ((void *) f) - offsetof(struct Bar, foo); 37 | 38 | printf("x=%d\n", b->x); 39 | } 40 | 41 | 42 | 43 | int main(void) { 44 | 45 | 46 | struct Bar b; 47 | b.x = 1234; 48 | b.foo.x = 45; 49 | 50 | printx(&b.foo); 51 | 52 | 53 | return 0; 54 | }; 55 | -------------------------------------------------------------------------------- /tests/success.c: -------------------------------------------------------------------------------- 1 | 2 | int main(void) { 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /tests/valgrind_run_tests: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # howto discusses valgrind suppression files and how to create 4 | # your own. 5 | # 6 | # https://wiki.wxwidgets.org/Valgrind_Suppression_File_Howto 7 | 8 | 9 | set -e 10 | 11 | if ! which valgrind > /dev/null ; then 12 | echo "valgrind was not found in your PATH" 13 | exit 1 14 | fi 15 | 16 | cd "$(dirname ${BASH_SOURCE[0]})" 17 | 18 | pre="$PWD" 19 | 20 | export VaLGRIND_RuN="valgrind\ 21 | --quiet\ 22 | --tool=memcheck\ 23 | --leak-check=full\ 24 | --trace-children=yes\ 25 | --show-leak-kinds=all\ 26 | --trace-children-skip='*'\ 27 | --suppressions="${pre}/valgrind_suppressions"\ 28 | --errors-for-leak-kinds=all\ 29 | --error-exitcode=211" 30 | 31 | 32 | exec ./run_tests $* 33 | 34 | # --gen-suppressions=all\ 35 | -------------------------------------------------------------------------------- /tests/valgrind_suppressions: -------------------------------------------------------------------------------- 1 | { 2 | name1 3 | Memcheck:Leak 4 | ... 5 | obj:/usr/bin/* 6 | ... 7 | } 8 | { 9 | name2 10 | Memcheck:Leak 11 | ... 12 | obj:/bin/* 13 | ... 14 | } 15 | { 16 | name3 17 | Memcheck:Leak 18 | ... 19 | obj:/lib/x86_64-linux-gnu/* 20 | ... 21 | } 22 | { 23 | Ignore dlopen bug. 24 | Memcheck:Leak 25 | ... 26 | fun:_dl_open 27 | ... 28 | } 29 | 30 | --------------------------------------------------------------------------------