1 /* 2 * Copyright (c) 2016-2021 Hanspeter Portner (dev@open-music-kontrollers.ch) 3 * 4 * This is free software: you can redistribute it and/or modify 5 * it under the terms of the Artistic License 2.0 as published by 6 * The Perl Foundation. 7 * 8 * This source is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * Artistic License 2.0 for more details. 12 * 13 * You should have received a copy of the Artistic License 2.0 14 * along the source as a COPYING file. If not, obtain it from 15 * http://www.perlfoundation.org/artistic_license_2_0. 16 */ 17 18 #ifndef _LV2LINT_H 19 #define _LV2LINT_H 20 21 #include <unistd.h> // isatty 22 #include <string.h> 23 #include <stdlib.h> 24 25 #include <lilv/lilv.h> 26 27 #include <lv2/worker/worker.h> 28 #include <lv2/state/state.h> 29 #include <lv2/options/options.h> 30 #include <lv2/ui/ui.h> 31 #include <lv2/midi/midi.h> 32 #include <lv2/time/time.h> 33 #include <lv2/presets/presets.h> 34 #include <lv2/uri-map/uri-map.h> 35 36 #include <ardour.lv2/lv2_extensions.h> 37 #include <kx.lv2/lv2_external_ui.h> 38 #include <kx.lv2/lv2_programs.h> 39 #include <kx.lv2/lv2_rtmempool.h> 40 41 #ifdef ENABLE_ONLINE_TESTS 42 # include <curl/curl.h> 43 #endif 44 45 #ifndef __unused 46 # define __unused __attribute__((unused)) 47 #endif 48 49 #ifndef LV2_UI__makeSONameResident 50 # define LV2_UI__makeSONameResident LV2_UI_PREFIX "makeSONameResident" 51 #endif 52 53 #define NODE(APP, ID) (APP)->nodes[ID] 54 55 typedef enum _ansi_color_t { 56 ANSI_COLOR_BOLD, 57 ANSI_COLOR_RED, 58 ANSI_COLOR_GREEN, 59 ANSI_COLOR_YELLOW, 60 ANSI_COLOR_BLUE, 61 ANSI_COLOR_MAGENTA, 62 ANSI_COLOR_CYAN, 63 ANSI_COLOR_RESET, 64 65 ANSI_COLOR_MAX 66 } ansi_color_t; 67 68 extern const char *colors [2][ANSI_COLOR_MAX]; 69 70 typedef union _var_t var_t; 71 typedef struct _white_t white_t; 72 typedef struct _urid_t urid_t; 73 typedef struct _app_t app_t; 74 typedef struct _test_t test_t; 75 typedef struct _ret_t ret_t; 76 typedef struct _res_t res_t; 77 typedef const ret_t *(*test_cb_t)(app_t *app); 78 79 typedef enum _lint_t { 80 LINT_NONE = 0, 81 LINT_NOTE = (1 << 1), 82 LINT_WARN = (1 << 2), 83 LINT_FAIL = (1 << 3), 84 LINT_PASS = (1 << 4) 85 } lint_t; 86 87 struct _white_t { 88 const char *uri; 89 const char *pattern; 90 white_t *next; 91 }; 92 93 struct _urid_t { 94 char *uri; 95 }; 96 97 struct _ret_t { 98 lint_t lnt; 99 lint_t pck; 100 const char *msg; 101 const char *uri; 102 const char *dsc; 103 }; 104 105 struct _res_t { 106 const ret_t *ret; 107 char *urn; 108 bool is_whitelisted; 109 }; 110 111 union _var_t { 112 uint32_t u32; 113 int32_t i32; 114 int64_t i64; 115 float f32; 116 double f64; 117 }; 118 119 typedef enum _stat_urid_t { 120 STAT_URID_INVALID = 0, 121 122 RDFS__label, 123 RDFS__comment, 124 RDFS__range, 125 RDFS__subClassOf, 126 127 RDF__type, 128 RDF__value, 129 130 DOAP__description, 131 DOAP__license, 132 DOAP__name, 133 DOAP__shortdesc, 134 135 XSD__int, 136 XSD__nonNegativeInteger, 137 XSD__long, 138 XSD__float, 139 XSD__double, 140 141 ATOM__Atom, 142 ATOM__AtomPort, 143 ATOM__Blank, 144 ATOM__Bool, 145 ATOM__Chunk, 146 ATOM__Double, 147 ATOM__Event, 148 ATOM__Float, 149 ATOM__Int, 150 ATOM__Literal, 151 ATOM__Long, 152 ATOM__Number, 153 ATOM__Object, 154 ATOM__Path, 155 ATOM__Property, 156 ATOM__Resource, 157 ATOM__Sequence, 158 ATOM__Sound, 159 ATOM__String, 160 ATOM__Tuple, 161 ATOM__URI, 162 ATOM__URID, 163 ATOM__Vector, 164 ATOM__atomTransfer, 165 ATOM__beatTime, 166 ATOM__bufferType, 167 ATOM__childType, 168 ATOM__eventTransfer, 169 ATOM__frameTime, 170 ATOM__supports, 171 ATOM__timeUnit, 172 173 BUF_SIZE__boundedBlockLength, 174 BUF_SIZE__coarseBlockLength, 175 BUF_SIZE__fixedBlockLength, 176 BUF_SIZE__maxBlockLength, 177 BUF_SIZE__minBlockLength, 178 BUF_SIZE__nominalBlockLength, 179 BUF_SIZE__powerOf2BlockLength, 180 BUF_SIZE__sequenceSize, 181 182 CORE__AllpassPlugin, 183 CORE__AmplifierPlugin, 184 CORE__AnalyserPlugin, 185 CORE__AudioPort, 186 CORE__BandpassPlugin, 187 CORE__CVPort, 188 CORE__ChorusPlugin, 189 CORE__CombPlugin, 190 CORE__CompressorPlugin, 191 CORE__ConstantPlugin, 192 CORE__ControlPort, 193 CORE__ConverterPlugin, 194 CORE__DelayPlugin, 195 CORE__DistortionPlugin, 196 CORE__DynamicsPlugin, 197 CORE__EQPlugin, 198 CORE__EnvelopePlugin, 199 CORE__ExpanderPlugin, 200 CORE__ExtensionData, 201 CORE__Feature, 202 CORE__FilterPlugin, 203 CORE__FlangerPlugin, 204 CORE__FunctionPlugin, 205 CORE__GatePlugin, 206 CORE__GeneratorPlugin, 207 CORE__HighpassPlugin, 208 CORE__InputPort, 209 CORE__InstrumentPlugin, 210 CORE__LimiterPlugin, 211 CORE__LowpassPlugin, 212 CORE__MixerPlugin, 213 CORE__ModulatorPlugin, 214 CORE__MultiEQPlugin, 215 CORE__OscillatorPlugin, 216 CORE__OutputPort, 217 CORE__ParaEQPlugin, 218 CORE__PhaserPlugin, 219 CORE__PitchPlugin, 220 CORE__Plugin, 221 CORE__PluginBase, 222 CORE__Point, 223 CORE__Port, 224 CORE__PortProperty, 225 CORE__Resource, 226 CORE__ReverbPlugin, 227 CORE__ScalePoint, 228 CORE__SimulatorPlugin, 229 CORE__SpatialPlugin, 230 CORE__Specification, 231 CORE__SpectralPlugin, 232 CORE__UtilityPlugin, 233 CORE__WaveshaperPlugin, 234 CORE__appliesTo, 235 CORE__binary, 236 CORE__connectionOptional, 237 CORE__control, 238 CORE__default, 239 CORE__designation, 240 CORE__documentation, 241 CORE__enumeration, 242 CORE__extensionData, 243 CORE__freeWheeling, 244 CORE__hardRTCapable, 245 CORE__inPlaceBroken, 246 CORE__index, 247 CORE__integer, 248 CORE__isLive, 249 CORE__latency, 250 CORE__maximum, 251 CORE__microVersion, 252 CORE__minimum, 253 CORE__minorVersion, 254 CORE__name, 255 CORE__optionalFeature, 256 CORE__port, 257 CORE__portProperty, 258 CORE__project, 259 CORE__prototype, 260 CORE__reportsLatency, 261 CORE__requiredFeature, 262 CORE__sampleRate, 263 CORE__scalePoint, 264 CORE__symbol, 265 CORE__toggled, 266 267 DATA_ACCESS, 268 269 DYN_MANIFEST, 270 271 EVENT__Event, 272 EVENT__EventPort, 273 EVENT__FrameStamp, 274 EVENT__TimeStamp, 275 EVENT__generatesTimeStamp, 276 EVENT__generic, 277 EVENT__inheritsEvent, 278 EVENT__inheritsTimeStamp, 279 EVENT__supportsEvent, 280 EVENT__supportsTimeStamp, 281 282 INSTANCE_ACCESS, 283 284 LOG__Entry, 285 LOG__Error, 286 LOG__Note, 287 LOG__Trace, 288 LOG__Warning, 289 LOG__log, 290 291 MIDI__ActiveSense, 292 MIDI__Aftertouch, 293 MIDI__Bender, 294 MIDI__ChannelPressure, 295 MIDI__Chunk, 296 MIDI__Clock, 297 MIDI__Continue, 298 MIDI__Controller, 299 MIDI__MidiEvent, 300 MIDI__NoteOff, 301 MIDI__NoteOn, 302 MIDI__ProgramChange, 303 MIDI__QuarterFrame, 304 MIDI__Reset, 305 MIDI__SongPosition, 306 MIDI__SongSelect, 307 MIDI__Start, 308 MIDI__Stop, 309 MIDI__SystemCommon, 310 MIDI__SystemExclusive, 311 MIDI__SystemMessage, 312 MIDI__SystemRealtime, 313 MIDI__Tick, 314 MIDI__TuneRequest, 315 MIDI__VoiceMessage, 316 MIDI__benderValue, 317 MIDI__binding, 318 MIDI__byteNumber, 319 MIDI__channel, 320 MIDI__chunk, 321 MIDI__controllerNumber, 322 MIDI__controllerValue, 323 MIDI__noteNumber, 324 MIDI__pressure, 325 MIDI__programNumber, 326 MIDI__property, 327 MIDI__songNumber, 328 MIDI__songPosition, 329 MIDI__status, 330 MIDI__statusMask, 331 MIDI__velocity, 332 333 MORPH__AutoMorphPort, 334 MORPH__MorphPort, 335 MORPH__interface, 336 MORPH__supportsType, 337 MORPH__currentType, 338 339 OPTIONS__Option, 340 OPTIONS__interface, 341 OPTIONS__options, 342 OPTIONS__requiredOption, 343 OPTIONS__supportedOption, 344 345 PARAMETERS__CompressorControls, 346 PARAMETERS__ControlGroup, 347 PARAMETERS__EnvelopeControls, 348 PARAMETERS__FilterControls, 349 PARAMETERS__OscillatorControls, 350 PARAMETERS__amplitude, 351 PARAMETERS__attack, 352 PARAMETERS__bypass, 353 PARAMETERS__cutoffFrequency, 354 PARAMETERS__decay, 355 PARAMETERS__delay, 356 PARAMETERS__dryLevel, 357 PARAMETERS__frequency, 358 PARAMETERS__gain, 359 PARAMETERS__hold, 360 PARAMETERS__pulseWidth, 361 PARAMETERS__ratio, 362 PARAMETERS__release, 363 PARAMETERS__resonance, 364 PARAMETERS__sampleRate, 365 PARAMETERS__sustain, 366 PARAMETERS__threshold, 367 PARAMETERS__waveform, 368 PARAMETERS__wetDryRatio, 369 PARAMETERS__wetLevel, 370 371 PATCH__Ack, 372 PATCH__Delete, 373 PATCH__Copy, 374 PATCH__Error, 375 PATCH__Get, 376 PATCH__Message, 377 PATCH__Move, 378 PATCH__Patch, 379 PATCH__Post, 380 PATCH__Put, 381 PATCH__Request, 382 PATCH__Response, 383 PATCH__Set, 384 PATCH__accept, 385 PATCH__add, 386 PATCH__body, 387 PATCH__context, 388 PATCH__destination, 389 PATCH__property, 390 PATCH__readable, 391 PATCH__remove, 392 PATCH__request, 393 PATCH__subject, 394 PATCH__sequenceNumber, 395 PATCH__value, 396 PATCH__wildcard, 397 PATCH__writable, 398 399 PORT_GROUPS__DiscreteGroup, 400 PORT_GROUPS__Element, 401 PORT_GROUPS__FivePointOneGroup, 402 PORT_GROUPS__FivePointZeroGroup, 403 PORT_GROUPS__FourPointZeroGroup, 404 PORT_GROUPS__Group, 405 PORT_GROUPS__InputGroup, 406 PORT_GROUPS__MidSideGroup, 407 PORT_GROUPS__MonoGroup, 408 PORT_GROUPS__OutputGroup, 409 PORT_GROUPS__SevenPointOneGroup, 410 PORT_GROUPS__SevenPointOneWideGroup, 411 PORT_GROUPS__SixPointOneGroup, 412 PORT_GROUPS__StereoGroup, 413 PORT_GROUPS__ThreePointZeroGroup, 414 PORT_GROUPS__center, 415 PORT_GROUPS__centerLeft, 416 PORT_GROUPS__centerRight, 417 PORT_GROUPS__element, 418 PORT_GROUPS__group, 419 PORT_GROUPS__left, 420 PORT_GROUPS__lowFrequencyEffects, 421 PORT_GROUPS__mainInput, 422 PORT_GROUPS__mainOutput, 423 PORT_GROUPS__rearCenter, 424 PORT_GROUPS__rearLeft, 425 PORT_GROUPS__rearRight, 426 PORT_GROUPS__right, 427 PORT_GROUPS__side, 428 PORT_GROUPS__sideChainOf, 429 PORT_GROUPS__sideLeft, 430 PORT_GROUPS__sideRight, 431 PORT_GROUPS__source, 432 PORT_GROUPS__subGroupOf, 433 434 PORT_PROPS__causesArtifacts, 435 PORT_PROPS__continuousCV, 436 PORT_PROPS__discreteCV, 437 PORT_PROPS__displayPriority, 438 PORT_PROPS__expensive, 439 PORT_PROPS__hasStrictBounds, 440 PORT_PROPS__logarithmic, 441 PORT_PROPS__notAutomatic, 442 PORT_PROPS__notOnGUI, 443 PORT_PROPS__rangeSteps, 444 PORT_PROPS__supportsStrictBounds, 445 PORT_PROPS__trigger, 446 447 PRESETS__Bank, 448 PRESETS__Preset, 449 PRESETS__bank, 450 PRESETS__preset, 451 PRESETS__value, 452 453 RESIZE_PORT__asLargeAs, 454 RESIZE_PORT__minimumSize, 455 RESIZE_PORT__resize, 456 457 STATE__State, 458 STATE__interface, 459 STATE__loadDefaultState, 460 STATE__freePath, 461 STATE__makePath, 462 STATE__mapPath, 463 STATE__state, 464 STATE__threadSafeRestore, 465 STATE__StateChanged, 466 467 TIME__Time, 468 TIME__Position, 469 TIME__Rate, 470 TIME__position, 471 TIME__barBeat, 472 TIME__bar, 473 TIME__beat, 474 TIME__beatUnit, 475 TIME__beatsPerBar, 476 TIME__beatsPerMinute, 477 TIME__frame, 478 TIME__framesPerSecond, 479 TIME__speed, 480 481 UI__CocoaUI, 482 UI__Gtk3UI, 483 UI__GtkUI, 484 UI__PortNotification, 485 UI__PortProtocol, 486 UI__Qt4UI, 487 UI__Qt5UI, 488 UI__UI, 489 UI__WindowsUI, 490 UI__X11UI, 491 UI__binary, 492 UI__fixedSize, 493 UI__idleInterface, 494 UI__noUserResize, 495 UI__notifyType, 496 UI__parent, 497 UI__plugin, 498 UI__portIndex, 499 UI__portMap, 500 UI__portNotification, 501 UI__portSubscribe, 502 UI__protocol, 503 UI__requestValue, 504 UI__floatProtocol, 505 UI__peakProtocol, 506 UI__resize, 507 UI__showInterface, 508 UI__touch, 509 UI__ui, 510 UI__updateRate, 511 UI__windowTitle, 512 UI__scaleFactor, 513 UI__foregroundColor, 514 UI__backgroundColor, 515 UI__makeSONameResident, 516 517 UNITS__Conversion, 518 UNITS__Unit, 519 UNITS__bar, 520 UNITS__beat, 521 UNITS__bpm, 522 UNITS__cent, 523 UNITS__cm, 524 UNITS__coef, 525 UNITS__conversion, 526 UNITS__db, 527 UNITS__degree, 528 UNITS__frame, 529 UNITS__hz, 530 UNITS__inch, 531 UNITS__khz, 532 UNITS__km, 533 UNITS__m, 534 UNITS__mhz, 535 UNITS__midiNote, 536 UNITS__mile, 537 UNITS__min, 538 UNITS__mm, 539 UNITS__ms, 540 UNITS__name, 541 UNITS__oct, 542 UNITS__pc, 543 UNITS__prefixConversion, 544 UNITS__render, 545 UNITS__s, 546 UNITS__semitone12TET, 547 UNITS__symbol, 548 UNITS__unit, 549 550 URID__map, 551 URID__unmap, 552 553 URI_MAP, 554 555 WORKER__interface, 556 WORKER__schedule, 557 558 EXTERNAL_UI__Widget, 559 560 INLINEDISPLAY__interface, 561 INLINEDISPLAY__queue_draw, 562 563 STAT_URID_MAX 564 } stat_urid_t; 565 566 struct _app_t { 567 LilvWorld *world; 568 const char *plugin_uri; 569 const LilvPlugin *plugin; 570 LilvInstance *instance; 571 const LV2_Descriptor *descriptor; 572 const LV2UI_Descriptor *ui_descriptor; 573 const LilvPort *port; 574 const LilvNode *parameter; 575 const LilvUI *ui; 576 const char *ui_uri; 577 LV2_URID_Map *map; 578 LV2_URID_Unmap *unmap; 579 void *ui_instance; 580 uintptr_t ui_widget; 581 LilvNodes *writables; 582 LilvNodes *readables; 583 const LV2_Worker_Interface *work_iface; 584 const LV2_Inline_Display_Interface *idisp_iface; 585 const LV2_State_Interface *state_iface; 586 const LV2_Options_Interface *opts_iface; 587 const LV2UI_Idle_Interface *ui_idle_iface; 588 const LV2UI_Show_Interface *ui_show_iface; 589 const LV2UI_Resize *ui_resize_iface; 590 var_t min; 591 var_t max; 592 var_t dflt; 593 lint_t show; 594 lint_t mask; 595 bool pck; 596 urid_t *urids; 597 LV2_URID nurids; 598 char **urn; 599 unsigned n_include_dirs; 600 char **include_dirs; 601 white_t *whitelist_symbols; 602 white_t *whitelist_libs; 603 white_t *whitelist_tests; 604 bool atty; 605 bool debug; 606 bool quiet; 607 #ifdef ENABLE_ONLINE_TESTS 608 bool online; 609 char *mail; 610 bool mailto; 611 CURL *curl; 612 char *greet; 613 #endif 614 LilvNode *nodes [STAT_URID_MAX]; 615 }; 616 617 struct _test_t { 618 const char *id; 619 test_cb_t cb; 620 }; 621 622 bool 623 test_plugin(app_t *app); 624 625 bool 626 test_port(app_t *app); 627 628 bool 629 test_parameter(app_t *app); 630 631 bool 632 test_ui(app_t *app); 633 634 #ifdef ENABLE_X11_TESTS 635 void 636 test_x11(app_t *app, bool *flag); 637 #endif 638 639 #ifdef ENABLE_ONLINE_TESTS 640 bool 641 is_url(const char *uri); 642 643 bool 644 test_url(app_t *app, const char *url); 645 #endif 646 647 #ifdef ENABLE_ELF_TESTS 648 bool 649 test_visibility(app_t *app, const char *path, const char *uri, 650 const char *description, char **symbols); 651 652 bool 653 check_for_symbol(app_t *app, const char *path, const char *description); 654 655 bool 656 test_shared_libraries(app_t *app, const char *path, const char *uri, 657 const char *const *whitelist, unsigned n_whitelist, 658 const char *const *blacklist, unsigned n_blacklist, 659 char **libraries); 660 #endif 661 662 int 663 lv2lint_vprintf(app_t *app, const char *fmt, va_list args); 664 665 int 666 lv2lint_printf(app_t *app, const char *fmt, ...); 667 668 void 669 lv2lint_report(app_t *app, const test_t *test, res_t *res, bool show_passes, bool *flag); 670 671 lint_t 672 lv2lint_extract(app_t *app, const ret_t *ret); 673 674 bool 675 lv2lint_test_is_whitelisted(app_t *app, const char *uri, const test_t *test); 676 677 char * 678 lv2lint_node_as_string_strdup(const LilvNode *node); 679 680 char * 681 lv2lint_node_as_uri_strdup(const LilvNode *node); 682 683 char * 684 lv2lint_strdup(const char *str); 685 686 int 687 log_vprintf(void *data, LV2_URID type , const char *fmt, va_list args); 688 689 int 690 log_printf(void *data, LV2_URID type, const char *fmt, ...); 691 692 #pragma GCC diagnostic push 693 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 694 uint32_t 695 uri_to_id(LV2_URI_Map_Callback_Data instance, const char *_map, const char *uri); 696 #pragma GCC diagnostic pop 697 698 #endif 699