• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

CLI interface to medialist (fossil mirror)


Commit MetaInfo

修訂f1ae6e3ca2c4cc608d3e97ae6cb05c16085676e5 (tree)
時間2023-04-06 11:34:50
作者mio <stigma@disr...>
Commitermio

Log Message

Update mlib files for trash 0.3.0

FossilOrigin-Name: f3652b1434c672564cded98949f06eb82af7e67fcf3fc9af9c8db870d3497c69

Change Summary

差異

--- a/dub.sdl
+++ b/dub.sdl
@@ -13,7 +13,7 @@ license "GPL-3.0"
1313
1414 # update_deps.sh
1515 dependency "mlib" \
16- path="/home/mio/Projects/mlib" \
16+ path="./mlib" \
1717 version="*"
1818
1919 sourceFiles "main.d" \
--- a/mlib/source/mlib/configparser.d
+++ /dev/null
@@ -1,775 +0,0 @@
1-/*
2- * Permission to use, copy, modify, and/or distribute this software for any
3- * purpose with or without fee is herby granted.
4- *
5- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
6- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
7- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
8- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
9- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
10- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
11- * OR IN CONNECTION WITH THE USE OR PEFORMANCE OF THIS SOFTWARE.
12- */
13-
14-
15-/**
16- * An incomplete single-file INI parser for D.
17- *
18- * The API should be similar to python's configparse module. Internally it
19- * uses the standard D associative array.
20- *
21- * Example:
22- * ---
23- * import configparser;
24- *
25- * auto config = new ConfigParser();
26- * // no sections initially
27- * assert(config.sections.length == 0);
28- * // Section names ("Program Settings") are case-sensitive
29- * conf.addSection("Storage Paths");
30- * // Option names ("CONFIG_PATH") are case-insensitive
31- * // (internally, they are all converted to lower-case)
32- * conf.set("Program Settings", "CONFIG_PATH", "/home/user/.local/config");
33- * ---
34- *
35- * Authors: nemophila
36- * Date: 2023-03-19
37- * Homepage: https://osdn.net/users/nemophila/pf/mlib
38- * License: 0BSD
39- * Version: 0.4
40- *
41- * History:
42- * 0.4 Add .write()
43- * 0.3 Fix option values not always being treated as lowercase.
44- * 0.2 Add .getBool()
45- * 0.1 Initial release
46- */
47-module mlib.configparser;
48-
49-private
50-{
51- import std.conv : ConvException;
52- import std.stdio : File;
53-}
54-
55-public class DuplicateSectionException : Exception
56-{
57- private string m_section;
58-
59- this(string section)
60- {
61- string msg = "Section " ~ section ~ " already exists.";
62- m_section = section;
63- super(msg);
64- }
65-
66- string section()
67- {
68- return m_section;
69- }
70-}
71-
72-///
73-/// An exception that is thrown by a strict parser which indicates
74-/// that an option appears twice within any one section.
75-///
76-public class DuplicateOptionException : Exception
77-{
78- private string m_option;
79- private string m_section;
80-
81- this(string option, string section)
82- {
83- string msg = "Option " ~ option ~ " in section " ~ section ~
84- " already exists.";
85- m_option = option;
86- m_section = section;
87- super(msg);
88- }
89-
90- string option()
91- {
92- return m_option;
93- }
94-
95- string section()
96- {
97- return m_section;
98- }
99-}
100-
101-public class NoSectionException : Exception
102-{
103- private string m_section;
104-
105- this(string section)
106- {
107- string msg = "Section '" ~ section ~ "' does not exist.";
108- m_section = section;
109- super(msg);
110- }
111-
112- string section()
113- {
114- return m_section;
115- }
116-}
117-
118-public class NoOptionException : Exception
119-{
120- private string m_section;
121- private string m_option;
122-
123- this(string section, string option)
124- {
125- string msg = "Section '" ~ section ~ "' does not have option '" ~
126- option ~ "'.";
127- m_section = section;
128- m_option = option;
129- super(msg);
130- }
131-
132- string section() { return m_section; }
133- string option() { return m_option; }
134-}
135-
136-/**
137- * The main configuration parser.
138- */
139-public class ConfigParser
140-{
141- private char[] m_delimiters;
142- private char[] m_commentPrefixes;
143- private bool m_strict;
144-
145- /** current section for parsing */
146- private string m_currentSection;
147- private string[string][string] m_sections;
148-
149- /**
150- * Creates a new instance of ConfigParser.
151- */
152- this(char[] delimiters = ['=', ':'],
153- char[] commentPrefixes = ['#', ';'],
154- bool strict = true)
155- {
156- m_delimiters = delimiters;
157- m_commentPrefixes = commentPrefixes;
158- m_strict = strict;
159- }
160-
161- /**
162- * Return an array containing the available sections.
163- */
164- string[] sections()
165- {
166- return m_sections.keys();
167- }
168-
169- ///
170- unittest
171- {
172- auto conf = new ConfigParser();
173-
174- assert(0 == conf.sections().length);
175-
176- conf.addSection("Section");
177-
178- assert(1 == conf.sections().length);
179- }
180-
181- /**
182- * Add a section named `section` to the instance.
183- *
184- * Throws:
185- * - DuplicateSectionError if a section by the given name already
186- * exists.
187- */
188- void addSection(string section)
189- {
190- if (section in m_sections)
191- throw new DuplicateSectionException(section);
192- m_sections[section] = null;
193- }
194-
195- ///
196- unittest
197- {
198- import std.exception : assertNotThrown, assertThrown;
199-
200- auto conf = new ConfigParser();
201-
202- /* doesn't yet exist */
203- assertNotThrown!DuplicateSectionException(conf.addSection("sample"));
204- /* already exists */
205- assertThrown!DuplicateSectionException(conf.addSection("sample"));
206- }
207-
208- /**
209- * Indicates whether the named `section` is present in the configuration.
210- *
211- * Params:
212- * section = The section to check for in the configuration.
213- *
214- * Returns: `true` if the section exists, `false` otherwise.
215- */
216- bool hasSection(string section)
217- {
218- auto exists = (section in m_sections);
219- return (exists !is null);
220- }
221-
222- ///
223- unittest
224- {
225- auto conf = new ConfigParser();
226- conf.addSection("nExt");
227- assert(true == conf.hasSection("nExt"), "Close the world.");
228- assert(false == conf.hasSection("world"), "Open the nExt.");
229- }
230-
231- string[] options(string section)
232- {
233- if (false == this.hasSection(section))
234- throw new NoSectionException(section);
235- return m_sections[section].keys();
236- }
237-
238- ///
239- unittest
240- {
241- import std.exception : assertNotThrown, assertThrown;
242-
243- auto conf = new ConfigParser();
244-
245- conf.addSection("Settings");
246-
247- assertNotThrown!NoSectionException(conf.options("Settings"));
248- assertThrown!NoSectionException(conf.options("void"));
249-
250- string[] options = conf.options("Settings");
251- assert(0 == options.length, "More keys than we need");
252- }
253-
254- bool hasOption(string section, string option)
255- {
256- import std.string : toLower;
257-
258- if (false == this.hasSection(section))
259- return false;
260-
261- scope lowercaseOption = toLower(option);
262- auto exists = (lowercaseOption in m_sections[section]);
263- return (exists !is null);
264- }
265- /*
266- string[] read(string[] filenames)
267- {
268- return null;
269- }*/
270-
271- void read(string filename)
272- {
273- File file = File(filename, "r");
274- scope(exit) { file.close(); }
275- read(file, false);
276- }
277-
278- ///
279- unittest
280- {
281- import std.file : remove;
282- import std.stdio : File;
283-
284- auto configFile = File("test.conf", "w+");
285- configFile.writeln("[Section 1]");
286- configFile.writeln("key=value");
287- configFile.writeln("\n[Section 2]");
288- configFile.writeln("key2 = value");
289- configFile.close();
290-
291- auto conf = new ConfigParser();
292- conf.read("test.conf");
293-
294- assert(2 == conf.sections.length, "Incorrect Sections length");
295- assert(true == conf.hasSection("Section 1"),
296- "Config file doesn't have Section 1");
297- assert(true == conf.hasOption("Section 1", "key"),
298- "Config file doesn't have 'key' in 'Section 1'");
299-
300- remove("test.conf");
301- }
302-
303- /**
304- * Parse a config file.
305- *
306- * Params:
307- * file = Reference to the file from which to read.
308- * close = Close the file when finished parsing.
309- */
310- void read(ref File file, bool close = true)
311- {
312- import std.array : array;
313- import std.algorithm.searching : canFind;
314- import std.string : strip;
315-
316- scope(exit) { if (close) file.close(); }
317-
318- string[] lines = file.byLineCopy.array;
319-
320- for (auto i = 0; i < lines.length; i++) {
321- string line = lines[i].strip();
322-
323- if (line == "")
324- continue;
325-
326- if ('[' == lines[i][0]) {
327- parseSectionHeader(lines[i]);
328- } else if (false == canFind(m_commentPrefixes, lines[i][0])) {
329- parseLine(lines[i]);
330- }
331- /* ignore comments */
332- }
333- }
334-
335- /*void readString(string str)
336- {
337- }*/
338-
339- /**
340- * Get an `option` value for the named `section`.
341- *
342- * Params:
343- * section = The section to look for the given `option`.
344- * option = The option to return the value of
345- * fallback = Fallback value if the `option` is not found. Can be null.
346- *
347- * Returns:
348- * - The value for `option` if it is found.
349- * - `null` if the `option` is not found and `fallback` is not provided.
350- * - `fallback` if the `option` is not found and `fallback` is provided.
351- *
352- * Throws:
353- * - NoSectionException if the `section` does not exist and no fallback is provided.
354- * - NoOptionException if the `option` does not exist and no fallback is provided.
355- */
356- string get(string section, string option)
357- {
358- import std.string : toLower;
359-
360- scope lowercaseOption = toLower(option);
361-
362- if (false == this.hasSection(section))
363- throw new NoSectionException(section);
364-
365- if (false == this.hasOption(section, lowercaseOption))
366- throw new NoOptionException(section, lowercaseOption);
367-
368- return m_sections[section][lowercaseOption];
369- }
370-
371- ///
372- unittest
373- {
374- import std.exception : assertThrown;
375-
376- auto conf = new ConfigParser();
377- conf.addSection("Section");
378- conf.set("Section", "option", "value");
379-
380- assert(conf.get("Section", "option") == "value");
381- assertThrown!NoSectionException(conf.get("section", "option"));
382- assertThrown!NoOptionException(conf.get("Section", "void"));
383- }
384-
385- /// Ditto
386- string get(string section, string option, string fallback)
387- {
388- string res = fallback;
389-
390- try {
391- res = get(section, option);
392- } catch (NoSectionException e) {
393- return res;
394- } catch (NoOptionException e) {
395- return res;
396- }
397-
398- return res;
399- }
400-
401- ///
402- unittest
403- {
404- import std.exception : assertThrown;
405-
406- auto conf = new ConfigParser();
407- conf.addSection("Section");
408- conf.set("Section", "option", "value");
409-
410- assert("value" == conf.get("Section", "option"));
411- assert("fallback" == conf.get("section", "option", "fallback"));
412- assert("fallback" == conf.get("Section", "void", "fallback"));
413-
414- /* can use null for fallback */
415- assert(null == conf.get("section", "option", null));
416- assert(null == conf.get("Section", "void", null));
417- }
418-
419- /**
420- * A convenience method which casts the value of `option` in `section`
421- * to an integer.
422- *
423- * Params:
424- * section = The section to look for the given `option`.
425- * option = The option to return the value for.
426- * fallback = The fallback value to use if `option` isn't found.
427- *
428- * Returns:
429- *
430- *
431- * Throws:
432- * - NoSectionFoundException if `section` doesn't exist.
433- * - NoOptionFoundException if the `section` doesn't contain `option`.
434- * - ConvException if it failed to parse the value to an int.
435- * - ConvOverflowException if the value would overflow an int.
436- *
437- * See_Also: get()
438- */
439- int getInt(string section, string option)
440- {
441- import std.conv : parse;
442-
443- string res;
444-
445- res = get(section, option);
446-
447- return parse!int(res);
448- }
449-
450- /// Ditto
451- int getInt(string section, string option, int fallback)
452- {
453- int res = fallback;
454-
455- try {
456- res = getInt(section, option);
457- } catch (Exception e) {
458- return res;
459- }
460-
461- return res;
462- }
463-
464- /*
465- double getDouble(string section, string option)
466- {
467- }
468-
469- double getDouble(string section, string option, double fallback)
470- {
471- }
472-
473- float getFloat(string section, string option)
474- {
475- }
476-
477- float getFloat(string section, string option, float fallback)
478- {
479- }*/
480-
481- /**
482- * A convenience method which coerces the $(I option) in the
483- * specified $(I section) to a boolean value.
484- *
485- * Note that the accepted values for the option are "1", "yes",
486- * "true", and "on", which cause this method to return `true`, and
487- * "0", "no", "false", and "off", which cause it to return `false`.
488- *
489- * These string values are checked in a case-insensitive manner.
490- *
491- * Params:
492- * section = The section to look for the given option.
493- * option = The option to return the value for.
494- * fallback = The fallback value to use if the option was not found.
495- *
496- * Throws:
497- * - NoSectionFoundException if `section` doesn't exist.
498- * - NoOptionFoundException if the `section` doesn't contain `option`.
499- * - ConvException if any other value was found.
500- */
501- bool getBool(string section, string option)
502- {
503- import std.string : toLower;
504-
505- string value = get(section, option);
506-
507- switch (value.toLower)
508- {
509- case "1":
510- case "yes":
511- case "true":
512- case "on":
513- return true;
514- case "0":
515- case "no":
516- case "false":
517- case "off":
518- return false;
519- default:
520- throw new ConvException("No valid boolean value found");
521- }
522- }
523-
524- /// Ditto
525- bool getBool(string section, string option, bool fallback)
526- {
527- try {
528- return getBool(section, option);
529- } catch (Exception e) {
530- return fallback;
531- }
532- }
533-
534- /*
535- string[string] items(string section)
536- {
537- }*/
538-
539- /**
540- * Remove the specified `option` from the specified `section`.
541- *
542- * Params:
543- * section = The section to remove from.
544- * option = The option to remove from section.
545- *
546- * Retruns:
547- * `true` if option existed, false otherwise.
548- *
549- * Throws:
550- * - NoSectionException if the specified section doesn't exist.
551- */
552- bool removeOption(string section, string option)
553- {
554- if ((section in m_sections) is null) {
555- throw new NoSectionException(section);
556- }
557-
558- if (option in m_sections[section]) {
559- m_sections[section].remove(option);
560- return true;
561- }
562-
563- return false;
564- }
565-
566- ///
567- unittest
568- {
569- import std.exception : assertThrown;
570-
571- auto conf = new ConfigParser();
572- conf.addSection("Default");
573- conf.set("Default", "exists", "true");
574-
575- assertThrown!NoSectionException(conf.removeOption("void", "false"));
576- assert(false == conf.removeOption("Default", "void"));
577- assert(true == conf.removeOption("Default", "exists"));
578- }
579-
580- /**
581- * Remove the specified `section` from the config.
582- *
583- * Params:
584- * section = The section to remove.
585- *
586- * Returns:
587- * `true` if the section existed, `false` otherwise.
588- */
589- bool removeSection(string section)
590- {
591- if (section in m_sections) {
592- m_sections.remove(section);
593- return true;
594- }
595- return false;
596- }
597-
598- ///
599- unittest
600- {
601- auto conf = new ConfigParser();
602- conf.addSection("Exists");
603- assert(false == conf.removeSection("DoesNotExist"));
604- assert(true == conf.removeSection("Exists"));
605- }
606-
607- void set(string section, string option, string value)
608- {
609- import std.string : toLower;
610-
611- if (false == this.hasSection(section))
612- throw new NoSectionException(section);
613-
614- scope lowercaseOption = toLower(option);
615- m_sections[section][lowercaseOption] = value;
616- }
617-
618- ///
619- unittest
620- {
621- import std.exception : assertThrown;
622-
623- auto conf = new ConfigParser();
624-
625- assertThrown!NoSectionException(conf.set("Section", "option",
626- "value"));
627-
628- conf.addSection("Section");
629- conf.set("Section", "option", "value");
630- assert(conf.get("Section", "option") == "value");
631- }
632-
633- ///
634- /// Write a representation of the configuration to the
635- /// provided *file*.
636- ///
637- /// This representation can be parsed by future calls to
638- /// `read`. This does **not** close the file after writing.
639- ///
640- /// Params:
641- /// file = An open file which was opened in text mode.
642- /// spaceAroundDelimiters = The delimiters between keys and
643- /// values are surrounded by spaces.
644- ///
645- /// Note: Comments from the original file are not preserved when
646- /// writing the configuration back.
647- ///
648- void write(ref File file, bool spaceAroundDelimiters = true)
649- {
650- string del = spaceAroundDelimiters ? " = " : "=";
651-
652- foreach(string section, string[string] options; m_sections) {
653- file.writefln("[%s]", section);
654-
655- foreach(string option, string value; options) {
656- file.writefln("%s%s%s", option, del, value);
657- }
658- }
659- }
660-
661- ///
662- unittest
663- {
664- import std.file : remove;
665- import std.stdio : File;
666-
667- auto writer = new ConfigParser();
668- writer.addSection("general");
669-
670- writer.addSection("GUI");
671- writer.set("GUI", "WINDOW_WIDTH", "848");
672- writer.set("GUI", "WINDOW_HEIGHT", "480");
673-
674- auto file = File("test.ini", "w+");
675- scope(exit) remove(file.name);
676- writer.write(file);
677-
678- file.rewind();
679-
680- auto reader = new ConfigParser();
681- reader.read(file);
682-
683- assert(reader.hasSection("general"), "reader does not contain general section");
684-
685- assert(reader.hasSection("GUI"), "reader does not contain GUI section");
686- assert(reader.get("GUI", "WINDOW_WIDTH") == "848", "reader GUI.WINDOW_WIDTH is not 848");
687- assert(reader.getInt("GUI", "WINDOW_WIDTH") == 848, "reader GUI.WINDOW_WIDTH is not 848 (int)");
688-
689- assert(reader.get("GUI", "WINDOW_HEIGHT") == "480", "reader GUI.WINDOW_HEIGHT is not 480");
690- assert(reader.getInt("GUI", "WINDOW_HEIGHT") == 480, "reader GUI.WINDOW_HEIGHT is not 480 (int)");
691- }
692-
693- private:
694-
695- void parseSectionHeader(ref string line)
696- {
697- import std.array : appender, assocArray;
698-
699- auto sectionHeader = appender!string;
700- /* presume that the last character is ] */
701- sectionHeader.reserve(line.length - 1);
702- string popped = line[1 .. $];
703-
704- foreach(c; popped) {
705- if (c != ']')
706- sectionHeader.put(c);
707- else
708- break;
709- }
710-
711- m_currentSection = sectionHeader.data();
712-
713- if (m_currentSection in m_sections && m_strict)
714- throw new DuplicateSectionException(m_currentSection);
715-
716- try {
717- this.addSection(m_currentSection);
718- } catch (DuplicateSectionException) {
719- }
720- }
721-
722- void parseLine(ref string line)
723- {
724- import std.string : indexOfAny, toLower, strip;
725-
726- ptrdiff_t idx = line.indexOfAny(m_delimiters);
727- if (-1 == idx) return;
728- string option = line[0 .. idx].dup.strip.toLower;
729- string value = line[idx + 1 .. $].dup.strip;
730-
731- if (option in m_sections[m_currentSection] && m_strict)
732- throw new DuplicateOptionException(option, m_currentSection);
733-
734- m_sections[m_currentSection][option] = value;
735- }
736-
737- unittest
738- {
739- import std.exception : assertThrown, assertNotThrown;
740- import std.file : remove;
741-
742- auto f = File("config.cfg", "w+");
743- f.writeln("[section]");
744- f.writeln("option = value");
745- f.writeln("Option = value");
746- f.close();
747- scope(exit) remove("config.cfg");
748-
749- // Duplicate option
750- scope parser = new ConfigParser();
751- assertThrown!DuplicateOptionException(parser.read("config.cfg"));
752-
753- // Duplicate section
754- f = File("config.cfg", "w+");
755- f.writeln("[section]");
756- f.writeln("option = value");
757- f.writeln("[section]");
758- f.close();
759-
760- assertThrown!DuplicateSectionException(parser.read("config.cfg"));
761-
762- // not strict
763- scope relaxedParser = new ConfigParser(['='], [], false);
764-
765- assertNotThrown!DuplicateSectionException(relaxedParser.read("config.cfg"));
766- assert(relaxedParser.hasSection("section"));
767-
768- f = File("config.cfg", "a+");
769- f.writeln("option = newValue");
770- f.close();
771-
772- assertNotThrown!DuplicateOptionException(relaxedParser.read("config.cfg"));
773- assert(relaxedParser.get("section", "option") == "newValue");
774- }
775-}
--- a/mlib/source/mlib/package.d
+++ /dev/null
@@ -1,7 +0,0 @@
1-///
2-/// A collection of public domain modules for the
3-/// $(LINK2 https://dlang.org, D Programming Language).
4-///
5-/// All modules are compatible with D versions 2.076.0 and newer.
6-///
7-module mlib;
--- a/mlib/source/mlib/trash.d
+++ b/mlib/source/mlib/trash.d
@@ -18,13 +18,14 @@
1818 * macOS will be implemented in a future version.
1919 *
2020 * Authors: nemophila
21- * Date: January 29, 2023
21+ * Date: April 05, 2023
2222 * Homepage: https://osdn.net/users/nemophila/pf/mlib
2323 * License: 0BSD
2424 * Standards: The FreeDesktop.org Trash Specification 1.0
25- * Version: 0.2.0
25+ * Version: 0.3.0
2626 *
2727 * History:
28+ * 0.3.0 fix XDG naming convention bug
2829 * 0.2.0 added support for Windows
2930 * 0.1.0 is the initial version
3031 *
@@ -291,12 +292,12 @@ version(Posix) {
291292 * directory. Even if a file with the same name and location gets trashed many times,
292293 * each subsequent trashing must not overwrite a previous copy." */
293294 size_t counter = 0;
294- string destname = basename;
295- string infoFilename = destname.setExtension(".trashinfo");
296- while (exists(buildPath(filesDir, destname)) || exists(buildPath(infoDir, infoFilename))) {
295+ string filesFilename = basename;
296+ string infoFilename = filesFilename ~ ".trashinfo";
297+ while (exists(buildPath(filesDir, filesFilename)) || exists(buildPath(infoDir, infoFilename))) {
297298 counter += 1;
298- destname = filename ~ "_" ~ to!string(counter) ~ ext;
299- infoFilename = destname.setExtension(".trashinfo");
299+ filesFilename = basename ~ "_" ~ to!string(counter) ~ ext;
300+ infoFilename = filesFilename ~ ".trashinfo";
300301 }
301302
302303 {
@@ -306,7 +307,7 @@ version(Posix) {
306307 infoFile.write(getInfo(path, topdir));
307308 }
308309 {
309- string filesPath = buildPath(filesDir, destname);
310+ string filesPath = buildPath(filesDir, filesFilename);
310311 rename(path, filesPath);
311312 pathInTrash = filesPath;
312313 }
--- a/update_deps.sh
+++ b/update_deps.sh
@@ -20,16 +20,26 @@ _DIR_COMMIT="8f1f7e3c05abc2734020727892988051ce25f29e"
2020 _TSH_COMMIT="1bfc9295af9ec716bf5b26c70f50b0187d7148bf"
2121
2222 _DUB_RAW_URL="https://osdn.net/users/nemophila/pf/mlib/scm/blobs/$_DUB_COMMIT/dub.sdl?export=raw"
23+_RDM_RAW_URL="https://osdn.net/users/nemophila/pf/mlib/scm/blobs/$_DUB_COMMIT/README?export=raw"
24+_LIC_RAW_URL="https://osdn.net/users/nemophila/pf/mlib/scm/blobs/$_DUB_COMMIT/LICENSE?export=raw"
25+
2326 _CNI_RAW_URL="https://osdn.net/users/nemophila/pf/mlib/scm/blobs/$_CNI_COMMIT/source/mlib/cni.d?export=raw"
2427 _DIR_RAW_URL="https://osdn.net/users/nemophila/pf/mlib/scm/blobs/$_DIR_COMMIT/source/mlib/directories.d?export=raw"
2528 _TSH_RAW_URL="https://osdn.net/users/nemophila/pf/mlib/scm/blobs/$_TSH_COMMIT/source/mlib/trash.d?export=raw"
2629
30+if [ -d mlib ]
31+then
32+ rm -rf mlib
33+fi
34+
2735 if [ $TRUE -eq $_HAVE_WGET ]
2836 then
2937 # Update by fetching archive with wget
30- [ ! -d mlib/source/mlib ] && mkdir -p mlib/source/mlib
38+ mkdir -p mlib/source/mlib
3139 cd mlib
3240 wget -O "dub.sdl" "$_DUB_RAW_URL" && sleep 2
41+ wget -O "README" "$_RDM_RAW_URL" && sleep 2
42+ wget -O "LICENSE" "$_LIC_RAW_URL" && sleep 2
3343 cd source/mlib
3444 wget -O "cni.d" "$_CNI_RAW_URL" && sleep 2
3545 wget -O "directories.d" "$_DIR_RAW_URL" && sleep 2
@@ -37,9 +47,11 @@ then
3747 elif [ $TRUE -eq $_HAVE_CURL ]
3848 then
3949 # Update by fetching archive with curl
40- [ ! -d mlib/source/mlib ] && mkdir -p mlib/source/mlib
50+ mkdir -p mlib/source/mlib
4151 cd mlib
4252 curl -o "dub.sdl" "$_DUB_RAW_URL" && sleep 2
53+ curl -o "README" "$_RDM_RAW_URL" && sleep 2
54+ curl -o "LICENSE" "$_LIC_RAW_URL" && sleep 2
4355 cd source/mlib
4456 curl -o "cni.d" "$_CNI_RAW_URL" && sleep 2
4557 curl -o "directories.d" "$_DIR_RAW_URL" && sleep 2