about summary refs log tree commit diff stats
path: root/archive/1.vm/099hardware_checks.cc
blob: c1039c1f29e4164b1383787bf6d623a70fcf39f2 (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
//: Let's raise errors when students use real hardware in any recipes besides
//: 'main'. Part of the goal is to teach them testing hygiene and dependency
//: injection.
//:
//: This is easy to sidestep, it's for feedback rather than safety.

:(before "End Globals")
vector<type_tree*> Real_hardware_types;
:(before "Begin transform_all")
setup_real_hardware_types();
:(before "End transform_all")
teardown_real_hardware_types();
:(code)
void setup_real_hardware_types() {
  Real_hardware_types.push_back(parse_type("address:screen"));
  Real_hardware_types.push_back(parse_type("address:console"));
  Real_hardware_types.push_back(parse_type("address:resources"));
}
type_tree* parse_type(string s) {
  reagent x("x:"+s);
  type_tree* result = x.type;
  x.type = NULL;  // don't deallocate on return
  return result;
}
void teardown_real_hardware_types() {
  for (int i = 0;  i < SIZE(Real_hardware_types);  ++i)
    delete Real_hardware_types.at(i);
  Real_hardware_types.clear();
}

:(before "End Checks")
Transform.push_back(check_for_misuse_of_real_hardware);
:(code)
void check_for_misuse_of_real_hardware(const recipe_ordinal r) {
  const recipe& caller = get(Recipe, r);
  if (caller.name == "main") return;
  if (starts_with(caller.name, "scenario_")) return;
  trace(101, "transform") << "--- check if recipe " << caller.name << " has any dependency-injection mistakes" << end();
  for (int index = 0;  index < SIZE(caller.steps);  ++index) {
    const instruction& inst = caller.steps.at(index);
    if (is_primitive(inst.operation)) continue;
    for (int i = 0;  i < SIZE(inst.ingredients);  ++i) {
      const reagent& ing = inst.ingredients.at(i);
      if (!is_literal(ing) || ing.name != "0") continue;
      const recipe& callee = get(Recipe, inst.operation);
      if (!callee.has_header) continue;
      if (i >= SIZE(callee.ingredients)) continue;
      const reagent& expected_ing = callee.ingredients.at(i);
      for (int j = 0;  j < SIZE(Real_hardware_types);  ++j) {
        if (*Real_hardware_types.at(j) == *expected_ing.type)
          raise << maybe(caller.name) << "'" << to_original_string(inst) << "': only 'main' can pass 0 into a " << to_string(expected_ing.type) << '\n' << end();
      }
    }
  }
}

void test_warn_on_using_real_screen_directly_in_non_main_recipe() {
  Hide_errors = true;
  transform(
      "def foo [\n"
      "  print 0, 34\n"
      "]\n"
  );
  CHECK_TRACE_CONTENTS(
      "error: foo: 'print 0, 34': only 'main' can pass 0 into a (address screen)\n"
  );
}
ass="nt">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.applications.html#Applications">ranger.applications.Applications</a>(<a href="builtins.html#object">builtins.object</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.applications.html#Applications">ranger.applications.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.applications.html#Applications">ranger.applications.Applications</a></dd> <dd><a href="builtins.html#object">builtins.object</a></dd> </dl> <hr> Methods defined here:<br> <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_editor"><strong>app_editor</strong></a> = <a href="#CustomApplications-app_vim">app_vim</a>(self, c)</dt></dl> <dl><dt><a name="CustomApplications-app_evince"><strong>app_evince</strong></a>(self, c)</dt></dl> <dl><dt><a name="CustomApplications-app_feh"><strong>app_feh</strong></a>(self, c)</dt></dl> <dl><dt><a name="CustomApplications-app_mplayer"><strong>app_mplayer</strong></a>(self, c)</dt></dl> <dl><dt><a name="CustomApplications-app_pager"><strong>app_pager</strong></a>(self, c)</dt><dd><tt>#&nbsp;-----------------------------------------&nbsp;application&nbsp;definitions</tt></dd></dl> <dl><dt><a name="CustomApplications-app_vim"><strong>app_vim</strong></a>(self, c)</dt></dl> <hr> Methods inherited from <a href="ranger.applications.html#Applications">ranger.applications.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-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> Data descriptors inherited from <a href="ranger.applications.html#Applications">ranger.applications.Applications</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>ALLOWED_FLAGS</strong> = 'sdpSDP'<br> <strong>PIPE</strong> = -1<br> <strong>devnull</strong> = &lt;_io.TextIOWrapper name='/dev/null' encoding='UTF-8'&gt;</td></tr></table> </body></html>