-
Notifications
You must be signed in to change notification settings - Fork 298
/
Util.mo
1763 lines (1571 loc) · 48 KB
/
Util.mo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2019, Open Source Modelica Consortium (OSMC),
* c/o Linköpings universitet, Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR
* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
* ACCORDING TO RECIPIENTS CHOICE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from OSMC, either from the above address,
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
* http://www.openmodelica.org, and in the OpenModelica distribution.
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/
encapsulated package Util
" file: Util.mo
package: Util
description: Miscellanous MetaModelica Compiler (MMC) utilities
This package contains various MetaModelica Compiler (MMC) utilities sigh, mostly
related to lists.
It is used pretty much everywhere. The difference between this
module and the ModUtil module is that ModUtil contains modelica
related utilities. The Util module only contains *low-level*
MetaModelica Compiler (MMC) utilities, for example finding elements in lists.
This modules contains many functions that use *type variables* in MetaModelica Compiler (MMC).
A type variable is exactly what it sounds like, a type bound to a variable.
It is used for higher order functions, i.e. in MetaModelica Compiler (MMC) the possibility to pass a
\"pointer\" to a function into another function. But it can also be used for
generic data types, like in C++ templates."
public uniontype Status "Used to signal success or failure of a function call"
record SUCCESS end SUCCESS;
record FAILURE end FAILURE;
end Status;
public uniontype DateTime
record DATETIME
Integer sec;
Integer min;
Integer hour;
Integer mday;
Integer mon;
Integer year;
end DATETIME;
end DateTime;
protected
import Autoconf;
import ClockIndexes;
import Global;
import List;
import Print;
import System;
public constant SourceInfo dummyInfo = SOURCEINFO("",false,0,0,0,0,0.0);
public function isIntGreater "Author: BZ"
input Integer lhs;
input Integer rhs;
output Boolean b = lhs > rhs;
end isIntGreater;
public function isRealGreater "Author: BZ"
input Real lhs;
input Real rhs;
output Boolean b = lhs > rhs;
end isRealGreater;
public function linuxDotSlash "If operating system is Linux/Unix, return a './', otherwise return empty string"
output String str;
algorithm
str := Autoconf.os;
str := if str == "linux" or str == "darwin" then "./" else "";
end linuxDotSlash;
public function flagValue "author: x02lucpo
Extracts the flagvalue from an argument list:
flagValue('-s',{'-d','hej','-s','file'}) => 'file'"
input String flag;
input list<String> arguments;
output String flagVal;
protected
String arg;
list<String> rest = arguments;
algorithm
while not listEmpty(rest) loop
arg :: rest := rest;
if arg == flag then
break;
end if;
end while;
flagVal := if listEmpty(rest) then "" else listHead(rest);
end flagValue;
public function selectFirstNonEmptyString
"Selects the first non-empty string from a list of strings.
Returns an empty string if no such string exists."
input list<String> inStrings;
output String outResult;
algorithm
for e in inStrings loop
if e <> "" then
outResult := e;
return;
end if;
end for;
outResult := "";
end selectFirstNonEmptyString;
public function compareTupleIntGt<T>
" Function could used with List.sort to sort a
List as list< tuple<Integer, Type_a> > by first argument.
"
input tuple<Integer, T> inTplA;
input tuple<Integer, T> inTplB;
output Boolean res;
protected
Integer a,b;
algorithm
(a, _) := inTplA;
(b, _) := inTplB;
res := intGt(a,b);
end compareTupleIntGt;
public function compareTupleIntLt<T>
" Function could used with List.sort to sort a
List as list< tuple<Integer, Type_a> > by first argument.
"
input tuple<Integer, T> inTplA;
input tuple<Integer, T> inTplB;
output Boolean res;
protected
Integer a,b;
algorithm
(a, _) := inTplA;
(b, _) := inTplB;
res := intLt(a,b);
end compareTupleIntLt;
public function compareTuple2IntGt<T>
" Function could used with List.sort to sort a
List as list< tuple<Type_a,Integer> > by second argument.
"
input tuple<T, Integer> inTplA;
input tuple<T, Integer> inTplB;
output Boolean res;
protected
Integer a,b;
algorithm
(_, a) := inTplA;
(_, b) := inTplB;
res := intGt(a,b);
end compareTuple2IntGt;
public function compareTuple2IntLt<T>
" Function could used with List.sort to sort a
List as list< tuple<Type_a,Integer> > by second argument.
"
input tuple<T, Integer> inTplA;
input tuple<T, Integer> inTplB;
output Boolean res;
protected
Integer a,b;
algorithm
(_, a) := inTplA;
(_, b) := inTplB;
res := intLt(a,b);
end compareTuple2IntLt;
public function tuple21<T1, T2>
"Takes a tuple of two values and returns the first value.
Example: tuple21(('a', 1)) => 'a'"
input tuple<T1, T2> inTuple;
output T1 outValue;
algorithm
(outValue, _) := inTuple;
end tuple21;
public function tuple22<T1, T2>
"Takes a tuple of two values and returns the second value.
Example: tuple22(('a',1)) => 1"
input tuple<T1, T2> inTuple;
output T2 outValue;
algorithm
(_, outValue) := inTuple;
end tuple22;
public function optTuple22<T1, T2>
"Takes an option tuple of two values and returns the second value.
Example: optTuple22(SOME('a',1)) => 1"
input Option<tuple<T1, T2>> inTuple;
output T2 outValue;
algorithm
SOME((_, outValue)) := inTuple;
end optTuple22;
public function tuple312<T1, T2, T3>
"Takes a tuple of three values and returns the tuple of the two first values.
Example: tuple312(('a',1,2)) => ('a',1)"
input tuple<T1, T2, T3> inTuple;
output tuple<T1, T2> outTuple;
protected
T1 e1;
T2 e2;
algorithm
(e1, e2, _) := inTuple;
outTuple := (e1, e2);
end tuple312;
public function tuple31<T1, T2, T3>
"Takes a tuple of three values and returns the first value.
Example: tuple31(('a',1,2)) => 'a'"
input tuple<T1, T2, T3> inValue;
output T1 outValue;
algorithm
(outValue, _, _) := inValue;
end tuple31;
public function tuple32<T1, T2, T3>
"Takes a tuple of three values and returns the second value.
Example: tuple32(('a',1,2)) => 1"
input tuple<T1, T2, T3> inValue;
output T2 outValue;
algorithm
(_, outValue, _) := inValue;
end tuple32;
public function tuple33<T1, T2, T3>
"Takes a tuple of three values and returns the first value.
Example: tuple33(('a',1,2)) => 2"
input tuple<T1, T2, T3> inValue;
output T3 outValue;
algorithm
(_, _, outValue) := inValue;
end tuple33;
public function tuple41<T1, T2, T3, T4>
input tuple<T1, T2, T3, T4> inTuple;
output T1 outValue;
algorithm
(outValue, _, _, _) := inTuple;
end tuple41;
public function tuple42<T1, T2, T3, T4>
input tuple<T1, T2, T3, T4> inTuple;
output T2 outValue;
algorithm
(_, outValue, _, _) := inTuple;
end tuple42;
public function tuple43<T1, T2, T3, T4>
input tuple<T1, T2, T3, T4> inTuple;
output T3 outValue;
algorithm
(_, _, outValue, _) := inTuple;
end tuple43;
public function tuple44<T1, T2, T3, T4>
input tuple<T1, T2, T3, T4> inTuple;
output T4 outValue;
algorithm
(_, _, _, outValue) := inTuple;
end tuple44;
public function tuple51<T1, T2, T3, T4, T5>
input tuple<T1, T2, T3, T4, T5> inTuple;
output T1 outValue;
algorithm
(outValue, _, _, _, _) := inTuple;
end tuple51;
public function tuple52<T1, T2, T3, T4, T5>
input tuple<T1, T2, T3, T4, T5> inTuple;
output T2 outValue;
algorithm
(_, outValue, _, _, _) := inTuple;
end tuple52;
public function tuple53<T1, T2, T3, T4, T5>
input tuple<T1, T2, T3, T4, T5> inTuple;
output T3 outValue;
algorithm
(_, _, outValue, _, _) := inTuple;
end tuple53;
public function tuple54<T1, T2, T3, T4, T5>
input tuple<T1, T2, T3, T4, T5> inTuple;
output T4 outValue;
algorithm
(_, _, _, outValue, _) := inTuple;
end tuple54;
public function tuple55<T1, T2, T3, T4, T5>
input tuple<T1, T2, T3, T4, T5> inTuple;
output T5 outValue;
algorithm
(_, _, _, _, outValue) := inTuple;
end tuple55;
public function tuple61<T1, T2, T3, T4, T5, T6>
input tuple<T1, T2, T3, T4, T5, T6> inTuple;
output T1 outValue;
algorithm
(outValue, _, _ ,_ ,_ ,_ ) := inTuple;
end tuple61;
public function tuple62<T1, T2, T3, T4, T5, T6>
input tuple<T1, T2, T3, T4, T5, T6> inTuple;
output T2 outValue;
algorithm
(_, outValue, _ ,_ ,_ ,_ ) := inTuple;
end tuple62;
public function stringContainsChar "Returns true if a string contains a specified character"
input String str;
input String char;
output Boolean res;
algorithm
res := matchcontinue()
case ()
equation
_::_::_ = stringSplitAtChar(str,char);
then true;
else false;
end matchcontinue;
end stringContainsChar;
public function stringDelimitListPrintBuf "
Author: BZ, 2009-11
Same functionality as stringDelimitListPrint, but writes to print buffer instead of string variable.
Usefull for heavy string operations(causes malloc error on some models when generating init file).
"
input list<String> inStringLst;
input String inDelimiter;
algorithm
_:=
matchcontinue (inStringLst)
local
String f,delim,str1,str2,str;
list<String> r;
case {} then ();
case {f} equation Print.printBuf(f); then ();
case f :: r
equation
stringDelimitListPrintBuf(r, inDelimiter);
Print.printBuf(f);
Print.printBuf(inDelimiter);
then
();
end matchcontinue;
end stringDelimitListPrintBuf;
public function stringDelimitListAndSeparate "author: PA
This function is similar to stringDelimitList, i.e it inserts string delimiters between
consecutive strings in a list. But it also count the lists and inserts a second string delimiter
when the counter is reached. This can be used when for instance outputting large lists of values
and a newline is needed after ten or so items."
input list<String> str;
input String sep1;
input String sep2;
input Integer n;
output String res;
protected
Integer handle;
algorithm
handle := Print.saveAndClearBuf();
stringDelimitListAndSeparate2(str, sep1, sep2, n, 0);
res := Print.getString();
Print.restoreBuf(handle);
end stringDelimitListAndSeparate;
protected function stringDelimitListAndSeparate2 "author: PA
Helper function to stringDelimitListAndSeparate"
input list<String> inStringLst1;
input String inString2;
input String inString3;
input Integer inInteger4;
input Integer inInteger5;
algorithm
_ := matchcontinue (inStringLst1,inString2,inString3,inInteger4,inInteger5)
local
String s,str1,str,f,sep1,sep2;
list<String> r;
Integer n,iter_1,iter;
case ({},_,_,_,_) then (); /* iterator */
case ({s},_,_,_,_) equation
Print.printBuf(s);
then ();
case ((f :: r),sep1,sep2,n,0)
equation
Print.printBuf(f);Print.printBuf(sep1);
stringDelimitListAndSeparate2(r, sep1, sep2, n, 1) "special case for first element" ;
then
();
case ((f :: r),sep1,sep2,n,iter)
equation
0 = intMod(iter, n) "insert second delimiter" ;
iter_1 = iter + 1;
Print.printBuf(f);Print.printBuf(sep1);Print.printBuf(sep2);
stringDelimitListAndSeparate2(r, sep1, sep2, n, iter_1);
then
();
case ((f :: r),sep1,sep2,n,iter)
equation
iter_1 = iter + 1 "not inserting second delimiter" ;
Print.printBuf(f);Print.printBuf(sep1);
stringDelimitListAndSeparate2(r, sep1, sep2, n, iter_1);
then
();
else
equation
print("- stringDelimitListAndSeparate2 failed\n");
then
fail();
end matchcontinue;
end stringDelimitListAndSeparate2;
public function stringDelimitListNonEmptyElts "the string delimiter inserted between those elements that are not empty.
Example: stringDelimitListNonEmptyElts({\"x\",\"\",\"z\"}, \", \") => \"x, z\""
input list<String> lst;
input String delim;
output String str;
protected
list<String> lst1;
algorithm
lst1 := List.select(lst, isNotEmptyString);
str := stringDelimitList(lst1, delim);
end stringDelimitListNonEmptyElts;
public function mulStringDelimit2Int
" splits the input string at the delimiter string in list of strings and converts to integer list which is then summarized
"
input String inString;
input String delim;
output Integer i;
protected
list<String> lst;
list<Integer> lst2;
algorithm
lst:=stringSplitAtChar(inString,delim);
lst2:=List.map(lst, stringInt);
if not listEmpty(lst2) then
i := List.fold(lst2,intMul,1);
else
i := 0;
end if;
end mulStringDelimit2Int;
public function stringReplaceChar "Takes a string and two chars and replaces the first char with the second char:
Example: string_replace_char(\"hej.b.c\",\".\",\"_\") => \"hej_b_c\"
2007-11-26 BZ: Now it is possible to replace chars with emptychar, and
replace a char with a string
Example: string_replace_char(\"hej.b.c\",\".\",\"_dot_\") => \"hej_dot_b_dot_c\"
"
input String inString1;
input String inString2;
input String inString3;
output String outString;
algorithm
outString := System.stringReplace(inString1, inString2, inString3);
end stringReplaceChar;
public function stringSplitAtChar "Takes a string and a char and split the string at the char returning the list of components.
Example: stringSplitAtChar(\"hej.b.c\",\".\") => {\"hej,\"b\",\"c\"}"
input String string;
input String token;
output list<String> strings = {};
protected
Integer ch = stringCharInt(token);
list<String> cur = {};
algorithm
for c in stringListStringChar(string) loop
if stringCharInt(c) == ch then
strings := stringAppendList(listReverse(cur)) :: strings;
cur := {};
else
cur := c :: cur;
end if;
end for;
if not listEmpty(cur) then
strings := stringAppendList(listReverse(cur)) :: strings;
end if;
strings := listReverse(strings);
end stringSplitAtChar;
public function boolOrList "Example:
boolOrList({true,false,false}) => true
boolOrList({false,false,false}) => false"
input list<Boolean> inBooleanLst;
output Boolean outBoolean = false;
algorithm
for b in inBooleanLst loop
if b then
outBoolean := true;
return;
end if;
end for;
end boolOrList;
public function boolAndList "Takes a list of boolean values and applies the boolean AND operator on the elements
Example:
boolAndList({}) => true
boolAndList({true, true}) => true
boolAndList({false,false,true}) => false"
input list<Boolean> inBooleanLst;
output Boolean outBoolean = true;
algorithm
for b in inBooleanLst loop
if not b then
outBoolean := false;
return;
end if;
end for;
end boolAndList;
public function applyOption<TI, TO>
"Takes an option value and a function over the value. It returns in another
option value, resulting from the application of the function on the value.
Example:
applyOption(SOME(1), intString) => SOME(\"1\")
applyOption(NONE(), intString) => NONE()
"
input Option<TI> inOption;
input FuncType inFunc;
output Option<TO> outOption;
partial function FuncType
input TI inValue;
output TO outValue;
end FuncType;
algorithm
outOption := match(inOption)
local
TI ival;
TO oval;
case SOME(ival) then SOME(inFunc(ival));
else NONE();
end match;
end applyOption;
public function applyOption1<TI, TO, ArgT>
"Like applyOption but takes an additional argument"
input Option<TI> inOption;
input FuncType inFunc;
input ArgT inArg;
output Option<TO> outOption;
partial function FuncType
input TI inValue;
input ArgT inArg;
output TO outValue;
end FuncType;
algorithm
outOption := match(inOption)
local
TI ival;
TO oval;
case SOME(ival) then SOME(inFunc(ival, inArg));
else NONE();
end match;
end applyOption1;
public function applyOptionOrDefault<TI, TO>
"Takes an optional value, a function and an extra value. If the optional value
is SOME, applies the function on that value and returns the result.
Otherwise returns the extra value."
input Option<TI> inValue;
input FuncType inFunc;
input TO inDefaultValue;
output TO outValue;
partial function FuncType
input TI inValue;
output TO outValue;
end FuncType;
algorithm
outValue := match(inValue)
local
TI value;
case SOME(value) then inFunc(value);
else inDefaultValue;
end match;
end applyOptionOrDefault;
public function applyOptionOrDefault1<TI, TO, ArgT>
"Takes an optional value, a function, an extra argument and an extra value.
If the optional value is SOME, applies the function on that value and the
extra argument and returns the result. Otherwise returns the extra value."
input Option<TI> inValue;
input FuncType inFunc;
input ArgT inArg;
input TO inDefaultValue;
output TO outValue;
partial function FuncType
input TI inValue;
input ArgT inArg;
output TO outValue;
end FuncType;
algorithm
outValue := match(inValue)
local
TI value;
case SOME(value) then inFunc(value, inArg);
else inDefaultValue;
end match;
end applyOptionOrDefault1;
public function applyOptionOrDefault2<TI, TO, ArgT1, ArgT2>
"Takes an optional value, a function, two extra arguments and an extra value.
If the optional value is SOME, applies the function on that value and the
extra argument and returns the result. Otherwise returns the extra value."
input Option<TI> inValue;
input FuncType inFunc;
input ArgT1 inArg1;
input ArgT2 inArg2;
input TO inDefaultValue;
output TO outValue;
partial function FuncType
input TI inValue;
input ArgT1 inArg1;
input ArgT2 inArg2;
output TO outValue;
end FuncType;
algorithm
outValue := match(inValue)
local
TI value;
case SOME(value) then inFunc(value, inArg1, inArg2);
else inDefaultValue;
end match;
end applyOptionOrDefault2;
public function applyOption_2<T>
input Option<T> inValue1;
input Option<T> inValue2;
input FuncType inFunc;
output Option<T> outValue;
partial function FuncType
input T inValue1;
input T inValue2;
output T outValue;
end FuncType;
algorithm
outValue := match (inValue1, inValue2)
case (NONE(), _) then inValue2;
case (_, NONE()) then inValue1;
else SOME(inFunc(getOption(inValue1), getOption(inValue2)));
end match;
end applyOption_2;
public function makeOption<T>
"Makes a value into value option, using SOME(value)"
input T inValue;
output Option<T> outOption = SOME(inValue);
annotation(__OpenModelica_EarlyInline = true);
end makeOption;
public function makeOptionOnTrue<T>
input Boolean inCondition;
input T inValue;
output Option<T> outOption = if inCondition then SOME(inValue) else NONE();
annotation(__OpenModelica_EarlyInline = true);
end makeOptionOnTrue;
public function stringOption "author: PA
Returns string value or empty string from string option."
input Option<String> inStringOption;
output String outString;
algorithm
outString:= match(inStringOption)
local
String s;
case SOME(s) then s;
else "";
end match;
end stringOption;
public function getOption<T>
"Returns an option value if SOME, otherwise fails"
input Option<T> inOption;
output T outValue;
algorithm
SOME(outValue) := inOption;
end getOption;
public function getOptionOrDefault<T>
"Returns an option value if SOME, otherwise the default"
input Option<T> inOption;
input T inDefault;
output T outValue;
algorithm
outValue := match(inOption)
local
T value;
case SOME(value) then value;
else inDefault;
end match;
end getOptionOrDefault;
public function intGreaterZero
"Returns true if integer value is greater zero (> 0)"
input Integer v;
output Boolean res = v > 0;
end intGreaterZero;
public function intPositive
"Returns true if integer value is positive (>= 0)"
input Integer v;
output Boolean res = v >= 0;
end intPositive;
public function intNegative
"Returns true if integer value is negative (< 0)"
input Integer v;
output Boolean res = v < 0;
end intNegative;
public function intSign
input Integer i;
output Integer o = if i == 0 then 0 elseif i > 0 then 1 else -1;
end intSign;
public function intCompare
"Compares two integers and return -1 if the first is smallest, 1 if the second
is smallest, or 0 if they are equal."
input Integer inN;
input Integer inM;
output Integer outResult = if inN == inM then 0 elseif inN > inM then 1 else -1;
end intCompare;
public function intPow
"Performs integer exponentiation."
input Integer base;
input Integer exponent;
output Integer result = 1;
algorithm
if exponent >= 0 then
for i in 1:exponent loop
result := result * base;
end for;
else
fail();
end if;
end intPow;
public function realNegative
"Returns true if the Real value is negative, otherwise false."
input Real v;
output Boolean res = v < 0;
end realNegative;
public function realCompare
"Compares two reals and return -1 if the first is smallest, 1 if the second
is smallest, or 0 if they are equal."
input Real inN;
input Real inM;
output Integer outResult = if inN == inM then 0 elseif inN > inM then 1 else -1;
end realCompare;
public function boolCompare
"Compares two booleans and return -1 if the first is smallest, 1 if the second
is smallest, or 0 if they are equal."
input Boolean inN;
input Boolean inM;
output Integer outResult = if inN == inM then 0 elseif inN > inM then 1 else -1;
end boolCompare;
public function isNotEmptyString "Returns true if string is not the empty string."
input String inString;
output Boolean outIsNotEmpty = stringLength(inString) > 0;
end isNotEmptyString;
public function writeFileOrErrorMsg "This function tries to write to a file and if it fails then it
outputs \"# Cannot write to file: <filename>.\" to errorBuf"
input String inFilename;
input String inString;
algorithm
try
System.writeFile(inFilename, inString);
else
Print.printErrorBuf("# Cannot write to file: " + inFilename + ".");
end try;
end writeFileOrErrorMsg;
public function stringStartsWith
input String inString1;
input String inString2;
output Boolean outEqual;
algorithm
outEqual := (0 == System.strncmp(inString1, inString2, stringLength(inString1)));
end stringStartsWith;
public function strncmp "Compare two strings up to the nth character
Returns true if they are equal."
input String inString1;
input String inString2;
input Integer inLength;
output Boolean outEqual;
algorithm
outEqual := (0 == System.strncmp(inString1, inString2, inLength));
end strncmp;
public function notStrncmp
"Compares two strings up to the nth character. Returns true if they are not
equal."
input String inString1;
input String inString2;
input Integer inLength;
output Boolean outEqual;
algorithm
outEqual := (0 <> System.strncmp(inString1, inString2, inLength));
end notStrncmp;
public function tickStr "author: PA
Returns tick as a string, i.e. an unique number."
output String s = intString(tick());
end tickStr;
public function replaceWindowsBackSlashWithPathDelimiter
"@author: adrpo
replace \\ with path delimiter only in Windows!"
input String inPath;
output String outPath;
algorithm
if Autoconf.os == "Windows_NT" then
outPath := System.stringReplace(inPath, "\\", Autoconf.pathDelimiter);
else
outPath := inPath;
end if;
end replaceWindowsBackSlashWithPathDelimiter;
public function getAbsoluteDirectoryAndFile "author: x02lucpo
splits the filepath in directory and filename
(\"c:\\programs\\file.mo\") => (\"c:\\programs\",\"file.mo\")
(\"..\\work\\file.mo\") => (\"c:\\openmodelica123\\work\", \"file.mo\")"
input String filename;
output String dirname;
output String basename;
protected
String realpath;
algorithm
realpath := System.realpath(filename);
dirname := System.dirname(realpath);
basename := System.basename(realpath);
dirname := replaceWindowsBackSlashWithPathDelimiter(dirname);
end getAbsoluteDirectoryAndFile;
public function rawStringToInputString "author: x02lucpo
replace the double-backslash with backslash"
input String inString;
output String outString;
algorithm
outString := System.stringReplace(inString, "\\\"", "\"") "change backslash-double-quote to double-quote ";
outString := System.stringReplace(outString, "\\\\", "\\") "double-backslash with backslash ";
end rawStringToInputString;
public function escapeModelicaStringToCString
input String modelicaString;
output String cString;
algorithm
// C cannot handle newline in string constants
cString := System.escapedString(modelicaString,true);
end escapeModelicaStringToCString;
public function escapeModelicaStringToJLString
input String modelicaString;
output String cString;
algorithm
//TODO. Do this the proper way. We just remove all the dollars for now
cString := System.stringReplace(modelicaString, "$", "");
cString := System.stringReplace(cString, "\"", "");
cString := System.stringReplace(cString, "\"", "");
cString := System.stringReplace(cString, "\"\"", "");
cString := System.escapedString(cString,true);
end escapeModelicaStringToJLString;
public function escapeModelicaStringToXmlString
input String modelicaString;
output String xmlString;
algorithm
// C cannot handle newline in string constants
xmlString := System.stringReplace(modelicaString, "&", "&");
xmlString := System.stringReplace(xmlString, "\"", """);
xmlString := System.stringReplace(xmlString, "<", "<");
xmlString := System.stringReplace(xmlString, ">", ">");
xmlString := System.stringReplace(xmlString, "\n", " ");
xmlString := System.stringReplace(xmlString, "\r", " ");
// TODO! FIXME!, we have issues with accented chars in comments
// that end up in the Model_init.xml file and makes it not well
// formed but the line below does not work if the xmlString is
// already UTF-8. We should somehow detect the encoding.
// xmlString := System.iconv(xmlString, "", "UTF-8");
end escapeModelicaStringToXmlString;
public function makeQuotedIdentifier
input String str;
output String quotedIdentifier;
algorithm
quotedIdentifier := System.stringReplace(str, "\\", "\\\\");
quotedIdentifier := System.stringReplace(quotedIdentifier, "'", "\\'");
quotedIdentifier := "'" + quotedIdentifier + "'";
end makeQuotedIdentifier;
public function escapeQuotes
input String str;
output String quotes;
algorithm
quotes := System.stringReplace(str, "\\", "\\\\");
quotes := System.stringReplace(quotes, "'", "\\'");
end escapeQuotes;
public function makeTuple<T1, T2>
input T1 inValue1;
input T2 inValue2;
output tuple<T1, T2> outTuple = (inValue1, inValue2);
annotation(__OpenModelica_EarlyInline = true);
end makeTuple;
public function makeTupleR<T1, T2>
input T1 inValue1;
input T2 inValue2;
output tuple<T2, T1> outTuple = (inValue2, inValue1);
annotation(__OpenModelica_EarlyInline = true);
end makeTupleR;
public function make3Tuple<T1, T2, T3>
input T1 inValue1;
input T2 inValue2;
input T3 inValue3;
output tuple<T1, T2, T3> outTuple = (inValue1, inValue2, inValue3);
annotation(__OpenModelica_EarlyInline = true);
end make3Tuple;
public function mulListIntegerOpt
input list<Option<Integer>> inList;
input Integer inAccum = 1;
output Integer outResult;
algorithm
outResult := match(inList)
local
Integer i;
list<Option<Integer>> rest;
case {} then inAccum;
case SOME(i) :: rest then mulListIntegerOpt(rest, i * inAccum);
case NONE() :: rest then mulListIntegerOpt(rest, inAccum);
end match;
end mulListIntegerOpt;
public type StatefulBoolean = array<Boolean> "A single boolean value that can be updated (a destructive operation). NOTE: Use Mutable<Boolean> instead. This implementation is kept since Susan cannot use that type.";
public function makeStatefulBoolean
"Create a boolean with state (that is, it is mutable)"
input Boolean b;
output StatefulBoolean sb = arrayCreate(1, b);
end makeStatefulBoolean;
public function getStatefulBoolean
"Create a boolean with state (that is, it is mutable)"
input StatefulBoolean sb;
output Boolean b = sb[1];
end getStatefulBoolean;
public function setStatefulBoolean
"Update the state of a mutable boolean"
input StatefulBoolean sb;
input Boolean b;