public Construct eval(ParseTree c, final Environment env) throws CancelCommandException { final Construct m = c.getData(); CurrentEnv = env; // TODO: Reevaluate if this line is needed. The script doesn't know the label inherently, the // environment does, and setting it this way taints the environment. CurrentEnv.getEnv(GlobalEnv.class).SetLabel(this.label); if (m.getCType() == ConstructType.FUNCTION) { env.getEnv(GlobalEnv.class).SetScript(this); if (m.val().matches("^_[^_].*")) { // Not really a function, so we can't put it in Function. Procedure p = getProc(m.val()); if (p == null) { throw new ConfigRuntimeException( "Unknown procedure \"" + m.val() + "\"", ExceptionType.InvalidProcedureException, m.getTarget()); } Environment newEnv = env; try { newEnv = env.clone(); } catch (Exception e) { } ProfilePoint pp = env.getEnv(GlobalEnv.class).GetProfiler().start(m.val() + " execution", LogLevel.INFO); Construct ret = p.cexecute(c.getChildren(), newEnv, m.getTarget()); pp.stop(); return ret; } final Function f; try { f = (Function) FunctionList.getFunction(m); } catch (ConfigCompileException e) { // Turn it into a config runtime exception. This shouldn't ever happen though. throw new ConfigRuntimeException("Unable to find function " + m.val(), m.getTarget()); } // We have special handling for loop and other control flow functions if (f instanceof assign) { if (c.getChildAt(0).getData() instanceof CFunction) { CFunction test = (CFunction) c.getChildAt(0).getData(); if (test.val().equals("array_get")) { env.getEnv(GlobalEnv.class).SetFlag("array_get_alt_mode", true); Construct arrayAndIndex = eval(c.getChildAt(0), env); env.getEnv(GlobalEnv.class).ClearFlag("array_get_alt_mode"); return ((assign) f) .array_assign(m.getTarget(), env, arrayAndIndex, eval(c.getChildAt(1), env)); } } } if (f.useSpecialExec()) { ProfilePoint p = null; if (f.shouldProfile() && env.getEnv(GlobalEnv.class).GetProfiler() != null && env.getEnv(GlobalEnv.class).GetProfiler().isLoggable(f.profileAt())) { p = env.getEnv(GlobalEnv.class) .GetProfiler() .start(f.profileMessageS(c.getChildren()), f.profileAt()); } Construct ret = f.execs(m.getTarget(), env, this, c.getChildren().toArray(new ParseTree[] {})); if (p != null) { p.stop(); } return ret; } ArrayList<Construct> args = new ArrayList<Construct>(); for (ParseTree c2 : c.getChildren()) { args.add(eval(c2, env)); } if (f.isRestricted()) { boolean perm = Static.hasCHPermission(f.getName(), env); if (!perm) { throw new ConfigRuntimeException( "You do not have permission to use the " + f.getName() + " function.", ExceptionType.InsufficientPermissionException, m.getTarget()); } } Object[] a = args.toArray(); Construct[] ca = new Construct[a.length]; for (int i = 0; i < a.length; i++) { ca[i] = (Construct) a[i]; // CArray, CBoolean, CDouble, CInt, CNull, CString, CVoid, CEntry, CLabel (only to sconcat). if (!(ca[i] instanceof CArray || ca[i] instanceof CBoolean || ca[i] instanceof CDouble || ca[i] instanceof CInt || ca[i] instanceof CNull || ca[i] instanceof CString || ca[i] instanceof CVoid || ca[i] instanceof IVariable || ca[i] instanceof CEntry || ca[i] instanceof CLabel) && (!f.getName().equals("__autoconcat__") && (ca[i] instanceof CLabel))) { throw new ConfigRuntimeException( "Invalid Construct (" + ca[i].getClass() + ") being passed as an argument to a function (" + f.getName() + ")", null, m.getTarget()); } if (env.getEnv(GlobalEnv.class).GetFlag("array_get_alt_mode") == Boolean.TRUE && i == 0) { continue; } while (f.preResolveVariables() && ca[i] instanceof IVariable) { IVariable cur = (IVariable) ca[i]; ca[i] = env.getEnv(GlobalEnv.class).GetVarList().get(cur.getName(), cur.getTarget()).ival(); } } { // It takes a moment to generate the toString of some things, so lets not do it // if we actually aren't going to profile ProfilePoint p = null; if (f.shouldProfile() && env.getEnv(GlobalEnv.class).GetProfiler() != null && env.getEnv(GlobalEnv.class).GetProfiler().isLoggable(f.profileAt())) { p = env.getEnv(GlobalEnv.class).GetProfiler().start(f.profileMessage(ca), f.profileAt()); } Construct ret = f.exec(m.getTarget(), env, ca); if (p != null) { p.stop(); } return ret; } } else if (m.getCType() == ConstructType.VARIABLE) { return new CString(m.val(), m.getTarget()); } else { return m; } }
public static String examples(String function, boolean staged) throws Exception { FunctionBase fb = FunctionList.getFunction(new CFunction(function, Target.UNKNOWN)); if (fb instanceof Function) { Function f = (Function) fb; String restricted = (f instanceof Function && ((Function) f).isRestricted()) ? "<div style=\"background-color: red; font-weight: bold; text-align: center;\">Yes</div>" : "<div style=\"background-color: green; font-weight: bold; text-align: center;\">No</div>"; String optimizationMessage = "None"; if (f instanceof Optimizable) { Set<Optimizable.OptimizationOption> options = ((Optimizable) f).optimizationOptions(); List<String> list = new ArrayList<String>(); for (Optimizable.OptimizationOption option : options) { list.add( "[[CommandHelper/" + (staged ? "Staged/" : "") + "Optimizer#" + option.name() + "|" + option.name() + "]]"); } optimizationMessage = StringUtils.Join(list, "<br />"); } DocInfo di = new DocInfo(f.docs()); StringBuilder thrown = new StringBuilder(); if (f instanceof Function && ((Function) f).thrown() != null) { List thrownList = Arrays.asList(((Function) f).thrown()); for (int i = 0; i < thrownList.size(); i++) { ExceptionType t = (ExceptionType) thrownList.get(i); if (i != 0) { thrown.append("<br />\n"); } thrown .append("[[CommandHelper/Exceptions#") .append(t.toString()) .append("|") .append(t.toString()) .append("]]"); } } String tableUsages = di.originalArgs.replace("|", "<hr />"); String[] usages = di.originalArgs.split("\\|"); StringBuilder usageBuilder = new StringBuilder(); for (String usage : usages) { usageBuilder .append("<pre>\n") .append(f.getName()) .append("(") .append(usage.trim()) .append(")\n</pre>"); } StringBuilder exampleBuilder = new StringBuilder(); if (f.examples() != null && f.examples().length > 0) { int count = 1; // If the output was automatically generated, change the color of the pre for (ExampleScript es : f.examples()) { exampleBuilder .append("====Example ") .append(count) .append("====\n") .append(es.getDescription()) .append("\n\n" + "Given the following code:\n"); exampleBuilder.append(SimpleSyntaxHighlighter.Highlight(es.getScript())).append("\n"); String style = ""; if (es.isAutomatic()) { style = " style=\"background-color: #BDC7E9\""; exampleBuilder.append("\n\nThe output would be:\n<pre"); } else { exampleBuilder.append("\n\nThe output might be:\n<pre"); } exampleBuilder.append(style).append(">").append(es.getOutput()).append("</pre>\n"); count++; } } else { exampleBuilder.append("Sorry, there are no examples for this function! :("); } Class[] seeAlso = f.seeAlso(); String seeAlsoText = ""; if (seeAlso != null && seeAlso.length > 0) { seeAlsoText += "===See Also===\n"; boolean first = true; for (Class<? extends Documentation> c : seeAlso) { if (Function.class.isAssignableFrom(c)) { Function f2 = (Function) c.newInstance(); if (!first) { seeAlsoText += ", "; } first = false; seeAlsoText += "[[CommandHelper/" + (staged ? "Staged/" : "") + "API/" + f2.getName() + "|" + f2.getName() + "]]"; } } } Map<String, String> templateFields = new HashMap<>(); templateFields.put("function_name", f.getName()); templateFields.put("returns", di.ret); templateFields.put("tableUsages", tableUsages); templateFields.put("throws", thrown.toString()); templateFields.put("since", f.since().toString()); templateFields.put("restricted", restricted); templateFields.put("optimizationMessage", optimizationMessage); templateFields.put( "description", di.extendedDesc == null ? di.desc : di.topDesc + "\n\n" + di.extendedDesc); templateFields.put("usages", usageBuilder.toString()); templateFields.put("examples", exampleBuilder.toString()); templateFields.put("staged", staged ? "Staged/" : ""); templateFields.put("seeAlso", seeAlsoText); String template = StreamUtils.GetString( DocGenTemplates.class.getResourceAsStream("/templates/example_templates")); // Find all the %%templates%% in the template Matcher m = Pattern.compile("%%(.*?)%%").matcher(template); try { while (m.find()) { String name = m.group(1); String templateValue = templateFields.get(name); template = template.replaceAll( "%%" + Pattern.quote(name) + "%%", templateValue.replace("$", "\\$").replaceAll("\\'", "\\\\'")); } return template; } catch (RuntimeException e) { throw new RuntimeException( "Caught a runtime exception while generating template for " + function, e); } } else { throw new RuntimeException(function + " does not implement Function"); } }