Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
* vim: set ts=8 sts=2 et sw=2 tw=80:
3
* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
// jsshell.cpp - Utilities for the JS shell
8
9
#include "shell/jsshell.h"
10
11
#include "mozilla/Sprintf.h"
12
13
#include "jsapi.h"
14
#include "jsfriendapi.h"
15
16
#include "util/StringBuffer.h"
17
18
using namespace JS;
19
20
namespace js {
21
namespace shell {
22
23
// Generate 'usage' and 'help' properties for the given object.
24
// JS_DefineFunctionsWithHelp will define individual function objects with both
25
// of those properties (eg getpid.usage = "getpid()" and getpid.help = "return
26
// the process id"). This function will generate strings for an "interface
27
// object", eg os.file, which contains some number of functions.
28
//
29
// .usage will be set to "<name> - interface object".
30
//
31
// .help will be set to a newline-separated list of functions that have either
32
// 'help' or 'usage' properties. Functions are described with their usage
33
// strings, if they have them, else with just their names.
34
//
35
bool GenerateInterfaceHelp(JSContext* cx, HandleObject obj, const char* name) {
36
RootedIdVector idv(cx);
37
if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN, &idv)) {
38
return false;
39
}
40
41
JSStringBuilder buf(cx);
42
int numEntries = 0;
43
for (size_t i = 0; i < idv.length(); i++) {
44
RootedId id(cx, idv[i]);
45
RootedValue v(cx);
46
if (!JS_GetPropertyById(cx, obj, id, &v)) {
47
return false;
48
}
49
if (!v.isObject()) {
50
continue;
51
}
52
RootedObject prop(cx, &v.toObject());
53
54
RootedValue usage(cx);
55
RootedValue help(cx);
56
if (!JS_GetProperty(cx, prop, "usage", &usage)) {
57
return false;
58
}
59
if (!JS_GetProperty(cx, prop, "help", &help)) {
60
return false;
61
}
62
if (!usage.isString() && !help.isString()) {
63
continue;
64
}
65
66
if (numEntries && !buf.append("\n")) {
67
return false;
68
}
69
numEntries++;
70
71
if (!buf.append(" ", 2)) {
72
return false;
73
}
74
75
if (!buf.append(usage.isString() ? usage.toString() : JSID_TO_STRING(id))) {
76
return false;
77
}
78
}
79
80
RootedString s(cx, buf.finishString());
81
if (!s || !JS_DefineProperty(cx, obj, "help", s, 0)) {
82
return false;
83
}
84
85
buf.clear();
86
if (!buf.append(name, strlen(name)) ||
87
!buf.append(" - interface object with ", 25)) {
88
return false;
89
}
90
char cbuf[100];
91
SprintfLiteral(cbuf, "%d %s", numEntries,
92
numEntries == 1 ? "entry" : "entries");
93
if (!buf.append(cbuf, strlen(cbuf))) {
94
return false;
95
}
96
s = buf.finishString();
97
if (!s || !JS_DefineProperty(cx, obj, "usage", s, 0)) {
98
return false;
99
}
100
101
return true;
102
}
103
104
bool CreateAlias(JSContext* cx, const char* dstName,
105
JS::HandleObject namespaceObj, const char* srcName) {
106
RootedObject global(cx, JS::GetNonCCWObjectGlobal(namespaceObj));
107
108
RootedValue val(cx);
109
if (!JS_GetProperty(cx, namespaceObj, srcName, &val)) {
110
return false;
111
}
112
113
if (!val.isObject()) {
114
JS_ReportErrorASCII(cx, "attempted to alias nonexistent function");
115
return false;
116
}
117
118
RootedObject function(cx, &val.toObject());
119
if (!JS_DefineProperty(cx, global, dstName, function, 0)) {
120
return false;
121
}
122
123
return true;
124
}
125
126
} // namespace shell
127
} // namespace js