1 String[char] : RawArray {
2 classvar <>unixCmdActions;
5 unixCmdActions = IdentityDictionary.new;
10 unixCmdActions[pid].value(res, pid);
11 unixCmdActions.removeAt(pid);
15 arg postOutput = true;
20 // runs a unix command and sends stdout to the post window
22 arg action, postOutput = true;
24 pid = this.prUnixCmd(postOutput);
26 unixCmdActions.put(pid, action);
31 // Like unixCmd but gets the result into a string
33 var pipe, lines, line;
35 pipe = Pipe.new(this, "r");
38 while({line.notNil}, {lines = lines ++ line ++ "\n"; line = pipe.getLine; });
57 ^Array.fill(this.size, { |i| this[i].ascii })
74 compare { arg aString, ignoreCase=false; _StringCompare }
75 < { arg aString; ^this.compare(aString, true) < 0 }
76 > { arg aString; ^this.compare(aString, true) > 0 }
77 <= { arg aString; ^this.compare(aString, true) <= 0 }
78 >= { arg aString; ^this.compare(aString, true) >= 0 }
79 == { arg aString; ^this.compare(aString, true) == 0 }
80 != { arg aString; ^this.compare(aString, true) != 0 }
83 // no sense doing collect as per superclass collection
84 performBinaryOpOnSimpleNumber { arg aSelector, aNumber;
85 ^aNumber.asString.perform(aSelector, this);
87 performBinaryOpOnComplex { arg aSelector, aComplex;
88 ^aComplex.asString.perform(aSelector, this);
93 asCompileString { _String_AsCompileString; }
98 postcln { "// ".post; this.postln; }
99 postc { "// ".post; this.post; }
101 postf { arg ... items; ^this.prFormat( items.collect(_.asString) ).post }
102 format { arg ... items; ^this.prFormat( items.collect(_.asString) ) }
103 prFormat { arg items; _String_Format ^this.primitiveFailed }
104 matchRegexp { arg string, start = 0, end; _String_Regexp ^this.primitiveFailed }
106 fformat { arg ... args;
107 var str, resArgs, val, func;
108 var suffixes, sig = false;
112 val = args.removeAt(0);
113 func = Post.formats[char];
115 resArgs = resArgs.add(val);
118 resArgs = resArgs.add(func.value(val))
124 if(char == $%) { sig = true };
126 ^str.format(*resArgs)
129 die { arg ... culprits;
130 if(culprits.notEmpty,{
131 ("\n\nFATAL ERROR: ").postln;
132 culprits.do({ arg c; if(c.isString,{c.postln},{c.dump}) });
136 error { "ERROR:\n".post; this.postln; }
137 warn { "WARNING:\n".post; this.postln }
138 inform { ^this.postln }
139 ++ { arg anObject; ^this prCat: anObject.asString; }
140 + { arg anObject; ^this prCat: " " prCat: anObject.asString; }
141 catArgs { arg ... items; ^this.catList(items) }
142 scatArgs { arg ... items; ^this.scatList(items) }
143 ccatArgs { arg ... items; ^this.ccatList(items) }
145 // concatenate this with a list as a string
146 var string = this.copy;
147 list.do({ arg item, i;
148 string = string ++ item;
153 var string = this.copy;
154 list.do({ arg item, i;
155 string = string prCat: " " ++ item;
160 var string = this.copy;
161 list.do({ arg item, i;
162 string = string prCat: ", " ++ item;
166 split { arg separator=$/;
169 separator=separator.ascii;
172 if(let.ascii != separator ,{
175 array=array.add(word);
182 containsStringAt { arg index, string;
183 ^compare( this[index..index + string.size-1], string, false) == 0
186 icontainsStringAt { arg index, string;
187 ^compare( this[index..index + string.size-1], string, true) == 0
191 contains { arg string, offset = 0;
192 ^this.find(string, false, offset).notNil
194 containsi { arg string, offset = 0;
195 ^this.find(string, true, offset).notNil
198 findRegexp { arg regexp, offset = 0;
200 ^this.primitiveFailed
203 findAllRegexp { arg string, offset = 0;
204 var indices = [], i=[];
206 i = this.findRegexp(string, offset);
207 i.notNil and: {i.size != 0}
209 indices = indices.add(i);
210 offset = i[0][0] + 1;
215 find { arg string, ignoreCase = false, offset = 0;
217 ^this.primitiveFailed
219 findBackwards { arg string, ignoreCase = false, offset = 0x7FFFFFFE;
220 _String_FindBackwards
221 ^this.primitiveFailed
223 endsWith { arg string;
224 ^this.contains(string, this.size - string.size)
226 beginsWith { arg string;
227 ^this.containsStringAt(0, string)
229 findAll { arg string, ignoreCase = false, offset=0;
232 i = this.find(string, ignoreCase, offset);
235 indices = indices.add(i);
240 replace { arg find, replace;
241 ^super.replace(find, replace).join
245 escapeChar { arg charToEscape; // $"
249 ^"'"++this.replace("'","'\\''")++"'"
252 ^"\"" ++ this ++ "\""
255 ^this.collect({ arg char;
256 if(char == from,{to},{char})
260 insert { arg index, string;
261 ^this.keep(index) ++ string ++ this.drop(index)
264 wrapExtend { arg size;
265 ^this.dup(size div: this.size).join ++ this.keep(size % this.size)
272 padLeft { arg size, string = " ";
273 ^string.wrapExtend(max(0, size - this.size)) ++ this
276 padRight { arg size, string = " ";
277 ^this ++ string.wrapExtend(max(0, size - this.size))
280 underlined { arg char = $-;
281 ^this ++ "\n" ++ String.fill(this.size, char)
285 ^this.as(Array).scramble.as(String)
289 ^this.as(Array).rotate(n).as(String)
292 compile { ^thisProcess.interpreter.compile(this); }
293 interpret { ^thisProcess.interpreter.interpret(this); }
294 interpretPrint { ^thisProcess.interpreter.interpretPrint(this); }
299 prCat { arg aString; _ArrayCat }
301 printOn { arg stream;
304 storeOn { arg stream;
305 stream.putAll(this.asCompileString);
308 inspectorClass { ^StringInspector }
313 _String_StandardizePath
314 ^this.primitiveFailed
318 ^this.primitiveFailed
321 var sep = thisProcess.platform.pathSeparator;
322 if(this.last != sep, {
328 withoutTrailingSlash {
329 var sep = thisProcess.platform.pathSeparator;
330 if(this.last == sep,{
331 ^this.copyRange(0, this.size-2)
339 sep = thisProcess.platform.pathSeparator;
341 if(first == sep){^this};
342 if(first == $~){^this.standardizePath};
343 ^File.getcwd ++ sep ++ this;
346 pathMatch { _StringPathMatch ^this.primitiveFailed } // glob
348 ^thisProcess.interpreter.executeFile(this);
350 loadPaths { |warn=true|
351 var paths = this.pathMatch;
352 if(warn and:{paths.isEmpty}) { ("no files found for this path:" + this.quote).warn };
353 ^paths.collect({ arg path;
354 thisProcess.interpreter.executeFile(path);
358 var path = thisProcess.nowExecutingPath;
359 if(path.isNil) { Error("can't load relative to an unsaved file").throw};
360 if(path.basename == this) { Error("should not load a file from itself").throw };
361 ^(path.dirname ++ thisProcess.platform.pathSeparator ++ this).loadPaths
365 caller = thisMethod.getBackTrace.caller.functionDef;
366 if(caller.isKindOf(Method) && (caller != Interpreter.findMethod(\interpretPrintCmdLine)), {
367 path = caller.filenameSymbol.asString;
369 path = thisProcess.nowExecutingPath;
371 if(this[0] == thisProcess.platform.pathSeparator, {^this});
372 if(path.isNil) { Error("can't resolve relative to an unsaved file").throw};
373 ^(path.dirname ++ thisProcess.platform.pathSeparator ++ this)
376 if(Quarks.isInstalled(this).not) {
377 Quarks.install(this);
378 "... the class library may have to be recompiled.".postln;
379 // maybe check later whether there are .sc files included.
383 if(Quarks.isInstalled(this)) {
384 Quarks.uninstall(this);
385 "... the class library may have to be recompiled.".postln;
390 ^this.primitiveFailed
394 ^this.primitiveFailed
397 this.reverseDo({ arg char, i;
399 ^[this.copyFromStart(this.size - 2 - i), this.copyToEnd(this.size - i)]
407 var pathSeparator = thisProcess.platform.pathSeparator;
409 if (path.respondsTo(\fullPath)) {
410 ^PathName(this +/+ path.fullPath)
413 if (this.last == pathSeparator or: { path.first == pathSeparator }) {
417 ^this ++ pathSeparator ++ path
420 asRelativePath { |relativeTo|
421 ^PathName(this).asRelativePath(relativeTo)
424 // changed because there is no need to create a separate object
425 // when String already knows how to make an absolute path
426 ^this.absolutePath; // was ^PathName(this).asAbsolutePath
429 // runs a unix command and returns the result code.
430 systemCmd { _String_System ^this.primitiveFailed }
432 gethostbyname { _GetHostByName ^this.primitiveFailed }
434 // gets value of environment variable
437 ^this.primitiveFailed
439 // sets value of environment variable
440 // value may be nil to unset the variable
443 ^this.primitiveFailed
450 codegen_UGenCtorArg { arg stream;
451 stream << this.asCompileString;
453 ugenCodeString { arg ugenIndex, isDecl, inputNames=#[], inputStrings=#[];
455 ^this.primitiveFailed
458 asSecs { |maxDays = 365| // assume a timeString of ddd:hh:mm:ss.sss. see asTimeString.
459 var time = 0, sign = 1, str = this;
460 var limits = [inf, 60, 60, 24, maxDays];
461 var scaling = [0.001, 1.0, 60.0, 3600.0, 86400.0];
462 var padding = [3, 2, 2, 2, 3];
464 if (this.first == $-) {
469 str.split($:).reverseDo { |num, i|
470 num = num.padRight(padding[i], "0").asInteger;
471 if (num > limits[i]) {
472 ("asSecs: number greater than allowed:" + this).warn;
476 ("asSecs: negative numbers within slots not supported:" + this).warn;
479 time = time + (num * scaling[i]);
484 speak { arg channel = 0, force = false;
485 var speech = GUI.current.speech;
486 if( speech.initialized.not, { speech.init });
487 speech.channels[ channel ].speak( this, force );
491 ^this.collect(_.toLower)
494 ^this.collect(_.toUpper)