I've seen many files with weird formatting because of line breaks that are either missing or incorrectly coded. So I just wrote a little code snippet to find them. Results are attached. Specifically I was looking for lines with non-whitespace, followed by anything, followed by tab and close-brace, to match things like this: Pdfsm : ListPattern { var >startState; *new { arg list, startState=0, repeats=1; ^super.new( list, repeats ).startState_(startState) } ... huh? Where'd the closing brace for *new go? Oh, it's tacked onto the end of the previous line. But it ended up finding a lot of files where dozens of lines are read in as one line. Why a problem? It makes grep really nasty to use on some parts of the classlib. If there are no objections, I'll try to figure out a way to fix them automatically. Thought I would ask because some of the most-affected files are in JITLib and crucial. Thanks. hjh |
./SCClassLibrary/Common/Audio/Demand.sc: 77: inputs.do { |in| if(in.rate == \audio) { in <! 0 } }; } ./SCClassLibrary/Common/Audio/Noise.sc: 74: } *ar { arg lo = 0, hi = 127, trig = 0.0; ^this.multiNew('audio', lo, hi, trig) } ./SCClassLibrary/Common/Collections/ArrayedCollection.sc: 272: // },{ false }); 273: // }); ./SCClassLibrary/Common/Collections/SequenceableCollection.sc: 502: // supports a variation of Mikael Laurson's rhythm list RTM-notation. convertRhythm { var list, tie; list = List.new; tie = this.convertOneRhythm(list); if (tie > 0.0, { list.add(tie) }); // check for tie at end of rhythm ^list } sumRhythmDivisions { var sum = 0; this.do {|beats| sum = sum + abs(if (beats.isSequenceableCollection) { beats[0]; }{ beats }); }; ^sum } convertOneRhythm { arg list, tie = 0.0, stretch = 1.0; var beats, divisions, repeats; #beats, divisions, repeats = this; repeats = repeats ? 1; stretch = stretch * beats / divisions.sumRhythmDivisions; repeats.do({ divisions.do { |val| if (val.isSequenceableCollection) { tie = val.convertOneRhythm(list, tie, stretch) }{ val = val * stretch; if (val > 0.0) { list.add(val + tie); tie = 0.0; }{ tie = tie - val }; }; }; }); ^tie } ./SCClassLibrary/Common/Control/Bus.sc: 123: printOn { arg stream; stream << this.class.name << "(" <<* [rate, index, numChannels, server] <<")" } ./SCClassLibrary/Common/Control/Node.sc: 193: hash { ^server.hash bitXor: nodeID.hash } ./SCClassLibrary/Common/Control/WII.sc: 252: // }).play; ./SCClassLibrary/Common/Control/asDefName.sc: 5: asDefName { ^name } ./SCClassLibrary/Common/Files/Help.sc: 595: *categories { ^ nil } ./SCClassLibrary/Common/GUI/osx/Base/SCCocoaView.sc: 6: mouseUpAction.value(this, x, y, modifiers, buttonNumber, clickCount, clickPos); } ./SCClassLibrary/Common/GUI/osx/Base/SCView.sc: 1244: defaultCanReceiveDrag { ^true; } 1271: this.setProperty(\clearDrawing); } 1279: this.setProperty(\clearOnRefresh, bool); } 1283: this.setProperty(\relativeOrigin, bool); } 1357: mouseTrack { arg x, y, modifiers; } 1524: mouseTrack { arg x, y, modifiers; } ./SCClassLibrary/Common/Math/SimpleNumber.sc: 302: Error("SimpleNumber-writeInputSpec constant not found: " ++ this.asFloat).throw; }; ./SCClassLibrary/Common/Streams/ListPatterns.sc: 174: ^super.new( list, repeats ).startState_(startState) } ./SCClassLibrary/Common/Streams/Patterns.sc: 504: inval = ((table.tableRand * (hiVal - loVal)) + loVal).yield; }; ./SCClassLibrary/Common/Streams/Ppar.sc: 141: numberOfGroups { ^list.size } ./SCClassLibrary/Common/Streams/TabFileReader.sc: 60: ^this.read(path, skipEmptyLines, skipBlanks, _.interpret, delimiter, startRow, skipSize ) } ./SCClassLibrary/JITLib/Patterns/Pdef.sc: 346: if(this.isPlaying) { this.play(quant:playQuant) } } ./SCClassLibrary/JITLib/ProxySpace/NodeProxy.sc: 62: this.class.defaultNumControl } 396: list.do { |item, i| this.put(i + index, item, channelOffset.wrapAt(i)) } } ./SCClassLibrary/JITLib/ProxySpace/extStoreOn.sc: 37: try { doc.bounds_(bounds) }; // swingosc safe } } ./SCClassLibrary/JITLib/ProxySpace/wrapForNodeProxy.sc: 259: XOut.kr(out, e, SynthDef.wrap(func, nil, [In.kr(out, proxy.numChannels)])) }; ./SCClassLibrary/JITLib/extras/History.sc: 166: [lines, lineShorts].do(_.removeAt(index)); }; ./SCClassLibrary/JITLib/extras/NodeProxyEditor.sc: 6: *new { arg proxy, pxKey, nSliders=16, win, comp, extras=[\scope, \doc, \reset], monitor=true, sinks=true, morph=false; ^super.new.nSliders_(nSliders).init(win, comp, extras, monitor, sinks, morph) .pxKey_(pxKey).proxy_(proxy); } proxy_ { arg px; if (px.isKindOf(NodeProxy), { proxy = px; editNameView.object_(px.source); editNameView.string_(px.key.asString); oldNodeMap = proxy.nodeMap; if (monitor.notNil) { monitor.proxy_(proxy) }; this.fullUpdate; }) } pxKey_ { arg key; if (key.notNil, { pxKey = key; { editNameView.string_(pxKey.asString); }.defer; }) } 7: clear { proxy = nil; pxKey = nil; { editNameView.object_(nil).string_(""); }.defer; this.fullUpdate; } init { arg win, comp, extras, monitor, sinks, morph; var bounds; skin = GUI.skin; font = GUI.font.new(*GUI.skin.fontSpecs); bounds = Rect(0, 0, 370, nSliders + 2 * skin.buttonHeight + 16); win = win ?? { "NodeProxyEditor: making internal win".postln; 13: this.makeTopLine(extras); if (monitor, { this.makePxMon; zone.decorator.nextLine.shift(0, 4); }); if (morph, { this.makeMorph; zone.decorator.nextLine.shift(0, 4); }); this.makeSinksSliders(sinks); this.makeSkipJack; } makePxMon { monitor = ProxyMonitorGui(proxy, zone, skin.buttonHeight, true, false); } makeMorph { zone.decorator.shift(0, 2); GUI.staticText.new(zone, Rect(0,0, 330, 1)).background_(Color.gray(0.2)); zone.decorator.shift(0, 2); PxPreset(proxy, zone) } makeTopLine { |extras| editNameView = GUI.dragSource.new(zone, Rect(0,0,90, skin.buttonHeight)) .font_(font).align_(\center) .background_(Color.white); GUI.button.new(zone, Rect(0,0,40, menuHeight)).states_([ ["watch", skin.fontcolor, Color.clear ], ["wait", skin.fontcolor, Color.clear ] ]) .action_({ |b| [ { this.stopUpdate }, { this.runUpdate } ][b.value].value }) .font_(font); GUI.button.new(zone, Rect(0, 0, 20, menuHeight)) .font_(font) .states_([ ["^", skin.fontcolor, Color.clear] ]) .action_({ this.class.new(proxy, pxKey, nSliders); }); if (extras.includes(\scope)) { GUI.button.new(zone, Rect(0,0,40, menuHeight)) .font_(font) .states_([["scope", skin.fontcolor, Color.clear]]) .action_({ arg btn; if(proxy.notNil, { proxy.scope }) }); }; if (extras.includes(\reset)) { GUI.button.new(zone, Rect(0,0,40, menuHeight)) .states_([["reset", skin.fontcolor, Color.clear ]]) .action_({ if(proxy.notNil) { proxy.nodeMap = ProxyNodeMap.new; this.fullUpdate; } }) .font_(font); }; if (extras.includes(\doc)) { GUI.button.new(zone, Rect(0,0,40, menuHeight)) .states_([["doc", skin.fontcolor, Color.clear ]]) .action_({ if(proxy.notNil and: currentEnvironment.isKindOf(ProxySpace)) { currentEnvironment.document(proxy.key) .title_("<" + proxy.key.asString + ">") } { 15: } }) .font_(font); }; 20: sinkWidth = if (bigSinks, 40, 0); // invisibly small #edits, sinks = Array.fill(nSliders, { arg i; var ez, sink; zone.decorator.nextLine; sink = GUI.dragBoth.new(zone, Rect(0,0, sinkWidth, skin.buttonHeight)) .string_("-").align_(\center).visible_(false); sink.action_({ arg sink; var px; if (sink.object.notNil) { px = currentEnvironment[sink.object.asSymbol]; if(px.isKindOf(NodeProxy)) { proxy.map(editKeys[i], px); this.fullUpdate; } } }); ez = GUI.ezSlider.new(zone, 290 @ skin.buttonHeight, "", nil.asSpec, labelWidth: 60, numberWidth: 42); ez.labelView.font_(font).align_(\center); 21: [ez, sink] }).flop; 32: } makeSkipJack { skipjack = SkipJack( { this.checkUpdate }, 0.2, { w.isClosed }, this.class.name ); w.onClose_({ skipjack.stop; }); this.runUpdate; } getCurrentKeysValues { if (proxy.isNil, {^[] }); currentSettings = proxy.getKeysValues(except: ignoreKeys); editKeys = currentSettings.collect({ |list| list.first.asSymbol }); } checkUpdate { var oldKeys; oldKeys = editKeys; this.getCurrentKeysValues; if (monitor.notNil) { monitor.updateAll }; if ( (editKeys != oldKeys), { this.updateAllEdits }, { this.updateVals }); } fullUpdate { this.getCurrentKeysValues; this.updateAllEdits; } updateVals { var sl, val, mapKey; 45: if (val != try { prevSettings[i][1] }) { // when in doubt, use this: // val = (currentSettings.detect { |set| set[0] == key } ? [])[1]; if(sl.numberView.hasFocus.not) { if (val.isKindOf(SimpleNumber), { sl.value_(val.value); sl.labelView.string_(this.replaceName(key)); sinks[i].string_("-"); }, { if (val.isKindOf(BusPlug), { mapKey = currentEnvironment.findKeyForValue(val) ? ""; sinks[i].object_(mapKey).string_(mapKey); sl.labelView.string = "->" + key; }); }); }; 46: }; }; 47: prevSettings = currentSettings; } replaceName { |key| 140: } runUpdate { skipjack.start } stopUpdate { skipjack.stop } } RecordProxyMixer { var <>proxymixer, bounds; var <recorder, <recType=\mix; var <>recHeaderFormat, <>recSampleFormat, <preparedForRecording=false; var skipjack, <display; *new { arg proxymixer, bounds; ^super.newCopyArgs(proxymixer, bounds).initDefaults.makeWindow } initDefaults { recHeaderFormat = recHeaderFormat ?? { this.server.recHeaderFormat }; recSampleFormat = recSampleFormat ?? { this.server.recSampleFormat }; } prepareForRecord { var numChannels=0, path, proxies, func; proxies = this.selectedKeys.collect { arg key; this.at(key) }; if(proxies.isEmpty) { "NodeProxyEditor: no proxies.".postln; ^nil }; if(recType == \multichannel) { proxies.do { |el| numChannels = numChannels + el.numChannels }; func = { proxies.collect(_.ar).flat }; // no vol for now! } { proxies.do { |el| numChannels = max(numChannels, el.numChannels) }; func = { var sum=0; proxies.do { |el| sum = sum +.s el.ar }; sum } }; path = thisProcess.platform.recordingsDir +/+ "SC_PX_" ++ numChannels ++ "_" ++ Date.localtime.stamp ++ "." ++ recHeaderFormat; recorder = RecNodeProxy.audio(this.server, numChannels); recorder.source = func; recorder.open(path, recHeaderFormat, recSampleFormat); preparedForRecording = true; ^numChannels } font { ^GUI.font.new(*GUI.skin.fontSpecs) } skin { ^GUI.skin } server { ^proxymixer.proxyspace.server } removeRecorder { recorder !? { recorder.close; recorder.clear; recorder = nil; }; preparedForRecording = false; } record { arg paused=false; if(recorder.notNil) {recorder.record(paused) }; } pauseRecorder { recorder !? {recorder.pause} } unpauseRecorder { recorder !? { if(recorder.isRecording) { recorder.unpause } { "not recording".postln } } } selectedKeys { ^proxymixer.selectedKeys } at { arg key; ^proxymixer.proxyspace.envir.at(key) } selectedKeysValues { ^this.selectedKeys.collect { |key| var proxy = this.at(key); [ key, proxy.numChannels ] }.flat; } makeWindow { var rw, recbut, pbut, numChannels, recTypeChoice; var font = this.font; rw = GUI.window.new("recording:" + proxymixer.title, bounds); rw.view.decorator = FlowLayout(rw.view.bounds.insetBy(20, 20)); rw.onClose = { this.removeRecorder; this.stopUpdate; }; rw.view.background = this.skin.background; recbut = GUI.button.new(rw, Rect(0, 0, 80, 20)).states_([ ["prepare rec", this.skin.fontcolor, Color.clear], ["record >", Color.red, Color.gray(0.1)], ["stop []", this.skin.fontcolor, Color.red] ]).action_({|b| var list; switch(b.value, 1, { numChannels = this.prepareForRecord; if(numChannels.isNil) { b.value = 0; pbut.value = 0 } }, 2, { this.record(pbut.value == 1) }, 0, { this.removeRecorder } ); if(b.value == 1 and: { numChannels.notNil }) { list = this.selectedKeysValues; this.displayString = format("recording % channels: %", numChannels, list.join(" ")); }; }).font_(font); pbut = GUI.button.new(rw, Rect(0, 0, 80, 20)).states_([ ["pause", this.skin.fontcolor, Color.clear], [">", Color.red, Color.gray(0.1)] ]).action_({|b| if(b.value == 1) { this.pauseRecorder } { this.unpauseRecorder } }).font_(font); recTypeChoice = GUI.popUpMenu.new(rw, Rect(0, 0, 110, 20)) .items_([ \mix, \multichannel ]) .action_({ arg view; recType = view.items[view.value]; if(recbut.value != 0) { recbut.valueAction = 0 } }) .font_(font); recTypeChoice.value = 1; GUI.button.new(rw, Rect(0, 0, 60, 20)) .states_([["cancel", this.skin.fontcolor, Color.clear]]) .action_({ if(recbut.value != 0) { recbut.valueAction = 0 } }) .font_(font); rw.view.decorator.nextLine; display = GUI.staticText.new(rw, Rect(30, 40, 300, 20)).font_(font); rw.front; this.makeSkipJack; this.runUpdate; ^rw } displayString_ { arg str; display.string = str; } updateZones { if(preparedForRecording.not) { this.displayStrin 141: g = format("proxies: %", this.selectedKeysValues.join(" ")); } } title { ^"recorder for" + proxymixer.title } runUpdate { skipjack.start; } stopUpdate { skipjack.stop } makeSkipJack { // stoptest should check window. skipjack = SkipJack({ this.updateZones }, 0.5, name: this.title); } } ./SCClassLibrary/JITLib/extras/ProxyMixer.sc: 4: *new { arg proxyspace, nProxies = 16, title, bounds; ^super.new.init(proxyspace, nProxies, title ?? { format("proxyspace: %", proxyspace.tryPerform(\name) ? "") }, bounds ); } init { arg space, nPxs = 16, argTitle, argBounds; var winHeight, globalLayout, height, color; skin = GUI.skin; 9: .background_(skin.foreground); compArZone.decorator = FlowLayout(compArZone.bounds).gap_(skin.gap); compKrZone.decorator = FlowLayout(compKrZone.bounds).gap_(skin.gap); compEditZone.decorator = FlowLayout(compEditZone.bounds).gap_(skin.gap); this.makeArZone; this.makeKrZone; this.makeEditZone; w.front; this.makeSkipJack; w.onClose_({ this.stopUpdate }); this.runUpdate; } runUpdate { editor.runUpdate; skippy.start; } stopUpdate { editor.stopUpdate; skippy.stop } makeWindow { w = GUI.window.new(this.title, origBounds); w.view.background = skin.background; } makeSkipJack { skippy = SkipJack({ this.updateZones }, 0.2, { w.isClosed }, title); } makeEditZone { editor = NodeProxyEditor(nil, nil, nProxies - 1, w, compEditZone); } openEditZone { arg flag; if(flag == 1 or: {editZoneOpen.not}) { if(editZoneOpen.not) { origBounds = w.bounds; w.bounds = w.bounds.setExtent(fullBounds.width, fullBounds.height); editZoneOpen = true; editZoneBtn.value = 1; this.update; } }{ w.bounds = w.bounds.setExtent(origBounds.width, origBounds.height); editZoneOpen = false; editZoneBtn.value = 0; }; } makeArZoneHead { GUI.popUpMenu.new(compArZone,Rect(10, 10, 110, skin.buttonHeight+2)) .items_([\existingProxies, \activeProxies, \playingProxies]) .action_({ arg view; selectMethod = view.items[view.value] }) .font_(font); GUI.button.new(compArZone, Rect(10, 10, 50, skin.buttonHeight+2)) .states_( [["reduce", skin.fontcolor, Color.clear]] ) .action_({ proxyspace.reduce }).font_(font); GUI.button.new(compArZone, Rect(10, 10, 30, skin.buttonHeight+2)) .states_( [["doc", skin.fontcolor, Color.clear]] ) .action_({ proxyspace.document }).font_(font); GUI.button.new(compArZone, Rect(10, 10, 30, skin.buttonHeight+2)) .states_( [["docc", skin.fontcolor, Color.clear]] ) .action_({ proxyspace.document(this.selectedKeys) }).font_(font); /* GUI.button.new.new(compArZone, Rect(10, 10, 20, skin.buttonHeight+2)).states_([ ["#", skin.fontcolor, Color.clear ] ]) .action_({ editor.pxKey !? { proxyspace.storeOn(Post, [editor.pxKey]) } }) .font_(font); */ editZoneBtn = GUI.button.new(compArZone, Rect(10, 10, 60, skin.buttonHeight+2)) .font_(font) .states_( [ ["openEdit", skin.fontcolor, Color.clear], ["closeEdit", skin.fontcolor, Color.clear] ] ) .action_({ |b| this.openEditZone(b.value) }); GUI.button.new(compArZone, Rect(10, 10, 20, skin.buttonHeight+2)) .font_(font) .states_( [ ["R", Color.red, Color.clear] ]) .action_({ RecordProxyMixer(this, origBounds.resizeTo(472, 100)) }); } makeArZone { var arLayout = compArZone.decorator; this.makeArZoneHead; arLayout.nextLine; arLayout.shift(0,4); #pxMons, editBtnsAr = Array.fill(nProxies, { arg i; var pxmon, edbut; pxmon = ProxyMonitorGui(nil, compArZone, skin.buttonHeight, true, false); pxmon.zone.visible_(false); // arLayout.shift(4); edbut = GUI.button.new(compArZone, Rect(0,0,16,16)) .font_(font) .visible_(false) .states_([ ["ed", Color.black, Color.grey(0.75)], ["ed", Color.black, Color.white]]) .action_({ arg btn; editor.proxy_(pxmon.proxy).pxKey_(pxmon.proxy.key); this.openEditZone(1); editBtnsAr.do { |b| b.value_(0) }; editBtnsKr.do { |b| b.value_(0) }; btn.value_(1); }); arLayout.nextLine; [pxmon, edbut] }).flop; 27: /* GUI.button.new(compKrZone, Rect(0,0,20, skin.buttonHeight)) .font_(Font("Helvetica-Bold", 12)) .states_([["+", Color.red, Color.white]]) .action_({ if(emergencySynth.isPlaying.not) { emergencySynth = Synth.tail(0, "proxymixer_emergency"); NodeWatcher.register(emergencySynth); } { emergencySynth.release } }); */ layout.nextLine; layout.nextLine; buttonLinesKr = Array.fill(nProxies, { arg i; var nameBtn, pausBtn, sendBtn, editBtn, pollBtn; nameBtn = GUI.dragSource.new(compKrZone, Rect(0,0,68, skin.buttonHeight)) .font_(font) .align_(\center); 68: [ nameBtn, pausBtn, sendBtn, editBtn, pollBtn].do({ arg v; v.visible_(false) }); }); 77: } updateZones { this.updateArSlots; this.updateKrSlots; } updateKrSlots { var krProxyNames; krProxyNames = proxyspace.krProxyNames; 94: showLine = key.notNil and: px.notNil; butLine.do(_.visible_(showLine)); } 96: prevKrNames = krProxyNames; } existingProxies { ^proxyspace.arProxyNames } activeProxies { ^proxyspace.arProxyNames({ |px, key| px.isPlaying }) } playingProxies { ^proxyspace.arProxyNames({ |px, key| px.monitor.isPlaying }) } selectedKeys { ^this.perform(selectMethod) } updateArSlots { var arPxNames, pxKey, px, pxMon; arPxNames = this.selectedKeys; if (arPxNames.size > nProxies) { 100: arPxNames = arPxNames.drop(keysRotationAr).keep(nProxies); } { 103: if (arPxNames != prevArNames) { nProxies.do { arg i; pxMon = pxMons[i]; pxKey = arPxNames[i]; px = proxyspace.envir.at(pxKey); if(px.notNil) { pxMon.zone.visible_(true); editBtnsAr[i].visible_(true); pxMon.proxy_(px); }{ pxMon.zone.visible_(false); editBtnsAr[i].visible_(false); } } 107: prevArNames = arPxNames; } adjustWindowSize { arg n; n = n ? nProxies; w.bounds = if(editZoneOpen) { origBounds.resizeBy(0, 330) } { origBounds.copy.height_(n * 18 + 80) }; } } ./SCClassLibrary/JITLib/extras/ProxyMonitorGui.sc: 1: *new { |px, w, height=16, usePlayN=true, makeWatcher=true| ^super.new.proxy_(px).init(w, height, usePlayN, makeWatcher); } init { |w, height, usePlayN, makeWatcher| 7: // swingosc: 16 is normal 24 is alt, ctl is off, and fn is 16 as well if(proxy.notNil) { [ { if ([524576, 24].includes(modif)) { proxy.end } { proxy.stop } }, { proxy.playN; } ].at(btn.value).value } }); setOutBox = GUI.numberBox.new(zone, Rect(0,0,16,height)) .font_(font).align_(0) .action_({ |box, mod| proxy.monitor.out_(box.value.max(0).asInteger); }); if (usesPlayN) { playNDialogBut = GUI.button.new(zone, Rect(0,0,20,height)) 11: box.value_(1 - box.value) }); }; pauseBut = GUI.button.new(zone, Rect(0,0,34,height)) 13: .action_({ arg btn; if(proxy.notNil, { [ { proxy.resume; }, { proxy.pause; } ].at(btn.value).value; }) }); sendBut = GUI.button.new(zone, Rect(0,0,34,height)) 16: // alt-click osx, swingosc if ([524576, 24].includes(mod) ) { proxy.rebuild } { proxy.send } }; 17: btn.value_(1 - btn.value) }) 18: ; if (win.isKindOf(GUI.window)) { win.front }; if (makeWatcher) { this.makeWatcher }; } makeWatcher { skipjack.stop; skipjack = SkipJack({ this.updateAll }, 0.5, { win.isClosed }, "PxMon" + try { proxy.key } ); skipjack.start; } updateAll { var monitor, outs, amps, newHasSeriesOut; 30: playsSpread = proxy.monitor.hasSeriesOuts.not; outs = monitor.outs; }); 58: oldState = currState; } clear { proxy = nil } } ./SCClassLibrary/crucial/Gui/CXMenu.sc: 18: wbounds = Rect(20,20,windowWidth ? buttonWidth + 10,height); },{ ./SCClassLibrary/crucial/KernalTools/AnnotatedDebugNodeWatcher.sc: 32: this.doPost("ON ", nodeID, prevID, nextID); } ./SCClassLibrary/crucial/KernalTools/CXObjectInspector.sc: 182: // },minWidth:width) ./SCClassLibrary/crucial/Players/AbstractPlayer.sc: 525: delta { ^this.beatDuration } ./SCClassLibrary/crucial/Players/PlayerMixerGui.sc: 0: PlayerMixerGui : AbstractPlayerGui { guiBody { arg layout; this.durationGui(layout); model.players.do({ arg pl; pl.gui(layout.startRow); }); } } ./SCClassLibrary/crucial/Players/SimpleTrigger.sc: 10: synthArg { ^spec.minval } rate { ^\control } addToSynthDef { arg synthDef,name; synthDef.addTr(name,this.synthArg); } instrArgFromControl { arg control; ^control } makePatchOut { patchOut = UpdatingScalarPatchOut(this,enabled: false); } didStop { ./SCClassLibrary/crucial/Players/SimpleTriggerGui.sc: 0: SimpleTriggerGui : AbstractPlayerGui { guiBody { arg layout; ActionButton(layout,model.name ? "trig",{ model.trig;}); } } ./SCClassLibrary/crucial/Players/pathUtilities.sc: 9: loadPath { arg warnIfNotFound=true; ^this.collect { arg obj; obj.loadPath(warnIfNotFound) } } ./SCClassLibrary/crucial/UncoupledUsefulThings/Constraint.sc: 4: not { ^Not(this) } 5: or { arg constraint; ^Any([this,constraint]) } ./SCClassLibrary/crucial/UncoupledUsefulThings/ZArchive.sc: 0: ZArchive : File { var stringCache,<>path,<>version=1.0; var lastItem,count=0,stringCacheStart; *write { arg pathName; ^super.new(pathName, "wb").path_(pathName).check.initStringCache } *read { arg pathName; ^super.new(pathName, "rb").path_(pathName).check .getStringCache } writeItem { arg thing, extraArgs; var check; // == has some problems check = lastItem === thing; if(check,{ count = count + 1; },{ lastItem = thing; this.saveCount; thing.writeZArchive(this,extraArgs); }); } readItem { arg class; // if class not nil, it will assert that the item is of that class var type,size,thing,classname; if(count > 0,{ count = count - 1; ^lastItem }); type = this.getChar; if(type == $.,{ // ... repetition count = this.getInt32 - 1; ^lastItem }); if(type == $N,{ if(class.notNil and: (Nil !== class),{ die("ZArchive got wrong type:",nil,"expected:",class.asString); }); ^lastItem = nil }); if(type == $F,{ thing = this.getFloat; if(class.notNil and: (thing.class !== class),{ die("ZArchive got wrong type:",thing,"expected:",class.asString); }); ^lastItem = thing }); if(type == $I,{ thing = this.getInt32; if(class.notNil and: (thing.class !== class),{ die("ZArchive got wrong type:",thing,"expected:",class.asString); }); ^lastItem = thing }); if(type == $s,{ // small string < 128 thing = this.readString; if(class.notNil and: (thing.class !== class),{ die("ZArchive got wrong type:",thing,"expected:",class.asString); }); ^lastItem = thing }); if(type == $S,{ // large string thing = this.readLargeString; if(class.notNil and: (thing.class !== class),{ die("ZArchive got wrong type:",thing,"expected:",class.asString); }); ^lastItem = thing }); if(type == $y,{ // symbol thing = this.readString.asSymbol; if(class.notNil and: (thing.class !== class),{ die("ZArchive got wrong type:",thing,"expected:",class.asString); }); ^lastItem = thing }); if(type == $D,{// dictionaries classname = this.readString; size = this.getInt32; thing = classname.asSymbol.asClass.new(size); if(class.notNil and: (thing.class !== class),{ die("ZArchive got wrong type:",thing,"expected:",class.asString); }); size.do({ arg i; thing.put(this.readItem,this.readItem); }); ^lastItem = thing }); if(type == $C,{ // collection classname = this.readString; size = this.getInt32; thing = classname.asSymbol.asClass.new(size); if(class.notNil and: (thing.class !== class),{ die("ZArchive got wrong type:",thing,"expected:",class.asString); }); size.do({ arg i; thing.add( this.readItem ); }); ^lastItem = thing }); if(type == $x,{ // small compile string thing = this.readString.interpret; if(class.notNil and: (thing.class !== class),{ die("ZArchive got wrong type:",thing,"expected:",class.asString); }); ^lastItem = thing }); if(type == $X,{ // large compile string thing = this.readLargeString.interpret; if(class.notNil and: (thing.class !== class),{ die("ZArchive got wrong type:",thing,"expected:",class.asString); }); ^lastItem = thing }); if(this.pos >= (stringCacheStart),{ this.close; "End of file, unable to read item".die(this); }); this.close; die("ZArchive read error, got bad type code:",type); } writeClose { var stringCacheStart; this.saveCount; stringCacheStart = this.pos; // if you do go over the limit, you could simply raise the limit but your old files aren't compatible if(stringCache.size >= (2**16),{ "Too many strings in archive ! Not supported.".die; }); this.putInt16(stringCache.size); stringCache.keysValuesDo({ |string,index| this.putInt16(index); this.putInt8(string.size); this.putString(string); }); this.putInt32(stringCacheStart); this.close; } //PRIVATE saveCount { if(count > 0,{ super.putChar($.); super.putInt32(count); count = 0; }); } check { if(this.isOpen.not,{ "Z 1: Archive failed to open".die(path); }); } initStringCache { stringCache = Dictionary.new } getStringCache { var size; this.seek(-4,2); // bytes from the end stringCacheStart = this.getInt32; this.seek(stringCacheStart,0); size = this.getInt16; stringCache = Array.newClear(size); size.do({ arg i; var index,ssize,string; index = this.getInt16; ssize = this.getInt8; /*if(ssize < 0,{ Error("ZArchive read error. String table returns negative sized item").throw; });*/ string = String.newClear(ssize); this.read(string); stringCache.put( index, string ); }); this.seek(0,0); // the one thing you will never archive is the archiver itself // so lastItem starts with this lastItem = this; // any other item in existence is something you might potentially save next // eg. Object, nil } writeString { arg string; var prev; prev = stringCache[string]; if(prev.isNil,{ prev = stringCache.size; stringCache[string] = prev; }); this.putInt16(prev); } readString { var ix,string; ix = this.getInt16; ^stringCache[ix] ?? {"ZArchive failed to find String : index:".die(ix);}; } writeLargeString { arg string; this.putInt32(string.size); this.putString(string); } readLargeString { var size,string; size = this.getInt32; string = String.newClear(size); this.read(string); ^string } asZArchive { ^this } } /* to detect repeats of dictionaries (or events) and arrays: instead of internally using writeItem/readItem, use prWriteItem,prReadItem. this would break current archives, so you could use a different type code for the new ones */ ./SCClassLibrary/crucial/Crucial.sc: 208: Library.at(\menuItems,\tools,'Server Node Report').value; },minWidth: 250); 211: Library.at(\menuItems,\tools,'Annotated Buses Report').value; },minWidth: 250); 214: Library.at(\menuItems,\tools,'listen to audio busses').value; },minWidth: 250); 221: Library.at(\menuItems,\tools,'Annotated Nodes Report').value; },minWidth: 250);
~top = "./SCClassLibrary/"; ~regexp = "[^ \n\r\t].*\t}"; ~threaded = true; ( // depth-first, why not? ~searchDirectory = { |path| var dirs = (path ++ "*/").pathMatch, files = (path ++ "*.sc").pathMatch; dirs.do({ |dir| ~searchDirectory.(dir); }); files.do({ |file| ~searchFile.(file); if(~threaded and: { thisThread.isKindOf(Routine) }) { 0.01.wait }; }); }; ~searchFile = { |path| var file = File(path, "r"), line, lineCount = 0, needToPostPath = true; if(file.isOpen) { protect { while { (line = file.getLine(4096)).notNil } { if("^//".matchRegexp(line).not and: { ~regexp.matchRegexp(line) }) { if(needToPostPath) { "\n%:\n".postf(path); needToPostPath = false; }; "%: %\n".postf(lineCount, line); }; lineCount = lineCount + 1; }; } { file.close }; } { "Failed to open %. Continuing.".format(path).warn; }; }; ) // test ~searchFile.(SCView.filenameSymbol.asString); // run for real { ~searchDirectory.(~top); }.fork(AppClock); : H. James Harkins .::!:.:.......:.::........:..!.::.::...:..:...:.:.:.:..: "Come said the Muse, Sing me a song no poet has yet chanted, Sing me the universal." -- Whitman |