Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,3 +37,6 @@ rebuildTags.sh

# caused py setup.py develop
pymatbridge.egg-info

# so vim-ers can use "YouCompleteMe"
.ycm_extra_conf.py
48 changes: 40 additions & 8 deletions pymatbridge/matlab/matlabserver.m
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
function matlabserver(socket_address)
function matlabserver(socket_address, exit_when_done)
%MATLABSERVER Take Commands from Python via ZMQ
% matlabserver(socket_address, exit_when_done)
% This function takes a socket address as input and initiates a ZMQ session
% over the socket. I then enters the listen-respond mode until it gets an
% "exit" command

json_startup
% over the socket. It then enters the listen-respond mode until it gets an
% "exit" command, at which point it returns (or exits if exit_when_done), or
% until it gets a "separate" command, at which point it launches the MATLAB
% desktop client and returns.
%

initialize_environment;
json_startup;
messenger('init', socket_address);

c=onCleanup(@()exit);
c = onCleanup(@stop_messenger);

while(1)
msg_in = messenger('listen');
Expand All@@ -17,15 +23,41 @@ function matlabserver(socket_address)
messenger('respond', 'connected');

case {'exit'}
messenger('exit');
break;

case {'eval'}
resp = pymat_eval(req);
messenger('respond', resp);

case {'separate'}
desktop; %no-op if desktop is already up
exit_when_done = false;
break;

otherwise
messenger('respond', 'i dont know what you want');
messenger('respond', 'Unknown command recieved by matlabserver via ZMQ.');

end
end

if nargin > 1 && exit_when_done
%c.task(); % already executed by "finish"
exit;
end

end %matlabserver

function stop_messenger()
if messenger('check')
messenger('exit');
end
end

function initialize_environment()
if ~exist('json_startup', 'file')
[pathstr, ~, ~] = fileparts(mfilename('fullpath'));
old_warning_state = warning('off','all');
addpath(genpath(pathstr));
warning(old_warning_state);
end
end
6 changes: 6 additions & 0 deletions pymatbridge/matlab/util/finish.m
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
% make sure socket gets closed no matter how MATLAB exists (sans crash)
if exist('messenger', 'file')
if messenger('check')
messenger('exit');
end
end
12 changes: 8 additions & 4 deletions pymatbridge/matlab/util/json_v0.2.2/json/json_dump.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,7 +106,7 @@
double_struct = struct;
double_struct.ndarray = 1;
value = double(value);
if isreal(value)
if isreal(value)
double_struct.data = base64encode(typecast(value(:), 'uint8'));
else
double_struct.real = base64encode(typecast(real(value(:)), 'uint8'));
Expand DownExpand Up@@ -142,9 +142,13 @@
obj.put(dump_data_(value{i}, options));
end
elseif isnumeric(value)
if isreal(value)
if ~isfinite(value)
json_non_finite = struct;
json_non_finite.json_non_finite = lower(num2str(value));
obj = dump_data_(json_non_finite, options);
elseif isreal(value)
obj = value;
% Encode complex number as a struct
% Encode finite complex number as a struct
else
complex_struct = struct;
complex_struct.real = real(value);
Expand All@@ -158,7 +162,7 @@
keys = fieldnames(value);
for i = 1:length(keys)
try
obj.put(keys{i},dump_data_(value.(keys{i}), options));
obj.put(keys{i},dump_data_(value.(keys{i}), options));
catch ME
obj.put(keys{i}, dump_data_(ME.message, options))
end
Expand Down
2 changes: 1 addition & 1 deletion pymatbridge/matlab/util/pymat_eval.m
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
function json_response = pymat_eval(req);
function json_response = pymat_eval(req)
% PYMAT_EVAL: Returns a json object of the result of calling the function
%
% json_response = pymat_eval(req);
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/matlab_magic.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@
from .compat import text_type


class MatlabInterperterError(RuntimeError):
class MatlabInterpreterError(RuntimeError):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

"""
Some error occurs while matlab is running
"""
Expand DownExpand Up@@ -87,7 +87,7 @@ def eval(self, line):
run_dict = self.Matlab.run_code(line)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])

# This is the matlab stdout:
return run_dict
Expand All@@ -99,7 +99,7 @@ def set_matlab_var(self, name, value):
run_dict = self.Matlab.set_variable(name, value)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])


@magic_arguments()
Expand DownExpand Up@@ -161,7 +161,7 @@ def matlab(self, line, cell=None, local_ns=None):

try:
result_dict = self.eval(code)
except MatlabInterperterError:
except MatlabInterpreterError:
raise
except:
raise RuntimeError('\n'.join([
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/messenger/make.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ def get_config():


def do_build(make_cmd, messenger_exe):
print('Building %s...' % messenger_exe)
print('Building {}...'.format(messenger_exe))
print(make_cmd)
messenger_dir = get_messenger_dir()
subprocess.check_output(shlex.split(make_cmd), shell=use_shell)
Expand All@@ -188,7 +188,7 @@ def do_build(make_cmd, messenger_exe):
def build_octave():
paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s"
paths = paths % get_config()
make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths
make_cmd = "mkoctfile --mex {} -lzmq ./src/messenger.c".format(paths)
do_build(make_cmd, 'messenger.mex')


Expand DownExpand Up@@ -264,10 +264,10 @@ def build_matlab(static=False):
# Build the mex file
mex = esc(os.path.join(matlab_bin, "mex"))
paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg
make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths)
make_cmd = '{} -O {} -lzmq ./src/messenger.c'.format(mex, paths)
if static:
make_cmd += ' -DZMQ_STATIC'
do_build(make_cmd, 'messenger.%s' % extension)
do_build(make_cmd, 'messenger.{}'.format(extension))


if __name__ == '__main__':
Expand Down
Binary file modifiedpymatbridge/messenger/mexa64/messenger.mexa64
Binary file not shown.
62 changes: 29 additions & 33 deletions pymatbridge/messenger/src/messenger.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,61 +48,58 @@ void cleanup (void) {
mexPrintf("Socket closed\n");
zmq_term(ctx);
mexPrintf("Context terminated\n");
initialized = 0;
}


/* Gateway function with Matlab */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
char *cmd;
mxLogical *p;
/* If no input argument, print out the usage */
if (nrhs == 0) {
mexErrMsgTxt("Usage: messenger('init|listen|respond', extra1, extra2, ...)");
}

if (nlhs > 1) {
mexErrMsgTxt("messenger: too many outputs, I return a single bool");
}
/* Get the input command */
if(!(cmd = mxArrayToString(prhs[0]))) {
mexErrMsgTxt("Cannot read the command");
}

/* we'll return true on completion of valid command, else false */
plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);
p[0] = false;
/* Initialize a new server session */
if (strcmp(cmd, "init") == 0) {
char *socket_addr;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
mexErrMsgTxt("Missing argument: socket address");
mexErrMsgTxt("Usage: messenger('init', socket_addr)");
}
if (!(socket_addr = mxArrayToString(prhs[1]))) {
mexErrMsgTxt("Cannot read socket address");
}

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (!initialized) {
if (!initialize(socket_addr)) {
p[0] = 1;
p[0] = true;
mexPrintf("Socket created at: %s\n", socket_addr);
} else {
p[0] = 0;
mexErrMsgTxt("Socket creation failed.");
}
} else {
mexErrMsgTxt("One socket has already been initialized.");
}

return;

/* Listen over an existing socket */
} else if (strcmp(cmd, "listen") == 0) {
int byte_recvd;
char *recv_buffer = mxCalloc(BUFLEN, sizeof(char));
zmq_pollitem_t polls[] = {{socket_ptr, 0, ZMQ_POLLIN, 0}};

if (!checkInitialized()) return;

/* allow MATLAB to draw its graphics every 20ms */
while (zmq_poll(polls, 1, 20000) == 0) {
mexEvalString("drawnow");
Expand All@@ -116,17 +113,14 @@ void mexFunction(int nlhs, mxArray *plhs[],
} else if (byte_recvd > BUFLEN){
mexErrMsgTxt("Receiver buffer overflow. Message truncated");
} else {
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
mexErrMsgTxt(recv_buffer);
}

return;

p[0] = true;
/* Send a message out */
} else if (strcmp(cmd, "respond") == 0) {
size_t msglen;
char *msg_out;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
Expand All@@ -138,24 +132,26 @@ void mexFunction(int nlhs, mxArray *plhs[],
msglen = mxGetNumberOfElements(prhs[1]);
msg_out = mxArrayToString(prhs[1]);

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (msglen == zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = 1;
if (msglen == (size_t) zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = true;
} else {
p[0] = 0;
mexErrMsgTxt("Failed to send message due to ZMQ error");
}

return;

/* Close the socket and context */
} else if (strcmp(cmd, "exit") == 0) {
cleanup();

return;
if (initialized) {
cleanup();
p[0] = true;
initialized = 0;
} else {
mexErrMsgTxt("No open socket to exit.");
}
} else if (strcmp(cmd, "check") == 0) {
if (initialized) {
p[0] = true;
}
} else {
mexErrMsgTxt("Unidentified command");
}
return;
}
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Inf fix by brunobeltran · Pull Request #218 · arokem/python-matlab-bridge · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,3 +37,6 @@ rebuildTags.sh

# caused py setup.py develop
pymatbridge.egg-info

# so vim-ers can use "YouCompleteMe"
.ycm_extra_conf.py
48 changes: 40 additions & 8 deletions pymatbridge/matlab/matlabserver.m
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
function matlabserver(socket_address)
function matlabserver(socket_address, exit_when_done)
%MATLABSERVER Take Commands from Python via ZMQ
% matlabserver(socket_address, exit_when_done)
% This function takes a socket address as input and initiates a ZMQ session
% over the socket. I then enters the listen-respond mode until it gets an
% "exit" command

json_startup
% over the socket. It then enters the listen-respond mode until it gets an
% "exit" command, at which point it returns (or exits if exit_when_done), or
% until it gets a "separate" command, at which point it launches the MATLAB
% desktop client and returns.
%

initialize_environment;
json_startup;
messenger('init', socket_address);

c=onCleanup(@()exit);
c = onCleanup(@stop_messenger);

while(1)
msg_in = messenger('listen');
Expand All@@ -17,15 +23,41 @@ function matlabserver(socket_address)
messenger('respond', 'connected');

case {'exit'}
messenger('exit');
break;

case {'eval'}
resp = pymat_eval(req);
messenger('respond', resp);

case {'separate'}
desktop; %no-op if desktop is already up
exit_when_done = false;
break;

otherwise
messenger('respond', 'i dont know what you want');
messenger('respond', 'Unknown command recieved by matlabserver via ZMQ.');

end
end

if nargin > 1 && exit_when_done
%c.task(); % already executed by "finish"
exit;
end

end %matlabserver

function stop_messenger()
if messenger('check')
messenger('exit');
end
end

function initialize_environment()
if ~exist('json_startup', 'file')
[pathstr, ~, ~] = fileparts(mfilename('fullpath'));
old_warning_state = warning('off','all');
addpath(genpath(pathstr));
warning(old_warning_state);
end
end
6 changes: 6 additions & 0 deletions pymatbridge/matlab/util/finish.m
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
% make sure socket gets closed no matter how MATLAB exists (sans crash)
if exist('messenger', 'file')
if messenger('check')
messenger('exit');
end
end
12 changes: 8 additions & 4 deletions pymatbridge/matlab/util/json_v0.2.2/json/json_dump.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,7 +106,7 @@
double_struct = struct;
double_struct.ndarray = 1;
value = double(value);
if isreal(value)
if isreal(value)
double_struct.data = base64encode(typecast(value(:), 'uint8'));
else
double_struct.real = base64encode(typecast(real(value(:)), 'uint8'));
Expand DownExpand Up@@ -142,9 +142,13 @@
obj.put(dump_data_(value{i}, options));
end
elseif isnumeric(value)
if isreal(value)
if ~isfinite(value)
json_non_finite = struct;
json_non_finite.json_non_finite = lower(num2str(value));
obj = dump_data_(json_non_finite, options);
elseif isreal(value)
obj = value;
% Encode complex number as a struct
% Encode finite complex number as a struct
else
complex_struct = struct;
complex_struct.real = real(value);
Expand All@@ -158,7 +162,7 @@
keys = fieldnames(value);
for i = 1:length(keys)
try
obj.put(keys{i},dump_data_(value.(keys{i}), options));
obj.put(keys{i},dump_data_(value.(keys{i}), options));
catch ME
obj.put(keys{i}, dump_data_(ME.message, options))
end
Expand Down
2 changes: 1 addition & 1 deletion pymatbridge/matlab/util/pymat_eval.m
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
function json_response = pymat_eval(req);
function json_response = pymat_eval(req)
% PYMAT_EVAL: Returns a json object of the result of calling the function
%
% json_response = pymat_eval(req);
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/matlab_magic.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@
from .compat import text_type


class MatlabInterperterError(RuntimeError):
class MatlabInterpreterError(RuntimeError):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

"""
Some error occurs while matlab is running
"""
Expand DownExpand Up@@ -87,7 +87,7 @@ def eval(self, line):
run_dict = self.Matlab.run_code(line)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])

# This is the matlab stdout:
return run_dict
Expand All@@ -99,7 +99,7 @@ def set_matlab_var(self, name, value):
run_dict = self.Matlab.set_variable(name, value)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])


@magic_arguments()
Expand DownExpand Up@@ -161,7 +161,7 @@ def matlab(self, line, cell=None, local_ns=None):

try:
result_dict = self.eval(code)
except MatlabInterperterError:
except MatlabInterpreterError:
raise
except:
raise RuntimeError('\n'.join([
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/messenger/make.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ def get_config():


def do_build(make_cmd, messenger_exe):
print('Building %s...' % messenger_exe)
print('Building {}...'.format(messenger_exe))
print(make_cmd)
messenger_dir = get_messenger_dir()
subprocess.check_output(shlex.split(make_cmd), shell=use_shell)
Expand All@@ -188,7 +188,7 @@ def do_build(make_cmd, messenger_exe):
def build_octave():
paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s"
paths = paths % get_config()
make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths
make_cmd = "mkoctfile --mex {} -lzmq ./src/messenger.c".format(paths)
do_build(make_cmd, 'messenger.mex')


Expand DownExpand Up@@ -264,10 +264,10 @@ def build_matlab(static=False):
# Build the mex file
mex = esc(os.path.join(matlab_bin, "mex"))
paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg
make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths)
make_cmd = '{} -O {} -lzmq ./src/messenger.c'.format(mex, paths)
if static:
make_cmd += ' -DZMQ_STATIC'
do_build(make_cmd, 'messenger.%s' % extension)
do_build(make_cmd, 'messenger.{}'.format(extension))


if __name__ == '__main__':
Expand Down
Binary file modifiedpymatbridge/messenger/mexa64/messenger.mexa64
Binary file not shown.
62 changes: 29 additions & 33 deletions pymatbridge/messenger/src/messenger.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,61 +48,58 @@ void cleanup (void) {
mexPrintf("Socket closed\n");
zmq_term(ctx);
mexPrintf("Context terminated\n");
initialized = 0;
}


/* Gateway function with Matlab */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
char *cmd;
mxLogical *p;
/* If no input argument, print out the usage */
if (nrhs == 0) {
mexErrMsgTxt("Usage: messenger('init|listen|respond', extra1, extra2, ...)");
}

if (nlhs > 1) {
mexErrMsgTxt("messenger: too many outputs, I return a single bool");
}
/* Get the input command */
if(!(cmd = mxArrayToString(prhs[0]))) {
mexErrMsgTxt("Cannot read the command");
}

/* we'll return true on completion of valid command, else false */
plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);
p[0] = false;
/* Initialize a new server session */
if (strcmp(cmd, "init") == 0) {
char *socket_addr;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
mexErrMsgTxt("Missing argument: socket address");
mexErrMsgTxt("Usage: messenger('init', socket_addr)");
}
if (!(socket_addr = mxArrayToString(prhs[1]))) {
mexErrMsgTxt("Cannot read socket address");
}

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (!initialized) {
if (!initialize(socket_addr)) {
p[0] = 1;
p[0] = true;
mexPrintf("Socket created at: %s\n", socket_addr);
} else {
p[0] = 0;
mexErrMsgTxt("Socket creation failed.");
}
} else {
mexErrMsgTxt("One socket has already been initialized.");
}

return;

/* Listen over an existing socket */
} else if (strcmp(cmd, "listen") == 0) {
int byte_recvd;
char *recv_buffer = mxCalloc(BUFLEN, sizeof(char));
zmq_pollitem_t polls[] = {{socket_ptr, 0, ZMQ_POLLIN, 0}};

if (!checkInitialized()) return;

/* allow MATLAB to draw its graphics every 20ms */
while (zmq_poll(polls, 1, 20000) == 0) {
mexEvalString("drawnow");
Expand All@@ -116,17 +113,14 @@ void mexFunction(int nlhs, mxArray *plhs[],
} else if (byte_recvd > BUFLEN){
mexErrMsgTxt("Receiver buffer overflow. Message truncated");
} else {
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
mexErrMsgTxt(recv_buffer);
}

return;

p[0] = true;
/* Send a message out */
} else if (strcmp(cmd, "respond") == 0) {
size_t msglen;
char *msg_out;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
Expand All@@ -138,24 +132,26 @@ void mexFunction(int nlhs, mxArray *plhs[],
msglen = mxGetNumberOfElements(prhs[1]);
msg_out = mxArrayToString(prhs[1]);

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (msglen == zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = 1;
if (msglen == (size_t) zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = true;
} else {
p[0] = 0;
mexErrMsgTxt("Failed to send message due to ZMQ error");
}

return;

/* Close the socket and context */
} else if (strcmp(cmd, "exit") == 0) {
cleanup();

return;
if (initialized) {
cleanup();
p[0] = true;
initialized = 0;
} else {
mexErrMsgTxt("No open socket to exit.");
}
} else if (strcmp(cmd, "check") == 0) {
if (initialized) {
p[0] = true;
}
} else {
mexErrMsgTxt("Unidentified command");
}
return;
}
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Inf fix by brunobeltran · Pull Request #218 · arokem/python-matlab-bridge · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,3 +37,6 @@ rebuildTags.sh

# caused py setup.py develop
pymatbridge.egg-info

# so vim-ers can use "YouCompleteMe"
.ycm_extra_conf.py
48 changes: 40 additions & 8 deletions pymatbridge/matlab/matlabserver.m
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
function matlabserver(socket_address)
function matlabserver(socket_address, exit_when_done)
%MATLABSERVER Take Commands from Python via ZMQ
% matlabserver(socket_address, exit_when_done)
% This function takes a socket address as input and initiates a ZMQ session
% over the socket. I then enters the listen-respond mode until it gets an
% "exit" command

json_startup
% over the socket. It then enters the listen-respond mode until it gets an
% "exit" command, at which point it returns (or exits if exit_when_done), or
% until it gets a "separate" command, at which point it launches the MATLAB
% desktop client and returns.
%

initialize_environment;
json_startup;
messenger('init', socket_address);

c=onCleanup(@()exit);
c = onCleanup(@stop_messenger);

while(1)
msg_in = messenger('listen');
Expand All@@ -17,15 +23,41 @@ function matlabserver(socket_address)
messenger('respond', 'connected');

case {'exit'}
messenger('exit');
break;

case {'eval'}
resp = pymat_eval(req);
messenger('respond', resp);

case {'separate'}
desktop; %no-op if desktop is already up
exit_when_done = false;
break;

otherwise
messenger('respond', 'i dont know what you want');
messenger('respond', 'Unknown command recieved by matlabserver via ZMQ.');

end
end

if nargin > 1 && exit_when_done
%c.task(); % already executed by "finish"
exit;
end

end %matlabserver

function stop_messenger()
if messenger('check')
messenger('exit');
end
end

function initialize_environment()
if ~exist('json_startup', 'file')
[pathstr, ~, ~] = fileparts(mfilename('fullpath'));
old_warning_state = warning('off','all');
addpath(genpath(pathstr));
warning(old_warning_state);
end
end
6 changes: 6 additions & 0 deletions pymatbridge/matlab/util/finish.m
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
% make sure socket gets closed no matter how MATLAB exists (sans crash)
if exist('messenger', 'file')
if messenger('check')
messenger('exit');
end
end
12 changes: 8 additions & 4 deletions pymatbridge/matlab/util/json_v0.2.2/json/json_dump.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,7 +106,7 @@
double_struct = struct;
double_struct.ndarray = 1;
value = double(value);
if isreal(value)
if isreal(value)
double_struct.data = base64encode(typecast(value(:), 'uint8'));
else
double_struct.real = base64encode(typecast(real(value(:)), 'uint8'));
Expand DownExpand Up@@ -142,9 +142,13 @@
obj.put(dump_data_(value{i}, options));
end
elseif isnumeric(value)
if isreal(value)
if ~isfinite(value)
json_non_finite = struct;
json_non_finite.json_non_finite = lower(num2str(value));
obj = dump_data_(json_non_finite, options);
elseif isreal(value)
obj = value;
% Encode complex number as a struct
% Encode finite complex number as a struct
else
complex_struct = struct;
complex_struct.real = real(value);
Expand All@@ -158,7 +162,7 @@
keys = fieldnames(value);
for i = 1:length(keys)
try
obj.put(keys{i},dump_data_(value.(keys{i}), options));
obj.put(keys{i},dump_data_(value.(keys{i}), options));
catch ME
obj.put(keys{i}, dump_data_(ME.message, options))
end
Expand Down
2 changes: 1 addition & 1 deletion pymatbridge/matlab/util/pymat_eval.m
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
function json_response = pymat_eval(req);
function json_response = pymat_eval(req)
% PYMAT_EVAL: Returns a json object of the result of calling the function
%
% json_response = pymat_eval(req);
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/matlab_magic.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@
from .compat import text_type


class MatlabInterperterError(RuntimeError):
class MatlabInterpreterError(RuntimeError):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

"""
Some error occurs while matlab is running
"""
Expand DownExpand Up@@ -87,7 +87,7 @@ def eval(self, line):
run_dict = self.Matlab.run_code(line)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])

# This is the matlab stdout:
return run_dict
Expand All@@ -99,7 +99,7 @@ def set_matlab_var(self, name, value):
run_dict = self.Matlab.set_variable(name, value)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])


@magic_arguments()
Expand DownExpand Up@@ -161,7 +161,7 @@ def matlab(self, line, cell=None, local_ns=None):

try:
result_dict = self.eval(code)
except MatlabInterperterError:
except MatlabInterpreterError:
raise
except:
raise RuntimeError('\n'.join([
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/messenger/make.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ def get_config():


def do_build(make_cmd, messenger_exe):
print('Building %s...' % messenger_exe)
print('Building {}...'.format(messenger_exe))
print(make_cmd)
messenger_dir = get_messenger_dir()
subprocess.check_output(shlex.split(make_cmd), shell=use_shell)
Expand All@@ -188,7 +188,7 @@ def do_build(make_cmd, messenger_exe):
def build_octave():
paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s"
paths = paths % get_config()
make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths
make_cmd = "mkoctfile --mex {} -lzmq ./src/messenger.c".format(paths)
do_build(make_cmd, 'messenger.mex')


Expand DownExpand Up@@ -264,10 +264,10 @@ def build_matlab(static=False):
# Build the mex file
mex = esc(os.path.join(matlab_bin, "mex"))
paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg
make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths)
make_cmd = '{} -O {} -lzmq ./src/messenger.c'.format(mex, paths)
if static:
make_cmd += ' -DZMQ_STATIC'
do_build(make_cmd, 'messenger.%s' % extension)
do_build(make_cmd, 'messenger.{}'.format(extension))


if __name__ == '__main__':
Expand Down
Binary file modifiedpymatbridge/messenger/mexa64/messenger.mexa64
Binary file not shown.
62 changes: 29 additions & 33 deletions pymatbridge/messenger/src/messenger.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,61 +48,58 @@ void cleanup (void) {
mexPrintf("Socket closed\n");
zmq_term(ctx);
mexPrintf("Context terminated\n");
initialized = 0;
}


/* Gateway function with Matlab */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
char *cmd;
mxLogical *p;
/* If no input argument, print out the usage */
if (nrhs == 0) {
mexErrMsgTxt("Usage: messenger('init|listen|respond', extra1, extra2, ...)");
}

if (nlhs > 1) {
mexErrMsgTxt("messenger: too many outputs, I return a single bool");
}
/* Get the input command */
if(!(cmd = mxArrayToString(prhs[0]))) {
mexErrMsgTxt("Cannot read the command");
}

/* we'll return true on completion of valid command, else false */
plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);
p[0] = false;
/* Initialize a new server session */
if (strcmp(cmd, "init") == 0) {
char *socket_addr;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
mexErrMsgTxt("Missing argument: socket address");
mexErrMsgTxt("Usage: messenger('init', socket_addr)");
}
if (!(socket_addr = mxArrayToString(prhs[1]))) {
mexErrMsgTxt("Cannot read socket address");
}

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (!initialized) {
if (!initialize(socket_addr)) {
p[0] = 1;
p[0] = true;
mexPrintf("Socket created at: %s\n", socket_addr);
} else {
p[0] = 0;
mexErrMsgTxt("Socket creation failed.");
}
} else {
mexErrMsgTxt("One socket has already been initialized.");
}

return;

/* Listen over an existing socket */
} else if (strcmp(cmd, "listen") == 0) {
int byte_recvd;
char *recv_buffer = mxCalloc(BUFLEN, sizeof(char));
zmq_pollitem_t polls[] = {{socket_ptr, 0, ZMQ_POLLIN, 0}};

if (!checkInitialized()) return;

/* allow MATLAB to draw its graphics every 20ms */
while (zmq_poll(polls, 1, 20000) == 0) {
mexEvalString("drawnow");
Expand All@@ -116,17 +113,14 @@ void mexFunction(int nlhs, mxArray *plhs[],
} else if (byte_recvd > BUFLEN){
mexErrMsgTxt("Receiver buffer overflow. Message truncated");
} else {
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
mexErrMsgTxt(recv_buffer);
}

return;

p[0] = true;
/* Send a message out */
} else if (strcmp(cmd, "respond") == 0) {
size_t msglen;
char *msg_out;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
Expand All@@ -138,24 +132,26 @@ void mexFunction(int nlhs, mxArray *plhs[],
msglen = mxGetNumberOfElements(prhs[1]);
msg_out = mxArrayToString(prhs[1]);

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (msglen == zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = 1;
if (msglen == (size_t) zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = true;
} else {
p[0] = 0;
mexErrMsgTxt("Failed to send message due to ZMQ error");
}

return;

/* Close the socket and context */
} else if (strcmp(cmd, "exit") == 0) {
cleanup();

return;
if (initialized) {
cleanup();
p[0] = true;
initialized = 0;
} else {
mexErrMsgTxt("No open socket to exit.");
}
} else if (strcmp(cmd, "check") == 0) {
if (initialized) {
p[0] = true;
}
} else {
mexErrMsgTxt("Unidentified command");
}
return;
}
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Inf fix by brunobeltran · Pull Request #218 · arokem/python-matlab-bridge · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,3 +37,6 @@ rebuildTags.sh

# caused py setup.py develop
pymatbridge.egg-info

# so vim-ers can use "YouCompleteMe"
.ycm_extra_conf.py
48 changes: 40 additions & 8 deletions pymatbridge/matlab/matlabserver.m
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
function matlabserver(socket_address)
function matlabserver(socket_address, exit_when_done)
%MATLABSERVER Take Commands from Python via ZMQ
% matlabserver(socket_address, exit_when_done)
% This function takes a socket address as input and initiates a ZMQ session
% over the socket. I then enters the listen-respond mode until it gets an
% "exit" command

json_startup
% over the socket. It then enters the listen-respond mode until it gets an
% "exit" command, at which point it returns (or exits if exit_when_done), or
% until it gets a "separate" command, at which point it launches the MATLAB
% desktop client and returns.
%

initialize_environment;
json_startup;
messenger('init', socket_address);

c=onCleanup(@()exit);
c = onCleanup(@stop_messenger);

while(1)
msg_in = messenger('listen');
Expand All@@ -17,15 +23,41 @@ function matlabserver(socket_address)
messenger('respond', 'connected');

case {'exit'}
messenger('exit');
break;

case {'eval'}
resp = pymat_eval(req);
messenger('respond', resp);

case {'separate'}
desktop; %no-op if desktop is already up
exit_when_done = false;
break;

otherwise
messenger('respond', 'i dont know what you want');
messenger('respond', 'Unknown command recieved by matlabserver via ZMQ.');

end
end

if nargin > 1 && exit_when_done
%c.task(); % already executed by "finish"
exit;
end

end %matlabserver

function stop_messenger()
if messenger('check')
messenger('exit');
end
end

function initialize_environment()
if ~exist('json_startup', 'file')
[pathstr, ~, ~] = fileparts(mfilename('fullpath'));
old_warning_state = warning('off','all');
addpath(genpath(pathstr));
warning(old_warning_state);
end
end
6 changes: 6 additions & 0 deletions pymatbridge/matlab/util/finish.m
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
% make sure socket gets closed no matter how MATLAB exists (sans crash)
if exist('messenger', 'file')
if messenger('check')
messenger('exit');
end
end
12 changes: 8 additions & 4 deletions pymatbridge/matlab/util/json_v0.2.2/json/json_dump.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,7 +106,7 @@
double_struct = struct;
double_struct.ndarray = 1;
value = double(value);
if isreal(value)
if isreal(value)
double_struct.data = base64encode(typecast(value(:), 'uint8'));
else
double_struct.real = base64encode(typecast(real(value(:)), 'uint8'));
Expand DownExpand Up@@ -142,9 +142,13 @@
obj.put(dump_data_(value{i}, options));
end
elseif isnumeric(value)
if isreal(value)
if ~isfinite(value)
json_non_finite = struct;
json_non_finite.json_non_finite = lower(num2str(value));
obj = dump_data_(json_non_finite, options);
elseif isreal(value)
obj = value;
% Encode complex number as a struct
% Encode finite complex number as a struct
else
complex_struct = struct;
complex_struct.real = real(value);
Expand All@@ -158,7 +162,7 @@
keys = fieldnames(value);
for i = 1:length(keys)
try
obj.put(keys{i},dump_data_(value.(keys{i}), options));
obj.put(keys{i},dump_data_(value.(keys{i}), options));
catch ME
obj.put(keys{i}, dump_data_(ME.message, options))
end
Expand Down
2 changes: 1 addition & 1 deletion pymatbridge/matlab/util/pymat_eval.m
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
function json_response = pymat_eval(req);
function json_response = pymat_eval(req)
% PYMAT_EVAL: Returns a json object of the result of calling the function
%
% json_response = pymat_eval(req);
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/matlab_magic.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@
from .compat import text_type


class MatlabInterperterError(RuntimeError):
class MatlabInterpreterError(RuntimeError):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

"""
Some error occurs while matlab is running
"""
Expand DownExpand Up@@ -87,7 +87,7 @@ def eval(self, line):
run_dict = self.Matlab.run_code(line)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])

# This is the matlab stdout:
return run_dict
Expand All@@ -99,7 +99,7 @@ def set_matlab_var(self, name, value):
run_dict = self.Matlab.set_variable(name, value)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])


@magic_arguments()
Expand DownExpand Up@@ -161,7 +161,7 @@ def matlab(self, line, cell=None, local_ns=None):

try:
result_dict = self.eval(code)
except MatlabInterperterError:
except MatlabInterpreterError:
raise
except:
raise RuntimeError('\n'.join([
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/messenger/make.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ def get_config():


def do_build(make_cmd, messenger_exe):
print('Building %s...' % messenger_exe)
print('Building {}...'.format(messenger_exe))
print(make_cmd)
messenger_dir = get_messenger_dir()
subprocess.check_output(shlex.split(make_cmd), shell=use_shell)
Expand All@@ -188,7 +188,7 @@ def do_build(make_cmd, messenger_exe):
def build_octave():
paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s"
paths = paths % get_config()
make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths
make_cmd = "mkoctfile --mex {} -lzmq ./src/messenger.c".format(paths)
do_build(make_cmd, 'messenger.mex')


Expand DownExpand Up@@ -264,10 +264,10 @@ def build_matlab(static=False):
# Build the mex file
mex = esc(os.path.join(matlab_bin, "mex"))
paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg
make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths)
make_cmd = '{} -O {} -lzmq ./src/messenger.c'.format(mex, paths)
if static:
make_cmd += ' -DZMQ_STATIC'
do_build(make_cmd, 'messenger.%s' % extension)
do_build(make_cmd, 'messenger.{}'.format(extension))


if __name__ == '__main__':
Expand Down
Binary file modifiedpymatbridge/messenger/mexa64/messenger.mexa64
Binary file not shown.
62 changes: 29 additions & 33 deletions pymatbridge/messenger/src/messenger.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,61 +48,58 @@ void cleanup (void) {
mexPrintf("Socket closed\n");
zmq_term(ctx);
mexPrintf("Context terminated\n");
initialized = 0;
}


/* Gateway function with Matlab */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
char *cmd;
mxLogical *p;
/* If no input argument, print out the usage */
if (nrhs == 0) {
mexErrMsgTxt("Usage: messenger('init|listen|respond', extra1, extra2, ...)");
}

if (nlhs > 1) {
mexErrMsgTxt("messenger: too many outputs, I return a single bool");
}
/* Get the input command */
if(!(cmd = mxArrayToString(prhs[0]))) {
mexErrMsgTxt("Cannot read the command");
}

/* we'll return true on completion of valid command, else false */
plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);
p[0] = false;
/* Initialize a new server session */
if (strcmp(cmd, "init") == 0) {
char *socket_addr;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
mexErrMsgTxt("Missing argument: socket address");
mexErrMsgTxt("Usage: messenger('init', socket_addr)");
}
if (!(socket_addr = mxArrayToString(prhs[1]))) {
mexErrMsgTxt("Cannot read socket address");
}

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (!initialized) {
if (!initialize(socket_addr)) {
p[0] = 1;
p[0] = true;
mexPrintf("Socket created at: %s\n", socket_addr);
} else {
p[0] = 0;
mexErrMsgTxt("Socket creation failed.");
}
} else {
mexErrMsgTxt("One socket has already been initialized.");
}

return;

/* Listen over an existing socket */
} else if (strcmp(cmd, "listen") == 0) {
int byte_recvd;
char *recv_buffer = mxCalloc(BUFLEN, sizeof(char));
zmq_pollitem_t polls[] = {{socket_ptr, 0, ZMQ_POLLIN, 0}};

if (!checkInitialized()) return;

/* allow MATLAB to draw its graphics every 20ms */
while (zmq_poll(polls, 1, 20000) == 0) {
mexEvalString("drawnow");
Expand All@@ -116,17 +113,14 @@ void mexFunction(int nlhs, mxArray *plhs[],
} else if (byte_recvd > BUFLEN){
mexErrMsgTxt("Receiver buffer overflow. Message truncated");
} else {
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
mexErrMsgTxt(recv_buffer);
}

return;

p[0] = true;
/* Send a message out */
} else if (strcmp(cmd, "respond") == 0) {
size_t msglen;
char *msg_out;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
Expand All@@ -138,24 +132,26 @@ void mexFunction(int nlhs, mxArray *plhs[],
msglen = mxGetNumberOfElements(prhs[1]);
msg_out = mxArrayToString(prhs[1]);

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (msglen == zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = 1;
if (msglen == (size_t) zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = true;
} else {
p[0] = 0;
mexErrMsgTxt("Failed to send message due to ZMQ error");
}

return;

/* Close the socket and context */
} else if (strcmp(cmd, "exit") == 0) {
cleanup();

return;
if (initialized) {
cleanup();
p[0] = true;
initialized = 0;
} else {
mexErrMsgTxt("No open socket to exit.");
}
} else if (strcmp(cmd, "check") == 0) {
if (initialized) {
p[0] = true;
}
} else {
mexErrMsgTxt("Unidentified command");
}
return;
}
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Inf fix by brunobeltran · Pull Request #218 · arokem/python-matlab-bridge · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,3 +37,6 @@ rebuildTags.sh

# caused py setup.py develop
pymatbridge.egg-info

# so vim-ers can use "YouCompleteMe"
.ycm_extra_conf.py
48 changes: 40 additions & 8 deletions pymatbridge/matlab/matlabserver.m
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
function matlabserver(socket_address)
function matlabserver(socket_address, exit_when_done)
%MATLABSERVER Take Commands from Python via ZMQ
% matlabserver(socket_address, exit_when_done)
% This function takes a socket address as input and initiates a ZMQ session
% over the socket. I then enters the listen-respond mode until it gets an
% "exit" command

json_startup
% over the socket. It then enters the listen-respond mode until it gets an
% "exit" command, at which point it returns (or exits if exit_when_done), or
% until it gets a "separate" command, at which point it launches the MATLAB
% desktop client and returns.
%

initialize_environment;
json_startup;
messenger('init', socket_address);

c=onCleanup(@()exit);
c = onCleanup(@stop_messenger);

while(1)
msg_in = messenger('listen');
Expand All@@ -17,15 +23,41 @@ function matlabserver(socket_address)
messenger('respond', 'connected');

case {'exit'}
messenger('exit');
break;

case {'eval'}
resp = pymat_eval(req);
messenger('respond', resp);

case {'separate'}
desktop; %no-op if desktop is already up
exit_when_done = false;
break;

otherwise
messenger('respond', 'i dont know what you want');
messenger('respond', 'Unknown command recieved by matlabserver via ZMQ.');

end
end

if nargin > 1 && exit_when_done
%c.task(); % already executed by "finish"
exit;
end

end %matlabserver

function stop_messenger()
if messenger('check')
messenger('exit');
end
end

function initialize_environment()
if ~exist('json_startup', 'file')
[pathstr, ~, ~] = fileparts(mfilename('fullpath'));
old_warning_state = warning('off','all');
addpath(genpath(pathstr));
warning(old_warning_state);
end
end
6 changes: 6 additions & 0 deletions pymatbridge/matlab/util/finish.m
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
% make sure socket gets closed no matter how MATLAB exists (sans crash)
if exist('messenger', 'file')
if messenger('check')
messenger('exit');
end
end
12 changes: 8 additions & 4 deletions pymatbridge/matlab/util/json_v0.2.2/json/json_dump.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,7 +106,7 @@
double_struct = struct;
double_struct.ndarray = 1;
value = double(value);
if isreal(value)
if isreal(value)
double_struct.data = base64encode(typecast(value(:), 'uint8'));
else
double_struct.real = base64encode(typecast(real(value(:)), 'uint8'));
Expand DownExpand Up@@ -142,9 +142,13 @@
obj.put(dump_data_(value{i}, options));
end
elseif isnumeric(value)
if isreal(value)
if ~isfinite(value)
json_non_finite = struct;
json_non_finite.json_non_finite = lower(num2str(value));
obj = dump_data_(json_non_finite, options);
elseif isreal(value)
obj = value;
% Encode complex number as a struct
% Encode finite complex number as a struct
else
complex_struct = struct;
complex_struct.real = real(value);
Expand All@@ -158,7 +162,7 @@
keys = fieldnames(value);
for i = 1:length(keys)
try
obj.put(keys{i},dump_data_(value.(keys{i}), options));
obj.put(keys{i},dump_data_(value.(keys{i}), options));
catch ME
obj.put(keys{i}, dump_data_(ME.message, options))
end
Expand Down
2 changes: 1 addition & 1 deletion pymatbridge/matlab/util/pymat_eval.m
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
function json_response = pymat_eval(req);
function json_response = pymat_eval(req)
% PYMAT_EVAL: Returns a json object of the result of calling the function
%
% json_response = pymat_eval(req);
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/matlab_magic.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@
from .compat import text_type


class MatlabInterperterError(RuntimeError):
class MatlabInterpreterError(RuntimeError):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

"""
Some error occurs while matlab is running
"""
Expand DownExpand Up@@ -87,7 +87,7 @@ def eval(self, line):
run_dict = self.Matlab.run_code(line)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])

# This is the matlab stdout:
return run_dict
Expand All@@ -99,7 +99,7 @@ def set_matlab_var(self, name, value):
run_dict = self.Matlab.set_variable(name, value)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])


@magic_arguments()
Expand DownExpand Up@@ -161,7 +161,7 @@ def matlab(self, line, cell=None, local_ns=None):

try:
result_dict = self.eval(code)
except MatlabInterperterError:
except MatlabInterpreterError:
raise
except:
raise RuntimeError('\n'.join([
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/messenger/make.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ def get_config():


def do_build(make_cmd, messenger_exe):
print('Building %s...' % messenger_exe)
print('Building {}...'.format(messenger_exe))
print(make_cmd)
messenger_dir = get_messenger_dir()
subprocess.check_output(shlex.split(make_cmd), shell=use_shell)
Expand All@@ -188,7 +188,7 @@ def do_build(make_cmd, messenger_exe):
def build_octave():
paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s"
paths = paths % get_config()
make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths
make_cmd = "mkoctfile --mex {} -lzmq ./src/messenger.c".format(paths)
do_build(make_cmd, 'messenger.mex')


Expand DownExpand Up@@ -264,10 +264,10 @@ def build_matlab(static=False):
# Build the mex file
mex = esc(os.path.join(matlab_bin, "mex"))
paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg
make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths)
make_cmd = '{} -O {} -lzmq ./src/messenger.c'.format(mex, paths)
if static:
make_cmd += ' -DZMQ_STATIC'
do_build(make_cmd, 'messenger.%s' % extension)
do_build(make_cmd, 'messenger.{}'.format(extension))


if __name__ == '__main__':
Expand Down
Binary file modifiedpymatbridge/messenger/mexa64/messenger.mexa64
Binary file not shown.
62 changes: 29 additions & 33 deletions pymatbridge/messenger/src/messenger.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,61 +48,58 @@ void cleanup (void) {
mexPrintf("Socket closed\n");
zmq_term(ctx);
mexPrintf("Context terminated\n");
initialized = 0;
}


/* Gateway function with Matlab */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
char *cmd;
mxLogical *p;
/* If no input argument, print out the usage */
if (nrhs == 0) {
mexErrMsgTxt("Usage: messenger('init|listen|respond', extra1, extra2, ...)");
}

if (nlhs > 1) {
mexErrMsgTxt("messenger: too many outputs, I return a single bool");
}
/* Get the input command */
if(!(cmd = mxArrayToString(prhs[0]))) {
mexErrMsgTxt("Cannot read the command");
}

/* we'll return true on completion of valid command, else false */
plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);
p[0] = false;
/* Initialize a new server session */
if (strcmp(cmd, "init") == 0) {
char *socket_addr;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
mexErrMsgTxt("Missing argument: socket address");
mexErrMsgTxt("Usage: messenger('init', socket_addr)");
}
if (!(socket_addr = mxArrayToString(prhs[1]))) {
mexErrMsgTxt("Cannot read socket address");
}

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (!initialized) {
if (!initialize(socket_addr)) {
p[0] = 1;
p[0] = true;
mexPrintf("Socket created at: %s\n", socket_addr);
} else {
p[0] = 0;
mexErrMsgTxt("Socket creation failed.");
}
} else {
mexErrMsgTxt("One socket has already been initialized.");
}

return;

/* Listen over an existing socket */
} else if (strcmp(cmd, "listen") == 0) {
int byte_recvd;
char *recv_buffer = mxCalloc(BUFLEN, sizeof(char));
zmq_pollitem_t polls[] = {{socket_ptr, 0, ZMQ_POLLIN, 0}};

if (!checkInitialized()) return;

/* allow MATLAB to draw its graphics every 20ms */
while (zmq_poll(polls, 1, 20000) == 0) {
mexEvalString("drawnow");
Expand All@@ -116,17 +113,14 @@ void mexFunction(int nlhs, mxArray *plhs[],
} else if (byte_recvd > BUFLEN){
mexErrMsgTxt("Receiver buffer overflow. Message truncated");
} else {
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
mexErrMsgTxt(recv_buffer);
}

return;

p[0] = true;
/* Send a message out */
} else if (strcmp(cmd, "respond") == 0) {
size_t msglen;
char *msg_out;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
Expand All@@ -138,24 +132,26 @@ void mexFunction(int nlhs, mxArray *plhs[],
msglen = mxGetNumberOfElements(prhs[1]);
msg_out = mxArrayToString(prhs[1]);

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (msglen == zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = 1;
if (msglen == (size_t) zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = true;
} else {
p[0] = 0;
mexErrMsgTxt("Failed to send message due to ZMQ error");
}

return;

/* Close the socket and context */
} else if (strcmp(cmd, "exit") == 0) {
cleanup();

return;
if (initialized) {
cleanup();
p[0] = true;
initialized = 0;
} else {
mexErrMsgTxt("No open socket to exit.");
}
} else if (strcmp(cmd, "check") == 0) {
if (initialized) {
p[0] = true;
}
} else {
mexErrMsgTxt("Unidentified command");
}
return;
}
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Inf fix by brunobeltran · Pull Request #218 · arokem/python-matlab-bridge · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,3 +37,6 @@ rebuildTags.sh

# caused py setup.py develop
pymatbridge.egg-info

# so vim-ers can use "YouCompleteMe"
.ycm_extra_conf.py
48 changes: 40 additions & 8 deletions pymatbridge/matlab/matlabserver.m
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
function matlabserver(socket_address)
function matlabserver(socket_address, exit_when_done)
%MATLABSERVER Take Commands from Python via ZMQ
% matlabserver(socket_address, exit_when_done)
% This function takes a socket address as input and initiates a ZMQ session
% over the socket. I then enters the listen-respond mode until it gets an
% "exit" command

json_startup
% over the socket. It then enters the listen-respond mode until it gets an
% "exit" command, at which point it returns (or exits if exit_when_done), or
% until it gets a "separate" command, at which point it launches the MATLAB
% desktop client and returns.
%

initialize_environment;
json_startup;
messenger('init', socket_address);

c=onCleanup(@()exit);
c = onCleanup(@stop_messenger);

while(1)
msg_in = messenger('listen');
Expand All@@ -17,15 +23,41 @@ function matlabserver(socket_address)
messenger('respond', 'connected');

case {'exit'}
messenger('exit');
break;

case {'eval'}
resp = pymat_eval(req);
messenger('respond', resp);

case {'separate'}
desktop; %no-op if desktop is already up
exit_when_done = false;
break;

otherwise
messenger('respond', 'i dont know what you want');
messenger('respond', 'Unknown command recieved by matlabserver via ZMQ.');

end
end

if nargin > 1 && exit_when_done
%c.task(); % already executed by "finish"
exit;
end

end %matlabserver

function stop_messenger()
if messenger('check')
messenger('exit');
end
end

function initialize_environment()
if ~exist('json_startup', 'file')
[pathstr, ~, ~] = fileparts(mfilename('fullpath'));
old_warning_state = warning('off','all');
addpath(genpath(pathstr));
warning(old_warning_state);
end
end
6 changes: 6 additions & 0 deletions pymatbridge/matlab/util/finish.m
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
% make sure socket gets closed no matter how MATLAB exists (sans crash)
if exist('messenger', 'file')
if messenger('check')
messenger('exit');
end
end
12 changes: 8 additions & 4 deletions pymatbridge/matlab/util/json_v0.2.2/json/json_dump.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,7 +106,7 @@
double_struct = struct;
double_struct.ndarray = 1;
value = double(value);
if isreal(value)
if isreal(value)
double_struct.data = base64encode(typecast(value(:), 'uint8'));
else
double_struct.real = base64encode(typecast(real(value(:)), 'uint8'));
Expand DownExpand Up@@ -142,9 +142,13 @@
obj.put(dump_data_(value{i}, options));
end
elseif isnumeric(value)
if isreal(value)
if ~isfinite(value)
json_non_finite = struct;
json_non_finite.json_non_finite = lower(num2str(value));
obj = dump_data_(json_non_finite, options);
elseif isreal(value)
obj = value;
% Encode complex number as a struct
% Encode finite complex number as a struct
else
complex_struct = struct;
complex_struct.real = real(value);
Expand All@@ -158,7 +162,7 @@
keys = fieldnames(value);
for i = 1:length(keys)
try
obj.put(keys{i},dump_data_(value.(keys{i}), options));
obj.put(keys{i},dump_data_(value.(keys{i}), options));
catch ME
obj.put(keys{i}, dump_data_(ME.message, options))
end
Expand Down
2 changes: 1 addition & 1 deletion pymatbridge/matlab/util/pymat_eval.m
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
function json_response = pymat_eval(req);
function json_response = pymat_eval(req)
% PYMAT_EVAL: Returns a json object of the result of calling the function
%
% json_response = pymat_eval(req);
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/matlab_magic.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@
from .compat import text_type


class MatlabInterperterError(RuntimeError):
class MatlabInterpreterError(RuntimeError):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

"""
Some error occurs while matlab is running
"""
Expand DownExpand Up@@ -87,7 +87,7 @@ def eval(self, line):
run_dict = self.Matlab.run_code(line)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])

# This is the matlab stdout:
return run_dict
Expand All@@ -99,7 +99,7 @@ def set_matlab_var(self, name, value):
run_dict = self.Matlab.set_variable(name, value)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])


@magic_arguments()
Expand DownExpand Up@@ -161,7 +161,7 @@ def matlab(self, line, cell=None, local_ns=None):

try:
result_dict = self.eval(code)
except MatlabInterperterError:
except MatlabInterpreterError:
raise
except:
raise RuntimeError('\n'.join([
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/messenger/make.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ def get_config():


def do_build(make_cmd, messenger_exe):
print('Building %s...' % messenger_exe)
print('Building {}...'.format(messenger_exe))
print(make_cmd)
messenger_dir = get_messenger_dir()
subprocess.check_output(shlex.split(make_cmd), shell=use_shell)
Expand All@@ -188,7 +188,7 @@ def do_build(make_cmd, messenger_exe):
def build_octave():
paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s"
paths = paths % get_config()
make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths
make_cmd = "mkoctfile --mex {} -lzmq ./src/messenger.c".format(paths)
do_build(make_cmd, 'messenger.mex')


Expand DownExpand Up@@ -264,10 +264,10 @@ def build_matlab(static=False):
# Build the mex file
mex = esc(os.path.join(matlab_bin, "mex"))
paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg
make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths)
make_cmd = '{} -O {} -lzmq ./src/messenger.c'.format(mex, paths)
if static:
make_cmd += ' -DZMQ_STATIC'
do_build(make_cmd, 'messenger.%s' % extension)
do_build(make_cmd, 'messenger.{}'.format(extension))


if __name__ == '__main__':
Expand Down
Binary file modifiedpymatbridge/messenger/mexa64/messenger.mexa64
Binary file not shown.
62 changes: 29 additions & 33 deletions pymatbridge/messenger/src/messenger.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,61 +48,58 @@ void cleanup (void) {
mexPrintf("Socket closed\n");
zmq_term(ctx);
mexPrintf("Context terminated\n");
initialized = 0;
}


/* Gateway function with Matlab */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
char *cmd;
mxLogical *p;
/* If no input argument, print out the usage */
if (nrhs == 0) {
mexErrMsgTxt("Usage: messenger('init|listen|respond', extra1, extra2, ...)");
}

if (nlhs > 1) {
mexErrMsgTxt("messenger: too many outputs, I return a single bool");
}
/* Get the input command */
if(!(cmd = mxArrayToString(prhs[0]))) {
mexErrMsgTxt("Cannot read the command");
}

/* we'll return true on completion of valid command, else false */
plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);
p[0] = false;
/* Initialize a new server session */
if (strcmp(cmd, "init") == 0) {
char *socket_addr;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
mexErrMsgTxt("Missing argument: socket address");
mexErrMsgTxt("Usage: messenger('init', socket_addr)");
}
if (!(socket_addr = mxArrayToString(prhs[1]))) {
mexErrMsgTxt("Cannot read socket address");
}

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (!initialized) {
if (!initialize(socket_addr)) {
p[0] = 1;
p[0] = true;
mexPrintf("Socket created at: %s\n", socket_addr);
} else {
p[0] = 0;
mexErrMsgTxt("Socket creation failed.");
}
} else {
mexErrMsgTxt("One socket has already been initialized.");
}

return;

/* Listen over an existing socket */
} else if (strcmp(cmd, "listen") == 0) {
int byte_recvd;
char *recv_buffer = mxCalloc(BUFLEN, sizeof(char));
zmq_pollitem_t polls[] = {{socket_ptr, 0, ZMQ_POLLIN, 0}};

if (!checkInitialized()) return;

/* allow MATLAB to draw its graphics every 20ms */
while (zmq_poll(polls, 1, 20000) == 0) {
mexEvalString("drawnow");
Expand All@@ -116,17 +113,14 @@ void mexFunction(int nlhs, mxArray *plhs[],
} else if (byte_recvd > BUFLEN){
mexErrMsgTxt("Receiver buffer overflow. Message truncated");
} else {
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
mexErrMsgTxt(recv_buffer);
}

return;

p[0] = true;
/* Send a message out */
} else if (strcmp(cmd, "respond") == 0) {
size_t msglen;
char *msg_out;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
Expand All@@ -138,24 +132,26 @@ void mexFunction(int nlhs, mxArray *plhs[],
msglen = mxGetNumberOfElements(prhs[1]);
msg_out = mxArrayToString(prhs[1]);

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (msglen == zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = 1;
if (msglen == (size_t) zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = true;
} else {
p[0] = 0;
mexErrMsgTxt("Failed to send message due to ZMQ error");
}

return;

/* Close the socket and context */
} else if (strcmp(cmd, "exit") == 0) {
cleanup();

return;
if (initialized) {
cleanup();
p[0] = true;
initialized = 0;
} else {
mexErrMsgTxt("No open socket to exit.");
}
} else if (strcmp(cmd, "check") == 0) {
if (initialized) {
p[0] = true;
}
} else {
mexErrMsgTxt("Unidentified command");
}
return;
}
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Inf fix by brunobeltran · Pull Request #218 · arokem/python-matlab-bridge · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,3 +37,6 @@ rebuildTags.sh

# caused py setup.py develop
pymatbridge.egg-info

# so vim-ers can use "YouCompleteMe"
.ycm_extra_conf.py
48 changes: 40 additions & 8 deletions pymatbridge/matlab/matlabserver.m
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
function matlabserver(socket_address)
function matlabserver(socket_address, exit_when_done)
%MATLABSERVER Take Commands from Python via ZMQ
% matlabserver(socket_address, exit_when_done)
% This function takes a socket address as input and initiates a ZMQ session
% over the socket. I then enters the listen-respond mode until it gets an
% "exit" command

json_startup
% over the socket. It then enters the listen-respond mode until it gets an
% "exit" command, at which point it returns (or exits if exit_when_done), or
% until it gets a "separate" command, at which point it launches the MATLAB
% desktop client and returns.
%

initialize_environment;
json_startup;
messenger('init', socket_address);

c=onCleanup(@()exit);
c = onCleanup(@stop_messenger);

while(1)
msg_in = messenger('listen');
Expand All@@ -17,15 +23,41 @@ function matlabserver(socket_address)
messenger('respond', 'connected');

case {'exit'}
messenger('exit');
break;

case {'eval'}
resp = pymat_eval(req);
messenger('respond', resp);

case {'separate'}
desktop; %no-op if desktop is already up
exit_when_done = false;
break;

otherwise
messenger('respond', 'i dont know what you want');
messenger('respond', 'Unknown command recieved by matlabserver via ZMQ.');

end
end

if nargin > 1 && exit_when_done
%c.task(); % already executed by "finish"
exit;
end

end %matlabserver

function stop_messenger()
if messenger('check')
messenger('exit');
end
end

function initialize_environment()
if ~exist('json_startup', 'file')
[pathstr, ~, ~] = fileparts(mfilename('fullpath'));
old_warning_state = warning('off','all');
addpath(genpath(pathstr));
warning(old_warning_state);
end
end
6 changes: 6 additions & 0 deletions pymatbridge/matlab/util/finish.m
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
% make sure socket gets closed no matter how MATLAB exists (sans crash)
if exist('messenger', 'file')
if messenger('check')
messenger('exit');
end
end
12 changes: 8 additions & 4 deletions pymatbridge/matlab/util/json_v0.2.2/json/json_dump.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,7 +106,7 @@
double_struct = struct;
double_struct.ndarray = 1;
value = double(value);
if isreal(value)
if isreal(value)
double_struct.data = base64encode(typecast(value(:), 'uint8'));
else
double_struct.real = base64encode(typecast(real(value(:)), 'uint8'));
Expand DownExpand Up@@ -142,9 +142,13 @@
obj.put(dump_data_(value{i}, options));
end
elseif isnumeric(value)
if isreal(value)
if ~isfinite(value)
json_non_finite = struct;
json_non_finite.json_non_finite = lower(num2str(value));
obj = dump_data_(json_non_finite, options);
elseif isreal(value)
obj = value;
% Encode complex number as a struct
% Encode finite complex number as a struct
else
complex_struct = struct;
complex_struct.real = real(value);
Expand All@@ -158,7 +162,7 @@
keys = fieldnames(value);
for i = 1:length(keys)
try
obj.put(keys{i},dump_data_(value.(keys{i}), options));
obj.put(keys{i},dump_data_(value.(keys{i}), options));
catch ME
obj.put(keys{i}, dump_data_(ME.message, options))
end
Expand Down
2 changes: 1 addition & 1 deletion pymatbridge/matlab/util/pymat_eval.m
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
function json_response = pymat_eval(req);
function json_response = pymat_eval(req)
% PYMAT_EVAL: Returns a json object of the result of calling the function
%
% json_response = pymat_eval(req);
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/matlab_magic.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@
from .compat import text_type


class MatlabInterperterError(RuntimeError):
class MatlabInterpreterError(RuntimeError):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

"""
Some error occurs while matlab is running
"""
Expand DownExpand Up@@ -87,7 +87,7 @@ def eval(self, line):
run_dict = self.Matlab.run_code(line)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])

# This is the matlab stdout:
return run_dict
Expand All@@ -99,7 +99,7 @@ def set_matlab_var(self, name, value):
run_dict = self.Matlab.set_variable(name, value)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])


@magic_arguments()
Expand DownExpand Up@@ -161,7 +161,7 @@ def matlab(self, line, cell=None, local_ns=None):

try:
result_dict = self.eval(code)
except MatlabInterperterError:
except MatlabInterpreterError:
raise
except:
raise RuntimeError('\n'.join([
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/messenger/make.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ def get_config():


def do_build(make_cmd, messenger_exe):
print('Building %s...' % messenger_exe)
print('Building {}...'.format(messenger_exe))
print(make_cmd)
messenger_dir = get_messenger_dir()
subprocess.check_output(shlex.split(make_cmd), shell=use_shell)
Expand All@@ -188,7 +188,7 @@ def do_build(make_cmd, messenger_exe):
def build_octave():
paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s"
paths = paths % get_config()
make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths
make_cmd = "mkoctfile --mex {} -lzmq ./src/messenger.c".format(paths)
do_build(make_cmd, 'messenger.mex')


Expand DownExpand Up@@ -264,10 +264,10 @@ def build_matlab(static=False):
# Build the mex file
mex = esc(os.path.join(matlab_bin, "mex"))
paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg
make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths)
make_cmd = '{} -O {} -lzmq ./src/messenger.c'.format(mex, paths)
if static:
make_cmd += ' -DZMQ_STATIC'
do_build(make_cmd, 'messenger.%s' % extension)
do_build(make_cmd, 'messenger.{}'.format(extension))


if __name__ == '__main__':
Expand Down
Binary file modifiedpymatbridge/messenger/mexa64/messenger.mexa64
Binary file not shown.
62 changes: 29 additions & 33 deletions pymatbridge/messenger/src/messenger.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,61 +48,58 @@ void cleanup (void) {
mexPrintf("Socket closed\n");
zmq_term(ctx);
mexPrintf("Context terminated\n");
initialized = 0;
}


/* Gateway function with Matlab */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
char *cmd;
mxLogical *p;
/* If no input argument, print out the usage */
if (nrhs == 0) {
mexErrMsgTxt("Usage: messenger('init|listen|respond', extra1, extra2, ...)");
}

if (nlhs > 1) {
mexErrMsgTxt("messenger: too many outputs, I return a single bool");
}
/* Get the input command */
if(!(cmd = mxArrayToString(prhs[0]))) {
mexErrMsgTxt("Cannot read the command");
}

/* we'll return true on completion of valid command, else false */
plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);
p[0] = false;
/* Initialize a new server session */
if (strcmp(cmd, "init") == 0) {
char *socket_addr;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
mexErrMsgTxt("Missing argument: socket address");
mexErrMsgTxt("Usage: messenger('init', socket_addr)");
}
if (!(socket_addr = mxArrayToString(prhs[1]))) {
mexErrMsgTxt("Cannot read socket address");
}

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (!initialized) {
if (!initialize(socket_addr)) {
p[0] = 1;
p[0] = true;
mexPrintf("Socket created at: %s\n", socket_addr);
} else {
p[0] = 0;
mexErrMsgTxt("Socket creation failed.");
}
} else {
mexErrMsgTxt("One socket has already been initialized.");
}

return;

/* Listen over an existing socket */
} else if (strcmp(cmd, "listen") == 0) {
int byte_recvd;
char *recv_buffer = mxCalloc(BUFLEN, sizeof(char));
zmq_pollitem_t polls[] = {{socket_ptr, 0, ZMQ_POLLIN, 0}};

if (!checkInitialized()) return;

/* allow MATLAB to draw its graphics every 20ms */
while (zmq_poll(polls, 1, 20000) == 0) {
mexEvalString("drawnow");
Expand All@@ -116,17 +113,14 @@ void mexFunction(int nlhs, mxArray *plhs[],
} else if (byte_recvd > BUFLEN){
mexErrMsgTxt("Receiver buffer overflow. Message truncated");
} else {
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
mexErrMsgTxt(recv_buffer);
}

return;

p[0] = true;
/* Send a message out */
} else if (strcmp(cmd, "respond") == 0) {
size_t msglen;
char *msg_out;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
Expand All@@ -138,24 +132,26 @@ void mexFunction(int nlhs, mxArray *plhs[],
msglen = mxGetNumberOfElements(prhs[1]);
msg_out = mxArrayToString(prhs[1]);

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (msglen == zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = 1;
if (msglen == (size_t) zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = true;
} else {
p[0] = 0;
mexErrMsgTxt("Failed to send message due to ZMQ error");
}

return;

/* Close the socket and context */
} else if (strcmp(cmd, "exit") == 0) {
cleanup();

return;
if (initialized) {
cleanup();
p[0] = true;
initialized = 0;
} else {
mexErrMsgTxt("No open socket to exit.");
}
} else if (strcmp(cmd, "check") == 0) {
if (initialized) {
p[0] = true;
}
} else {
mexErrMsgTxt("Unidentified command");
}
return;
}
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Inf fix by brunobeltran · Pull Request #218 · arokem/python-matlab-bridge · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,3 +37,6 @@ rebuildTags.sh

# caused py setup.py develop
pymatbridge.egg-info

# so vim-ers can use "YouCompleteMe"
.ycm_extra_conf.py
48 changes: 40 additions & 8 deletions pymatbridge/matlab/matlabserver.m
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
function matlabserver(socket_address)
function matlabserver(socket_address, exit_when_done)
%MATLABSERVER Take Commands from Python via ZMQ
% matlabserver(socket_address, exit_when_done)
% This function takes a socket address as input and initiates a ZMQ session
% over the socket. I then enters the listen-respond mode until it gets an
% "exit" command

json_startup
% over the socket. It then enters the listen-respond mode until it gets an
% "exit" command, at which point it returns (or exits if exit_when_done), or
% until it gets a "separate" command, at which point it launches the MATLAB
% desktop client and returns.
%

initialize_environment;
json_startup;
messenger('init', socket_address);

c=onCleanup(@()exit);
c = onCleanup(@stop_messenger);

while(1)
msg_in = messenger('listen');
Expand All@@ -17,15 +23,41 @@ function matlabserver(socket_address)
messenger('respond', 'connected');

case {'exit'}
messenger('exit');
break;

case {'eval'}
resp = pymat_eval(req);
messenger('respond', resp);

case {'separate'}
desktop; %no-op if desktop is already up
exit_when_done = false;
break;

otherwise
messenger('respond', 'i dont know what you want');
messenger('respond', 'Unknown command recieved by matlabserver via ZMQ.');

end
end

if nargin > 1 && exit_when_done
%c.task(); % already executed by "finish"
exit;
end

end %matlabserver

function stop_messenger()
if messenger('check')
messenger('exit');
end
end

function initialize_environment()
if ~exist('json_startup', 'file')
[pathstr, ~, ~] = fileparts(mfilename('fullpath'));
old_warning_state = warning('off','all');
addpath(genpath(pathstr));
warning(old_warning_state);
end
end
6 changes: 6 additions & 0 deletions pymatbridge/matlab/util/finish.m
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
% make sure socket gets closed no matter how MATLAB exists (sans crash)
if exist('messenger', 'file')
if messenger('check')
messenger('exit');
end
end
12 changes: 8 additions & 4 deletions pymatbridge/matlab/util/json_v0.2.2/json/json_dump.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -106,7 +106,7 @@
double_struct = struct;
double_struct.ndarray = 1;
value = double(value);
if isreal(value)
if isreal(value)
double_struct.data = base64encode(typecast(value(:), 'uint8'));
else
double_struct.real = base64encode(typecast(real(value(:)), 'uint8'));
Expand DownExpand Up@@ -142,9 +142,13 @@
obj.put(dump_data_(value{i}, options));
end
elseif isnumeric(value)
if isreal(value)
if ~isfinite(value)
json_non_finite = struct;
json_non_finite.json_non_finite = lower(num2str(value));
obj = dump_data_(json_non_finite, options);
elseif isreal(value)
obj = value;
% Encode complex number as a struct
% Encode finite complex number as a struct
else
complex_struct = struct;
complex_struct.real = real(value);
Expand All@@ -158,7 +162,7 @@
keys = fieldnames(value);
for i = 1:length(keys)
try
obj.put(keys{i},dump_data_(value.(keys{i}), options));
obj.put(keys{i},dump_data_(value.(keys{i}), options));
catch ME
obj.put(keys{i}, dump_data_(ME.message, options))
end
Expand Down
2 changes: 1 addition & 1 deletion pymatbridge/matlab/util/pymat_eval.m
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
function json_response = pymat_eval(req);
function json_response = pymat_eval(req)
% PYMAT_EVAL: Returns a json object of the result of calling the function
%
% json_response = pymat_eval(req);
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/matlab_magic.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@
from .compat import text_type


class MatlabInterperterError(RuntimeError):
class MatlabInterpreterError(RuntimeError):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

"""
Some error occurs while matlab is running
"""
Expand DownExpand Up@@ -87,7 +87,7 @@ def eval(self, line):
run_dict = self.Matlab.run_code(line)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])

# This is the matlab stdout:
return run_dict
Expand All@@ -99,7 +99,7 @@ def set_matlab_var(self, name, value):
run_dict = self.Matlab.set_variable(name, value)

if not run_dict['success']:
raise MatlabInterperterError(line, run_dict['content']['stdout'])
raise MatlabInterpreterError(line, run_dict['content']['stdout'])


@magic_arguments()
Expand DownExpand Up@@ -161,7 +161,7 @@ def matlab(self, line, cell=None, local_ns=None):

try:
result_dict = self.eval(code)
except MatlabInterperterError:
except MatlabInterpreterError:
raise
except:
raise RuntimeError('\n'.join([
Expand Down
8 changes: 4 additions & 4 deletions pymatbridge/messenger/make.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -172,7 +172,7 @@ def get_config():


def do_build(make_cmd, messenger_exe):
print('Building %s...' % messenger_exe)
print('Building {}...'.format(messenger_exe))
print(make_cmd)
messenger_dir = get_messenger_dir()
subprocess.check_output(shlex.split(make_cmd), shell=use_shell)
Expand All@@ -188,7 +188,7 @@ def do_build(make_cmd, messenger_exe):
def build_octave():
paths = "-L%(octave_lib)s -I%(octave_inc)s -L%(zmq_lib)s -I%(zmq_inc)s"
paths = paths % get_config()
make_cmd = "mkoctfile --mex %s -lzmq ./src/messenger.c" % paths
make_cmd = "mkoctfile --mex {} -lzmq ./src/messenger.c".format(paths)
do_build(make_cmd, 'messenger.mex')


Expand DownExpand Up@@ -264,10 +264,10 @@ def build_matlab(static=False):
# Build the mex file
mex = esc(os.path.join(matlab_bin, "mex"))
paths = "-L%(zmq_lib)s -I%(zmq_inc)s" % cfg
make_cmd = '%s -O %s -lzmq ./src/messenger.c' % (mex, paths)
make_cmd = '{} -O {} -lzmq ./src/messenger.c'.format(mex, paths)
if static:
make_cmd += ' -DZMQ_STATIC'
do_build(make_cmd, 'messenger.%s' % extension)
do_build(make_cmd, 'messenger.{}'.format(extension))


if __name__ == '__main__':
Expand Down
Binary file modifiedpymatbridge/messenger/mexa64/messenger.mexa64
Binary file not shown.
62 changes: 29 additions & 33 deletions pymatbridge/messenger/src/messenger.c
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,61 +48,58 @@ void cleanup (void) {
mexPrintf("Socket closed\n");
zmq_term(ctx);
mexPrintf("Context terminated\n");
initialized = 0;
}


/* Gateway function with Matlab */
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]) {
char *cmd;
mxLogical *p;
/* If no input argument, print out the usage */
if (nrhs == 0) {
mexErrMsgTxt("Usage: messenger('init|listen|respond', extra1, extra2, ...)");
}

if (nlhs > 1) {
mexErrMsgTxt("messenger: too many outputs, I return a single bool");
}
/* Get the input command */
if(!(cmd = mxArrayToString(prhs[0]))) {
mexErrMsgTxt("Cannot read the command");
}

/* we'll return true on completion of valid command, else false */
plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);
p[0] = false;
/* Initialize a new server session */
if (strcmp(cmd, "init") == 0) {
char *socket_addr;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
mexErrMsgTxt("Missing argument: socket address");
mexErrMsgTxt("Usage: messenger('init', socket_addr)");
}
if (!(socket_addr = mxArrayToString(prhs[1]))) {
mexErrMsgTxt("Cannot read socket address");
}

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (!initialized) {
if (!initialize(socket_addr)) {
p[0] = 1;
p[0] = true;
mexPrintf("Socket created at: %s\n", socket_addr);
} else {
p[0] = 0;
mexErrMsgTxt("Socket creation failed.");
}
} else {
mexErrMsgTxt("One socket has already been initialized.");
}

return;

/* Listen over an existing socket */
} else if (strcmp(cmd, "listen") == 0) {
int byte_recvd;
char *recv_buffer = mxCalloc(BUFLEN, sizeof(char));
zmq_pollitem_t polls[] = {{socket_ptr, 0, ZMQ_POLLIN, 0}};

if (!checkInitialized()) return;

/* allow MATLAB to draw its graphics every 20ms */
while (zmq_poll(polls, 1, 20000) == 0) {
mexEvalString("drawnow");
Expand All@@ -116,17 +113,14 @@ void mexFunction(int nlhs, mxArray *plhs[],
} else if (byte_recvd > BUFLEN){
mexErrMsgTxt("Receiver buffer overflow. Message truncated");
} else {
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
sprintf(recv_buffer, "Failed to receive a message due to ZMQ error %s", strerror(errno));
mexErrMsgTxt(recv_buffer);
}

return;

p[0] = true;
/* Send a message out */
} else if (strcmp(cmd, "respond") == 0) {
size_t msglen;
char *msg_out;
mxLogical *p;

/* Check if the input format is valid */
if (nrhs != 2) {
Expand All@@ -138,24 +132,26 @@ void mexFunction(int nlhs, mxArray *plhs[],
msglen = mxGetNumberOfElements(prhs[1]);
msg_out = mxArrayToString(prhs[1]);

plhs[0] = mxCreateLogicalMatrix(1, 1);
p = mxGetLogicals(plhs[0]);

if (msglen == zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = 1;
if (msglen == (size_t) zmq_send(socket_ptr, msg_out, msglen, 0)) {
p[0] = true;
} else {
p[0] = 0;
mexErrMsgTxt("Failed to send message due to ZMQ error");
}

return;

/* Close the socket and context */
} else if (strcmp(cmd, "exit") == 0) {
cleanup();

return;
if (initialized) {
cleanup();
p[0] = true;
initialized = 0;
} else {
mexErrMsgTxt("No open socket to exit.");
}
} else if (strcmp(cmd, "check") == 0) {
if (initialized) {
p[0] = true;
}
} else {
mexErrMsgTxt("Unidentified command");
}
return;
}
Loading