summary refs log tree commit diff stats
path: root/doc/pydoc/ranger.defaults.apps.html
blob: fb820921140055b5ff27d9d11851c8c607157862 (plain) (blame)
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
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ranger.defaults.apps</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head><body bgcolor="#f0f0f8">

<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="ranger.html"><font color="#ffffff">ranger</font></a>.<a href="ranger.defaults.html"><font color="#ffffff">defaults</font></a>.apps</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/code/ranger/ranger/defaults/apps.py">/home/hut/code/ranger/ranger/defaults/apps.py</a></font></td></tr></table>
    <p><tt>This&nbsp;is&nbsp;the&nbsp;default&nbsp;ranger&nbsp;configuration&nbsp;file&nbsp;for&nbsp;filetype&nbsp;detection<br>
and&nbsp;application&nbsp;handling.<br>
&nbsp;<br>
You&nbsp;can&nbsp;place&nbsp;this&nbsp;file&nbsp;in&nbsp;your&nbsp;~/.ranger/&nbsp;directory&nbsp;and&nbsp;it&nbsp;will&nbsp;be&nbsp;used<br>
instead&nbsp;of&nbsp;this&nbsp;one.&nbsp;&nbsp;Though,&nbsp;to&nbsp;minimize&nbsp;your&nbsp;effort&nbsp;when&nbsp;upgrading&nbsp;ranger,<br>
you&nbsp;may&nbsp;want&nbsp;to&nbsp;subclass&nbsp;<a href="#CustomApplications">CustomApplications</a>&nbsp;rather&nbsp;than&nbsp;making&nbsp;a&nbsp;full&nbsp;copy.<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
This&nbsp;example&nbsp;modifies&nbsp;the&nbsp;behaviour&nbsp;of&nbsp;"feh"&nbsp;and&nbsp;adds&nbsp;a&nbsp;custom&nbsp;media&nbsp;player:<br>
&nbsp;<br>
####&nbsp;start&nbsp;of&nbsp;the&nbsp;~/.ranger/apps.py&nbsp;example<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;ranger.defaults.apps&nbsp;import&nbsp;<a href="#CustomApplications">CustomApplications</a>&nbsp;as&nbsp;DefaultApps<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;ranger.api.apps&nbsp;import&nbsp;*<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;<a href="#CustomApplications">CustomApplications</a>(DefaultApps):<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;app_kaffeine(self,&nbsp;c):<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;tup('kaffeine',&nbsp;*c)<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;app_feh_fullscreen_by_default(self,&nbsp;c):<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;tup('feh',&nbsp;'-F',&nbsp;*c)<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;app_default(self,&nbsp;c):<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;f&nbsp;=&nbsp;c.file&nbsp;#shortcut<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;f.video&nbsp;or&nbsp;f.audio:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;app_kaffeine(c)<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;f.image&nbsp;and&nbsp;c.mode&nbsp;==&nbsp;0:<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;app_feh_fullscreen_by_default(c)<br>
&nbsp;<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;DefaultApps.app_default(self,&nbsp;c)<br>
####&nbsp;end&nbsp;of&nbsp;the&nbsp;example</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#aa55cc">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
    
<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
</td><td width="25%" valign=top><a href="re.html">re</a><br>
</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
    
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="ranger.api.apps.html#Applications">ranger.api.apps.Applications</a>(<a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>)
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="ranger.defaults.apps.html#CustomApplications">CustomApplications</a>
</font></dt></dl>
</dd>
</dl>
 <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="CustomApplications">class <strong>CustomApplications</strong></a>(<a href="ranger.api.apps.html#Applications">ranger.api.apps.Applications</a>)</font></td></tr>
    
<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl><dt>Method resolution order:</dt>
<dd><a href="ranger.defaults.apps.html#CustomApplications">CustomApplications</a></dd>
<dd><a href="ranger.api.apps.html#Applications">ranger.api.apps.Applications</a></dd>
<dd><a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a></dd>
<dd><a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a></dd>
<dd><a href="builtins.html#object">builtins.object</a></dd>
</dl>
<hr>
Methods defined here:<br>
<dl><dt><strong>app_apvlv</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><a name="CustomApplications-app_aunpack"><strong>app_aunpack</strong></a>(self, c)</dt></dl>

<dl><dt><a name="CustomApplications-app_default"><strong>app_default</strong></a>(self, c)</dt><dd><tt>How&nbsp;to&nbsp;determine&nbsp;the&nbsp;default&nbsp;application?</tt></dd></dl>

<dl><dt><a name="CustomApplications-app_edit_or_run"><strong>app_edit_or_run</strong></a>(self, c)</dt></dl>

<dl><dt><a name="CustomApplications-app_editor"><strong>app_editor</strong></a>(self, c)</dt></dl>

<dl><dt><strong>app_elinks</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><strong>app_eog</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><strong>app_evince</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><strong>app_fceux</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><a name="CustomApplications-app_feh"><strong>app_feh</strong></a>(self, c)</dt></dl>

<dl><dt><strong>app_firefox</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><strong>app_gimp</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><a name="CustomApplications-app_java"><strong>app_java</strong></a>(self, c)</dt></dl>

<dl><dt><strong>app_javac</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><a name="CustomApplications-app_make"><strong>app_make</strong></a>(self, c)</dt></dl>

<dl><dt><strong>app_mirage</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><a name="CustomApplications-app_mplayer"><strong>app_mplayer</strong></a>(self, c)</dt></dl>

<dl><dt><strong>app_opera</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><a name="CustomApplications-app_pager"><strong>app_pager</strong></a>(self, c)</dt><dd><tt>#&nbsp;-----------------------------------------&nbsp;application&nbsp;definitions<br>
#&nbsp;Note:&nbsp;Trivial&nbsp;applications&nbsp;are&nbsp;defined&nbsp;at&nbsp;the&nbsp;bottom</tt></dd></dl>

<dl><dt><a name="CustomApplications-app_totem"><strong>app_totem</strong></a>(self, c)</dt></dl>

<dl><dt><strong>app_vim</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><strong>app_wine</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><strong>app_zathura</strong> <em>lambda</em> self, context</dt></dl>

<dl><dt><strong>app_zsnes</strong> <em>lambda</em> self, context</dt></dl>

<hr>
Methods inherited from <a href="ranger.api.apps.html#Applications">ranger.api.apps.Applications</a>:<br>
<dl><dt><a name="CustomApplications-all"><strong>all</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;with&nbsp;all&nbsp;application&nbsp;functions</tt></dd></dl>

<dl><dt><a name="CustomApplications-app_self"><strong>app_self</strong></a>(self, context)</dt><dd><tt>Run&nbsp;the&nbsp;file&nbsp;itself</tt></dd></dl>

<dl><dt><a name="CustomApplications-apply"><strong>apply</strong></a>(self, app, context)</dt></dl>

<dl><dt><a name="CustomApplications-either"><strong>either</strong></a>(self, context, *args)</dt></dl>

<dl><dt><a name="CustomApplications-get"><strong>get</strong></a>(self, app)</dt><dd><tt>Looks&nbsp;for&nbsp;an&nbsp;application,&nbsp;returns&nbsp;app_default&nbsp;if&nbsp;it&nbsp;doesn't&nbsp;exist</tt></dd></dl>

<dl><dt><a name="CustomApplications-has"><strong>has</strong></a>(self, app)</dt><dd><tt>Returns&nbsp;whether&nbsp;an&nbsp;application&nbsp;is&nbsp;defined</tt></dd></dl>

<hr>
Class methods inherited from <a href="ranger.api.apps.html#Applications">ranger.api.apps.Applications</a>:<br>
<dl><dt><a name="CustomApplications-generic"><strong>generic</strong></a>(cls, *args, **keywords)<font color="#909090"><font face="helvetica, arial"> from <a href="builtins.html#type">builtins.type</a></font></font></dt></dl>

<hr>
Data and other attributes inherited from <a href="ranger.shared.html#FileManagerAware">ranger.shared.FileManagerAware</a>:<br>
<dl><dt><strong>fm</strong> = None</dl>

<hr>
Data descriptors inherited from <a href="ranger.shared.html#Awareness">ranger.shared.Awareness</a>:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#55aa55">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
    
<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><strong>DELETE_WARNING</strong> = 'delete seriously? '<br>
<strong>INTERPRETED_LANGUAGES</strong> = &lt;_sre.SRE_Pattern object&gt;</td></tr></table>
</body></html>
/span> character))}, y:offset 4:boolean <- equal 1:address:array:character, 3:address:array:character ] +mem: storing 1 in location 4 :(before "End element_type Special-cases") if (contains_type_ingredient(element)) { if (!base.type->right) raise << "illegal type " << names_to_string(base.type) << " seems to be missing a type ingredient or three\n" << end(); replace_type_ingredients(element.type, base.type->right, info); } :(code) bool contains_type_ingredient(const reagent& x) { return contains_type_ingredient(x.type); } bool contains_type_ingredient(const type_tree* type) { if (!type) return false; if (type->value >= START_TYPE_INGREDIENTS) return true; assert(!is_type_ingredient_name(type->name)); return contains_type_ingredient(type->left) || contains_type_ingredient(type->right); } // replace all type_ingredients in element_type with corresponding elements of callsite_type // todo: too complicated and likely incomplete; maybe avoid replacing in place? void replace_type_ingredients(type_tree* element_type, const type_tree* callsite_type, const type_info& container_info) { if (!callsite_type) return; // error but it's already been raised above if (!element_type) return; // A. recurse first to avoid nested replaces (which I can't reason about yet) replace_type_ingredients(element_type->left, callsite_type, container_info); replace_type_ingredients(element_type->right, callsite_type, container_info); if (element_type->value < START_TYPE_INGREDIENTS) return; const int type_ingredient_index = element_type->value-START_TYPE_INGREDIENTS; if (!has_nth_type(callsite_type, type_ingredient_index)) { raise << "illegal type " << names_to_string(callsite_type) << " seems to be missing a type ingredient or three\n" << end(); return; } // B. replace the current location const type_tree* replacement = NULL; bool splice_right = true ; bool zig_left = false; { const type_tree* curr = callsite_type; for (int i = 0; i < type_ingredient_index; ++i) curr = curr->right; if (curr && curr->left) { replacement = curr->left; zig_left = true; } else { // We want foo:_t to be used like foo:number, which expands to {foo: number} // rather than {foo: (number)} // We'd also like to use it with multiple types: foo:address:number. replacement = curr; splice_right = final_type_ingredient(type_ingredient_index, container_info); } } if (element_type->right && replacement->right && zig_left) { // ZERO confidence that this condition is accurate element_type->name = ""; element_type->value = 0; element_type->left = new type_tree(*replacement); } else { string old_name = element_type->name; element_type->name = replacement->name; element_type->value = replacement->value; assert(!element_type->left); // since value is set element_type->left = replacement->left ? new type_tree(*replacement->left) : NULL; if (splice_right) { type_tree* old_right = element_type->right; element_type->right = replacement->right ? new type_tree(*replacement->right) : NULL; append(element_type->right, old_right); } } } bool final_type_ingredient(int type_ingredient_index, const type_info& container_info) { for (map<string, type_ordinal>::const_iterator p = container_info.type_ingredient_names.begin(); p != container_info.type_ingredient_names.end(); ++p) { if (p->second > START_TYPE_INGREDIENTS+type_ingredient_index) return false; } return true; } void append(type_tree*& base, type_tree* extra) { if (!base) { base = extra; return; } type_tree* curr = base; while (curr->right) curr = curr->right; curr->right = extra; } void append(string_tree*& base, string_tree* extra) { if (!base) { base = extra; return; } string_tree* curr = base; while (curr->right) curr = curr->right; curr->right = extra; } void test_replace_type_ingredients_entire() { run("container foo:_elem [\n" " x:_elem\n" " y:number\n" "]\n"); reagent callsite("x:foo:point"); reagent element = element_type(callsite, 0); CHECK_EQ(element.name, "x"); CHECK_EQ(element.type->name, "point"); CHECK(!element.type->right); } void test_replace_type_ingredients_tail() { run("container foo:_elem [\n" " x:_elem\n" "]\n" "container bar:_elem [\n" " x:foo:_elem\n" "]\n"); reagent callsite("x:bar:point"); reagent element = element_type(callsite, 0); CHECK_EQ(element.name, "x"); CHECK_EQ(element.type->name, "foo"); CHECK_EQ(element.type->right->name, "point"); CHECK(!element.type->right->right); } void test_replace_type_ingredients_head_tail_multiple() { run("container foo:_elem [\n" " x:_elem\n" "]\n" "container bar:_elem [\n" " x:foo:_elem\n" "]\n"); reagent callsite("x:bar:address:array:character"); reagent element = element_type(callsite, 0); CHECK_EQ(element.name, "x"); CHECK_EQ(element.type->name, "foo"); CHECK_EQ(element.type->right->name, "address"); CHECK_EQ(element.type->right->right->name, "array"); CHECK_EQ(element.type->right->right->right->name, "character"); CHECK(!element.type->right->right->right->right); } void test_replace_type_ingredients_head_middle() { run("container foo:_elem [\n" " x:_elem\n" "]\n" "container bar:_elem [\n" " x:foo:_elem:number\n" "]\n"); reagent callsite("x:bar:address"); reagent element = element_type(callsite, 0); CHECK_EQ(element.name, "x"); CHECK(element.type) CHECK_EQ(element.type->name, "foo"); CHECK(element.type->right) CHECK_EQ(element.type->right->name, "address"); CHECK(element.type->right->right) CHECK_EQ(element.type->right->right->name, "number"); CHECK(!element.type->right->right->right); } void test_replace_last_type_ingredient_with_multiple() { run("container foo:_a:_b [\n" " x:_a\n" " y:_b\n" "]\n"); reagent callsite("{f: (foo number (address array character))}"); reagent element1 = element_type(callsite, 0); CHECK_EQ(element1.name, "x"); CHECK_EQ(element1.type->name, "number"); CHECK(!element1.type->right); reagent element2 = element_type(callsite, 1); CHECK_EQ(element2.name, "y"); CHECK_EQ(element2.type->name, "address"); CHECK_EQ(element2.type->right->name, "array"); CHECK_EQ(element2.type->right->right->name, "character"); CHECK(!element2.type->right->right->right); } void test_replace_middle_type_ingredient_with_multiple() { run("container foo:_a:_b:_c [\n" " x:_a\n" " y:_b\n" " z:_c\n" "]\n"); reagent callsite("{f: (foo number (address array character) boolean)}"); reagent element1 = element_type(callsite, 0); CHECK_EQ(element1.name, "x"); CHECK_EQ(element1.type->name, "number"); CHECK(!element1.type->right); reagent element2 = element_type(callsite, 1); CHECK_EQ(element2.name, "y"); CHECK_EQ(element2.type->name, "address"); CHECK_EQ(element2.type->right->name, "array"); CHECK_EQ(element2.type->right->right->name, "character"); CHECK(!element2.type->right->right->right); reagent element3 = element_type(callsite, 2); CHECK_EQ(element3.name, "z"); CHECK_EQ(element3.type->name, "boolean"); CHECK(!element3.type->right); } void test_replace_middle_type_ingredient_with_multiple2() { run("container foo:_key:_value [\n" " key:_key\n" " value:_value\n" "]\n"); reagent callsite("{f: (foo (address array character) number)}"); reagent element = element_type(callsite, 0); CHECK_EQ(element.name, "key"); CHECK_EQ(element.type->name, "address"); CHECK_EQ(element.type->right->name, "array"); CHECK_EQ(element.type->right->right->name, "character"); CHECK(!element.type->right->right->right); } void test_replace_middle_type_ingredient_with_multiple3() { run("container foo_table:_key:_value [\n" " data:address:array:foo_table_row:_key:_value\n" "]\n" "\n" "container foo_table_row:_key:_value [\n" " key:_key\n" " value:_value\n" "]\n"); reagent callsite("{f: (foo_table (address array character) number)}"); reagent element = element_type(callsite, 0); CHECK_EQ(element.name, "data"); CHECK_EQ(element.type->name, "address"); CHECK_EQ(element.type->right->name, "array"); CHECK_EQ(element.type->right->right->name, "foo_table_row"); CHECK(element.type->right->right->right->left); CHECK_EQ(element.type->right->right->right->left->name, "address"); CHECK_EQ(element.type->right->right->right->left->right->name, "array"); CHECK_EQ(element.type->right->right->right->left->right->right->name, "character"); CHECK_EQ(element.type->right->right->right->right->name, "number"); CHECK(!element.type->right->right->right->right->right); } bool has_nth_type(const type_tree* base, int n) { assert(n >= 0); if (base == NULL) return false; if (n == 0) return true; return has_nth_type(base->right, n-1); } :(scenario get_on_shape_shifting_container_error) % Hide_errors = true; container foo:_t [ x:_t y:number ] def main [ 10:foo:point <- merge 14, 15, 16 1:number <- get 10:foo, 1:offset ] +error: illegal type "foo" seems to be missing a type ingredient or three //: 'merge' on shape-shifting containers :(scenario merge_check_shape_shifting_container_containing_exclusive_container) container foo:_elem [ x:number y:_elem ] exclusive-container bar [ x:number y:number ] def main [ 1:foo:bar <- merge 23, 1/y, 34 ] +mem: storing 23 in location 1 +mem: storing 1 in location 2 +mem: storing 34 in location 3 $error: 0 :(scenario merge_check_shape_shifting_container_containing_exclusive_container_2) % Hide_errors = true; container foo:_elem [ x:number y:_elem ] exclusive-container bar [ x:number y:number ] def main [ 1:foo:bar <- merge 23, 1/y, 34, 35 ] +error: main: too many ingredients in '1:foo:bar <- merge 23, 1/y, 34, 35' :(scenario merge_check_shape_shifting_exclusive_container_containing_container) exclusive-container foo:_elem [ x:number y:_elem ] container bar [ x:number y:number ] def main [ 1:foo:bar <- merge 1/y, 23, 34 ] +mem: storing 1 in location 1 +mem: storing 23 in location 2 +mem: storing 34 in location 3 $error: 0 :(scenario merge_check_shape_shifting_exclusive_container_containing_container_2) exclusive-container foo:_elem [ x:number y:_elem ] container bar [ x:number y:number ] def main [ 1:foo:bar <- merge 0/x, 23 ] $error: 0 :(scenario merge_check_shape_shifting_exclusive_container_containing_container_3) % Hide_errors = true; exclusive-container foo:_elem [ x:number y:_elem ] container bar [ x:number y:number ] def main [ 1:foo:bar <- merge 1/y, 23 ] +error: main: too few ingredients in '1:foo:bar <- merge 1/y, 23' :(before "End variant_type Special-cases") if (contains_type_ingredient(element)) { if (!base.type->right) raise << "illegal type '" << to_string(base.type) << "' seems to be missing a type ingredient or three\n" << end(); replace_type_ingredients(element.type, base.type->right, info); }