*/
Script("utils.js")
Script("pre.js")
Script("killring.js")
Script("history.js")
Script("readline.js")
Script("shell.js")
Script("pathhandler.js")
websh=Require("main.js")
console.log("websh library loaded.");
};
BundleModuleCode['main.js']=function (module,exports,global,process){
function websh(index,config,prompt,callback) {
var shell_panel_id="shell-panel-"+index,
shell_view_id="shell-view-"+index,
input_id="shell-cli-"+index,
parameter=config;
$(document).ready(function() {
var history = new Josh.History({ key : 'josh.websh', volatile : false });
var shell = Josh.Shell({
shell_panel_id:shell_panel_id,
shell_view_id:shell_view_id,
input_id:input_id,
prompt:prompt,
history:history
});
shell.index=index;
shell.fontSize = 16
var promptCounter = 0;
Object.keys(config).forEach ( p => {
switch (p) {
case 'WORK':
case 'WORKDIR':
shell.workdir=parameter[p]
break;
case 'PORT':
shell.port=Number(parameter[p]);
break;
default:
shell.setCommandHandler(p,{
exec : function(cmd, args, callback, output) {
console.log(cmd,args,parameter[p])
if (parameter[p][0]=='$') {
// internal JS command
var argv = parameter[p].split(' ')
argv[0]=argv[0].slice(1)
if (typeof window[argv[0]] == 'function') {
window[argv[0]](output,shell.workdir,argv.slice(1).concat(args));
callback('');
return;
} else return callback('Unknown internal command '+argv[0]);
}
var exec = parameter[p]+' '+args.join(',')
callback(exec);
shell.socket.send(exec+'\n');
}
});
}
})
Utils.POST('localhost:11111',{command:'session'},function (reply) {
if (reply.status==0) {
try {
var socket = Utils.connectShell(reply.reply,shell.outputString)
shell.socket=socket
setTimeout(function () { shell.socket.send('cd '+shell.workdir+'\n') },200);
} catch (e) {
alert(e)
}
} else alert(reply.status)
})
shell.onNewPrompt(function(callback) {
promptCounter++;
callback("[" + promptCounter + "] $");
});
shell.setCommandHandler("size", {
exec : function(cmd, args, callback) {
if (args[0]=='+') shell.fontSize++;
else if (args[0]=='-') shell.fontSize--;
else if (!isNaN(Number(args[0]))) shell.fontSize=Number(args[0])
Utils.addCSS('body { font-size:'+shell.fontSize+'px; }');
callback('')
}
});
['*'].forEach(cmd => {
shell.setCommandHandler(cmd, {
exec : function(cmd, args, callback, output) {
callback('')
shell.socket.send(cmd+' '+args.join(' ')+'\n')
}
});
})
shell.onCancel(function () {
shell.socket.signal('SIGTERM')
});
shell.activate();
shell.setActive(false);
if (!shell.workdir) shell.workdir=PATH.dirname(document.URL.replace(/\?.+$/,'').replace('file://',''))
shell.outputLine('Ready ['+shell.workdir+']')
shell.outputLine(Object.keys(parameter).join(' '))
$('#'+shell_panel_id).on( "mouseenter", function() {
console.log('main.shell.activate',shell.index,shell_panel_id)
shell.setActive(true)
}).on( "mouseleave", function() {
console.log('main.shell.deactivate',shell.index,shell_panel_id)
shell.setActive(false)
})
});
}
if (typeof module == 'object') module.exports=websh
};
Utils = {
addCSS : function (styles) {
var styleSheet = document.createElement("style")
styleSheet.type = "text/css"
styleSheet.innerText = styles
document.head.appendChild(styleSheet)
},
blobToText : function (data, callback) {
var textDecoder = new TextDecoder();
var fileReader = new FileReader();
fileReader.addEventListener('load', function () {
var str = textDecoder.decode(fileReader.result);
callback(str);
});
fileReader.readAsArrayBuffer(data);
},
connectShell : function (port,outputString) {
var hostname = 'localhost'
var protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
var socketURL = protocol + hostname + ':' + port;
console.log('connectShell',socketURL)
var socket = new WebSocket(socketURL);
socket.addEventListener('message', function (ev) {
// console.log(ev)
var message = JSON.parse(ev.data)
if (message.stdout) outputString(message.stdout);
if (message.stderr) outputString(message.stderr);
});
// oninput handler function
return {
socket : socket,
signal : function (data) {
socket.send(JSON.stringify({signal:data}));
},
send : function (data) {
socket.send(JSON.stringify({stdin:data}));
}
}
},
parseUrl : function (url) {
if (!url) return {};
url = url.replace(/#[^$]+$/,'');
var queryString = url.substring( url.indexOf('?') + 1 );
if (queryString == url) return {};
var params = {}, queries, temp, i, l;
// Split into key/value pairs
queries = queryString.split("&");
// Convert the array of strings into an object
for ( i = 0, l = queries.length; i < l; i++ ) {
temp = queries[i].split('=');
if (temp[1]==undefined) temp[1]='true';
params[temp[0]] = temp[1].replace('%20',' ');
}
return params;
},
textToBlob : function (str) {
return new Blob([str]);
},
GET: function (url,params,cb,sync) {
var result;
// if (sync && !cb) cb=function (_result) { result=_result };
// promise?
if (!cb && !sync) {
return new Promise(function (resolve,reject){
Utils.GET(url,params,function (result) {
resolve(result);
})
})
}
if (url.indexOf('http')!=0) url = 'http://'+url;
try {
if (params) {
var o=params,sep='';
params='/?';
for(var p in o) {
params = params + sep + p + '='+o[p];
sep='&';
}
} else params='';
// print(url+params)
var request = new XMLHttpRequest();
request.open("GET",url+params, !sync);
request.onreadystatechange = function () {
if(request.readyState === 4)
{
if(request.status === 200 || request.status == 0)
{
var allText = request.responseText;
if (allText!='') result=JSON.parse(allText);
else result = new Error('GET data error (empty data)');
if (cb) cb(result);
} else {
result=new Error('GET from '+url+params+' failed (status '+request.status+')'+
(request.responseText?' '+request.responseText:''));
if (cb) cb(result)
}
}
}
request.onerror = function (error) {
if (result) return;
result='Error: GET from '+url+params+' failed: '+error;
if (cb) cb(result);
}
request.send(null);
} catch (error) {
result=new Error('GET from '+url+params+' failed: '+error.toString());
if (cb) cb(result);
}
return result;
},
Get: function (url,params,mimetype,cb,sync) {
if (typeof mimetype=='function') { sync=cb; cb=mimetype; mimetype=undefined };
var result;
// console.log(url,params,mimetype);
// if (sync && !cb) cb=function (_result) { result=_result };
// promise?
if (!cb && !sync) {
return new Promise(function (resolve,reject){
Utils.Get(url,params,mimetype,function (result) {
resolve(result);
})
})
}
if (url.indexOf('http')!=0) url = 'http://'+url;
try {
if (params) {
var o=params,params='',sep='';
for(var p in o) {
params = params + sep + p + '='+o[p];
sep='&';
}
if (params) params = '?'+params;
} else params='';
// print(url+params)
var request = new XMLHttpRequest();
request.open("GET",url+params, !sync);
if (mimetype=='binary') request.overrideMimeType("text/plain; charset=x-user-defined");
request.onreadystatechange = function () {
if(request.readyState === 4)
{
if(request.status === 200 || request.status == 0)
{
var allText = mimetype=='binary'?request.response:request.responseText;
// console.log(request.response.length);
result=allText;
if (cb) cb(result);
} else {
result=new Error('Get from '+url+params+' failed (status '+request.status+')'+
(request.responseText?' '+request.responseText:''));
if (cb) cb(result)
}
}
}
request.onerror = function (error) {
if (result) return;
result='Error: Get from '+url+params+' failed: '+error;
if (cb) cb(result);
}
request.send(null);
} catch (error) {
result=new Error('Get from '+url+params+' failed: '+error.toString());
if (cb) cb(result);
}
return result;
},
// JSON POST
POST: function (url,data,cb,sync){
var result;
// if (sync && !cb) cb=function (_result) { result=_result };
// console.log(url,data);
// promise?
if (!cb && !sync) {
return new Promise(function (resolve,reject){
Utils.POST(url,data,function (result) {
resolve(result);
})
})
}
if (url.indexOf('http')!=0) url = 'http://'+url;
try {
var request = new XMLHttpRequest();
request.open("POST", url, !sync);
request.onreadystatechange = function () {
if(request.readyState === 4)
{
if(request.status === 200 || request.status == 0)
{ /*console.log(request);*/
var allText = request.responseText;
try {
if (allText!='') result=JSON.parse(allText)
else result=new Error('POST data error (empty data)');
} catch (e) {
result = new Error(e.toString());
}
if (cb) cb(result);
} else {
result = new Error('POST to '+url+' failed (status '+request.status+')'+
(request.responseText?' '+request.responseText:''));
if (cb) cb(result);
}
}
}
request.onerror = function (error) {
if (result) return;
result = new Error('POST to '+url+' failed: '+error);
if (cb) cb(result)
}
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send(JSON.stringify(data));
} catch (error) {
result=new Error('POST to '+url+' failed: '+error.toString());
if (cb) cb(result)
}
return result;
},
// Formdata POST, data:{} => attr1=val&attr2=val2...
Post: function (url,data,cb,sync){
var result;
// if (sync && !cb) cb=function (_result) { result=_result };
// promise?
if (!cb && !sync) {
return new Promise(function (resolve,reject){
Utils.Post(url,data,function (result) {
resolve(result);
})
})
}
if (url.indexOf('http')!=0) url = 'http://'+url;
try {
var request = new XMLHttpRequest();
request.open("POST", url, !sync);
request.onreadystatechange = function () {
if(request.readyState === 4)
{
if(request.status === 200 || request.status == 0)
{ /*console.log(request);*/
var allText = request.responseText;
try {
if (allText!='') result=JSONfn.parse(allText)
else result=new Error('POST data error (empty data)');
} catch (e) {
result = new Error(e.toString());
}
if (cb) cb(result);
} else {
result = new Error('POST to '+url+' failed (status '+request.status+')'+
(request.responseText?' '+request.responseText:''));
if (cb) cb(result);
}
}
}
request.onerror = function (error) {
if (result) return;
result = new Error('POST to '+url+' failed: '+error);
if (cb) cb(result)
}
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
var text=[];
for(var p in data) {
text.push(p+'='+escape(data[p]));
}
request.send(text.join('&'));
} catch (error) {
result=new Error('POST to '+url+' failed: '+error.toString());
if (cb) cb(result)
}
return result;
},
}
PATH = {
basename : function (path,extension) {
if (path[path.length-1]=='/') return '/';
return extension?
path.split('/').reverse()[0].replace(RegExp(extension.replace(/\./,'\\.')+'$'),'')
:
path.split('/').reverse()[0];
},
dirname : function (path) {
var el=path.split('/');
el.pop();
return el.join('/');
},
extension : function (file) {
return file.replace(/^[^\.]+\./,'');
}
}
if (typeof hljs != 'undefined') hljs.initHighlightingOnLoad();
Josh = {Debug: false };
/* ------------------------------------------------------------------------*
* Copyright 2013 Arne F. Claassen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------*/
var Josh = Josh || {};
(function(root) {
Josh.KillRing = function(config) {
config = config || {};
var _console = Josh.Debug && root.console ? root.console : {log: function() {
}};
var _ring = config.ring || [];
var _cursor = config.cursor || 0;
var _uncommitted = false;
var _yanking = false;
if(_ring.length == 0) {
_cursor = -1;
} else if(_cursor >= _ring.length) {
_cursor = _ring.length - 1;
}
var self = {
isinkill: function() {
return _uncommitted;
},
lastyanklength: function() {
if(!_yanking) {
return 0;
}
return _ring[_cursor].length;
},
append: function(value) {
_yanking = false;
if(!value) {
return;
}
if(_ring.length == 0 || !_uncommitted) {
_ring.push('');
}
_cursor = _ring.length - 1;
_console.log("appending: " + value);
_uncommitted = true;
_ring[_cursor] += value;
},
prepend: function(value) {
_yanking = false;
if(!value) {
return;
}
if(_ring.length == 0 || !_uncommitted) {
_ring.push('');
}
_cursor = _ring.length - 1;
_console.log("prepending: " + value);
_uncommitted = true;
_ring[_cursor] = value + _ring[_cursor];
},
commit: function() {
_console.log("committing");
_yanking = false;
_uncommitted = false;
},
yank: function() {
self.commit();
if(_ring.length == 0) {
return null;
}
_yanking = true;
return _ring[_cursor];
},
rotate: function() {
if(!_yanking || _ring.length == 0) {
return null;
}
--_cursor;
if(_cursor < 0) {
_cursor = _ring.length - 1;
}
return self.yank();
},
items: function() {
return _ring.slice(0);
},
clear: function() {
_ring = [];
_cursor = -1;
_yanking = false;
_uncommited = false;
}
};
return self;
}
})(this);
/* ------------------------------------------------------------------------*
* Copyright 2013 Arne F. Claassen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------*/
var Josh = Josh || {};
(function (root) {
Josh.History = function (config) {
config = config || {};
var _console = Josh.Debug && root.console ? root.console : {log: function() {}};
var _history = config.history || [''];
var _cursor = config.cursor || 0;
var _searchCursor = _cursor;
var _lastSearchTerm = '';
var _storage = config.storage || root.localStorage;
var _key = config.key || 'josh.history';
console.log('History',config)
if (!config.volatile && _storage) {
var data = _storage.getItem(_key);
if (data) {
_history = JSON.parse(data);
_searchCursor = _cursor = _history.length - 1;
} else {
save();
}
}
function save() {
if (!config.volatile && _storage) {
_storage.setItem(_key, JSON.stringify(_history));
}
}
function setHistory() {
_searchCursor = _cursor;
_lastSearchTerm = '';
return _history[_cursor];
}
return {
update:function (text) {
_console.log("updating history to " + text);
_history[_cursor] = text;
save();
},
accept:function (text) {
_console.log("accepting history " + text);
var last = _history.length - 1;
if (text) {
if (_cursor == last) {
_console.log("we're at the end already, update last position");
_history[_cursor] = text;
} else if (!_history[last]) {
_console.log("we're not at the end, but the end was blank, so update last position");
_history[last] = text;
} else {
_console.log("appending to end");
_history.push(text);
}
_history.push('');
}
_searchCursor = _cursor = _history.length - 1;
save();
},
items:function () {
return _history.slice(0, _history.length - 1);
},
clear:function () {
_history = [_history[_history.length - 1]];
save();
},
hasNext:function () {
return _cursor < (_history.length - 1);
},
hasPrev:function () {
return _cursor > 0;
},
prev:function () {
--_cursor;
return setHistory();
},
next:function () {
++_cursor;
return setHistory();
},
top:function () {
_cursor = 0;
return setHistory();
},
end:function () {
_cursor = _history.length - 1;
return setHistory();
},
search:function (term) {
if (!term && !_lastSearchTerm) {
return null;
}
var iterations = _history.length;
if (term == _lastSearchTerm) {
_searchCursor--;
iterations--;
}
if (!term) {
term = _lastSearchTerm;
}
_lastSearchTerm = term;
for (var i = 0; i < iterations; i++) {
if (_searchCursor < 0) {
_searchCursor = _history.length - 1;
}
var idx = _history[_searchCursor].indexOf(term);
if (idx != -1) {
return {
text:_history[_searchCursor],
cursoridx:idx,
term:term
};
}
_searchCursor--;
}
return null;
},
applySearch:function () {
if (_lastSearchTerm) {
_console.log("setting history to position" + _searchCursor + "(" + _cursor + "): " + _history[_searchCursor]);
_cursor = _searchCursor;
return _history[_cursor];
}
return null;
}
};
};
})(this);
/* ------------------------------------------------------------------------*
* Copyright 2013 Arne F. Claassen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------*/
// HACK
var Josh = Josh || {};
Josh.readlines = []
var root = this
Josh.Version = "0.2.9";
Josh.Keys = {
Special: {
Backspace: 8,
Tab: 9,
Enter: 13,
Pause: 19,
CapsLock: 20,
Escape: 27,
Space: 32,
PageUp: 33,
PageDown: 34,
End: 35,
Home: 36,
Left: 37,
Up: 38,
Right: 39,
Down: 40,
Insert: 45,
Delete: 46
}
};
Josh.ReadLine = function(config) {
config = config || {};
// instance fields
var _console = config.console || (Josh.Debug && root.console ? root.console : {
log: function() {
}
});
var _history = config.history || new Josh.History();
var _killring = config.killring || new Josh.KillRing();
var _boundToElement = config.element ? true : false;
var _element = config.element || root;
var _active = false;
var _onActivate;
var _onDeactivate;
var _onCompletion;
var _onEnter;
var _onChange;
var _onCancel;
var _onEOT;
var _onClear;
var _onSearchStart;
var _onSearchEnd;
var _onSearchChange;
var _inSearch = false;
var _searchMatch;
var _lastSearchText = '';
var _text = '';
var _cursor = 0;
var _lastCmd;
var _completionActive;
var _cmdQueue = [];
var _suspended = false;
var _cmdMap = {
complete: cmdComplete,
done: cmdDone,
noop: cmdNoOp,
history_top: cmdHistoryTop,
history_end: cmdHistoryEnd,
history_next: cmdHistoryNext,
history_previous: cmdHistoryPrev,
end: cmdEnd,
home: cmdHome,
left: cmdLeft,
right: cmdRight,
cancel: cmdCancel,
delete: cmdDeleteChar,
backspace: cmdBackspace,
kill_eof: cmdKillToEOF,
kill_wordback: cmdKillWordBackward,
kill_wordforward: cmdKillWordForward,
yank: cmdYank,
clear: cmdClear,
search: cmdReverseSearch,
wordback: cmdBackwardWord,
wordforward: cmdForwardWord,
yank_rotate: cmdRotate
}
var _keyMap = {
default: {
8: cmdBackspace, // Backspace
9: cmdComplete, // Tab
13: cmdDone, // Enter
27: cmdEsc, // Esc
33: cmdHistoryTop, // Page Up
34: cmdHistoryEnd, // Page Down
35: cmdEnd, // End
36: cmdHome, // Home
37: cmdLeft, // Left
38: cmdHistoryPrev, // Up
39: cmdRight, // Right
40: cmdHistoryNext, // Down
46: cmdDeleteChar, // Delete
10: cmdNoOp, // Pause
19: cmdNoOp, // Caps Lock
45: cmdNoOp // Insert
},
control: {
65: cmdHome, // A
66: cmdLeft, // B
67: cmdCancel, // C
68: cmdDeleteChar, // D
69: cmdEnd, // E
70: cmdRight, // F
80: cmdHistoryPrev, // P
78: cmdHistoryNext, // N
75: cmdKillToEOF, // K
89: cmdYank, // Y
76: cmdClear, // L
82: cmdReverseSearch // R
},
meta: {
8: cmdKillWordBackward, // Backspace
66: cmdBackwardWord, // B
68: cmdKillWordForward, // D
70: cmdForwardWord, // F
89: cmdRotate // Y
}
};
// public methods
var self = {
isActive: function() {
return _active;
},
setActive : function (on) {
console.log('readline.setActive',on)
_active=on
return on
},
activate: function() {
console.log('readline.activate')
_active = true;
if(_onActivate) {
_onActivate();
}
},
deactivate: function() {
console.log('readline.deactivate')
_active = false;
if(_onDeactivate) {
_onDeactivate();
}
},
bind: function(key, action) {
var k = getKey(key);
var cmd = _cmdMap[action];
if(!cmd) {
return;
}
_keyMap[k.modifier][k.code];
},
unbind: function(key) {
var k = getKey(key);
delete _keyMap[k.modifier][k.code];
},
attach: function(el) {
if(_element) {
self.detach();
}
_console.log("attaching");
_console.log(el);
_element = el;
_boundToElement = true;
addEvent(_element, "focus", self.activate);
addEvent(_element, "blur", self.deactivate);
subscribeToKeys();
},
detach: function() {
removeEvent(_element, "focus", self.activate);
removeEvent(_element, "blur", self.deactivate);
_element = null;
_boundToElement = false;
},
onActivate: function(completionHandler) {
_onActivate = completionHandler;
},
onDeactivate: function(completionHandler) {
_onDeactivate = completionHandler;
},
onChange: function(changeHandler) {
_onChange = changeHandler;
},
onClear: function(completionHandler) {
_onClear = completionHandler;
},
onEnter: function(enterHandler) {
_onEnter = enterHandler;
},
onCompletion: function(completionHandler) {
_onCompletion = completionHandler;
},
onCancel: function(completionHandler) {
_onCancel = completionHandler;
},
onEOT: function(completionHandler) {
_onEOT = completionHandler;
},
onSearchStart: function(completionHandler) {
_onSearchStart = completionHandler;
},
onSearchEnd: function(completionHandler) {
_onSearchEnd = completionHandler;
},
onSearchChange: function(completionHandler) {
_onSearchChange = completionHandler;
},
getLine: function() {
return {
text: _text,
cursor: _cursor
};
},
setLine: function(line) {
_text = line.text;
_cursor = line.cursor;
refresh();
},
// Hacks to propagate key events from inactive to active readline
// if there is more than one shell
handleKeyEvent:handleKeyEvent,
handleKeyPress:handleKeyPress
};
// private methods
function addEvent(element, name, callback) {
if(element.addEventListener) {
element.addEventListener(name, callback, false);
} else if(element.attachEvent) {
element.attachEvent('on' + name, callback);
}
}
function removeEvent(element, name, callback) {
if(element.removeEventListener) {
element.removeEventListener(name, callback, false);
} else if(element.detachEvent) {
element.detachEvent('on' + name, callback);
}
}
function getKeyInfo(e) {
var code = e.keyCode || e.charCode;
var c = String.fromCharCode(code);
return {
code: code,
character: c,
shift: e.shiftKey,
control: e.controlKey,
alt: e.altKey,
isChar: true
};
}
function getKey(key) {
var k = {
modifier: 'default',
code: key.keyCode
};
if(key.metaKey || key.altKey) {
k.modifier = 'meta';
} else if(key.ctrlKey) {
k.modifier = 'control';
}
if(key.char) {
k.code = key.char.charCodeAt(0);
}
return k;
}
function queue(cmd) {
if(_suspended) {
_cmdQueue.push(cmd);
return;
}
call(cmd);
}
function call(cmd) {
_console.log('calling: ' + cmd.name + ', previous: ' + _lastCmd);
if(_inSearch && cmd.name != "cmdKeyPress" && cmd.name != "cmdReverseSearch") {
_inSearch = false;
if(cmd.name == 'cmdEsc') {
_searchMatch = null;
}
if(_searchMatch) {
if(_searchMatch.text) {
_cursor = _searchMatch.cursoridx;
_text = _searchMatch.text;
_history.applySearch();
}
_searchMatch = null;
}
if(_onSearchEnd) {
_onSearchEnd();
}
}
if(!_inSearch && _killring.isinkill() && cmd.name.substr(0, 7) != 'cmdKill') {
_killring.commit();
}
_lastCmd = cmd.name;
cmd();
}
function suspend(asyncCall) {
_suspended = true;
asyncCall(resume);
}
function resume() {
var cmd = _cmdQueue.shift();
if(!cmd) {
_suspended = false;
return;
}
call(cmd);
resume();
}
function cmdNoOp() {
// no-op, used for keys we capture and ignore
}
function cmdEsc() {
// no-op, only has an effect on reverse search and that action was taken in call()
}
function cmdBackspace() {
if(_cursor == 0) {
return;
}
--_cursor;
_text = remove(_text, _cursor, _cursor + 1);
refresh();
}
function cmdComplete() {
if(!_onCompletion) {
return;
}
suspend(function(resumeCallback) {
_onCompletion(self.getLine(), function(completion) {
if(completion) {
_text = insert(_text, _cursor, completion);
updateCursor(_cursor + completion.length);
}
_completionActive = true;
resumeCallback();
});
});
}
function cmdDone() {
if(!_text) {
return;
}
var text = _text;
_history.accept(text);
_text = '';
_cursor = 0;
if(!_onEnter) {
return;
}
suspend(function(resumeCallback) {
_onEnter(text, function(text) {
if(text) {
_text = text;
_cursor = _text.length;
}
if(_onChange) {
_onChange(self.getLine());
}
resumeCallback();
});
});
}
function cmdEnd() {
updateCursor(_text.length);
}
function cmdHome() {
updateCursor(0);
}
function cmdLeft() {
if(_cursor == 0) {
return;
}
updateCursor(_cursor - 1);
}
function cmdRight() {
if(_cursor == _text.length) {
return;
}
updateCursor(_cursor + 1);
}
function cmdBackwardWord() {
if(_cursor == 0) {
return;
}
updateCursor(findBeginningOfPreviousWord());
}
function cmdForwardWord() {
if(_cursor == _text.length) {
return;
}
updateCursor(findEndOfCurrentWord());
}
function cmdHistoryPrev() {
if(!_history.hasPrev()) {
return;
}
getHistory(_history.prev);
}
function cmdHistoryNext() {
if(!_history.hasNext()) {
return;
}
getHistory(_history.next);
}
function cmdHistoryTop() {
getHistory(_history.top);
}
function cmdHistoryEnd() {
getHistory(_history.end);
}
function cmdDeleteChar() {
if(_text.length == 0) {
if(_onEOT) {
_onEOT();
return;
}
}
if(_cursor == _text.length) {
return;
}
_text = remove(_text, _cursor, _cursor + 1);
refresh();
}
function cmdCancel() {
if(_onCancel) {
_onCancel();
}
}
function cmdKillToEOF() {
_killring.append(_text.substr(_cursor));
_text = _text.substr(0, _cursor);
refresh();
}
function cmdKillWordForward() {
if(_text.length == 0) {
return;
}
if(_cursor == _text.length) {
return;
}
var end = findEndOfCurrentWord();
if(end == _text.length - 1) {
return cmdKillToEOF();
}
_killring.append(_text.substring(_cursor, end))
_text = remove(_text, _cursor, end);
refresh();
}
function cmdKillWordBackward() {
if(_cursor == 0) {
return;
}
var oldCursor = _cursor;
_cursor = findBeginningOfPreviousWord();
_killring.prepend(_text.substring(_cursor, oldCursor));
_text = remove(_text, _cursor, oldCursor);
refresh();
}
function cmdYank() {
var yank = _killring.yank();
if(!yank) {
return;
}
_text = insert(_text, _cursor, yank);
updateCursor(_cursor + yank.length);
}
function cmdRotate() {
var lastyanklength = _killring.lastyanklength();
if(!lastyanklength) {
return;
}
var yank = _killring.rotate();
if(!yank) {
return;
}
var oldCursor = _cursor;
_cursor = _cursor - lastyanklength;
_text = remove(_text, _cursor, oldCursor);
_text = insert(_text, _cursor, yank);
updateCursor(_cursor + yank.length);
}
function cmdClear() {
if(_onClear) {
_onClear();
} else {
refresh();
}
}
function cmdReverseSearch() {
if(!_inSearch) {
_inSearch = true;
if(_onSearchStart) {
_onSearchStart();
}
if(_onSearchChange) {
_onSearchChange({});
}
} else {
if(!_searchMatch) {
_searchMatch = {term: ''};
}
search();
}
}
function updateCursor(position) {
_cursor = position;
refresh();
}
function addText(c) {
_text = insert(_text, _cursor, c);
++_cursor;
refresh();
}
function addSearchText(c) {
if(!_searchMatch) {
_searchMatch = {term: ''};
}
_searchMatch.term += c;
search();
}
function search() {
_console.log("searchtext: " + _searchMatch.term);
var match = _history.search(_searchMatch.term);
if(match != null) {
_searchMatch = match;
_console.log("match: " + match);
if(_onSearchChange) {
_onSearchChange(match);
}
}
}
function refresh() {
if(_onChange) {
_onChange(self.getLine());
}
}
function getHistory(historyCall) {
_history.update(_text);
_text = historyCall();
updateCursor(_text.length);
}
function findBeginningOfPreviousWord() {
var position = _cursor - 1;
if(position < 0) {
return 0;
}
var word = false;
for(var i = position; i > 0; i--) {
var word2 = isWordChar(_text[i]);
if(word && !word2) {
return i + 1;
}
word = word2;
}
return 0;
}
function findEndOfCurrentWord() {
if(_text.length == 0) {
return 0;
}
var position = _cursor + 1;
if(position >= _text.length) {
return _text.length - 1;
}
var word = false;
for(var i = position; i < _text.length; i++) {
var word2 = isWordChar(_text[i]);
if(word && !word2) {
return i;
}
word = word2;
}
return _text.length - 1;
}
function isWordChar(c) {
if(c == undefined) {
return false;
}
var code = c.charCodeAt(0);
return (code >= 48 && code <= 57)
|| (code >= 65 && code <= 90)
|| (code >= 97 && code <= 122);
}
function remove(text, from, to) {
if(text.length <= 1 || text.length <= to - from) {
return '';
}
if(from == 0) {
// delete leading characters
return text.substr(to);
}
var left = text.substr(0, from);
var right = text.substr(to);
return left + right;
}
function insert(text, idx, ins) {
if(idx == 0) {
return ins + text;
}
if(idx >= text.length) {
return text + ins;
}
var left = text.substr(0, idx);
var right = text.substr(idx);
return left + ins + right;
}
function handleKeyEvent(e) {
_console.log('websh.readline.handleKeyEvent',_active,"key: " + e.keyCode);
// return as unhandled if we're not active or the key is just a modifier key
if(e.keyCode == 16 || e.keyCode == 17 || e.keyCode == 18 || e.keyCode == 91) {
return true;
}
// check for some special first keys, regardless of modifiers
var cmd = _keyMap.default[e.keyCode];
// intercept ctrl- and meta- sequences (may override the non-modifier cmd captured above
var mod;
if(e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey) {
mod = _keyMap.control[e.keyCode];
if(mod) {
cmd = mod;
}
} else if((e.altKey || e.metaKey) && !e.ctrlKey && !e.shiftKey) {
mod = _keyMap.meta[e.keyCode];
if(mod) {
cmd = mod;
}
}
if(!cmd) {
return true;
}
queue(cmd);
e.preventDefault();
e.stopPropagation();
e.cancelBubble = true;
return false;
}
function handleKeyPress(e) {
_console.log('websh.readline.handleKeyPress',_active);
var key = getKeyInfo(e);
if(key.code == 0 || e.defaultPrevented || e.metaKey || e.altKey || e.ctrlKey) {
return false;
}
queue(function cmdKeyPress() {
if(_inSearch) {
addSearchText(key.character);
} else {
addText(key.character);
}
});
e.preventDefault();
e.stopPropagation();
e.cancelBubble = true;
return false;
}
Josh.readlines.push(self)
function subscribeToKeys() {
// set up key capture
_element.onkeydown = function(e) {
e = e || window.event;
_console.log('websh.readline.onkeydown',_active,"key: " + e.keyCode);
if (!_active) {
for(var i=0;i
Ziel dieser Übung ist Implentierung und Unersuchung des ADT Liste mit zugehörigen Operationen.
Ausgabe : 9.1.2026
Abgabe : 19.1.2026
Es dürfen keine Standard Java Packages verwendet werden mit Ausnahme von System und String.
In dieser Aufgabe soll ein einfaches Speichermanagement mit Listen implementiert werden. Es sollen zwei Ansätze untersucht werden:
Es gibt einen Hauptspeicher eines Rechners der eine Größe von N Bytes haben soll. Dieser ist zunächst frei. Dann werden in Folge Speicherbereiche angefragt (allocate) und auch wieder zurück gegeben (release).
Es solle eine Liste aller freien Bereiche verwaltet werden. Zunächst gibt es nur ein Element mit dem gesamtem Speicherbereich.
Es wird zunächst die FirstFit Belegungsmethode verwendet. D.h. wenn ein Speicherbereich mit eine bestimmten Größe n Bytes angefragt wird findet ein Suche in der Lister der freien Blöcke statt bis ein Block gefunden wird der mindestens der gesuchten Größe n entspricht.
Ein freier Block wird am Anfang geteilt wenn Speicher belegt werden soll. Also z.B. gibt es einen freien Bereich [1000,1100] und es sollen 50 Bytes belegt werden. Dann ist danach der freie Block [1050,1100], und es wird der Bereich [1000,1049] als belegter Bereich verwendet.
Die Allokation soll immer die Startadresse (im Beispiel 1000) und die Endadresse (im Beispiel 1049) des Bereichs zurückgeben.
Die Freigabe eines Blocks erzeugt in der Liste ein weiteres Element.
Sowohl belegte als auch freie Blöcke werden einheitlich mit einer Datenstruktur / Objektklasse Block verwaltet:
In einer zweiten Strategie soll das BestFit Verfahren verwendet werden welches den kleinsten frein Block sucht der mindestens n Bytes umfasst. Das obige Beispiel ändert sich dann.
Bisher wurden die freien Blöcke immer am Ende der Liste angehängt. Wir wollen hier drei Verfahren untersuchen:
Jetzt brauchen wir noch eine Datenstruktur / Objektklasse für die Verkettung:
Aufgabe 1. Die Daten der Listenelemente werden durch die Klasse Block implementiert. Implementiere die Klasse Block.
Aufgabe 2. Die Daten der Listenelemente werden durch die Klasse Node1 als einfach verkettete Liste verbunden. Implementiere die Klasse List1 die die Klasse *Node1' verwendet.
Aufgabe 3. Notiere die Ergebnisse.
Aufgabe 4. Die Daten der Listenelemente werden durch die Klasse Node2 als doppelt verkettete Liste verbunden. Implementiere die Klasse List2 die die Klasse *Node2' verwendet.
[JAVA] { lines:10; height:30; incremental:1; progress:1 }
Aufgabe 5. Notiere die Ergebnisse.
Aufgabe 6. Welcher Belegungsalgorithmus liefert bei den Testfällen am Ende das beste Ergebnis (also am wenigstens Fragmentierung)? Wie hängt das Ergebnis von der Einfügestrategie ab? Bietet die doppelt verkettete Liste Vorteile, wenn ja bei welchen Fällen?
')))+'
');
}
self.scrollToBottom(true);
}
function outputString(output) {
if(output) {
if (output[0]=='<')
$(id(_input_id)).before(output);
else
$(id(_input_id)).before(expandSpaces(expandTabs(output.replace(/\n/g,'
'))));
}
self.scrollToBottom(true);
}
function activate() {
_console.log("activating shell");
if(!_view) {
_view = $(id(_shell_view_id));
}
if(!_panel) {
_panel = $(id(_shell_panel_id));
}
if($(id(_input_id)).length == 0) {
_view.append(self.templates.input_cmd({id:_input_id,class:"shell-cli"}));
}
self.refresh();
_active = true;
blinkCursor();
if(_promptHandler) {
_promptHandler(function(prompt) {
self.setPrompt(prompt);
})
}
if(_activationHandler) {
_activationHandler();
}
}
// init
_readline.onActivate(function() {
if(!_initialized) {
_initialized = true;
if(_initializationHandler) {
return _initializationHandler(activate);
}
}
return activate();
});
_readline.onDeactivate(function() {
if(_deactivationHandler) {
_deactivationHandler();
}
});
_readline.onChange(function(line) {
_line = line;
self.render();
});
_readline.onClear(function() {
_cmdHandlers.clear.exec(null, null, function() {
renderOutput(null, function() {
});
});
});
_readline.onSearchStart(function() {
$(id(_input_id)).replaceWith(self.templates.input_search({id:_input_id}));
_console.log('started search');
});
_readline.onSearchEnd(function() {
$(id(_input_id)).replaceWith(self.templates.input_cmd({id:_input_id}));
_searchMatch = null;
self.render();
_console.log("ended search");
});
_readline.onSearchChange(function(match) {
_searchMatch = match;
self.render();
});
_readline.onEnter(function(cmdtext, callback) {
_console.log("got command: " + cmdtext);
var parts = split(cmdtext);
var cmd = parts[0];
var args = parts.slice(1);
var handler = getHandler(cmd);
return handler.exec(cmd, args, function(output, cmdtext) {
renderOutput(output, function() {
callback(cmdtext)
});
},outputLine);
});
_readline.onCompletion(function(line, callback) {
if(!line) {
return callback();
}
var text = line.text.substr(0, line.cursor);
var parts = split(text);
var cmd = parts.shift() || '';
var arg = parts.pop() || '';
_console.log("getting completion handler for " + cmd);
var handler = getHandler(cmd);
if(handler != _cmdHandlers._default && cmd && cmd == text) {
_console.log("valid cmd, no args: append space");
// the text to complete is just a valid command, append a space
return callback(' ');
}
if(!handler.completion) {
// handler has no completion function, so we can't complete
return callback();
}
_console.log("calling completion handler for " + cmd);
return handler.completion(cmd, arg, line, function(match) {
_console.log("completion: " + JSON.stringify(match));
if(!match) {
return callback();
}
if(match.suggestions && match.suggestions.length > 1) {
return renderOutput(self.templates.suggest({suggestions: match.suggestions}), function() {
callback(match.completion);
});
}
return callback(match.completion);
});
});
return self;
}
/* ------------------------------------------------------------------------*
* Copyright 2013 Arne F. Claassen
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------*/
var Josh = Josh || {};
var root = this
Josh.PathHandler = function(shell, config) {
config = config || {};
var _console = config.console || (Josh.Debug && root.console ? root.console : {
log: function() {
}
});
var _shell = shell;
_shell.templates.not_found = _.template("
")}return q}function m(r,u,p){var v=h(r,p);var t=a(r);if(t=="no-highlight"){return}var w=t?d(t,v,true):g(v);t=w.language;var o=c(r);if(o.length){var q=document.createElementNS("http://www.w3.org/1999/xhtml","pre");q.innerHTML=w.value;w.value=j(o,c(q),v)}w.value=i(w.value,u,p);var s=r.className;if(!s.match("(\\s|^)(language-)?"+t+"(\\s|$)")){s=s?(s+" "+t):t}r.innerHTML=w.value;r.className=s;r.result={language:t,kw:w.keyword_count,re:w.r};if(w.second_best){r.second_best={language:w.second_best.language,kw:w.second_best.keyword_count,re:w.second_best.r}}}function n(){if(n.called){return}n.called=true;Array.prototype.map.call(document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml","pre"),b).filter(Boolean).forEach(function(o){m(o,hljs.tabReplace)})}function k(){window.addEventListener("DOMContentLoaded",n,false);window.addEventListener("load",n,false)}var e={};this.LANGUAGES=e;this.highlight=d;this.highlightAuto=g;this.fixMarkup=i;this.highlightBlock=m;this.initHighlighting=n;this.initHighlightingOnLoad=k;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|\\.|-|-=|/|/=|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE],r:0};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE],r:0};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.inherit=function(q,r){var o={};for(var p in q){o[p]=q[p]}if(r){for(var p in r){o[p]=r[p]}}return o}}();hljs.LANGUAGES.ruleslanguage=function(a){return{k:{keyword:"BILL_PERIOD BILL_START BILL_STOP RS_EFFECTIVE_START RS_EFFECTIVE_STOP RS_JURIS_CODE RS_OPCO_CODE INTDADDATTRIBUTE|5 INTDADDVMSG|5 INTDBLOCKOP|5 INTDBLOCKOPNA|5 INTDCLOSE|5 INTDCOUNT|5 INTDCOUNTSTATUSCODE|5 INTDCREATEMASK|5 INTDCREATEDAYMASK|5 INTDCREATEFACTORMASK|5 INTDCREATEHANDLE|5 INTDCREATEMASK|5 INTDCREATEOVERRIDEDAYMASK|5 INTDCREATEOVERRIDEMASK|5 INTDCREATESTATUSCODEMASK|5 INTDCREATETOUPERIOD|5 INTDDELETE|5 INTDDIPTEST|5 INTDEXPORT|5 INTDGETERRORCODE|5 INTDGETERRORMESSAGE|5 INTDISEQUAL|5 INTDJOIN|5 INTDLOAD|5 INTDLOADACTUALCUT|5 INTDLOADDATES|5 INTDLOADHIST|5 INTDLOADLIST|5 INTDLOADLISTDATES|5 INTDLOADLISTENERGY|5 INTDLOADLISTHIST|5 INTDLOADRELATEDCHANNEL|5 INTDLOADSP|5 INTDLOADSTAGING|5 INTDLOADUOM|5 INTDLOADUOMDATES|5 INTDLOADUOMHIST|5 INTDLOADVERSION|5 INTDOPEN|5 INTDREADFIRST|5 INTDREADNEXT|5 INTDRECCOUNT|5 INTDRELEASE|5 INTDREPLACE|5 INTDROLLAVG|5 INTDROLLPEAK|5 INTDSCALAROP|5 INTDSCALE|5 INTDSETATTRIBUTE|5 INTDSETDSTPARTICIPANT|5 INTDSETSTRING|5 INTDSETVALUE|5 INTDSETVALUESTATUS|5 INTDSHIFTSTARTTIME|5 INTDSMOOTH|5 INTDSORT|5 INTDSPIKETEST|5 INTDSUBSET|5 INTDTOU|5 INTDTOURELEASE|5 INTDTOUVALUE|5 INTDUPDATESTATS|5 INTDVALUE|5 STDEV INTDDELETEEX|5 INTDLOADEXACTUAL|5 INTDLOADEXCUT|5 INTDLOADEXDATES|5 INTDLOADEX|5 INTDLOADEXRELATEDCHANNEL|5 INTDSAVEEX|5 MVLOAD|5 MVLOADACCT|5 MVLOADACCTDATES|5 MVLOADACCTHIST|5 MVLOADDATES|5 MVLOADHIST|5 MVLOADLIST|5 MVLOADLISTDATES|5 MVLOADLISTHIST|5 IF FOR NEXT DONE SELECT END CALL ABORT CLEAR CHANNEL FACTOR LIST NUMBER OVERRIDE SET WEEK DISTRIBUTIONNODE ELSE WHEN THEN OTHERWISE IENUM CSV INCLUDE LEAVE RIDER SAVE DELETE NOVALUE SECTION WARN DELETE SAVE SAVE_UPDATE CLEAR DETERMINANT LABEL REPORT REVENUE ABORT CALL DONE LEAVE EACH IN LIST NOVALUE FROM TOTAL CHARGE BLOCK AND OR CSV_FILE BILL_PERIOD RATE_CODE AUXILIARY_DEMAND UIDACCOUNT RS BILL_PERIOD_SELECT HOURS_PER_MONTH INTD_ERROR_STOP SEASON_SCHEDULE_NAME ACCOUNTFACTOR ARRAYUPPERBOUND CALLSTOREDPROC GETADOCONNECTION GETCONNECT GETDATASOURCE GETQUALIFIER GETUSERID HASVALUE LISTCOUNT LISTOP LISTUPDATE LISTVALUE PRORATEFACTOR RSPRORATE SETBINPATH SETDBMONITOR WQ_OPEN BILLINGHOURS DATE DATEFROMFLOAT DATETIMEFROMSTRING DATETIMETOSTRING DATETOFLOAT DAY DAYDIFF DAYNAME DBDATETIME HOUR MINUTE MONTH MONTHDIFF MONTHHOURS MONTHNAME ROUNDDATE SAMEWEEKDAYLASTYEAR SECOND WEEKDAY WEEKDIFF YEAR YEARDAY YEARSTR COMPSUM HISTCOUNT HISTMAX HISTMIN HISTMINNZ HISTVALUE MAXNRANGE MAXRANGE MINRANGE COMPIKVA COMPKVA COMPKVARFROMKQKW COMPLF IDATTR FLAG LF2KW LF2KWH MAXKW POWERFACTOR READING2USAGE AVGSEASON MAXSEASON MONTHLYMERGE SEASONVALUE SUMSEASON ACCTREADDATES ACCTTABLELOAD CONFIGADD CONFIGGET CREATEOBJECT CREATEREPORT EMAILCLIENT EXPBLKMDMUSAGE EXPMDMUSAGE EXPORT_USAGE FACTORINEFFECT GETUSERSPECIFIEDSTOP INEFFECT ISHOLIDAY RUNRATE SAVE_PROFILE SETREPORTTITLE USEREXIT WATFORRUNRATE TO TABLE ACOS ASIN ATAN ATAN2 BITAND CEIL COS COSECANT COSH COTANGENT DIVQUOT DIVREM EXP FABS FLOOR FMOD FREPM FREXPN LOG LOG10 MAX MAXN MIN MINNZ MODF POW ROUND ROUND2VALUE ROUNDINT SECANT SIN SINH SQROOT TAN TANH FLOAT2STRING FLOAT2STRINGNC INSTR LEFT LEN LTRIM MID RIGHT RTRIM STRING STRINGNC TOLOWER TOUPPER TRIM ABORT WARN NUMDAYS RATE_CODE READ_DATE STAGING",built_in:"IDENTIFIER OPTIONS XML_ELEMENT XML_OP XML_ELEMENT_OF DOMDOCCREATE DOMDOCLOADFILE DOMDOCLOADXML DOMDOCSAVEFILE DOMDOCGETROOT DOMDOCADDPI DOMNODEGETNAME DOMNODEGETTYPE DOMNODEGETVALUE DOMNODEGETCHILDCT DOMNODEGETFIRSTCHILD DOMNODEGETSIBLING DOMNODECREATECHILDELEMENT DOMNODESETATTRIBUTE DOMNODEGETCHILDELEMENTCT DOMNODEGETFIRSTCHILDELEMENT DOMNODEGETSIBLINGELEMENT DOMNODEGETATTRIBUTECT DOMNODEGETATTRIBUTEI DOMNODEGETATTRIBUTEBYNAME DOMNODEGETBYNAME"},c:[a.CLCM,a.CBLCLM,a.ASM,a.QSM,a.CNM,{cN:"array",b:"#[a-zA-Z .]+"}]}}(hljs);hljs.LANGUAGES.ruby=function(e){var a="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?";var j="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?";var g={keyword:"and false then defined module in return redo if BEGIN retry end for true self when next until do begin unless END rescue nil else break undef not super class case require yield alias while ensure elsif or include"};var c={cN:"yardoctag",b:"@[A-Za-z]+"};var k=[{cN:"comment",b:"#",e:"$",c:[c]},{cN:"comment",b:"^\\=begin",e:"^\\=end",c:[c],r:10},{cN:"comment",b:"^__END__",e:"\\n$"}];var d={cN:"subst",b:"#\\{",e:"}",l:a,k:g};var i=[e.BE,d];var b=[{cN:"string",b:"'",e:"'",c:i,r:0},{cN:"string",b:'"',e:'"',c:i,r:0},{cN:"string",b:"%[qw]?\\(",e:"\\)",c:i},{cN:"string",b:"%[qw]?\\[",e:"\\]",c:i},{cN:"string",b:"%[qw]?{",e:"}",c:i},{cN:"string",b:"%[qw]?<",e:">",c:i,r:10},{cN:"string",b:"%[qw]?/",e:"/",c:i,r:10},{cN:"string",b:"%[qw]?%",e:"%",c:i,r:10},{cN:"string",b:"%[qw]?-",e:"-",c:i,r:10},{cN:"string",b:"%[qw]?\\|",e:"\\|",c:i,r:10},{cN:"string",b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/}];var h={cN:"function",bWK:true,e:" |$|;",k:"def",c:[{cN:"title",b:j,l:a,k:g},{cN:"params",b:"\\(",e:"\\)",l:a,k:g}].concat(k)};var f=k.concat(b.concat([{cN:"class",bWK:true,e:"$|;",k:"class module",c:[{cN:"title",b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?",r:0},{cN:"inheritance",b:"<\\s*",c:[{cN:"parent",b:"("+e.IR+"::)?"+e.IR}]}].concat(k)},h,{cN:"constant",b:"(::)?(\\b[A-Z]\\w*(::)?)+",r:0},{cN:"symbol",b:":",c:b.concat([{b:j}]),r:0},{cN:"symbol",b:a+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"("+e.RSR+")\\s*",c:k.concat([{cN:"regexp",b:"/",e:"/[a-z]*",i:"\\n",c:[e.BE,d]},{cN:"regexp",b:"%r{",e:"}[a-z]*",i:"\\n",c:[e.BE,d]},{cN:"regexp",b:"%r\\(",e:"\\)[a-z]*",i:"\\n",c:[e.BE,d]},{cN:"regexp",b:"%r!",e:"![a-z]*",i:"\\n",c:[e.BE,d]},{cN:"regexp",b:"%r\\[",e:"\\][a-z]*",i:"\\n",c:[e.BE,d]}]),r:0}]));d.c=f;h.c[1].c=f;return{l:a,k:g,c:f}}(hljs);hljs.LANGUAGES.haml=function(a){return{cI:true,c:[{cN:"doctype",b:"^!!!( (5|1\\.1|Strict|Frameset|Basic|Mobile|RDFa|XML\\b.*))?$",r:10},{cN:"comment",b:"^\\s*(-#|/).*$",r:0},{b:"^\\s*-(?!#)",starts:{e:"\\n",sL:"ruby"},r:0},{cN:"tag",b:"^\\s*%",c:[{cN:"title",b:"\\w+",r:0},{cN:"value",b:"[#\\.]\\w+",r:0},{b:"{\\s*",e:"\\s*}",eE:true,c:[{b:":\\w+\\s*=>",e:",\\s+",rB:true,eW:true,r:0,c:[{cN:"symbol",b:":\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0},{b:"\\(\\s*",e:"\\s*\\)",eE:true,c:[{b:"\\w+\\s*=",e:"\\s+",rB:true,eW:true,r:0,c:[{cN:"attribute",b:"\\w+",r:0},{cN:"string",b:'"',e:'"',r:0},{cN:"string",b:"'",e:"'",r:0},{b:"\\w+",r:0}]},],r:0}],r:10},{cN:"bullet",b:"^\\s*[=~]\\s*",r:0},{b:"#{",starts:{e:"}",sL:"ruby"},r:0}]}}(hljs);hljs.LANGUAGES.haskell=function(f){var h={cN:"comment",b:"--",e:"$"};var g={cN:"comment",c:["self"],b:"{-",e:"-}"};var e={cN:"pragma",b:"{-#",e:"#-}"};var b={cN:"preprocessor",b:"^#",e:"$"};var d={cN:"type",b:"\\b[A-Z][\\w']*",r:0};var c={cN:"container",b:"\\(",e:"\\)",i:'"',c:[e,h,g,b,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},{cN:"title",b:"[_a-z][\\w']*"}]};var a={cN:"container",b:"{",e:"}",c:c.c};return{k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{cN:"module",b:"\\bmodule ",e:"where",k:"module where",c:[c,g],i:"\\W\\.|;"},{cN:"import",b:"\\bimport ",e:"$",k:"import qualified as hiding",c:[c,h,g],i:"\\W\\.|;"},{cN:"class",b:"\\b(class |instance )",e:"where",k:"class family instance where",c:[d,c,g]},{cN:"typedef",b:"\\b(data |(new)?type )",e:"$",k:"data family type newtype deriving",c:[e,h,g,d,c,a]},{cN:"default",b:"\\bdefault ",e:"$",k:"default",c:[d,c,h,g]},{cN:"infix",b:"\\b(infix |infixl |infixr )",e:"$",k:"infix infixl infixr",c:[f.CNM,h,g]},{cN:"foreign",b:"\\bforeign ",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[d,f.QSM,h,g]},{cN:"shebang",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},e,h,g,b,f.QSM,f.CNM,d,{cN:"title",b:"^[_a-z][\\w']*"},{b:"->|<-"}]}}(hljs);hljs.LANGUAGES.xml=function(a){var c="[A-Za-z0-9\\._:-]+";var b={eW:true,r:0,c:[{cN:"attribute",b:c,r:0},{b:'="',rB:true,e:'"',c:[{cN:"value",b:'"',eW:true}]},{b:"='",rB:true,e:"'",c:[{cN:"value",b:"'",eW:true}]},{b:"=",c:[{cN:"value",b:"[^\\s/>]+"}]}]};return{cI:true,c:[{cN:"pi",b:"<\\?",e:"\\?>",r:10},{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"",rE:true,sL:"css"}},{cN:"tag",b:"
Gruppennummer und Namen der Gruppenmitglieder (Zeilenformat!)
AuD Übung 07 (Stefan Bosse) [9.1.2026]
Punkte: Total /2 1. /2 2. /2 3. /2 4. /2 5. /2 6. /2 Listen
Speicher allocate(m1) allocate(m2)
│ 0 ┌――――――――┐ ┌――――――――┐ ┌――――――――┐
│ │ │ │ │ │ │
│ │ │ │ │ │ │
│ │ │ │ belegt │ │ belegt │
│ │ │ │ │ │ │
│ │ │ ├――――――――┤ ├――――――――┤
│ │ │ │ │ │ belegt │
│ │ │ │ │ │ │
│ │ frei │ │ │ ├――――――――┤
│ │ │ │ │ │ │
│ │ │ │ frei │ │ │
│ │ │ │ │ │ │
│ │ │ │ │ │ frei │
│ │ │ │ │ │ │
│ │ │ │ │ │ │
▼ N-1 └――――――――┘ └――――――――┘ └――――――――┘
Block = {
start : number,
end : number,
flag : number // 0:frei, 1:belegt
}
[0,999]
allocate(10) -> [0,9]
[10,999]
allocate(20) -> [10,19]
[20,999]
release([0,9])
[20,999],[0,9]
allocate(5) -> [20,24]
[25,999],[0,9]
release([10,19])
[25,999],[0,9],[10,19]
[0,999]
allocate(10) -> [0,9]
[10,999]
allocate(20) -> [10,19]
[20,999]
release([0,9])
[20,999],[0,9]
allocate(5) -> [0,4]
[25,999],[5,9]
release([10,19])
[25,999],[5,9],[10,19]
function firstFit(L,size) {
node=L.head
while (node && (node.end-node.start+1)<size) {
node=node.next
}
return node
}
function bestFit(L,size) {
node=L.head
best=null
while (node) {
s1=(node.end-node.start+1)
if (s1>=size && !best) best=node
s2=(best.end-best.start+1)
if (s1>=size && s2>s1) {
best=node
}
node=node.next
}
return best
}
M=Memory(N=50)
B1=allocate(M,10)
B2=allocate(M,20)
release(B1)
B3=allocate(M,5)
release(B2)
print(M)
B4=allocate(M,5)
print(M)
rlease(B3)
B5=allocate(M,4)
print(M)
aW1wb3J0IGphdmEubGFuZy4qOwppbXBvcnQgdWoubGFuZy4qOwpwdWJsaWMgY2xhc3MgQmxvY2sgewogIGludCBzdGFydDsKICBpbnQgZW5kOwogIGludCBmbGFnOwogIHB1YmxpYyBCbG9jayAoaW50IHN0YXJ0LCBpbnQgZW5kLCBpbnQgZmxhZykgewogICAgdGhpcy5zdGFydD1zdGFydDsKICAgIHRoaXMuZW5kPWVuZDsKICAgIHRoaXMuZmxhZz1mbGFnOwogIH0KICBwdWJsaWMgaW50IGdldFN0YXJ0ICgpIHsKICAgIHJldHVybiB0aGlzLnN0YXJ0OwogIH0KICBwdWJsaWMgaW50IGdldEVuZCAoKSB7CiAgICByZXR1cm4gdGhpcy5lbmQ7CiAgfQogIHB1YmxpYyBpbnQgZ2V0RmxhZyAoKSB7CiAgICByZXR1cm4gdGhpcy5mbGFnOwogIH0KICBwdWJsaWMgaW50IGdldExlbmd0aCAoKSB7CiAgICByZXR1cm4gdGhpcy5lbmQtdGhpcy5zdGFydCsxOwogIH0KfQ==
aW1wb3J0IGphdmEubGFuZy4qOwppbXBvcnQgdWoubGFuZy4qOwpwdWJsaWMgY2xhc3MgTm9kZTEgewogIEJsb2NrIGRhdGE7CiAgTm9kZTEgbmV4dDsKICBwdWJsaWMgTm9kZTEoQmxvY2sgZGF0YSkgewogICAgdGhpcy5kYXRhPWRhdGE7CiAgICB0aGlzLm5leHQ9bnVsbDsKICB9Cn0=
Einfach verkettete Listen Klasse für die Speicherverwaltung mit alternativen BestFit oder FirstFit Belegungsalgorithmus. Führe die Tests für alle drei Einfügestrategien durch (siehe oben). (websh0)
aW1wb3J0IGphdmEubGFuZy4qOwppbXBvcnQgdWoubGFuZy4qOwpwdWJsaWMgY2xhc3MgTGlzdDEgewogIE5vZGUxIGhlYWQ7CiAgY2hhciBhbGxvY2FNZXRob2Q7CiAgY2hhciBpbnNlcnRNZXRob2Q7CiAgcHVibGljIExpc3QxKGNoYXIgYWxsb2NhTWV0aG9kLGNoYXIgaW5zZXJ0TWV0aG9kKSB7CiAgICAvLyBhbGxvY2FNZXRob2QgPSAnQicgfCAnRicgQmVzdEZpdCAvIEZpcnN0Rml0CiAgICAvLyBpbnNlcnRNZXRob2QgPSAnSCcgfCAnVCcgfCAnUycKICAgIHRoaXMuYWxsb2NhTWV0aG9kPWFsbG9jYU1ldGhvZDsKICAgIHRoaXMuaW5zZXJ0TWV0aG9kPWluc2VydE1ldGhvZDsKICAgIHRoaXMuaGVhZD1udWxsOwogIH0KICBwdWJsaWMgdm9pZCByZW1vdmUoTm9kZTEgbm9kZSkgewogICAgTm9kZTEgbmV4dD10aGlzLmhlYWQ7CiAgICBOb2RlMSBwcmV2PXRoaXMuaGVhZDsKICAgIHdoaWxlIChuZXh0ICYmIG5leHQuZGF0YS5zdGFydCE9bm9kZS5kYXRhLnN0YXJ0KSB7CiAgICAgIHByZXYgPSBuZXh0OwogICAgICBuZXh0ID0gbmV4dC5uZXh0OwogICAgfQogICAgaWYgKCFuZXh0KSB0aHJvdyAiRUlOVkFMSUQiOwogICAgaWYgKHByZXYuZGF0YS5zdGFydD09bmV4dC5kYXRhLnN0YXJ0KSB0aGlzLmhlYWQ9dGhpcy5oZWFkLm5leHQ7CiAgICBlbHNlIHByZXYubmV4dD1uZXh0Lm5leHQ7CiAgfQogIHB1YmxpYyB2b2lkIGluc2VydChOb2RlMSBub2RlKSB7CiAgICBzd2l0Y2ggKHRoaXMuaW5zZXJ0TWV0aG9kKSB7CiAgICAgIGNhc2UgJ0gnOiB0aGlzLmluc2VydEhlYWQobm9kZSk7IHJldHVybjsKICAgICAgY2FzZSAnVCc6IHRoaXMuaW5zZXJ0VGFpbChub2RlKTsgcmV0dXJuOwogICAgICBjYXNlICdTJzogdGhpcy5pbnNlcnRTb3J0ZWQobm9kZSk7IHJldHVybjsKICAgIH0KICB9CiAgcHVibGljIHZvaWQgaW5zZXJ0SGVhZChOb2RlMSBub2RlKSB7CiAgICBpZiAodGhpcy5oZWFkPT1udWxsKSB0aGlzLmhlYWQ9bm9kZTsKICAgIGVsc2UgewogICAgICBub2RlLm5leHQ9dGhpcy5oZWFkOwogICAgICB0aGlzLmhlYWQ9bm9kZTsKICAgIH0KICB9CiAgcHVibGljIHZvaWQgaW5zZXJ0VGFpbChOb2RlMSBub2RlKSB7CiAgICBpZiAodGhpcy5oZWFkPT1udWxsKSB0aGlzLmhlYWQ9bm9kZTsKICAgIGVsc2UgewogICAgICBOb2RlMSBuZXh0PXRoaXMuaGVhZDsKICAgICAgd2hpbGUgKG5leHQubmV4dCkgewogICAgICAgIG5leHQ9bmV4dC5uZXh0OwogICAgICB9CiAgICAgIG5leHQubmV4dD1ub2RlOwogICAgfQogIH0KICBwdWJsaWMgdm9pZCBpbnNlcnRTb3J0ZWQoTm9kZTEgbm9kZSkgewogICAgaWYgKHRoaXMuaGVhZD09bnVsbCkgdGhpcy5oZWFkPW5vZGU7CiAgICBlbHNlIHsKICAgICAgTm9kZTEgcHJldj10aGlzLmhlYWQ7CiAgICAgIE5vZGUxIG5leHQ9dGhpcy5oZWFkOwogICAgICB3aGlsZSAobmV4dCAmJiBuZXh0Lm5leHQgJiYgbmV4dC5uZXh0LmRhdGEuc3RhcnQ8bm9kZS5kYXRhLnN0YXJ0KSB7CiAgICAgICAgcHJldj1uZXh0OwogICAgICAgIG5leHQ9bmV4dC5uZXh0OwogICAgICB9CiAgICAgIHByZXYubmV4dD1ub2RlOwogICAgICBub2RlLm5leHQ9bmV4dDsKICAgIH0KICB9CiAgcHVibGljIEJsb2NrIGFsbG9jYXRlKGludCBzaXplKSB7CiAgICBOb2RlMSBuZXh0LGJlc3QsYWRkcjsKICAgIHN3aXRjaCAodGhpcy5hbGxvY2FNZXRob2QpIHsKICAgICAgY2FzZSAnRic6CiAgICAgICAgbmV4dD10aGlzLmhlYWQ7CiAgICAgICAgd2hpbGUobmV4dCAmJiAobmV4dC5kYXRhLmVuZC1uZXh0LmRhdGEuc3RhcnQrMSk8c2l6ZSkgewogICAgICAgICAgbmV4dD1uZXh0Lm5leHQ7CiAgICAgICAgfQogICAgICAgIGlmICghbmV4dCkgdGhyb3cgIk9VVE9GTUVNIjsKICAgICAgICBhZGRyID0gbmV4dC5kYXRhLnN0YXJ0OwogICAgICAgIG5leHQuZGF0YS5zdGFydCs9c2l6ZTsKICAgICAgICBpZiAobmV4dC5kYXRhLnN0YXJ0PT1uZXh0LmRhdGEuZW5kKSB7CiAgICAgICAgICAvLyBzaG91bGQgYmUgcmVtb3ZlZAogICAgICAgICAgdGhpcy5yZW1vdmUobmV4dCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgQmxvY2soYWRkcixhZGRyK3NpemUtMSwxKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnQic6CiAgICAgICAgbmV4dD10aGlzLmhlYWQ7CiAgICAgICAgYmVzdD1udWxsOwogICAgICAgIHdoaWxlKG5leHQpIHsKICAgICAgICAgIGlmICgobmV4dC5kYXRhLmVuZC1uZXh0LmRhdGEuc3RhcnQrMSk8c2l6ZSkgewogICAgICAgICAgICBpZiAoIWJlc3QpIGJlc3Q9bmV4dDsKICAgICAgICAgICAgZWxzZSBpZiAoKG5leHQuZGF0YS5lbmQtbmV4dC5kYXRhLnN0YXJ0KzEpPChiZXN0LmRhdGEuZW5kLWJlc3QuZGF0YS5zdGFydCsxKSkgYmVzdD1uZXh0OwogICAgICAgICAgfQogICAgICAgICAgbmV4dD1uZXh0Lm5leHQ7CiAgICAgICAgfQogICAgICAgIGlmICghYmVzdCkgdGhyb3cgIk9VVE9GTUVNIjsKICAgICAgICBhZGRyID0gYmVzdC5kYXRhLnN0YXJ0OwogICAgICAgIGJlc3QuZGF0YS5zdGFydCs9c2l6ZTsKICAgICAgICBpZiAoYmVzdC5kYXRhLnN0YXJ0PT1iZXN0LmRhdGEuZW5kKSB7CiAgICAgICAgICAvLyBzaG91bGQgYmUgcmVtb3ZlZAogICAgICAgICAgdGhpcy5yZW1vdmUoYmVzdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgQmxvY2soYWRkcixhZGRyK3NpemUtMSwxKTsKICAgICAgICBicmVhazsKICAgIH0KICB9CiAgcHVibGljIHZvaWQgcmVsZWFzZShCbG9jayBibG9jaykgewogICAgYmxvY2suZmxhZz0wOwogICAgdGhpcy5pbnNlcnQobmV3IE5vZGUxKGJsb2NrKSk7CiAgfQogIHB1YmxpYyB2b2lkIHByaW50KCkgewogICAgTm9kZTEgbmV4dD10aGlzLmhlYWQ7CiAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PT09IE1FTU9SWSA9PT09PT09PT09Iik7CiAgICB3aGlsZSAobmV4dCkgewogICAgICBTeXN0ZW0ub3V0LnByaW50bG4obmV4dC5kYXRhLnN0YXJ0KyIgICIrbmV4dC5kYXRhLmVuZCsiICAiK25leHQuZGF0YS5mbGFnKTsKICAgICAgbmV4dD1uZXh0Lm5leHQ7CiAgICB9CiAgfQp9
Main Test. Ergänze die obigen Testfälle und prüfe das Ergebnis. Führe die Tests für alle drei Einfügestrategien durch (siehe oben). (websh0)
Test der einfach verketteten Listen Klasse List1. Prüfe die Ergebnisse der Speicherbelegung der Beispiele. Ausführung von make (Linux, Mac) oder makew (Windows) und run. (websh0) help or hit TAB for a list of commands.
aW1wb3J0IGphdmEubGFuZy4qOwppbXBvcnQgdWoubGFuZy4qOwpwdWJsaWMgY2xhc3MgTm9kZTIgewogIEJsb2NrIGRhdGE7CiAgTm9kZTIgbmV4dDsKICBOb2RlMiBwcmV2OwogIHB1YmxpYyBOb2RlMihCbG9jayBkYXRhKSB7CiAgICB0aGlzLmRhdGE9ZGF0YTsKICAgIHRoaXMubmV4dD1udWxsOwogICAgdGhpcy5wcmV2PW51bGw7CiAgfQp9
Doppelt verkettete Listen Klasse für die Speicherverwaltung mit alternativen BestFit oder FirstFit Belegungsalgorithmus. (websh1)
aW1wb3J0IGphdmEubGFuZy4qOwppbXBvcnQgdWoubGFuZy4qOwpwdWJsaWMgY2xhc3MgTGlzdDIgewogIE5vZGUyIGhlYWQ7CiAgY2hhciBhbGxvY2FNZXRob2Q7CiAgY2hhciBpbnNlcnRNZXRob2Q7CiAgcHVibGljIExpc3QyKGNoYXIgYWxsb2NhTWV0aG9kLGNoYXIgaW5zZXJ0TWV0aG9kKSB7CiAgICAvLyBhbGxvY2FNZXRob2QgPSAnQicgfCAnRicgQmVzdEZpdCAvIEZpcnN0Rml0CiAgICAvLyBpbnNlcnRNZXRob2RlID0gJ0gnIHwgJ1QnIHwgJ1MnCiAgICB0aGlzLmFsbG9jYU1ldGhvZD1hbGxvY2FNZXRob2Q7CiAgICB0aGlzLmluc2VydE1ldGhvZD1pbnNlcnRNZXRob2Q7CiAgICB0aGlzLmhlYWQ9bnVsbDsKICB9CiAgcHVibGljIHZvaWQgcmVtb3ZlKE5vZGUxIG5vZGUpIHsKICAgIE5vZGUyIG5leHQ9dGhpcy5oZWFkOwogICAgd2hpbGUgKG5leHQgJiYgbmV4dC5kYXRhLnN0YXJ0IT1ub2RlLmRhdGEuc3RhcnQpIHsKICAgICAgbmV4dCA9IG5leHQubmV4dDsKICAgIH0KICAgIGlmICghbmV4dCkgdGhyb3cgIkVJTlZBTElEIjsKCiAgICBpZiAodGhpcy5oZWFkLmRhdGEuc3RhcnQ9PW5leHQuZGF0YS5zdGFydCkgdGhpcy5oZWFkPXRoaXMuaGVhZC5uZXh0OwogICAgZWxzZSBuZXh0LnByZXYubmV4dD1uZXh0Lm5leHQ7CiAgfQogIHB1YmxpYyB2b2lkIGluc2VydChOb2RlMiBub2RlKSB7CiAgICBzd2l0Y2ggKHRoaXMuaW5zZXJ0TWV0aG9kKSB7CiAgICAgIGNhc2UgJ0gnOiB0aGlzLmluc2VydEhlYWQobm9kZSk7IHJldHVybjsKICAgICAgY2FzZSAnVCc6IHRoaXMuaW5zZXJ0VGFpbChub2RlKTsgcmV0dXJuOwogICAgICBjYXNlICdTJzogdGhpcy5pbnNlcnRTb3J0ZWQobm9kZSk7IHJldHVybjsKICAgIH0KICB9CiAgcHVibGljIHZvaWQgaW5zZXJ0SGVhZChOb2RlMiBub2RlKSB7CiAgICBpZiAodGhpcy5oZWFkPT1udWxsKSB0aGlzLmhlYWQ9bm9kZTsKICAgIGVsc2UgewogICAgICBub2RlLm5leHQ9dGhpcy5oZWFkOwogICAgICB0aGlzLmhlYWQ9bm9kZTsKICAgIH0KICB9CiAgcHVibGljIHZvaWQgaW5zZXJ0VGFpbChOb2RlMiBub2RlKSB7CiAgICBpZiAodGhpcy5oZWFkPT1udWxsKSB0aGlzLmhlYWQ9bm9kZTsKICAgIGVsc2UgewogICAgICBOb2RlMiBuZXh0PXRoaXMuaGVhZDsKICAgICAgd2hpbGUgKG5leHQubmV4dCkgewogICAgICAgIG5leHQ9bmV4dC5uZXh0OwogICAgICB9CiAgICAgIG5leHQubmV4dD1ub2RlOwogICAgfQogIH0KICBwdWJsaWMgdm9pZCBpbnNlcnRTb3J0ZWQoTm9kZTIgbm9kZSkgewogICAgaWYgKHRoaXMuaGVhZD09bnVsbCkgdGhpcy5oZWFkPW5vZGU7CiAgICBlbHNlIHsKICAgICAgTm9kZTIgbmV4dD10aGlzLmhlYWQ7CiAgICAgIHdoaWxlIChuZXh0ICYmIG5leHQubmV4dCAmJiBuZXh0Lm5leHQuZGF0YS5zdGFydDxub2RlLmRhdGEuc3RhcnQpIHsKICAgICAgICBuZXh0PW5leHQubmV4dDsKICAgICAgfQogICAgICBuZXh0LnByZXYubmV4dD1ub2RlOwogICAgICBub2RlLm5leHQ9bmV4dDsKICAgIH0KICB9CiAgcHVibGljIEJsb2NrIGFsbG9jYXRlKGludCBzaXplKSB7CiAgICBOb2RlMSBuZXh0LGJlc3QsYWRkcjsKICAgIHN3aXRjaCAodGhpcy5hbGxvY2FNZXRob2QpIHsKICAgICAgY2FzZSAnRic6CiAgICAgICAgbmV4dD10aGlzLmhlYWQ7CiAgICAgICAgd2hpbGUobmV4dCAmJiAobmV4dC5kYXRhLmVuZC1uZXh0LmRhdGEuc3RhcnQrMSk8c2l6ZSkgewogICAgICAgICAgbmV4dD1uZXh0Lm5leHQ7CiAgICAgICAgfQogICAgICAgIGlmICghbmV4dCkgdGhyb3cgIk9VVE9GTUVNIjsKICAgICAgICBhZGRyID0gbmV4dC5kYXRhLnN0YXJ0OwogICAgICAgIG5leHQuZGF0YS5zdGFydCs9c2l6ZTsKICAgICAgICBpZiAobmV4dC5kYXRhLnN0YXJ0PT1uZXh0LmRhdGEuZW5kKSB7CiAgICAgICAgICAvLyBzaG91bGQgYmUgcmVtb3ZlZAogICAgICAgICAgdGhpcy5yZW1vdmUobmV4dCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgQmxvY2soYWRkcixhZGRyK3NpemUtMSwxKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAnQic6CiAgICAgICAgbmV4dD10aGlzLmhlYWQ7CiAgICAgICAgYmVzdD1udWxsOwogICAgICAgIHdoaWxlKG5leHQpIHsKICAgICAgICAgIGlmICgobmV4dC5kYXRhLmVuZC1uZXh0LmRhdGEuc3RhcnQrMSk8c2l6ZSkgewogICAgICAgICAgICBpZiAoIWJlc3QpIGJlc3Q9bmV4dDsKICAgICAgICAgICAgZWxzZSBpZiAoKG5leHQuZGF0YS5lbmQtbmV4dC5kYXRhLnN0YXJ0KzEpPChiZXN0LmRhdGEuZW5kLWJlc3QuZGF0YS5zdGFydCsxKSkgYmVzdD1uZXh0OwogICAgICAgICAgfQogICAgICAgICAgbmV4dD1uZXh0Lm5leHQ7CiAgICAgICAgfQogICAgICAgIGlmICghYmVzdCkgdGhyb3cgIk9VVE9GTUVNIjsKICAgICAgICBhZGRyID0gYmVzdC5kYXRhLnN0YXJ0OwogICAgICAgIGJlc3QuZGF0YS5zdGFydCs9c2l6ZTsKICAgICAgICBpZiAoYmVzdC5kYXRhLnN0YXJ0PT1iZXN0LmRhdGEuZW5kKSB7CiAgICAgICAgICAvLyBzaG91bGQgYmUgcmVtb3ZlZAogICAgICAgICAgdGhpcy5yZW1vdmUoYmVzdCk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBuZXcgQmxvY2soYWRkcixhZGRyK3NpemUtMSwxKTsKICAgICAgICBicmVhazsKICAgIH0KICB9CiAgcHVibGljIHZvaWQgcmVsZWFzZShCbG9jayBibG9jaykgewogICAgYmxvY2suZmxhZz0wOwogICAgdGhpcy5pbnNlcnQobmV3IE5vZGUyKGJsb2NrKSk7CiAgfQogIHB1YmxpYyB2b2lkIHByaW50KCkgewogICAgTm9kZTIgbmV4dD10aGlzLmhlYWQ7CiAgICBTeXN0ZW0ub3V0LnByaW50bG4oIj09PT09PT09IE1FTU9SWSA9PT09PT09PT09Iik7CiAgICB3aGlsZSAobmV4dCkgewogICAgICBTeXN0ZW0ub3V0LnByaW50bG4obmV4dC5kYXRhLnN0YXJ0KyIgICIrbmV4dC5kYXRhLmVuZCsiICAiK25leHQuZGF0YS5mbGFnKTsKICAgICAgbmV4dD1uZXh0Lm5leHQ7CiAgICB9CiAgfQp9
Test der doppelt verketteten Listen Klasse List2. Ausführung von make (Linux, Mac) oder makew (Windows) und run. (websh1) help or hit TAB for a list of commands.
Hilfe