Page MenuHome

blender-command-port-patch.2007-06-26.txt

File Metadata

Author
Dietrich Bollmann (diresu)
Created
Nov 13 2013, 1:25 PM

blender-command-port-patch.2007-06-26.txt

This file is larger than 256 KB, so syntax highlighting was skipped.
Index: README
===================================================================
--- README (.../vendor/blender/working/current/blender) (revision 79)
+++ README (.../blender/working/branches/bcp/blender) (revision 79)
@@ -24,7 +24,7 @@
-------------------------------------Links--------------------------------------
Getting Involved:
-http://www.blender.org/docs/get_involved.html
+http://www.blender.org/community/get-involved/
Community:
http://www.blender3d.org/Community/
Index: source/creator/creator.c
===================================================================
--- source/creator/creator.c (.../vendor/blender/working/current/blender) (revision 79)
+++ source/creator/creator.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -25,8 +25,14 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s):
*
+ * - Dietrich Bollmann (dietrich), 2007/06/21:
+ * - commandport initialization code,
+ * - debug option (--debug, UTL_debug),
+ * - functions to simplify use of command line options (UTL_parse_options),
+ * - geometry option (--geometry, UTL_parse_options_geometry).
+ *
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include <stdlib.h>
@@ -81,11 +87,19 @@
#include "RE_pipeline.h"
+#include "UTL_debug.h"
+#include "UTL_parse_options.h"
+#include "UTL_parse_options_geometry.h"
+
#include "playanim_ext.h"
#include "mydevice.h"
#include "nla.h"
#include "datatoc.h"
+#ifdef WITH_COMMAND_PORT
+#include "commandport.h" /* the Blender command port (dietrich) */
+#endif
+
/* for passing information between creator and gameengine */
#include "SYS_System.h"
@@ -107,8 +121,15 @@
/* Local Function prototypes */
static void print_help();
+static void print_help_debug(); /* (dietrich) */
static void print_version();
+/* handle command port option (dietrich) */
+#ifdef WITH_COMMAND_PORT
+void handle_commandport_option_delete(int *argc, char **argv);
+#endif
+void handle_debug_option_delete(int *argc, char **argv);
+void handle_geometry_option_delete(int *argc, char **argv);
/* defined in ghostwinlay and winlay, we can't include carbon here, conflict with DNA */
#ifdef __APPLE__
@@ -199,6 +220,9 @@
printf (" -W\t\tForce opening without borders\n");
printf (" -p <sx> <sy> <w> <h>\tOpen with lower left corner at <sx>, <sy>\n");
printf (" \tand width and height <w>, <h>\n");
+ printf (" --geometry <width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>\n"); /* (dietrich) */
+ printf (" \t--geometry can be used alternatively to the -p option\n");
+ printf (" \tto specify size and position of the Blender window.\n");
printf ("\nGame Engine specific options:\n");
printf (" -g fixedtime\t\tRun on 50 hertz without dropping frames\n");
printf (" -g vertexarrays\tUse Vertex Arrays for rendering (usually faster)\n");
@@ -207,7 +231,22 @@
printf (" -g linearmipmap\tLinear Texture Mipmapping instead of Nearest (default)\n");
printf ("\nMisc options:\n");
- printf (" -d\t\tTurn debugging on\n");
+ printf (" -d | --debug <modA>[:<levelA>],<modB>[:<levelB>],...\n"); /* (dietrich) */
+ printf (" \t\tTurn debugging on for module <modX>.\n");
+ printf (" \t\tSet the debug level if <levelX> is given.\n");
+ printf (" \t\tTo see which debug options can be used, try -hd or --help=debug.\n");
+#ifdef WITH_COMMAND_PORT
+ printf (" \t\tExample:\n");
+ printf (" \t\t blender --debug debug,bcp:2,opt ...\n");
+ printf (" \t\tDebug the debug option itself,\n");
+ printf (" \t\tthe command port at verbosity level 2 (`bcp:2')\n");
+ printf (" \t\tand some command line options (`opt').\n");
+#else
+ printf (" \t\tExample:\n");
+ printf (" \t\t blender --debug debug,opt ...\n");
+ printf (" \t\tDebug the debug option itself\n");
+ printf (" \t\tand some command line options (`opt').\n");
+#endif
printf (" -noaudio\tDisable audio on systems that support audio\n");
printf (" -h\t\tPrint this help text\n");
printf (" -y\t\tDisable script links, use -Y to find out why its -y\n");
@@ -215,23 +254,101 @@
#ifdef WIN32
printf (" -R\t\tRegister .blend extension\n");
#endif
+#ifdef WITH_COMMAND_PORT
+ printf (" -c <port number> | --bcp <port number>\tStart the Blender Command Port\n"
+ " \t\tusing port <port number>\n"); /* (dietrich) */
+#endif
printf (" -v\t\tPrint Blender version and exit\n");
}
+/**
+ help message for debugging mode
+
+ (dietrich)
+*/
+static void print_help_debug()
+{
+ printf("\n"
+ "* Blender Debug Modes\n"
+ "\n"
+ " Usage:\n"
+ "\n"
+ " blender --debug | -d <modA>[:<levelA>],<modB>[:<levelB>],... [more options]\n"
+ "\n"
+ " Turn on debugging for module <modX>;\n"
+ " if <levelX> is given, set debug level for module <modX> to <levelX>\n"
+ "\n"
+ " Possible Arguments:\n"
+ "\n"
+ " debug -- debug the -d | --debug option itself.\n"
+ " opt -- debug some command line options.\n"
+#ifdef WITH_COMMAND_PORT
+ " bcp -- debug the command port.\n"
+ "\n"
+ " This option has to be used together with `--bcp <port>'.\n"
+ " The following debug verbosity levels are available\n"
+ " for debugging the command port:\n"
+ "\n"
+ " bcp:1 -- print general command port debug messages.\n"
+ " bcp:2 -- print more detailed information about\n"
+ " the evaluation of received commands,\n"
+ " the command packages received from a Blender client and\n"
+ " the result packages sent back to the client\n"
+ " after evaluating the commands.\n"
+ " bcp:3 -- hexdump the received packages before processing them.\n"
+ " bcp:4 -- hexdump the received packages without processing them.\n"
+#endif
+ "\n"
+ );
+}
+
+
double PIL_check_seconds_timer(void);
extern void winlay_get_screensize(int *width_r, int *height_r);
int main(int argc, char **argv)
{
- int a, i, stax, stay, sizx, sizy;
+ int a, stax, stay, sizx, sizy, i;
SYS_SystemHandle syshandle;
Scene *sce;
+ int audio;
+ /* Handle unix and windows style help requests */
+ if (option_is_defined_delete(&argc, argv, "-h", "--help") ||
+ option_is_defined_delete(&argc, argv, "/?", "/help" )
+ ) {
+ print_help();
+ exit(0);
+ }
+
+ /* Handle unix and windows style help requests */
+ if (option_is_defined_delete(&argc, argv, "-hd", "--help=debug")) {
+ print_help_debug();
+ exit(0);
+ }
+
+ /* Handle version request */
+ if (option_is_defined_delete(&argc, argv, "-v", "--version")) {
+ print_version();
+ exit(0);
+ }
+
+ /* Handle debug mode requests */
+ handle_debug_option_delete(&argc, argv);
+
+ /* Handle geometry option */
+ handle_geometry_option_delete(&argc, argv);
+
+#ifdef WITH_COMMAND_PORT
+ /* Handle Blender command port option (dietrich) */
+ handle_commandport_option_delete(&argc, argv);
+#endif
+
#if defined(WIN32) || defined (__linux__)
- int audio = 1;
+ audio = 1;
#else
- int audio = 0;
+ audio = 0;
#endif
setCallbacks();
@@ -308,20 +425,9 @@
for(a=1; a<argc; a++) {
- /* Handle unix and windows style help requests */
- if ((!strcmp(argv[a], "--help")) || (!strcmp(argv[a], "/?"))){
- print_help();
- exit(0);
- }
+ /* Handle -* switches */
+ if (argv[a][0] == '-') {
- /* Handle long version request */
- if (!strcmp(argv[a], "--version")){
- print_version();
- exit(0);
- }
-
- /* Handle -* switches */
- else if(argv[a][0] == '-') {
switch(argv[a][1]) {
case 'a':
playanim(argc-1, argv+1);
@@ -353,12 +459,6 @@
exit(252);
- case 'h':
- print_help();
- exit(0);
- case 'v':
- print_version();
- exit(0);
default:
break;
}
@@ -395,6 +495,12 @@
a++;
sizy= atoi(argv[a]);
+ if (debug("opt")) { /* use blender --debug opt ... for debugging (dietrich) */
+ printf("[DEBUG opt] Setting window geometry - "
+ "size <%d, %d>, position: <%d, %d>.\n",
+ sizx, sizy, stax, stay);
+ }
+
setprefsize(stax, stay, sizx, sizy, 0);
break;
case 'd':
@@ -444,6 +550,11 @@
if (G.f & G_DEBUG) printf("setting audio to: %d\n", audio);
}
break;
+ default:
+ printf("\nError: Undefined option: %s\n", argv[a]); /* (dietrich) */
+ printf("Try %s --help for usage information.\n\n", argv[0]);
+ exit(2);
+ break;
}
}
}
@@ -459,7 +570,7 @@
BIF_init();
}
- else {
+ else { /* G.background != 0 */
BPY_start_python(argc, argv);
// (ton) Commented out. I have no idea whats thisfor... will mail around!
@@ -671,6 +782,13 @@
printf("\nError: you must specify a path after '- '.\n");
}
break;
+
+ default:
+ printf("\nError: Undefined option: %s\n", argv[a]); /* (dietrich) */
+ printf("Try %s --help for usage information.\n\n", argv[0]);
+ exit(2);
+ break;
+
}
}
else {
@@ -691,6 +809,10 @@
set_scene(sce);
}
+ /* flush stdout and stderr */
+ fflush(stdout);
+ fflush(stderr);
+
screenmain();
return 0;
@@ -718,3 +840,141 @@
BLI_setInterruptCallBack(blender_test_break);
}
+
+/**
+ Init debug mode.
+
+ Parse argv for debug options
+ -d <modules> or
+ -d <modules>:<debug level> or
+ --debug <modules> or
+ --debug <modules>:<debug level>
+ process them
+ and delete them from argv / argc.
+
+ (dietrich)
+*/
+void handle_debug_option_delete(int *argc, char **argv)
+{
+ char* debug_options;
+ int i;
+
+ /* init debug mode */
+ debug_options = get_string_option_delete_allocate(argc, argv, "-d", "--debug");
+
+ if (debug_options != (char*) NULL) {
+
+ G.f |= G_DEBUG; /* std output printf's */
+
+ /* print version */
+ printf ("Blender V %d.%02d\n", G.version/100, G.version%100);
+#ifdef NAN_BUILDINFO
+ printf("Build: %s %s %s %s\n", build_date, build_time, build_platform, build_type);
+#endif // NAN_BUILDINFO
+
+ MEM_set_memory_debug();
+
+ for (i = 0; i < *argc; i++) {
+ printf("argv[%d] = %s\n", i, argv[i]);
+ }
+
+ /* init the debug mode */
+ init_debug_mode(debug_options);
+
+ /* free memory */
+ free(debug_options);
+ }
+}
+
+/**
+ Handle the geometry option.
+
+ Parse argv for command port options
+ -G <width>{xX}<height>][{+-}<xoffset>{+-}<yoffset> or
+ --geometry <width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>
+ delete them from argv / argc and set the Geometry of the Blender window
+ to the given values.
+
+ The values for size and position passed into the function
+ are only changed if the respective values have been specified.
+
+ (dietrich)
+*/
+void handle_geometry_option_delete(int *argc, char **argv)
+{
+ char* geometry;
+ int sizex, sizey, x, y;
+ int debug_level;
+ debug_level = debug("opt"); /* use blender --debug opt ... for debugging */
+
+ /* set defaults */
+
+ /* window default position = lower left corner */
+ x = y = 0;
+
+ /* window default size = maximal size */
+ winlay_get_screensize(&sizex, &sizey);
+
+ /* get the geometry value string */
+ geometry = get_string_option_delete_allocate(argc, argv, "-G", "--geometry");
+
+ if (geometry != (char*) NULL) {
+
+ /* parse the value string,
+ overwrite default values with parsed values and
+ set geometry
+ */
+ if (parse_geometry(geometry, &sizex, &sizey, &x, &y)) {
+
+ if (debug_level) {
+ printf("[DEBUG opt] Setting window geometry - "
+ "size <%d, %d>, position: <%d, %d>.\n",
+ sizex, sizey, x, y);
+ }
+
+ setprefsize(x, y, sizex, sizey, 0);
+
+ } else {
+
+ /* the geometry string is ill-formed -
+ print an error message and exit
+ */
+ printf("\nError: Ill-formed geometry value: %s\n", geometry);
+ printf("\n");
+ printf(" try something like:\n");
+ printf(" --geometry 800x600\n");
+ printf(" --geometry +10+20\n");
+ printf(" --geometry 800x600+10+20\n");
+ printf("\n");
+ exit(2);
+ }
+ }
+}
+
+#ifdef WITH_COMMAND_PORT
+/**
+ Handle command port options.
+
+ Parse argv for command port options
+ -c <port number> or
+ --bcp <port number>
+ and delete them from argv / argc.
+ If the options have been given, init the command port.
+
+ (dietrich)
+*/
+void handle_commandport_option_delete(int *argc, char **argv)
+{
+ /* get the port number */
+ unsigned short port;
+ port = (unsigned short) get_int_option_delete(argc, argv, "-c", "--bcp");
+
+ /* do nothing if the bcp option hasn't been found */
+ if (port == 0) return;
+
+ /* init the command port */
+ commandport_init(port);
+}
+#endif
+
+/* fin */
Index: source/creator/SConscript
===================================================================
--- source/creator/SConscript (.../vendor/blender/working/current/blender) (revision 79)
+++ source/creator/SConscript (.../blender/working/branches/bcp/blender) (revision 79)
@@ -15,4 +15,8 @@
incs += ' ' + env['BF_QUICKTIME_INC']
defs.append('WITH_QUICKTIME')
+# command port (dietrich)
+if env['WITH_COMMAND_PORT'] == 1:
+ incs += ' ../blender/commandport/include'
+
env.BlenderLib ( libname = 'blender_creator', sources = Split(sources), includes = Split(incs), defines = defs, libtype='core', priority = 1 )
Index: source/blender/blenkernel/intern/parse_options_geometry.c
===================================================================
--- source/blender/blenkernel/intern/parse_options_geometry.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/blenkernel/intern/parse_options_geometry.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,290 @@
+/*
+ * $Id: parse_options_geometry.c, v 1.0 2007/05/31, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Functions to parse the `<geometry>' value
+ * of the `--geometry <geometry>' option.
+ *
+ * geometry pattern: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]
+ *
+ * header file: ../../include/UTL_parse_options_geometry.h
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+/* declaration local functions */
+int is_digit(char c);
+int is_digit(char c);
+int digit_to_integer(char c);
+int is_sign(char c);
+int parse_character(char **str, char c);
+int parse_sign(char **str, int* sign);
+int parse_integer(char **str, int* result);
+int parse_size(char **geometry, int* x, int* y);
+int parse_position(char **geometry, int* x, int* y);
+
+/* function definitions */
+
+/**
+ Returns true if `c' is a digit.
+ */
+int is_digit(char c)
+{
+ return ('0' <= c) && (c <= '9');
+}
+
+/**
+ Converts a digit to an integer.
+ */
+int digit_to_integer(char c)
+{
+ return c - '0';
+}
+
+/**
+ Returns true if `c' is `+' or `-'.
+ */
+int is_sign(char c)
+{
+ return (c == '+') || (c == '-');
+}
+
+/**
+ Try to parse the character `c' from `*str'.
+
+ If successful, return 1 and increment `*str';
+ if not (`*str' doesnt start with `c'), leave `*str' as it is and return 0.
+ */
+int parse_character(char **str, char c)
+{
+ /* when given, skip leading `=' */
+ if (**str == c) {
+ (*str)++;
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/**
+ Try to parse a sign (`+' or `-') from `*str'.
+
+ If successful,
+ - increment `*str'
+ - set `*sign' to
+ - 1 if `+' was parsed, to
+ - -1 if `-' was parsed and
+ return 1.
+
+ if `*str' doesnt start with a sign,
+ - set `*sign' to 0,
+ - leave `*str' as it is and
+ - return 0.
+ */
+int parse_sign(char **str, int* sign)
+{
+ /* parse sign */
+ if (**str == '+') {
+ (*str)++;
+ *sign = 1;
+ return 1;
+ } else if (**str == '-') {
+ (*str)++;
+ *sign = -1;
+ return 1;
+ } else {
+ *sign = 0;
+ return 0;
+ }
+}
+
+/**
+ Parse an integer from the beginning of `*str'.
+
+ `*result' is set to the parsed integer.
+ The length of the parsed integer string is returned by the function.
+ */
+int parse_integer(char **str, int* result)
+{
+ /* parse integer */
+ int len = 0;
+ *result = 0;
+ while (*str != NULL && is_digit(**str)) {
+ len++;
+ *result = (*result * 10) + digit_to_integer(**str);
+ (*str)++;
+ }
+
+ /* return length of parsed integer */
+ return len;
+}
+
+/**
+ Try to parse the size pattern from `*geometry'.
+
+ size pattern: [<width>{xX}<height>]
+
+ In the case of success,
+ - `*x' and `*y' are set to the parsed size values,
+ - `*geometry' is set at the end of the parsed string and
+ - 1 is returned.
+
+ If the size couldn't be parsed,
+ - the values of `*x' and `*y' are not changed,
+ - `*geometry' is not changed either and
+ - 0 is returned.
+*/
+int parse_size(char **geometry, int* x, int* y)
+{
+ int len, xx, yy;
+ char* geo;
+ geo = *geometry;
+
+ /* try to parse size */
+
+ /* parse the x dimension */
+ len = parse_integer(&geo, &xx);
+
+ /* if no integer could be parsed, return 0 for fail */
+ if (!len) return 0;
+
+ /* parse 'x' or 'X' */
+ len = parse_character(&geo, 'x') || parse_character(&geo, 'X');
+
+ /* if neither 'x' nor 'X' could be parsed, return 0 for fail */
+ if (!len) return 0;
+
+ /* parse the y dimension */
+ len = parse_integer(&geo, &yy);
+
+ /* if no integer could be parsed, return 0 for fail */
+ if (!len) return 0;
+
+ /* the size was passed successfully */
+
+ /* overwrite the defaults */
+ *x = xx;
+ *y = yy;
+
+ /* set `*geometry' to first char after the parsed size string */
+ *geometry = geo;
+
+ /* return 1 for success */
+ return 1;
+}
+
+/**
+ Try to parse the position pattern from `*geometry'.
+
+ size pattern: [{+-}<xoffset>{+-}<yoffset>]
+
+ In the case of success,
+ - `*x' and `*y' are set to the parsed position values,
+ - `*geometry' is set at the end of the parsed string and
+ - 1 is returned.
+
+ If the position couldn't be parsed,
+ - the values of `*x' and `*y' are not changed,
+ - `*geometry' is not changed either and
+ - 0 is returned.
+*/
+int parse_position(char **geometry, int* x, int* y)
+{
+ int xsign, xabs, ysign, yabs;
+ char* geo;
+ geo = *geometry;
+
+ /* try to parse position */
+
+ /* parse sign of x position */
+ if (!parse_sign(&geo, &xsign)) return 0;
+
+ /* parse absolute x position */
+ if (!parse_integer(&geo, &xabs)) return 0;
+
+ /* parse sign of y position */
+ if (!parse_sign(&geo, &ysign)) return 0;
+
+ /* parse absolute y position */
+ if (!parse_integer(&geo, &yabs)) return 0;
+
+ /* the position was passed successfully */
+
+ /* overwrite the defaults */
+ *x = xsign * xabs;
+ *y = ysign * yabs;
+
+ /* set `*geometry' to first char after the parsed size string */
+ *geometry = geo;
+
+ /* return 1 for success */
+ return 1;
+}
+
+/**
+ */
+int parse_geometry(char *geometry, int* sizex, int* sizey, int* x, int* y)
+{
+ int result, sx, sy, px, py;
+ char* geo;
+ geo = geometry;
+ result = 0;
+
+ /* when given, skip leading `=' */
+ parse_character(&geo, '=');
+
+ /* parse size */
+ if (parse_size(&geo, &sx, &sy)) result += 1;
+
+ /* parse position */
+ if (parse_position(&geo, &px, &py)) result += 2;
+
+ /* if the whole string could be parsed,
+ overwrite the defaults and
+ return a value indicating if
+ size, position or both could be parsed.
+ */
+ if (*geo == '\0') {
+
+ switch (result) {
+ case 1: *sizex = sx; *sizey = sy; break;
+ case 2: *x = px; *y = py; break;
+ case 3: *sizex = sx; *sizey = sy; *x = px; *y = py; break;
+ }
+ return result;
+
+ } else {
+
+ return 0;
+
+ }
+}
+
+/* fin */
Index: source/blender/blenkernel/intern/parse_options.c
===================================================================
--- source/blender/blenkernel/intern/parse_options.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/blenkernel/intern/parse_options.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,219 @@
+/*
+ * $Id: UTL_parse_options.c, v 1.0 2007/05/31, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Functions to parse command-line options.
+ *
+ * header file: ../../include/UTL_parse_options.h
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "UTL_debug.h"
+
+#include "UTL_parse_options.h"
+
+/* definition of local functions */
+int get_option_index(int argc, char **argv, char *option_short, char *option_long);
+void delete_args(int *argc, char **argv, int index, int number);
+void print_argv(int argc, char **argv);
+
+/**
+ Parse argv for an option and return its index.
+ The option can be given in two different forms: a short form and a long form.
+ If the option was not found 0 is returned.
+ (dietrich)
+*/
+int get_option_index(int argc, char **argv, char *option_short, char *option_long)
+{
+ int i;
+ for(i = 1; i < argc; i++) {
+ if ((option_short != NULL) && (strcmp(argv[i], option_short) == 0)) return i;
+ if ((option_long != NULL) && (strcmp(argv[i], option_long) == 0)) return i;
+ }
+ return 0;
+}
+
+/**
+*/
+int option_is_defined_delete(int *argc, char **argv, char *option_short, char *option_long)
+{
+ /* get the index of option if given */
+ int i_option;
+ i_option = get_option_index(*argc, argv, option_short, option_long);
+
+ /* return 0 if the option hasn't been found */
+ if (i_option == 0) return 0;
+
+ /* delete the options from argv and decrement *argc accordingly */
+ delete_args(argc, argv, i_option, 1);
+
+ /* check if the option was given a second time */
+ if (get_option_index(*argc, argv, option_short, option_long)) {
+ printf("\nERROR: The option %s / %s can only be used once!\n",
+ option_short, option_long);
+ exit(2);
+ }
+
+ /* return true */
+ return 1;
+}
+
+/**
+*/
+int get_int_option_delete(int *argc, char **argv, char *option_short, char *option_long)
+{
+ int i_option;
+ int i_value;
+ int value;
+
+ /* get the index of option if given */
+ i_option = get_option_index(*argc, argv, option_short, option_long);
+
+ /* return 0 if the option hasn't been found */
+ if (i_option == 0) return 0;
+
+ /* check if a value for the option has been given */
+ i_value = i_option + 1;
+ if (i_value >= *argc) {
+ printf("\nUsage: %s <value> | %s <value>\n", option_short, option_long);
+ exit(2);
+ }
+
+ /* get the value */
+ value = atoi(argv[i_value]);
+
+ /* delete the options from argv and decrement *argc accordingly */
+ delete_args(argc, argv, i_option, 2);
+
+ /* check if the option was given a second time */
+ if (get_option_index(*argc, argv, option_short, option_long)) {
+ printf("\nERROR: The option %s / %s can only be used once!\n",
+ option_short, option_long);
+ exit(2);
+ }
+
+ /* return the option value */
+ return value;
+}
+
+/**
+*/
+char* get_string_option_delete_allocate(int *argc, char **argv,
+ char *option_short, char *option_long)
+
+{
+ int i_option, i_value, length;
+ char* value_str;
+
+ /* get the index of option if given */
+ i_option = get_option_index(*argc, argv, option_short, option_long);
+
+ /* return 0 if the option hasn't been found */
+ if (i_option == 0) return (char*) NULL;
+
+ /* check if a value for the option has been given */
+ i_value = i_option + 1;
+ if (i_value >= *argc) {
+ printf("\nUsage: %s <value> | %s <value>\n", option_short, option_long);
+ exit(2);
+ }
+
+ /* get the value */
+ length = strlen(argv[i_value]);
+ value_str = (char*) malloc((length + 1) * sizeof(char));
+ memcpy(value_str, argv[i_value], length);
+ value_str[length]= '\0';
+
+ /* delete the options from argv and decrement *argc accordingly */
+ delete_args(argc, argv, i_option, 2);
+
+ /* check if the option was given a second time */
+ if (get_option_index(*argc, argv, option_short, option_long)) {
+ printf("\nERROR: The option %s / %s can only be used once!\n",
+ option_short, option_long);
+ exit(2);
+ }
+
+ /* return the option value */
+ return value_str;
+}
+
+/**
+ Delete `number' of options from argv starting at `index'
+ and decrement `*argc' by `number'.
+ (dietrich)
+*/
+void delete_args(int *argc, char **argv, int index, int number)
+{
+ int i;
+
+ /* check if argc/argv is big enough */
+ if ((index + number - 1) >= *argc) {
+ printf("\nERROR: Not enough arguments given "
+ "for deleting %d args starting at %d from argv:\n", number, index);
+ print_argv(*argc, argv);
+ exit(2);
+ }
+
+ /* if in debug mode - print a message */
+ if (debug("opt")) {
+ printf("[DEBUG args] Deleting \"");
+ for(i = index; i < (index + number); i++) {
+ if (i > index) printf(" ");
+ printf(argv[i]);
+ }
+ printf("\" from ");
+ print_argv(*argc, argv);
+ }
+
+ /* delete the args */
+ *argc -= number;
+ for( ; index < *argc; index++) {
+ argv[index] = argv[index + number];
+ }
+}
+
+/**
+ Print argc/argv.
+ (dietrich)
+*/
+void print_argv(int argc, char **argv)
+{
+ int i;
+ printf("argv[%d]: ", argc);
+ for(i = 0; i < argc; i++) {
+ if (i > 0) printf(" ");
+ printf(argv[i]);
+ }
+ printf("\n");
+}
+
+/* fin */
Index: source/blender/blenkernel/intern/debug.c
===================================================================
--- source/blender/blenkernel/intern/debug.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/blenkernel/intern/debug.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,375 @@
+/*
+ * $Id: debug.c, v 1.0 2007/06/20, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Debug command line option functionality.
+ *
+ * When starting Blender, the option
+ *
+ * -d[ebug] <module A>[:<debug level for module A>],<module B>[:<debug level for module B>],...
+ *
+ * can be used to switch on debug mode and to specify a debug level
+ * for certain modules.
+ *
+ * Example:
+ *
+ * blender --debug debug,opt,bcp:2 -geometry 650x600+0+100 --bcp 6789
+ *
+ * Start blender and print debug messages for the
+ *
+ * debug -- debug the debug option itself
+ * opt -- debug some Blender command line options, see:
+ * - source/blender/blenkernel/intern/parse_options.c and
+ * - source/creator/creator.c
+ * bcp:2 -- debug the Blender command port, debug level 2,
+ * see files in: source/blender/commandport/
+ *
+ * Note that for the debug option argument `bcp:<level>' first
+ * the command port has to be activated via the `--bcp <port>' option.
+ *
+ * The debug level for the specified modules is stored by the debugging functions
+ * in `source/blender/commandport/utilities/{include/bcp_debug.h,src/bcp_debug.c}'
+ * and can be queried by the functions implementing the modules via the
+ * function `debug("name of module")'.
+ *
+ * Example:
+ *
+ * // print command port debug message (bcp)
+ * if (debug("bcp") > 2) print_a_level_2_debug_message();
+ *
+ * For a list of modules currently using the debug functionality see
+ * the help text defined in function `print_help_debug()', file `source/creator/creator.c'
+ * or call `blender --help=debug'.
+ *
+ * header file: ../../include/UTL_debug.h
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "BKE_global.h"
+
+#include "UTL_debug.h"
+
+/* struct to store an option with level */
+typedef struct option_struct {
+ char* name;
+ int level;
+ struct option_struct* next;
+} option_struct;
+
+/**
+ Array holding the flags indicating which modules should be debugged.
+*/
+option_struct* g_debug_module_list = NULL;
+int g_debug = 0;
+
+
+/* function declarations */
+char* get_next_option_allocate(char* options, option_struct** option);
+option_struct* new_option(char* name, int level);
+void delete_option(option_struct* option);
+char* new_string(char* str, int length);
+void dump_options();
+
+
+/**
+
+ example:
+ The command `blender --debug debug,bcp:2,args' turns debugging on for
+ - this module (the debug module),
+ - the Blender Command Port module (debug level 2) and
+ - the `args' module.
+*/
+void init_debug_mode(char* options)
+{
+ /* DEBUG */
+ extern int g_debug;
+ extern option_struct* g_debug_module_list;
+
+ char *p, *next;
+ option_struct *first, *last, *option;
+
+ /* check if the debug code itself should be debugged */
+ if (((p = strstr(options, "debug")) != NULL) /* "`debug' is a substring of `options' */
+ && ((p == options) /* `options' starts with "debug" (ex: "debug...") */
+ || (*(p-1) == ',')) /* or follows directly a ',' (ex: "...,debug") */
+ && ((*(p+5) == ':') /* and the character after "debug" is one of ':', (ex: "debug:10") */
+ || (*(p+5) == ',') /* ',' (ex: "debug,...") */
+ || (*(p+5) == '\0')) /* and '\0' (ex: "...debug") */
+ ) { /* print debug messages also for the debug module :) */
+ g_debug = 1;
+ }
+
+ /* DEBUG */
+ if (g_debug) printf("[DEBUG debug] found the following debug options: %s\n", options);
+
+ /* pointer to the first and last read option */
+ first = NULL;
+ last = NULL;
+
+ next = options;
+ while (NULL != (next = get_next_option_allocate(next, &option))) {
+
+ /* DEBUG */
+ printf("[DEBUG] Turning debugging on for module `%s' (level: %d).\n",
+ option->name, option->level);
+
+ /* this option is the new last one */
+ option->next = NULL;
+
+ /* append the option the the option queue */
+ if (first == NULL) {
+
+ /* this is the first option to be stored */
+ first = option;
+ last = option;
+
+ } else {
+
+ /* append this option to the last option */
+ last->next = option;
+ last = option;
+
+ }
+ }
+
+ /* init the global variable
+ which stores the list of parsed options
+ */
+ g_debug_module_list = first;
+
+ /* DEBUG */
+ if (g_debug) dump_options();
+}
+
+
+/**
+*/
+char* get_next_option_allocate(char* options, option_struct** option)
+{
+ char* cp;
+ int olength, level, noi;
+ option_struct* opt;
+
+ /* if `options' is an empty string return NULL */
+ if (*options == '\0') {
+ option = NULL;
+ return NULL;
+ }
+
+ /* parse next option */
+ for (cp = options, olength = 0;
+ *cp != ':' && *cp != ',' && *cp != '\0';
+ cp++, olength++
+ ) {};
+
+ /* the default debug level is 1 */
+ level = 1;
+
+ /* if a level is given in the option (<option>:<level>)
+ parse level */
+ if (*cp == ':') {
+
+ /* advance to first char after ':' */
+ cp++;
+
+ /* scan level integer */
+ noi = sscanf(cp, "%d", &level); /* noi = number of scanned items */
+ if (noi != 1) level = 0;
+
+ /* advance cp to the next char after the integer string */
+ for( ; *cp != ':' && *cp != ',' && *cp != '\0'; cp++) {};
+ }
+
+ /* advance to next option if present */
+ if (*cp != '\0') cp++;
+
+ /* allocate memory to store the found option and debug level */
+ opt = new_option(new_string(options, olength), level);
+
+ *option = opt;
+
+ /* return pointer to next option */
+ return cp;
+}
+
+
+/**
+*/
+option_struct* new_option(char* name, int level)
+{
+ option_struct* option;
+ option = (option_struct*) malloc(sizeof(option_struct));
+
+ if (option == NULL) {
+ fprintf(stderr, "ERROR: Couldn't allocate memory for new blender debug option!\n");
+ exit(1);
+ }
+
+ option->name = name;
+ option->level = level;
+ option->next = NULL;
+
+ return option;
+}
+
+
+/**
+*/
+void delete_option(option_struct* option)
+{
+ free(option->name);
+ free(option);
+}
+
+
+/**
+*/
+char* new_string(char* str, int length)
+{
+ /* allocate memory for new string */
+ char* newstr;
+ newstr = (char*) malloc((length + 1) * sizeof(char));
+
+ /* check for error */
+ if (newstr == NULL) {
+ fprintf(stderr, "ERROR: Couldn't allocate memory for a new string!\n");
+ exit(1);
+ }
+
+ /* copy content of original strint */
+ memcpy(newstr, str, length);
+ newstr[length]= '\0';
+
+ return newstr;
+}
+
+
+/**
+*/
+void cleanup_debug_mode()
+{
+ /* DEBUG */
+ extern int g_debug;
+
+ /* get global option queue */
+ extern option_struct* g_debug_module_list;
+
+ int i;
+
+ /* init option pointer */
+ option_struct *o, *current;
+ o = g_debug_module_list;
+
+ /* free memory used to store options */
+ i = 0;
+ while (o != NULL) {
+
+ /* get current option */
+ current = o;
+
+ /* get next stored option */
+ o = o->next;
+
+ /* DEBUG */
+ if (g_debug) {
+ printf("[DEBUG debug] Freeing debug option %d: %s, level: %d\n",
+ i++, current->name, current->level);
+ }
+
+ /* free current option */
+ delete_option(current);
+ }
+}
+
+
+/**
+*/
+int debug(char* module)
+{
+ /* get global option queue */
+ extern option_struct* g_debug_module_list;
+ extern int g_debug;
+
+ int level, i;
+ option_struct* o;
+
+ /* default level is 0 (debugging of `module' is off) */
+ level = 0;
+
+ /* search if a debug level for `module' is defined */
+ for (o = g_debug_module_list, i = 0;
+ o != NULL;
+ o = o->next, i++
+ ) {
+
+ if (strcmp(module, o->name) == 0) {
+ level = o->level;
+ break;
+ }
+ }
+
+ /* DEBUG */
+ if (g_debug) {
+ printf("[DEBUG debug] The debug level for module `%s' is %d.\n", module, level);
+ }
+
+ /* return debug level */
+ return level;
+}
+
+
+/**
+*/
+void dump_options()
+{
+ extern option_struct* g_debug_module_list; /* get global option queue */
+ option_struct* o; /* init option pointer */
+ int i;
+
+ i = 0;
+ o = g_debug_module_list;
+
+ printf("[DEBUG debug] stored debug options:\n");
+
+ while (o != NULL) {
+
+ printf("[DEBUG debug] (%d) option: %s, level: %d\n", i, o->name, o->level);
+
+ /* get next stored option */
+ i++;
+ o = o->next;
+ }
+
+ printf("[DEBUG debug] fin.\n");
+}
+
+/* fin */
Index: source/blender/include/UTL_parse_options.h
===================================================================
--- source/blender/include/UTL_parse_options.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/include/UTL_parse_options.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,98 @@
+/*
+ * $Id: UTL_parse_options.h, v 1.0 2007/05/31, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Functions to parse command-line options.
+ *
+ * source file: ../blenkernel/intern/UTL_parse_options.c
+ *
+ */
+
+#ifndef UTL_PARSE_OPTIONS_H
+#define UTL_PARSE_OPTIONS_H
+
+/**
+ Parse argv for an integer option,
+ delete it from argv/argc and return its value.
+
+ The option can be given in two different forms: a short form and a long form.
+ If the option was not found 0 is returned;
+ if it was specified more than once an error is printed.
+
+ Example:
+
+ option: -i | --int <int value>
+ usage: int value = get_int_option_delete(&argc, argv, "-i", "--int");
+
+ (dietrich)
+*/
+int get_int_option_delete(int *argc, char **argv, char *option_short, char *option_long);
+
+/**
+ Parse argv for a string option,
+ delete it from argv/argc,
+ copy the value into newly allocated memory
+ and return it.
+
+ The option can be given in two different forms: a short form and a long form.
+ If the option was not found 0 is returned;
+ if it was specified more than once an error is printed.
+
+ Example:
+
+ option: -s | --string <value>
+ usage: char* value = get_string_option_delete_allocate(&argc, argv, "-s", "--string");
+
+ (dietrich)
+*/
+char* get_string_option_delete_allocate(int *argc, char **argv,
+ char *option_short, char *option_long);
+
+/**
+ Check for an option.
+
+ Parse argv for the option and delete it from argc/argv.
+ Return 1 if the option was given, 0 if not.
+
+ The option can be specified in two different forms: a short form and a long form.
+ if it was specified more than once an error is printed.
+
+ Example:
+
+ option: -d | --debug
+ usage: if (option_is_defined_delete(&argc, argv, "-d", "--debug") do_something();
+
+ (dietrich)
+*/
+int option_is_defined_delete(int *argc, char **argv, char *option_short, char *option_long);
+
+#endif /* UTL_PARSE_OPTIONS_H */
+
+/* fin */
+
+
Index: source/blender/include/mydevice.h
===================================================================
--- source/blender/include/mydevice.h (.../vendor/blender/working/current/blender) (revision 79)
+++ source/blender/include/mydevice.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -35,8 +35,9 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
- *
+ * Contributor(s):
+ * - Dietrich Bollmann - added command port queue event definition (COMMAND_PORT_INPUT)
+ *
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -207,6 +208,9 @@
#define UI_BUT_EVENT 0x4008
#define AUTOSAVE_FILE 0x4009
#define UNDOPUSH 0x400A
+#ifdef WITH_COMMAND_PORT
+#define COMMAND_PORT_INPUT 0x400B /* (dietrich) */
+#endif
/* REDRAWVIEW3D has to be the first one (lowest number) for buttons! */
#define REDRAWVIEW3D 0x4010
Index: source/blender/include/BIF_mainqueue.h
===================================================================
--- source/blender/include/BIF_mainqueue.h (.../vendor/blender/working/current/blender) (revision 79)
+++ source/blender/include/BIF_mainqueue.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -27,7 +27,10 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): none yet.
+ * Contributor(s):
+ * - Dietrich Bollmann
+ * - added thread protection (mainqueue_mutex) for main queue.
+ * - added the new parameter 'args' to pass an argument struct pointer
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -37,11 +40,26 @@
#define MAXQUEUE 4096
-unsigned short mainqtest (void);
-unsigned short mainqread (short *val, char *ascii);
-void mainqenter (unsigned short event, short val);
-void mainqenter_ext (unsigned short event, short val, char ascii);
-void mainqpushback (unsigned short event, short val, char ascii);
+unsigned short mainqtest (void);
+unsigned short mainqread (short *val, char *ascii);
+unsigned short mainqread_args (short *val, char *ascii
+#ifdef WITH_COMMAND_PORT
+ , void** args
+#endif
+ );
+void mainqenter (unsigned short event, short val);
+void mainqenter_ext (unsigned short event, short val, char ascii);
+void mainqenter_args (unsigned short event, short val, char ascii
+#ifdef WITH_COMMAND_PORT
+ , void* args
+#endif
+ );
+void mainqpushback (unsigned short event, short val, char ascii);
+void mainqpushback_args (unsigned short event, short val, char ascii
+#ifdef WITH_COMMAND_PORT
+ , void* args
+#endif
+ );
#endif /* BIF_MAINQUEUE_H */
Index: source/blender/include/UTL_parse_options_geometry.h
===================================================================
--- source/blender/include/UTL_parse_options_geometry.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/include/UTL_parse_options_geometry.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,64 @@
+/*
+ * $Id: UTL_parse_options_geometry.h, v 1.0 2007/05/31, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Functions to parse the `<geometry>' value
+ * of the `--geometry <geometry>' option.
+ *
+ * geometry pattern: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]
+ *
+ * source file: ../blenkernel/intern/parse_options_geometry.c
+ *
+ */
+
+#ifndef UTL_PARSE_OPTIONS_GEOMETRY_H
+#define UTL_PARSE_OPTIONS_GEOMETRY_H
+
+/**
+ Parse the `<geometry>' value
+ of the `--geometry <geometry>' option.
+
+ geometry pattern: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]
+
+ The `*sizex', `*sizey' and / or `*x', `*y' parameters are only
+ changed, if the size and / or the position could be parsed
+ from the `*geometry' string.
+
+ The function returns
+ - 0, if neither position nor size could be parsed;
+ - 1, if only the size could be parsed;
+ - 2, if only the position could be parsed;
+ - 3, if both - position and size - could be parsed.
+ */
+int parse_geometry(char *geometry, int* sizex, int* sizey, int* x, int* y);
+
+#endif /* <FILE_NAME_H> */
+
+/* fin */
+
+
Index: source/blender/include/UTL_debug.h
===================================================================
--- source/blender/include/UTL_debug.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/include/UTL_debug.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,94 @@
+/*
+ * $Id: UTL_debug.h, v 1.0 2007/06/20, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Debug command line option functionality.
+ *
+ * When starting Blender, the option
+ *
+ * -d[ebug] <module A>[:<debug level for module A>],<module B>[:<debug level for module B>],...
+ *
+ * can be used to switch on debug mode and to specify a debug level
+ * for certain modules.
+ *
+ * Example:
+ *
+ * blender --debug debug,opt,bcp:2 -geometry 650x600+0+100 --bcp 6789
+ *
+ * Start blender and print debug messages for the
+ *
+ * debug -- debug the debug option itself
+ * opt -- debug some Blender command line options, see:
+ * - source/blender/blenkernel/intern/parse_options.c and
+ * - source/creator/creator.c
+ * bcp:2 -- debug the Blender command port, debug level 2,
+ * see files in: source/blender/commandport/
+ *
+ * Note that for the debug option argument `bcp:<level>' first
+ * the command port has to be activated via the `--bcp <port>' option.
+ *
+ * The debug level for the specified modules is stored by the debugging functions
+ * in `source/blender/commandport/utilities/{include/bcp_debug.h,src/bcp_debug.c}'
+ * and can be queried by the functions implementing the modules via the
+ * function `debug("name of module")'.
+ *
+ * Example:
+ *
+ * // print command port debug message (bcp)
+ * if (debug("bcp") > 2) print_a_level_2_debug_message();
+ *
+ * For a list of modules currently using the debug functionality see
+ * the help text defined in function `print_help_debug()', file `source/creator/creator.c'
+ * or call `blender --help=debug'.
+ *
+ * source file: ../blenkernel/intern/debug.c
+ *
+ */
+
+#ifndef UTL_DEBUG_H
+#define UTL_DEBUG_H
+
+/**
+ Enter debug mode.
+*/
+void init_debug_mode(char* options);
+
+/**
+ Cleanup the memory used by the debug functionality.
+ To be called when blender exits.
+*/
+void cleanup_debug_mode();
+
+/**
+ Return 1 if the given module should be debugged, 0 else.
+*/
+int debug(char* module);
+
+#endif /* UTL_DEBUG_H */
+
+/* fin */
Index: source/blender/commandport/include/commandport.h
===================================================================
--- source/blender/commandport/include/commandport.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/include/commandport.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,94 @@
+/*
+ * $Id: commandport.h, v 1.0 2007/05/02, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Main Blender Command Port header file.
+ *
+ * All command port functionality in files outside of the
+ * directory `source/blender/commandport/' is implemented
+ * by calling the functions imported from this file:
+ *
+ * - `commandport_init()' initializes the command port and
+ * is called from function `main()'
+ * in file `source/creator/creator.c'
+ * when Blender is started with the `-c' / `--bcp' option;
+ *
+ * - `commandport_start()' starts the command port and
+ * is called from function `screenmain()'
+ * in file `source/blender/src/editscreen.c'
+ * when Blender is started with the `-c' / `--bcp' option;
+ *
+ * - When the command port thread receives a command sequence from
+ * a client, a `COMMAND_PORT_INPUT' event token is appended
+ * to the end of the Blender main event loop queue.
+ * When the Blender main event handler finds such a token,
+ * the function `commandport_handle_input_allocate()' is
+ * called to handle the event.
+ * See the Blender main event loop in function `screenmain()',
+ * file `source/blender/src/editscreen.c'.
+ *
+ * - When Blender was started with the `-c' / `--bcp' option
+ * the function `commandport_destroy()' cleans up the command port code
+ * when Blender exists.
+ * It is called from function `exit_usiblender()'
+ * in file `source/blender/src/usiblender.c'.
+ *
+ * source file: ../blender/src/commandport.c
+ *
+ */
+
+#ifndef COMMANDPORT_H
+#define COMMANDPORT_H
+
+/**
+ Called from function `main()'
+ in file `source/creator/creator.c'
+*/
+void commandport_init(unsigned short port);
+
+/**
+ Called from function `screenmain()'
+ in file `source/blender/src/editscreen.c'
+*/
+void commandport_start();
+
+/**
+ Called from function `screenmain()'
+ in file `source/blender/src/editscreen.c'
+*/
+void commandport_handle_input_allocate(void* args);
+
+/**
+ Called from function `exit_usiblender()'
+ in file `source/blender/src/usiblender.c'
+*/
+void commandport_destroy();
+
+#endif /* COMMANDPORT_H */
+
+/* fin */
Index: source/blender/commandport/SConscript
===================================================================
--- source/blender/commandport/SConscript (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/SConscript (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,49 @@
+# -*- mode: python -*-
+#
+# $Id: SConscript, v 1.0 2007/05/01, dietrich, tokyo $
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2007 by the Blender Foundation.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Author: Dietrich Bollmann
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+# Command port main build file.
+#
+
+Import('env')
+
+sconscripts = []
+
+if env['WITH_COMMAND_PORT'] == 1:
+ sconscripts.append('blender/SConscript')
+
+if env['WITH_BLASH'] == 1:
+ sconscripts.append('blash/SConscript')
+
+if env['WITH_COMMAND_PORT'] == 1 or env['WITH_BLASH'] == 1:
+ sconscripts.append('utilities/SConscript')
+
+SConscript(sconscripts)
+
+# fin.
Index: source/blender/commandport/blash/SConscript
===================================================================
--- source/blender/commandport/blash/SConscript (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/blash/SConscript (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,38 @@
+# -*- mode: python -*-
+#
+# $Id: SConscript, v 1.0 2007/05/01, dietrich, tokyo $
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2007 by the Blender Foundation.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Author: Dietrich Bollmann
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+# blash main build file.
+#
+
+SConscript([
+ 'src/SConscript',
+ ])
+
+# fin.
Index: source/blender/commandport/blash/src/SConscript
===================================================================
--- source/blender/commandport/blash/src/SConscript (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/blash/src/SConscript (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,44 @@
+# -*- mode: python -*-
+#
+# $Id: SConscript, v 1.0 2007/05/01, dietrich, tokyo $
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2007 by the Blender Foundation.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Author: Dietrich Bollmann
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+# blash source build file.
+
+Import ('env')
+
+incs = '''
+ ../include
+ ../../utilities/include
+'''
+
+sources = env.Glob('*.c')
+
+env.BlenderLib ('blash', sources, Split(incs), [], libtype=['blash'], priority=[0])
+
+# fin.
Index: source/blender/commandport/blash/src/blash.c
===================================================================
--- source/blender/commandport/blash/src/blash.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/blash/src/blash.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,192 @@
+/*
+ * $Id: blash.c, v 1.0 2007/05/01, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * blash main file.
+ *
+ */
+
+/* fin */
+/* shell_client.c - Dietrich Bollmann */
+
+#include <stdio.h> /* for printf() and fprintf() */
+#include <stdlib.h> /* for atoi() and exit() */
+#include <getopt.h> /* for getopt() */
+
+#include "bcp_debug.h" /* for bcp_debug() */
+#include "bcp_shell.h" /* for bcp_shell() */
+#include "bcp_defaults.h" /* default values: default IP address, default port, ... */
+#include "message_client.h" /* message client to read and send messages */
+#include "string_buffer.h" /* string buffer */
+
+
+/**
+ Parameters:
+ Using 'getopt' to parse the parameters.
+*/
+extern char* optarg; /* needed to access option arguments */
+
+/* Parameter definitions */
+static struct option longopts[] = {
+ { "debug", optional_argument, NULL, 'd' },
+ { "help", no_argument, NULL, 'h' },
+ { "IP-address", required_argument, NULL, 'i' },
+ { "port", required_argument, NULL, 'p' },
+ { "shell-mode", no_argument, NULL, 's' },
+ { "eval-mode", no_argument, NULL, 'e' },
+ { "file-mode", no_argument, NULL, 'f' },
+ { "retries", required_argument, NULL, 'r' },
+ { "retry-sleeptime", required_argument, NULL, 't' },
+ { NULL, 0, NULL, 0 }
+};
+
+/* function declarations */
+void print_usage();
+
+/**
+ Print `blash' usage information / help text.
+ */
+void print_usage(char* name)
+{
+ /* "01234567890123456789012345678901234567890123456789012345678901234567890123456789\n" */
+ printf(" \n"
+ " This is Blash - the GNU BLender-Again SHell.\n"
+ " \n"
+ " Blash is used to connect to a running Blender instance\n"
+ " started in server mode and to \"remote control\" it\n"
+ " via the Blender Python scripting API.\n"
+ " \n"
+ " Usage: %s [OPTION]*...\n"
+ " \n"
+ " Options:\n"
+ " \n"
+ " -h, --help Print this help message.\n"
+ " -d[<level>], --debug[=<level>] Print debug messages. The higher the \n"
+ " verbosity level, the more detailed are \n"
+ " the debug messages. Currently 3 levels \n"
+ " are implemented (level 0, 1, 2).\n"
+ " Default: debug level 0; --debug / -d has\n"
+ " the same effect as --debug=1 / -d1. \n"
+ " -i, --IP-address <IP address> IP address of Blender server.\n"
+ " default: %s\n"
+ " -p, --port <port> Port of Blender server.\n"
+ " Default: %d\n"
+ " -s, --shell-mode start in shell (single) mode (default).\n"
+ " -e, --eval-mode start in eval mode.\n"
+ " -f, --file-mode start in file mode.\n"
+ " -r, --retries <no of retries> Number of times blash should retry to \n"
+ " connect to the Blender server.\n"
+ " -t, --retry-sleeptime <seconds> Time to sleep before next try to connect.\n"
+ " Te be used together with `--retries'.\n"
+ " \n"
+ " Examples:\n"
+ " \n"
+ " %s\n"
+ " %s --IP-address %s --port %d --shell-mode\n"
+ " %s --retries 20 --retry-sleeptime 0.1\n"
+ " \n"
+ " Copyright (c) published under the GNU General Public License.\n"
+ " Written by Dietrich Bollmann.\n"
+ " \n",
+ name,
+ BCP_DEFAULT_IP,
+ BCP_DEFAULT_PORT,
+ name, /* example 1 */
+ name, BCP_DEFAULT_IP, BCP_DEFAULT_PORT, /* example 2 */
+ name /* example 3 */
+ );
+}
+
+/**
+ blash main function.
+ */
+int main(int argc, char *argv[])
+{
+ char* server_IP_address; /* server IP address (dotted quad) */
+ unsigned short server_port; /* server port */
+ int mode; /* shell-mode / text-mode */
+ int retries; /* number of times to try to connect to server */
+ double retry_sleeptime; /* time to sleep before retrying to connect to server
+ * in seconds used only if `retries' is not 0 */
+ int c;
+
+ /* defaults */
+ server_IP_address = BCP_DEFAULT_IP;
+ server_port = BCP_DEFAULT_PORT;
+ mode = BCP_SINGLE_MODE;
+ retries = 0;
+ retry_sleeptime = 0.5;
+
+ /* parsing the command line parameters */
+ while ((c = getopt_long(argc, argv, "hd::i:p:sefr:t:", longopts, NULL)) != -1) {
+
+ switch(c) {
+
+ /* help */
+ case 'h': print_usage(argv[0]); exit(0); break;
+
+ /* set debug message level */
+ case 'd': bcp_set_debug_level((optarg == NULL) ? 1 : atoi(optarg)); break;
+
+ /* server address and port */
+ case 'i': server_IP_address = optarg; break;
+ case 'p': server_port = atoi(optarg); break;
+
+ /* shell modes */
+ case 's': mode = BCP_SINGLE_MODE; break;
+ case 'e': mode = BCP_EVAL_MODE; break;
+ case 'f': mode = BCP_FILE_MODE; break;
+
+ /* retries to connect to Blender server */
+ case 'r': retries = atoi(optarg); break;
+ case 't': retry_sleeptime = atof(optarg); break;
+
+ default:
+ printf("ERROR: Unrecognized option `-%c'\n", c);
+ printf("\n");
+ print_usage(argv[0]);
+ exit(1);
+ }
+ }
+
+ /* start the shell */
+ printf("This is Blash - the GNU BLender-Again SHell :)\n");
+ if (bcp_debug()) printf("Connecting to Blender server at IP-address %s, port %d...\n",
+ server_IP_address, server_port);
+
+ /* starting the shell */
+ bcp_shell_wait(server_IP_address, server_port, mode, retries, retry_sleeptime);
+
+ /* done */
+ printf("\n");
+ printf("bye...\n");
+ printf("\n");
+ exit(0);
+}
+
+/* fin */
Index: source/blender/commandport/blash/README
===================================================================
--- source/blender/commandport/blash/README (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/blash/README (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,72 @@
+#
+# $Id: README, v 1.0 2007/05/01, dietrich, tokyo $
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2007 by the Blender Foundation.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Author: Dietrich Bollmann
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+# blash readme file.
+
+
+* blash - the BLender-Again SHell
+
+Blash is a Blender-Python shell which can be used together
+with Blender when started in server mode.
+
+See also the BCP (Blender Command Port) README (../README).
+
+Example:
+
+ # starting the Blender server:
+
+ $ blender --geometry 800x600+10+10 --bcp 6789 &
+
+ # using blash to send Python commands to the Blender server:
+
+ $ blash --port 6789
+
+ This is Blash - the GNU BLender-Again SHell :)
+ Connection to Blender Server established. (IP address: 127.0.0.1, port: 6789)
+
+ >>> from Blender import *
+ >>>
+ >>> vertices = [[1, 1, 0], [-1, 1, 0], [-1, -1, 0], [1, -1, 0], [0, 0, 1.27]]
+ >>> faces = [[3, 2, 1, 0], [0, 1, 4], [1, 2, 4], [2, 3, 4], [3, 0, 4]]
+ >>>
+ >>> mesh = Mesh.New('mesh')
+ >>> mesh.verts.extend(vertices)
+ >>> mesh.faces.extend(faces)
+ >>>
+ >>> scene = Scene.GetCurrent()
+ >>> object = scene.objects.new(mesh, 'object')
+ >>> Redraw()
+ >>>
+ >>> bye
+
+ bye...
+
+For more information see http://formgames.org/blender/command-port
+
+# fin.
Index: source/blender/commandport/utilities/test/bcp_package_test.c
===================================================================
--- source/blender/commandport/utilities/test/bcp_package_test.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/test/bcp_package_test.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,52 @@
+/*
+ * $Id: bcp_package_test.c, v 1.0 2007/06/13, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Main function for testing the
+ * Blender Commandport Package functionality
+ * using the tests defined in ../src/bcp_package.c
+ *
+ * usage:
+ *
+ * cd <path to blender source tree>/blender/source/blender/commandport/utilities/test/
+ * scons -f SConstruct.bcp_package.test
+ * ./test
+ *
+ */
+
+#include <stdio.h>
+
+#include "bcp_package.h"
+
+int main(int argc, char *argv[])
+{
+ /* test */
+ bcp_package_test();
+}
+
+/* fin */
Index: source/blender/commandport/utilities/test/SConstruct.bcp_package.test
===================================================================
--- source/blender/commandport/utilities/test/SConstruct.bcp_package.test (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/test/SConstruct.bcp_package.test (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,52 @@
+# -*- mode: python -*-
+#
+# $Id: SConstruct.bcp_package.test, v 1.0 2007/06/13, dietrich, tokyo $
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2007 by the Blender Foundation.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Author: Dietrich Bollmann
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+# A simple build file for testing the
+# Blender Commandport Package functionality
+# using the tests defined in bcp_package_test.c and ../src/bcp_package.c
+#
+# usage:
+#
+# cd <path to blender source tree>/blender/source/blender/commandport/utilities/test/
+# scons -f SConstruct.bcp_package.test
+# ./test
+
+env = Environment()
+
+env.Append(CPPPATH = ['../include'])
+
+test = env.Program('test', [
+ '../src/bcp_package.c',
+ 'bcp_package_test.c'
+ ])
+
+Default(test)
+
+# fin.
Index: source/blender/commandport/utilities/include/bcp_debug.h
===================================================================
--- source/blender/commandport/utilities/include/bcp_debug.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/bcp_debug.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,72 @@
+/*
+ * $Id: bcp_debug.h, v 1.0 2007/05/30, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Module for initializing, storing and querying
+ * the Blender command port debug level.
+ *
+ * The command port can be made to print debug messages in different
+ * verbosity levels via the command line option `--debug bcp:<level>'.
+ * `<level>' can be one of 1, 2, 3, 4.
+ *
+ * For more information see the debug help text defined in function
+ * `print_help_debug()' in file `../../blender/src/bcp_handle_client.c'
+ * or call Blender with the option `-hd' / `--help=debug'.
+ *
+ * For the command port debug code search sources for `debug("bcp")'
+ * and `bcp_debug()'.
+ *
+ * source file: ../src/bcp_debug.c
+ *
+ */
+
+#ifndef BCP_DEBUG_H
+#define BCP_DEBUG_H
+
+/**
+ Set BCP debug level.
+
+ This option currently is used in
+ - blender/source/blender/commandport/blender/src/commandport.c and
+ - blender/source/blender/commandport/blash/src/blash.c
+ to init the debug level for the Blender command port server / client
+ respectively.
+*/
+void bcp_set_debug_level(int level);
+
+/**
+ Returns the debug level for the Blender command port.
+
+ Used in all functions printing debug messages
+ which depend on the debug level.
+*/
+int bcp_debug();
+
+#endif /* BCP_DEBUG_H */
+
+/* fin */
Index: source/blender/commandport/utilities/include/bcp_meta_commands.h
===================================================================
--- source/blender/commandport/utilities/include/bcp_meta_commands.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/bcp_meta_commands.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,85 @@
+/*
+ * $Id: bcp_meta_commands.h, v 1.0 2007/06/13, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * The Meta Commands class defines codes used by the command port.
+ *
+ * Different classes of codes / meta commands exist:
+ *
+ * - codes to tell the Blender Python interpreter how to evaluate the
+ * messages send by a client
+ *
+ * - codes to change the Python print mode
+ *
+ * - codes to reset the command port
+ *
+ * - codes expressing the result of the evaluation of Python command string
+ *
+ * - codes to tell the client if the send command string is a complete or
+ * incomplete Python command sequence
+ *
+ * included by the following files:
+ *
+ * - ../../blender/src/bcp_python.c
+ * - ../src/bcp_shell.c
+ *
+ */
+
+#ifndef BCP_META_COMMANDS_H
+#define BCP_META_COMMANDS_H
+
+/* BCP input modes */
+#define BCP_SINGLE_MODE_COMMAND 'S' /* single command input mode */
+#define BCP_EVAL_MODE_COMMAND 'E' /* eval command input mode */
+#define BCP_FILE_MODE_COMMAND 'F' /* file command input mode (default) */
+
+/* result print modes */
+#define BCP_REPR_PRINT_MODE_COMMAND 'r' /* reset the command port (default) */
+#define BCP_STR_PRINT_MODE_COMMAND 's' /* reset the command port */
+
+/* reset the BCP namespace */
+#define BCP_RESET_COMMAND 'R' /* reset the command port */
+
+/**
+ Result codes -
+*/
+#define BCP_RESULT_CODE_SUCCESS 0 /* The python evaluation was successful */
+#define BCP_RESULT_CODE_INCOMPLETE_INPUT 1 /* The entered python code is incomplete
+ and the blender server waits for more
+ input lines to complete the input */
+#define BCP_RESULT_CODE_ERROR 2 /* An error occured during the
+ evaluation ot the python code */
+#define BCP_RESULT_CODE_UNDEFINED 3 /* This code should never be returned
+ and indicates that an unexpecte result
+ was returned by the Python interpreter */
+#define BCP_RESULT_CODE_EMPTY_INPUT 4 /* Returned if the shell input was emtpy */
+
+#endif /* BCP_META_COMMANDS_H */
+
+/* fin */
+
Index: source/blender/commandport/utilities/include/bcp_defaults.h
===================================================================
--- source/blender/commandport/utilities/include/bcp_defaults.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/bcp_defaults.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,47 @@
+/*
+ * $Id: bcp_defaults.h, v 1.0 2007/06/13, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Default definitions for the Blender Command Port.
+ *
+ */
+
+#ifndef BCP_DEFAULTS_H
+#define BCP_DEFAULTS_H
+
+/**
+ Defaults
+*/
+
+/* IP and port */
+#define BCP_DEFAULT_IP "127.0.0.1"
+#define BCP_DEFAULT_PORT 5555
+
+#endif /* BCP_DEFAULTS_H */
+
+/* fin */
Index: source/blender/commandport/utilities/include/bcp_shell.h
===================================================================
--- source/blender/commandport/utilities/include/bcp_shell.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/bcp_shell.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,90 @@
+/*
+ * $Id: bcp_shell.h, v 1.0 2007/05/31, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Defines the interactive shell called by blash's `main()' function.
+ *
+ * source file: ../src/bcp_shell.c
+ *
+ */
+
+#ifndef BCP_SHELL_H
+
+/**
+ Shell Evaluation Modes
+
+ Three different modes can be used from the interactive bash shell:
+
+ * BCP_SINGLE_MODE
+
+ This is the normal shell mode:
+ Python commands are entered line by line.
+ If a single line can be interpreted as complete python command,
+ it is evaluated and the result is printed;
+ if the first line doesn't correspond to a complete python command,
+ all lines following this first line are stored until an empty line
+ is entered. At this point all lines together are evaluated and the
+ result is printed to the shell.
+
+ * BCP_EVAL_MODE
+
+ The entered string is interpreted as a complete, isolated Python expression and
+ evaluated by the python interpreter. The result is printed to the shell.
+
+ * BCP_FILE_MODE
+
+ A sequences of Python statements can be entered and executed by the Python interpreter. No result is printed.
+ This mode is usefull when a full program is entered at once. It is also useful for
+ executing definitions which contain blank lines.
+
+ For more informatin concerning the shell evaluation modes compare the
+ documentation in `bcp_python.h' and `bcp_python.c'.
+
+*/
+#define BCP_SINGLE_MODE 0
+#define BCP_EVAL_MODE 1
+#define BCP_FILE_MODE 2
+
+/**
+ Open a new Blender command port shell.
+*/
+void bcp_shell(char* server_IP_address, unsigned short server_port, int mode);
+
+/**
+ Open a new Blender command port shell.
+
+ If the connection to the Blender server could not been established immediately,
+ retry up to `retries' times. Sleep `retry_sleeptime' seconds before trying again.
+*/
+void bcp_shell_wait(char* server_IP_address, unsigned short server_port, int mode,
+ int retries, float retry_sleeptime);
+
+#define BCP_SHELL_H
+#endif /* BCP_SHELL_H */
+
+/* fin */
Index: source/blender/commandport/utilities/include/fsleep.h
===================================================================
--- source/blender/commandport/utilities/include/fsleep.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/fsleep.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,50 @@
+/*
+ * $Id: fsleep.h, v 1.0 2007/05/19, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * sleep for an amount of time - the time might be any fraction of seconds given as float.
+ *
+ * source file: ../src/fsleep.c
+ *
+ */
+
+#ifndef FSLEEP_H
+#define FSLEEP_H
+
+/**
+ sleep for an amount of time -
+
+ the time might be any fraction of seconds given as float.
+*/
+int fsleep(float seconds);
+
+#endif /* FSLEEP_H */
+
+/* fin */
+
+
Index: source/blender/commandport/utilities/include/string_buffer_test.h
===================================================================
--- source/blender/commandport/utilities/include/string_buffer_test.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/string_buffer_test.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,48 @@
+/*
+ * $Id: string_buffer_test.h, v 1.0 2007/05/30, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Some functions to test the `string_buffer' functions.
+ *
+ * see: `../include/string_buffer.h' and `../src/string_buffer.c'
+ *
+ * source file: ../src/string_buffer_test.c
+ *
+ */
+
+#ifndef STRING_BUFFER_TEST_H
+#define STRING_BUFFER_TEST_H
+
+/**
+ main string_buffer testing function...
+*/
+void string_buffer_test();
+
+#endif /* STRING_BUFFER_TEST_H */
+
+/* fin */
Index: source/blender/commandport/utilities/include/bcp_package.h
===================================================================
--- source/blender/commandport/utilities/include/bcp_package.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/bcp_package.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,162 @@
+/*
+ * $Id: bcp_package.h, v 1.0 2007/05/31, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Functions to pack and unpack integers, strings and commands into a
+ * single string for sending them over the command port socket.
+ *
+ * source file: ../src/bcp_package.c
+ *
+ */
+
+#ifndef BCP_PACKAGE_H
+#define BCP_PACKAGE_H
+
+/* types */
+#define BCP_PACKAGE_TYPE_EMPTY 'e'
+#define BCP_PACKAGE_TYPE_UNDEFINED 'u'
+#define BCP_PACKAGE_TYPE_INT 'i'
+#define BCP_PACKAGE_TYPE_STRING 's'
+#define BCP_PACKAGE_TYPE_COMMAND 'c'
+
+/**
+ bcp_package type definition
+*/
+typedef struct bcp_package_struct *bcp_package;
+
+/**
+ Make a new package.
+*/
+bcp_package bcp_package_new();
+
+/**
+ Delete a package.
+*/
+void bcp_package_delete(bcp_package package);
+
+/**
+ Empty a package.
+*/
+void bcp_package_make_empty(bcp_package package);
+
+/**
+ Add integer.
+*/
+void bcp_package_add_int(bcp_package package, int i);
+
+/**
+ Add string.
+*/
+void bcp_package_add_string(bcp_package package, char* s);
+
+/**
+ Add command.
+*/
+void bcp_package_add_command(bcp_package package, char command);
+
+/**
+ Convert the package to a string representation
+ which can be stored / send via the internet ....
+
+ Note:
+ The memory for the string returned by this function
+ has to be freed by the caller!
+*/
+char* bcp_package_pack_allocate(bcp_package package);
+
+/**
+ Unpack the elements in the string `packed'
+ and return the result package.
+
+ Note:
+ The string `is manipulated' and not printable as
+ one string after calling this function.
+ Note also that no new memory is allocated
+ for unpacked string elements.
+ `packed' therefore only can be freed after
+ the processing of the unpacked elements is finished.
+*/
+bcp_package bcp_package_unpack(char* packed);
+
+
+/* =========================================================
+ * BCP package enumerator functions
+ * ---------------------------------------------------------
+ */
+
+/**
+ bcp_package enumerator type definition
+*/
+typedef struct bcp_package_enumerator_struct *bcp_package_enumerator;
+
+/**
+ Make a new package enumerator.
+*/
+bcp_package_enumerator bcp_package_enumerator_new(bcp_package p);
+
+/**
+ Delete a package enumerator.
+*/
+void bcp_package_enumerator_delete(bcp_package_enumerator enumerator);
+
+/**
+ Reset enumerator.
+*/
+void bcp_package_enumerator_reset(bcp_package_enumerator e);
+
+/**
+ Get next element in package.
+*/
+void* bcp_package_enumerator_get_next_element(bcp_package_enumerator e, char* type);
+
+/**
+ Debugging function:
+ Dump an unpacked package
+*/
+void dump_package(bcp_package p);
+
+/* =========================================================
+ * Test functions
+ * ---------------------------------------------------------
+ */
+
+/* to build the test functions, uncomment the following define: */
+#define BCP_PACKAGE_TEST
+
+#ifdef BCP_PACKAGE_TEST
+
+/**
+ test
+*/
+void bcp_package_test();
+
+#endif /* BCP_PACKAGE_TEST */
+
+#endif /* BCP_PACKAGE_H */
+
+/* fin */
Index: source/blender/commandport/utilities/include/string_buffer.h
===================================================================
--- source/blender/commandport/utilities/include/string_buffer.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/string_buffer.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,187 @@
+/*
+ * $Id: string_buffer.h, v 1.0 2007/05/30, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * A buffer to save c strings in chunks.
+ *
+ * Every string chunk (or slice) appended (or prepended) to the
+ * buffer is copied into newly allocated memory which is appended (or
+ * prepended) to a queue. Only when the whole string is needed (or
+ * some other operation is performed for which the whole string is
+ * needed), the slices are copied into a single newly allocated c
+ * buffer.
+ *
+ * source file: ../src/string_buffer.c
+ *
+ */
+
+#ifndef STRING_BUFFER_H
+#define STRING_BUFFER_H
+
+typedef struct string_buffer_struct *string_buffer;
+
+/**
+ Make a new text buffer.
+*/
+string_buffer string_buffer_new();
+
+/**
+ Delete a text buffer.
+*/
+void string_buffer_delete(string_buffer buffer);
+
+/**
+ Return true if the string buffer is empty and false if not.
+*/
+int string_buffer_is_empty(string_buffer buffer);
+
+/**
+ Empty a text buffer.
+*/
+void string_buffer_make_empty(string_buffer buffer);
+
+/**
+ Prepend a string to a string buffer.
+*/
+void string_buffer_prepend(string_buffer buffer, char* str);
+
+/**
+ Append a newline caracter to 'str' and
+ prepend the result to a string buffer.
+*/
+void string_buffer_prepend_newline(string_buffer buffer, char* str);
+
+/**
+ Append a line to a text buffer.
+*/
+void string_buffer_append(string_buffer buffer, char* str);
+
+/**
+ Append a string and a newline caracter to a string buffer.
+*/
+void string_buffer_append_newline(string_buffer buffer, char* str);
+
+/**
+ Get the length of a string buffer.
+*/
+int string_buffer_get_length(string_buffer buffer);
+
+/**
+ Cleanup a string buffer.
+ Returns the length of the string buffer.
+
+ Append the string slices constituting a string buffer
+ into one single string slice.
+*/
+int string_buffer_cleanup(string_buffer buffer);
+
+/**
+ Like strcmp - but for string buffers :)
+*/
+int string_buffer_compare_to_string(string_buffer buffer, char* str);
+
+/**
+ Check if the string buffer starts with the given prefix.
+ Return 1 if this is the case and 0 otherwise.
+*/
+int string_buffer_starts_with_prefix(string_buffer buffer, char* prefix);
+
+/**
+ Check if the string buffer is empty
+ or only contains white space.
+*/
+int string_buffer_is_empty_or_white_space_string(string_buffer buffer);
+
+/**
+ Transform a string buffer into a newly allocated character array.
+ A pointer to the allocated char array is returned.
+ The length of the string is returned as second parameter.
+*/
+char* string_buffer_to_char_array_allocate(string_buffer buffer, int* length);
+
+/**
+ Read a single line from stdin.
+ The function returns the accumulated length of lines in 'buffer'.
+*/
+int string_buffer_read_line_from_stdin(string_buffer buffer);
+
+/**
+ Get the line prompt.
+ The returned string is a copy of the original prompt in newly allocated memory.
+*/
+char* string_buffer_get_line_prompt_allocate(string_buffer buffer);
+
+/**
+ Get the text prompt.
+ The returned string is a copy of the original prompt in newly allocated memory.
+*/
+char* string_buffer_get_text_prompt_allocate(string_buffer buffer);
+
+/**
+ Get the text coninue prompt.
+ The returned string is a copy of the original prompt in newly allocated memory.
+*/
+char* string_buffer_get_text_coninue_prompt_allocate(string_buffer buffer);
+
+/**
+ Set the read line prompt.
+*/
+void string_buffer_set_line_prompt(string_buffer buffer, char *prompt);
+
+/**
+ Read a text (a sequence of lines) from stdin.
+ The input is terminated by a line containing only a dot character '.'.
+
+ The function returns the accumulated length of all read lines.
+*/
+int string_buffer_read_text_from_stdin(string_buffer buffer);
+
+/**
+ Set the read text prompt.
+*/
+void string_buffer_set_text_prompt(string_buffer buffer, char *prompt);
+
+/**
+ Set the read text continue prompt.
+*/
+void string_buffer_set_text_coninue_prompt(string_buffer buffer, char *prompt);
+
+/**
+ Print a text buffer.
+*/
+void string_buffer_print(string_buffer buffer);
+
+/**
+ Dump the inner structure of a string buffer to stdout.
+ Note: This function is only for use during development.
+*/
+void string_buffer_dump(string_buffer buffer);
+
+#endif /* STRING_BUFFER_H */
+
+/* fin */
Index: source/blender/commandport/utilities/include/hexdump_string.h
===================================================================
--- source/blender/commandport/utilities/include/hexdump_string.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/hexdump_string.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,128 @@
+/*
+ * $Id: hexdump_string.h, v 1.0 2007/05/30, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Hexdump functions to debug the Blender Command Port...
+ *
+ * source file: ../src/hexdump_string.c
+ *
+ */
+
+#ifndef HEXDUMP_STRING_H
+#define HEXDUMP_STRING_H
+
+/**
+ Print ascii code table.
+
+ +---+----------------------------------------------------------------+
+ | \ | 0 1 2 3 4 5 6 7 8 9 A B C D E F |
+ +---+----------------------------------------------------------------+
+ | 0 | NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI |
+ | 1 | DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US |
+ | 2 | SP ! " # $ % & ' ( ) * + , - . / |
+ | 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
+ | 4 | @ A B C D E F G H I J K L M N O |
+ | 5 | P Q R S T U V W X Y Z [ \ ] ^ _ |
+ | 6 | ` a b c d e f g h i j k l m n o |
+ | 7 | p q r s t u v w x y z { | } ~ DEL |
+ +---+----------------------------------------------------------------+
+*/
+void print_ascii_code_table();
+
+/**
+ Print the code table used in last column by `hexdump_string()'.
+
+ The character codes are represented by the following characters:
+
+ - the character represented by the code itself - if printable
+ - '>' for tab (0x09 - ascii: HT = Horizontal Tab)
+ - '^' for newline (0x0a - ascii: LF = Line Feed)
+ - '0' for the null character (0x00 - ascii: NUL = Null char.)
+ - '?' for things which might cause problems - and ? itself :)
+
+ +---+----------------------------------------------------------------+
+ | \ | 0 1 2 3 4 5 6 7 8 9 A B C D E F |
+ +---+----------------------------------------------------------------+
+ | 0 | 0 ? ? ? ? ? ? ? ? > ^ ? ? ? ? ? |
+ | 1 | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
+ | 2 | SP ! " # $ % & ' ( ) * + , - . / |
+ | 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
+ | 4 | @ A B C D E F G H I J K L M N O |
+ | 5 | P Q R S T U V W X Y Z [ \ ] ^ _ |
+ | 6 | ` a b c d e f g h i j k l m n o |
+ | 7 | p q r s t u v w x y z { | } ~ ? |
+ +---+----------------------------------------------------------------+
+*/
+void print_printable_dump_code_table();
+
+/**
+ Dump the hex codes a string is made of.
+
+ Example:
+
+ The string
+ "eins zwei drei vier fuenf sechs sieben, tab: '\t', newline: '\n' and - to terminate the string - the nullchar: "
+ is dumped as:
+
+ ==============================================================================
+ addr 0 1 2 3 4 5 6 7 8 9 A B C D E F | printable repr.|
+ ------------------------------------------------------------+----------------+
+ 00000000 65 69 6e 73 20 7a 77 65 69 20 64 72 65 69 20 76 |eins zwei drei v|
+ 00000010 69 65 72 20 66 75 65 6e 66 20 73 65 63 68 73 20 |ier fuenf sechs |
+ 00000020 73 69 65 62 65 6e 2c 20 74 61 62 3a 20 27 09 27 |sieben, tab: '>'|
+ 00000030 2c 20 6e 65 77 6c 69 6e 65 3a 20 27 0a 27 20 61 |, newline: '^' a|
+ 00000040 6e 64 20 2d 20 74 6f 20 74 65 72 6d 69 6e 61 74 |nd - to terminat|
+ 00000050 65 20 74 68 65 20 73 74 72 69 6e 67 20 2d 20 74 |e the string - t|
+ 00000060 68 65 20 6e 75 6c 6c 63 68 61 72 3a 20 00 |he nullchar: 0|
+ ==============================================================================
+*/
+void hexdump_string(char* prefix, char* string);
+
+/**
+ Dump the hex codes a string is made of.
+
+ Simple formatting - example:
+
+ The string "eins zwei drei vier fuenf sechs sieben."
+ is dumped as:
+
+ 65 69 6e 73 20 7a 77 65 69 20 64 72 65 69 20 76
+ 69 65 72 20 66 75 65 6e 66 20 73 65 63 68 73 20
+ 73 69 65 62 65 6e 2e 00
+*/
+void simple_hexdump_string(char* string);
+
+/**
+ Test the hexdump functions.
+*/
+void hexdump_string_test();
+
+#endif /* HEXDUMP_STRING_H */
+
+/* fin */
+
Index: source/blender/commandport/utilities/include/message_handler.h
===================================================================
--- source/blender/commandport/utilities/include/message_handler.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/message_handler.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,69 @@
+/*
+ * $Id: message_handler.h, v 1.0 2007/06/13, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * The message handler class implements the protocol used by the
+ * commandport for exchanging text messages via a socket connection.
+ * A message is defined as a string of an arbitrary length terminated
+ * with a '\0' character.
+ *
+ * source file: ../src/message_handler.c
+ *
+ */
+
+#ifndef MESSAGE_HANDLER_H
+#define MESSAGE_HANDLER_H
+
+typedef struct message_handler_data* message_handler;
+
+#include "error_codes.h"
+
+/**
+ Make a new message socket handler.
+*/
+message_handler message_handler_new(int socket);
+
+/**
+ Delete a message socket handler.
+*/
+void message_handler_delete(message_handler handler);
+
+/**
+ Send a message.
+ */
+void message_handler_send_message(message_handler handler, char* message);
+
+/**
+ Receive a message.
+ The return value NULL signals the end of the client connection.
+*/
+char* message_handler_receive_message_allocate(message_handler handler);
+
+#endif /* MESSAGE_HANDLER_H */
+
+/* fin */
Index: source/blender/commandport/utilities/include/message_client.h
===================================================================
--- source/blender/commandport/utilities/include/message_client.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/message_client.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,84 @@
+/*
+ * $Id: message_client.h, v 1.0 2007/06/13, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * The message client class is the central part of a Blender Command
+ * Port client written in c. It implements the functionality for
+ * connecting and disconnecting to / from a Blender Server and for
+ * sending and receiving text messages.
+ *
+ * source file: ../src/message_client.c
+ *
+ */
+
+#ifndef MESSAGE_CLIENT_H
+#define MESSAGE_CLIENT_H
+
+#include "error_codes.h"
+
+typedef struct message_client_struct *message_client;
+
+/**
+ Make a new message client.
+*/
+message_client message_client_new(char *server_IP_address, unsigned short server_port);
+
+/**
+ Make a new message client.
+
+ If the connection could not been established immediately, retry up to `retries' times.
+ Sleep `retry_sleeptime' seconds before trying again.
+*/
+message_client message_client_new_wait(char *server_IP_address, unsigned short server_port,
+ int retries, float retry_sleeptime);
+
+/**
+ Delete a message client.
+*/
+void message_client_delete(message_client client);
+
+/**
+ Send a message.
+ */
+void message_client_send(message_client client, char* message);
+
+/**
+ Receive a message.
+ The return value NULL signals the end of the client connection.
+ */
+char* message_client_receive_allocate(message_client client);
+
+/**
+ Send a message and return the answer.
+ */
+char* message_client_send_receive_allocate(message_client client, char* message);
+
+#endif /* MESSAGE_CLIENT_H */
+
+/* fin */
+
Index: source/blender/commandport/utilities/include/error_codes.h
===================================================================
--- source/blender/commandport/utilities/include/error_codes.h (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/include/error_codes.h (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,52 @@
+/*
+ * $Id: error_codes.h, v 1.0 2007/06/13, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Blender Command Port error codes.
+ *
+ */
+
+#ifndef ERROR_CODES_H
+#define ERROR_CODES_H
+
+#define ERROR_TEXTBUFFER 2
+#define ERROR_MEMORY 3
+#define ERROR_RECEIVE 4
+#define ERROR_SEND 5
+#define ERROR_SOCKET 6
+#define ERROR_CONNECTION 7
+#define ERROR_SYNCHRONIZATION 8
+#define ERROR_UNKNOWN_TYPE 9
+#define ERROR_PARSER 10
+#define ERROR_IN_BCP_PROTOCOL 11
+#define ERROR_BCP_PYTHON 12
+
+#endif /* ERROR_CODES_H */
+
+/* fin */
+
Index: source/blender/commandport/utilities/SConscript
===================================================================
--- source/blender/commandport/utilities/SConscript (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/SConscript (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,37 @@
+# -*- mode: python -*-
+#
+# $Id: SConscript, v 1.0 2007/06/13, dietrich, tokyo $
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2007 by the Blender Foundation.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Author: Dietrich Bollmann
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+# Build file for the Blender Commandport Utilities.
+
+SConscript([
+ 'src/SConscript',
+ ])
+
+# fin.
Index: source/blender/commandport/utilities/src/fsleep.c
===================================================================
--- source/blender/commandport/utilities/src/fsleep.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/fsleep.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,58 @@
+/*
+ * $Id: fsleep.c, v 1.0 2007/05/19, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * sleep for an amount of time - the time might be any fraction of seconds given as float.
+ *
+ * header file: ../include/fsleep.h
+ *
+ */
+
+#include <stdlib.h>
+
+/**
+ sleep for an amount of time -
+
+ the time might be any fraction of seconds given as float.
+*/
+int fsleep(float seconds)
+{
+ /* separate in seconds and nanoseconds */
+ int sec = (int) seconds;
+ int nsec = (int) ((seconds - (float) sec) * 1.0e9);
+
+ /* fill timespec to pass to nanosleep() */
+ struct timespec requested_time, remaining;
+ requested_time.tv_sec = sec;
+ requested_time.tv_nsec = nsec;
+
+ /* sleep */
+ nanosleep(&requested_time, &remaining);
+}
+
+/* fin */
Index: source/blender/commandport/utilities/src/string_buffer_test.c
===================================================================
--- source/blender/commandport/utilities/src/string_buffer_test.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/string_buffer_test.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,123 @@
+/*
+ * $Id: string_buffer_test.c, v 1.0 2007/05/30, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Some functions to test the `string_buffer' functions.
+ *
+ * see: `../include/string_buffer.h' and `../src/string_buffer.c'
+ *
+ * header file: ../include/string_buffer_test.h
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "string_buffer.h"
+
+void string_buffer_test_append()
+{
+ string_buffer text = string_buffer_new();
+
+ string_buffer_append(text, "hi die :)\n");
+ string_buffer_append(text, " was");
+ string_buffer_append(text, " ");
+ string_buffer_append(text, "macht\n");
+ string_buffer_append(text, " das Leben?\n");
+
+ string_buffer_print(text);
+
+ string_buffer_delete(text);
+}
+
+void string_buffer_cleanup_test()
+{
+ /* init buffer */
+ string_buffer buffer = string_buffer_new();
+
+ string_buffer_append(buffer, "hi die :)\n");
+ string_buffer_append(buffer, " was");
+ string_buffer_append(buffer, " ");
+ string_buffer_append(buffer, "macht\n");
+ string_buffer_append(buffer, " das Leben?\n");
+
+ /* clean up the buffer buffer */
+ /* DEBUG */
+ printf("===\n");
+ printf("Buffer before cleanup (length: %d):\n", string_buffer_get_length(buffer));
+ printf("===\n");
+ string_buffer_print(buffer);
+ string_buffer_dump(buffer);
+
+ int length = string_buffer_cleanup(buffer);
+
+ /* DEBUG */
+ printf("Buffer after cleanup (length: %d):\n", string_buffer_get_length(buffer));
+ printf("===\n");
+ string_buffer_print(buffer);
+ string_buffer_dump(buffer);
+
+ string_buffer_delete(buffer);
+}
+
+/**
+ Reading a sequende of non-empty lines from stdin
+ The input is terminated by entering an empty line.
+ */
+void test_string_buffer_read_text_from_stdin()
+{
+ /* allocate a string buffer for the lines to read */
+ string_buffer paragraph = string_buffer_new();
+
+ /* read a paragraph from stdin */
+ int length = string_buffer_read_text_from_stdin(paragraph);
+ printf("\n");
+
+ /* print the paragraph */
+ printf("The paragraph is %d characters long...\n", length);
+ printf("---\n");
+ string_buffer_dump(paragraph);
+ string_buffer_print(paragraph);
+ printf("---\n");
+ printf("\n");
+}
+
+/**
+ main string_buffer testing function...
+*/
+void string_buffer_test()
+{
+ string_buffer_test_append();
+ string_buffer_cleanup_test();
+ test_string_buffer_read_text_from_stdin();
+
+ printf("\nend of string_buffer tests...\n\n");
+}
+
+/* fin */
Index: source/blender/commandport/utilities/src/string_buffer.c
===================================================================
--- source/blender/commandport/utilities/src/string_buffer.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/string_buffer.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,690 @@
+/*
+ * $Id: string_buffer.c, v 1.0 2007/05/30, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * A buffer to save c strings in chunks.
+ *
+ * Every string chunk (or slice) appended (or prepended) to the
+ * buffer is copied into newly allocated memory which is appended (or
+ * prepended) to a queue. Only when the whole string is needed (or
+ * some other operation is performed for which the whole string is
+ * needed), the slices are copied into a single newly allocated c
+ * buffer.
+ *
+ * header file: ../include/string_buffer.h
+ *
+ */
+
+/* string_buffer.c - Dietrich Bollmann */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h> /* isspace(c) */
+#include <stdlib.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+
+#include "error_codes.h"
+
+#include "string_buffer.h"
+
+typedef struct string_slice_struct *string_slice;
+typedef struct string_slice_struct {
+ char* str;
+ string_slice next;
+} string_slice_struct;
+
+typedef struct string_buffer_struct {
+ string_slice first;
+ string_slice last;
+ char* line_prompt;
+ char* text_prompt;
+ char* text_coninue_prompt;
+} string_buffer_struct;
+
+#define LINE_PROMPT ">>> "
+#define TEXT_PROMPT ">>> "
+#define TEXT_CONTINUE_PROMPT "... "
+
+/* Declaration of utility functions */
+void set_prompt(char** target, char* prompt);
+string_slice new_string_slice(char* str, int append_newline_flag);
+char* copy_string_allocate(char* string);
+
+/**
+ Make a new string buffer.
+*/
+string_buffer string_buffer_new()
+{
+ string_buffer buffer;
+ buffer = (string_buffer) malloc(sizeof(string_buffer_struct));
+
+ if (buffer == NULL) {
+ fprintf(stderr, "Couldn't allocate memory for new string_buffer!\n");
+ exit(ERROR_MEMORY);
+ }
+
+ buffer->first = (string_slice) NULL;
+ buffer->last = (string_slice) NULL;
+
+ /* prompts used by the input functions */
+ /* initializing them with NULL -
+ required by the 'string_buffer_set_*_prompt' function
+ */
+ buffer->line_prompt = NULL;
+ buffer->text_prompt = NULL;
+ buffer->text_coninue_prompt = NULL;
+ /* init with defaults */
+ string_buffer_set_line_prompt( buffer, LINE_PROMPT );
+ string_buffer_set_text_prompt( buffer, TEXT_PROMPT );
+ string_buffer_set_text_coninue_prompt( buffer, TEXT_CONTINUE_PROMPT );
+
+ return buffer;
+}
+
+/**
+ Delete a string buffer.
+*/
+void string_buffer_delete(string_buffer buffer)
+{
+ /* empty the buffer - free all slices */
+ string_buffer_make_empty(buffer);
+
+ /* free the momory for the prompts */
+ free(buffer->line_prompt);
+ free(buffer->text_prompt);
+ free(buffer->text_coninue_prompt);
+
+ /* free string buffer structure */
+ free(buffer);
+}
+
+/**
+ Get the line prompt.
+ The returned string is a copy of the original prompt in newly allocated memory.
+*/
+char* string_buffer_get_line_prompt_allocate(string_buffer buffer)
+{
+ return copy_string_allocate(buffer->line_prompt);
+}
+
+/**
+ Get the text prompt.
+ The returned string is a copy of the original prompt in newly allocated memory.
+*/
+char* string_buffer_get_text_prompt_allocate(string_buffer buffer)
+{
+ return copy_string_allocate(buffer->text_prompt);
+}
+
+/**
+ Get the text coninue prompt.
+ The returned string is a copy of the original prompt in newly allocated memory.
+*/
+char* string_buffer_get_text_coninue_prompt_allocate(string_buffer buffer)
+{
+ return copy_string_allocate(buffer->text_coninue_prompt);
+}
+
+/**
+ Set a prompt.
+*/
+void set_prompt(char** target, char* prompt)
+{
+ /* if defined, free memory of former prompt */
+ if (*target != NULL) { free(*target); }
+
+ /* copy the prompt */
+ char* newprompt = copy_string_allocate(prompt);
+
+ /* setting new prompt */
+ *target = newprompt;
+}
+
+/**
+ Set the read line prompt.
+*/
+void string_buffer_set_line_prompt(string_buffer buffer, char *prompt)
+{
+ set_prompt(&buffer->line_prompt, prompt);
+}
+
+/**
+ Set the read text prompt.
+*/
+void string_buffer_set_text_prompt(string_buffer buffer, char *prompt)
+{
+ set_prompt(&buffer->text_prompt, prompt);
+}
+
+/**
+ Set the read text continue prompt.
+*/
+void string_buffer_set_text_coninue_prompt(string_buffer buffer, char *prompt)
+{
+ set_prompt(&buffer->text_coninue_prompt, prompt);
+}
+
+/**
+ Return 1 if the string buffer is empty and 0 if not.
+*/
+int string_buffer_is_empty(string_buffer buffer)
+{
+ return ((buffer->first == (string_slice) NULL) &&
+ (buffer->last == (string_slice) NULL));
+}
+
+/**
+ Empty a string buffer.
+*/
+void string_buffer_make_empty(string_buffer buffer)
+{
+ /* free the slice buffers */
+ string_slice next;
+ string_slice slice = buffer->first;
+ while(slice != NULL) {
+ /* save pointer to the next slice buffer */
+ next = slice->next;
+
+ /* free the string holding the slice */
+ free(slice->str);
+
+ /* free the slice struct itself */
+ free(slice);
+
+ /* get the next slice */
+ slice = next;
+ }
+
+ /* finally set the string slice pointers to NULL
+ (signifying a string buffer to be empty)
+ */
+ buffer->first = (string_slice) NULL;
+ buffer->last = (string_slice) NULL;
+}
+
+/**
+ Append a string_slice to a string_buffer.
+
+ Note:
+ Only for internal use: No new memory is allocated for the string_slice!
+*/
+void string_buffer_append_string_slice(string_buffer buffer, string_slice sliceBuffer)
+{
+ /* Ensure that the next pointer of the appended slice is NULL */
+ sliceBuffer->next = (string_slice) NULL; /* The new slice is the last one */
+
+ /* Append the new string_slice buffer to 'buffer' */
+ if (buffer->first == NULL) {
+ buffer->first = sliceBuffer;
+ } else {
+ buffer->last->next = sliceBuffer;
+ }
+ buffer->last = sliceBuffer;
+}
+
+/**
+ Prepend a string_slice to a string_buffer.
+
+ Note:
+ Only for internal use: No new memory is allocated for the string_slice!
+*/
+void string_buffer_prepend_string_slice(string_buffer buffer, string_slice sliceBuffer)
+{
+ /* The former first slice now is the second one
+ works also for an empty buffer (buffer->first == NULL) */
+ sliceBuffer->next = buffer->first;
+
+ /* The new slice is the new first one */
+ buffer->first = sliceBuffer;
+
+ /* If the string buffer is empty (buffer->last == NULL),
+ the new slice is also the last one */
+ if (buffer->last == NULL) {
+ buffer->last = sliceBuffer;
+ }
+}
+
+
+/**
+ Allocate a new string slice for the string parameter.
+ If the 'append_newline_flag' is set, append a newline to 'string'.
+*/
+string_slice new_string_slice(char* str, int append_newline_flag)
+{
+ /* Make a new string_slice for the string */
+ string_slice sliceBuffer;
+ sliceBuffer = (string_slice) malloc(sizeof(string_slice_struct));
+
+ if (sliceBuffer == NULL) {
+ fprintf(stderr, "Couldn't allocate memory for new slice in string_buffer!\n");
+ exit(ERROR_MEMORY);
+ }
+
+ /* Copy the string into the new slice struct */
+
+ /* allocate memory and copy the string */
+ int length = strlen(str);
+ if (append_newline_flag) {
+ length++; /* add 1 for the newline */
+ }
+ char* newstr = (char*) malloc((length + 1) * sizeof(char));
+ memcpy(newstr, str, length);
+ if (append_newline_flag) {
+ newstr[length - 1]= '\n'; /* append the newline */
+ }
+ newstr[length]= '\0';
+
+ /* hang the string into the new slice buffer */
+ sliceBuffer->str = newstr;
+
+ /* No next slice for the moment -
+ initializing the pointer to the next slice with NULL */
+ sliceBuffer->next = (string_slice) NULL;
+
+ /* return the new string slice */
+ return sliceBuffer;
+}
+
+
+/**
+ Append a string to a string buffer.
+*/
+void string_buffer_append(string_buffer buffer, char* str)
+{
+ /* Make a new string_slice for the string */
+ string_slice sliceBuffer = new_string_slice(str, 0);
+
+ /* append the new string_slice to 'buffer' */
+ string_buffer_append_string_slice(buffer, sliceBuffer);
+}
+
+
+/**
+ Append a string and a newline caracter to a string buffer.
+*/
+void string_buffer_append_newline(string_buffer buffer, char* str)
+{
+ /* Make a new string_slice for the string */
+ string_slice sliceBuffer = new_string_slice(str, 1);
+
+ /* append the new string_slice to 'buffer' */
+ string_buffer_append_string_slice(buffer, sliceBuffer);
+}
+
+
+/**
+ Prepend a string to a string buffer.
+*/
+void string_buffer_prepend(string_buffer buffer, char* str)
+{
+ /* Make a new string_slice for the string */
+ string_slice sliceBuffer = new_string_slice(str, 0);
+
+ /* prepend the new string_slice to 'buffer' */
+ string_buffer_prepend_string_slice(buffer, sliceBuffer);
+}
+
+
+/**
+ Append a newline to 'str' and
+ prepend the result to a string buffer.
+*/
+void string_buffer_prepend_newline(string_buffer buffer, char* str)
+{
+ /* Make a new string_slice for the string */
+ string_slice sliceBuffer = new_string_slice(str, 1);
+
+ /* prepend the new string_slice to 'buffer' */
+ string_buffer_prepend_string_slice(buffer, sliceBuffer);
+}
+
+
+/**
+ Get the length of a string buffer.
+*/
+int string_buffer_get_length(string_buffer buffer)
+{
+
+ /* sum up the length of all string slices */
+ int length = 0;
+ string_slice slice;
+ for (slice = buffer->first; slice != NULL; slice = slice->next) {
+ int slice_length = strlen(slice->str);
+ length += slice_length;
+ }
+
+ /* return the lenth of the buffer */
+ return length;
+}
+
+/**
+ Cleanup a string buffer.
+ Returns the length of the string buffer.
+
+ Append the string slices constituting a string buffer
+ into one single string slice.
+*/
+int string_buffer_cleanup(string_buffer buffer)
+{
+ /* no cleanup necessary if the buffer is empty
+ ('buffer->first' and 'buffer->last->next' are both NULL)
+ or there is only one string slice in the string buffer
+ (the first string slice is also the last )
+ - both can be tested with
+ (buffer->first == buffer->last)
+ */
+ if (buffer->first == buffer->last) {
+ /* no cleanup necessary */
+ return string_buffer_get_length(buffer);
+ }
+
+ /* copy the content of the string_buffer into a newly allocated char array */
+ int length;
+ char* content = string_buffer_to_char_array_allocate(buffer, &length);
+
+ /* free the old slices */
+ string_buffer_make_empty(buffer);
+
+ /* Make a new string_slice for the content */
+ string_slice sliceBuffer;
+ sliceBuffer = (string_slice) malloc(sizeof(string_slice_struct));
+
+ if (sliceBuffer == NULL) {
+ fprintf(stderr, "Couldn't allocate memory for new slice in string_buffer!\n");
+ exit(ERROR_MEMORY);
+ }
+
+ /* link the new buffer into 'sliceBuffer' */
+ sliceBuffer->str = content;
+
+ /* the pointer 'sliceBuffer->next'
+ is set to NULL by 'string_buffer_append_string_slice()',
+ signalling that the new slice is the last one.
+ */
+
+ /* append the new and only string_slice to 'buffer' */
+ string_buffer_append_string_slice(buffer, sliceBuffer);
+
+ /* return the length */
+ return length;
+}
+
+/**
+ Like strcmp - but for string buffers :)
+*/
+int string_buffer_compare_to_string(string_buffer buffer, char* str)
+{
+ /* simlify the buffer by copying all slices into a single one */
+ string_buffer_cleanup(buffer);
+
+ /* the string of the remaining slice now can be combined with strcmp */
+ return strcmp(buffer->first->str, str);
+}
+
+/**
+ Check if the string buffer starts with the given prefix.
+ Return 1 if this is the case and 0 otherwise.
+*/
+int string_buffer_starts_with_prefix(string_buffer buffer, char* prefix)
+{
+ /* simlify the buffer by copying all slices into a single one */
+ string_buffer_cleanup(buffer);
+
+ /* get the length of the prefix */
+ int length = strlen(prefix);
+
+ /* compare the first 'length' caracters of the string buffer
+ to the prefix and return the result of the comparison */
+ if (strncmp(buffer->first->str, prefix, length) == 0) {
+ /* the buffer starts with the prefix */
+ return 1;
+ } else {
+ /* the buffer does not start with the prefix */
+ return 0;
+ }
+}
+
+/**
+ Check if the string buffer is empty
+ or only contains white space.
+*/
+int string_buffer_is_empty_or_white_space_string(string_buffer buffer)
+{
+ /* if string buffer is empty return true */
+ if (string_buffer_is_empty(buffer)) return 1;
+
+ /* simlify the buffer by copying all slices into a single one */
+ string_buffer_cleanup(buffer);
+
+ /* get the length of the buffer content */
+ int length;
+ length = string_buffer_get_length(buffer);
+
+ /* get pointer to first char in the buffer */
+ char* c = buffer->first->str;
+ char* limit = c + length;
+
+ /* if one of the characters in the buffer is not a white space character, return false */
+ for ( ; c < limit; c++) {
+ /* isspace(c) <=> c is one of: space, formfeed, newline,
+ carriage return, tab, vertical tab (defined in <ctype.h>)
+ */
+ if (!isspace(*c)) return 0;
+ }
+
+ /* all characters are white space characters */
+ return 1;
+}
+
+/**
+ Transform a string buffer into a newly allocated character array.
+ A pointer to the allocated char array is returned.
+ The length of the string is returned as second parameter.
+ If NULL is supplied as second parameter, it is ignored.
+*/
+char* string_buffer_to_char_array_allocate(string_buffer buffer, int* length)
+{
+ /* allocate a new buffer 'content'
+ to hold the whole content of the current string buffer */
+ int buffer_length;
+ buffer_length = string_buffer_get_length(buffer);
+ char* content = (char*) malloc( (buffer_length + 1) * sizeof(char) );
+
+ /* copy the content of the slices into the newly allocated buffer */
+ string_slice slice;
+ char* p = content; /* init pointer to position in new string buffer */
+ for (slice = buffer->first; slice != NULL; slice = slice->next) {
+ int slice_length = strlen(slice->str); /* get length of the current string slice */
+ memcpy(p, slice->str, slice_length);
+ p += slice_length; /* set pointer to the end in new string buffer */
+ }
+ *p = '\0'; /* mark the end of the buffer with the character '\0' */
+
+ /* return the result */
+ if (length != (int*) NULL) *length = buffer_length;
+ return content;
+}
+
+/**
+ Read a single line from stdin.
+ The function returns the accumulated length of lines in 'buffer'.
+*/
+int string_buffer_read_line_from_stdin(string_buffer buffer)
+{
+ /* print prompt and
+ get the next line using GNU readline() */
+ char* line = NULL;
+ line = readline(buffer->line_prompt);
+
+ /* checking the result */
+ if (line == NULL) {
+
+ /* - either there was a problem while trying to read a line from stdin -
+ - or blash received an EOT (End-Of-Transmission character)
+ for example because CTRL-D was pressed...
+ */
+
+ return -1;
+ }
+
+ /* save non-empty lines in readline() history */
+ if (strlen(line) > 0) {
+ add_history(line);
+ }
+
+ /* append read line to buffer */
+ string_buffer_append(buffer, line);
+
+ /* free the string buffer allocated by readline() */
+ free(line);
+
+ /* clean up the buffer buffer */
+ int length = string_buffer_cleanup(buffer);
+
+ /* return the length of the read buffer */
+ return length;
+}
+
+/**
+ Read a text (a sequence of lines) from stdin.
+ The input is terminated by a line containing only a dot character '.'.
+
+ The function returns the accumulated length of all read lines.
+
+ If the there was a problem while trying to read an input
+ - for example because CTRL-D was hit - -1 is returned.
+*/
+int string_buffer_read_text_from_stdin(string_buffer buffer)
+{
+ /* set prompt for first line */
+ char* prompt = NULL;
+ prompt = buffer->text_prompt;
+
+ /* loop to read a sequence of lines from stdin */
+ char* line = NULL;
+ while (1) {
+
+ /* print prompt and get the next line */
+ line = readline(prompt);
+
+ /* checking the result */
+ if (line == NULL) {
+
+ /* - either there was a problem while trying to read a line from stdin -
+ - or blash received an EOT (End-Of-Transmission character)
+ for example because CTRL-D was pressed...
+ */
+
+ return -1;
+ }
+
+ /* save non-empty lines in readline() history */
+ if (strlen(line) > 0) {
+ add_history(line);
+ }
+
+ /* a line containing only a '.' signals the end of the sequence of input lines */
+ if (strcmp(line, ".") == 0) {
+
+ /* if the buffer is still empty an empty text was entered:
+ Set the buffer to an empty text */
+ if (string_buffer_is_empty(buffer)) {
+ string_buffer_append(buffer, "");
+ }
+
+ free(line); /* free the string buffer allocated by readline() */
+ break; /* exit the readline loop */
+ }
+
+ /* append read line to buffer */
+ string_buffer_append_newline(buffer, line);
+
+ /* free the string buffer allocated by readline() */
+ free(line);
+
+ /* use "continue prompt" for all following lines...
+ signalling that the loop is in the process to read a buffer */
+ prompt = buffer->text_coninue_prompt;
+ }
+
+ /* clean up the buffer buffer */
+ int length = string_buffer_cleanup(buffer);
+
+ /* return the length of the read buffer */
+ return length;
+}
+
+/**
+ Print a string buffer.
+*/
+void string_buffer_print(string_buffer buffer)
+{
+ string_slice slice;
+ for (slice = buffer->first; slice != NULL; slice = slice->next) {
+ printf(slice->str);
+ }
+}
+
+/**
+ Dump the inner structure of a string buffer to stdout.
+ Note: This function is only for use during development.
+*/
+void string_buffer_dump(string_buffer buffer)
+{
+ printf("===\n");
+
+ string_slice slice;
+ int i;
+ for (slice = buffer->first, i = 0; slice != NULL; slice = slice->next, i++) {
+ if (i > 0) printf("---\n");
+ printf(">>> Slice #%d, length %d:\n", i, strlen(slice->str));
+ printf("---\n");
+ printf(slice->str);
+ }
+
+ printf("===\n");
+}
+
+/**
+ Copy string.
+ Return a copy of a string in newly allocated memory.
+*/
+char* copy_string_allocate(char* string)
+{
+ /* allocating memory for the copy */
+ int length = strlen(string);
+ char* newstr = (char*) malloc((length + 1) * sizeof(char));
+ memcpy(newstr, string, length);
+ newstr[length]= '\0';
+
+ /* return the newly allocated copy */
+ return newstr;
+}
+
+/* fin */
Index: source/blender/commandport/utilities/src/bcp_package.c
===================================================================
--- source/blender/commandport/utilities/src/bcp_package.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/bcp_package.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,1139 @@
+/*
+ * $Id: bcp_package.c, v 1.0 2007/05/31, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Functions to pack and unpack integers, strings and commands into a
+ * single string for sending them over the command port socket.
+ *
+ * header file: ../include/bcp_package.h
+ *
+ */
+
+/* fin */
+/* bcp_package.c */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "bcp_package.h"
+#include "error_codes.h"
+
+/**
+ element type
+*/
+typedef struct element_struct *element;
+typedef struct element_struct {
+ char type;
+ union {
+ int vint;
+ char* vstr;
+ char vcmd;
+ } element;
+ element next;
+} element_struct;
+
+/**
+ package type struct
+*/
+typedef struct bcp_package_struct {
+ element first;
+ element last;
+} bcp_package_struct;
+
+
+/* Declaration of utility functions */
+element new_element_allocate();
+void add_element(bcp_package p, element e);
+void delete_element(element e);
+element new_int_element(int i);
+element new_string_element(char* s);
+int intlen(int e);
+int length_packed_element(element e);
+int length_packed(bcp_package p);
+
+char* pack_element(char* buffer, element e);
+char unpack_element(bcp_package p, char** packed);
+
+int parse_int(char** s);
+char parse_char(char** s);
+char parse_type(char** s);
+void parse_newline(char** s);
+int parse_int_element(char** s);
+char* parse_string(char** s);
+char* parse_string_element(char** s);
+char parse_command_element(char** s);
+
+/* test functions */
+#ifdef BCP_PACKAGE_TEST
+#define BUFFER_SIZE 80
+void print_element(element e);
+void dump_packed_package(bcp_package p);
+void dump_packed_element(element e);
+void dump_element_header(char* header);
+#endif /* BCP_PACKAGE_TEST */
+
+
+/**
+ Make a new package.
+*/
+bcp_package bcp_package_new()
+{
+ bcp_package package;
+ package = (bcp_package) malloc(sizeof(bcp_package_struct));
+
+ if (package == NULL) {
+ fprintf(stderr, "Couldn't allocate memory for new bcp_package!\n");
+ exit(ERROR_MEMORY);
+ }
+
+ package->first = (element) NULL;
+ package->last = (element) NULL;
+
+ return package;
+}
+
+
+/**
+ Delete a package.
+*/
+void bcp_package_delete(bcp_package package)
+{
+ /* empty the package */
+ bcp_package_make_empty(package);
+
+ /* free package structure */
+ free(package);
+}
+
+
+/**
+ Empty a package.
+*/
+void bcp_package_make_empty(bcp_package package)
+{
+ /* delete all elements */
+ element e = package->first;
+ for( ; e != NULL; e = e->next) {
+ delete_element(e);
+ }
+
+ /* set pointers to NULL
+ to indicate that the package is empty */
+ package->first = (element) NULL;
+ package->last = (element) NULL;
+}
+
+
+/**
+ Allocate memory for a new package element.
+*/
+element new_element_allocate()
+{
+ element e;
+ e = (element) malloc(sizeof(element_struct));
+
+ if (e == NULL) {
+ fprintf(stderr, "Couldn't allocate memory for new bcp_package element!\n");
+ exit(ERROR_MEMORY);
+ }
+
+ e->type = BCP_PACKAGE_TYPE_UNDEFINED;
+ e->next = NULL;
+
+ return e;
+}
+
+
+/**
+ Add an element to a package.
+*/
+void add_element(bcp_package p, element e)
+{
+ /* set the 'next' member to NULL
+ to indicate that it is the last element */
+ e->next = (element) NULL;
+
+ /* append the new element to the element list of the package */
+ if (p->first == NULL) {
+ p->first = e;
+ } else {
+ p->last->next = e;
+ }
+ p->last = e;
+}
+
+
+/**
+ Delete a package element.
+*/
+void delete_element(element e)
+{
+ free(e);
+}
+
+/**
+ Make a new integer element.
+*/
+element new_int_element(int i)
+{
+ element e;
+ e = new_element_allocate();
+
+ e->type = BCP_PACKAGE_TYPE_INT;
+ e->element.vint = i;
+
+ return e;
+}
+
+/**
+ Make a new string element.
+*/
+element new_string_element(char* s)
+{
+ element e;
+ e = new_element_allocate();
+
+ e->type = BCP_PACKAGE_TYPE_STRING;
+ e->element.vstr = s;
+
+ return e;
+}
+
+/**
+ Make a new command element.
+*/
+element new_command_element(char command)
+{
+ element e;
+ e = new_element_allocate();
+
+ e->type = BCP_PACKAGE_TYPE_COMMAND;
+ e->element.vcmd = command;
+
+ return e;
+}
+
+/**
+ Add integer.
+*/
+void bcp_package_add_int(bcp_package package, int i)
+{
+ /* make a new integer element */
+ element e;
+ e = new_int_element(i);
+ add_element(package, e);
+}
+
+/**
+ Add string.
+*/
+void bcp_package_add_string(bcp_package package, char* s)
+{
+ /* make a new string element */
+ element e;
+ e = new_string_element(s);
+ add_element(package, e);
+}
+
+/**
+ Add command.
+*/
+void bcp_package_add_command(bcp_package package, char command)
+{
+ /* make a new command element */
+ element e;
+ e = new_command_element(command);
+ add_element(package, e);
+}
+
+/**
+ Calculate the length of an integers string representation.
+*/
+int intlen(int i)
+{
+ /* 0 has the length 1 */
+ if (i == 0) return 1;
+
+ /* calculate length for i > 0 */
+ int length;
+ for (length = 0; i > 0; i /= 10, length++);
+
+ /* done */
+ return length;
+}
+
+/**
+ Calculate the length of a packed element.
+*/
+int length_packed_element(element e)
+{
+ /* an undefined element will not be packed
+ - return 0 */
+ if (e->type == BCP_PACKAGE_TYPE_UNDEFINED) return 0;
+
+ /* length accumulator */
+ int length = 0;
+
+ /* add length of prefix '#' */
+ length += 1;
+
+ /* add length of the element type code
+ - the type is represented by a caracter of length 1 */
+ length += 1;
+
+ /* the header is terminated by '\n' - add 1 */
+ length += 1;
+
+ /* the rest of the header depends on the element type */
+ int vlen;
+ switch (e->type) {
+
+ case BCP_PACKAGE_TYPE_INT:
+
+ /* integer are coded as part of the header
+ example: 123 is coded as "#i123\n" */
+
+ /* add the length of the integer value */
+ length += intlen(e->element.vint);
+
+ /* done */
+ break;
+
+ case BCP_PACKAGE_TYPE_STRING:
+
+ /* the header of a string element
+ contains the lenght of the string.
+ The string value itself followes the header.
+ example: "hallo" is coded as "#s5\nhallo\n"
+ */
+
+ /* calculate the length of the string value */
+ vlen = strlen(e->element.vstr);
+
+ /* the length of the string value is written into the header
+ - add the necessary length */
+ length += intlen(vlen);
+
+ /* add the length of the string value */
+ length += vlen;
+
+ /* to faciliate the readability of the packed representation
+ a newline is added after the value - add its length */
+ length += 1;
+
+ /* done */
+ break;
+
+ case BCP_PACKAGE_TYPE_COMMAND:
+
+ /* commands are characters coded as part of the header
+ example: 'c' is coded as "#cc\n" */
+
+ /* add 1 for the command caracter */
+ length += 1;
+
+ /* done */
+ break;
+
+ default:
+ fprintf(stderr, "Found a bcp_package element with an unknown type!\n");
+ exit(ERROR_UNKNOWN_TYPE);
+ }
+
+ /* done */
+ return length;
+}
+
+/**
+ Calculate the length of the packed
+ representation of a package.
+*/
+int length_packed(bcp_package p)
+{
+ /* add the length of all elements */
+ int length = 0;
+ element e = p->first;
+ for( ; e != NULL; e = e->next) {
+ length += length_packed_element(e);
+ }
+
+ /* done */
+ return length;
+}
+
+/**
+ Code the package
+ as a human readable string.
+*/
+char* bcp_package_pack_allocate(bcp_package package)
+{
+ /* calculate length */
+ int length = length_packed(package);
+
+ /* allocate memory for the packed string representation */
+ char* packed = (char*) malloc((length + 1) * sizeof(char));
+ if (packed == NULL) {
+ fprintf(stderr, "Couldn't allocate memory to pack a bcp_package!\n");
+ exit(ERROR_MEMORY);
+ }
+
+ /* write all elements to the buffer */
+ char* p = packed;
+ element e = package->first;
+ for( ; e != NULL; e = e->next) {
+ p = pack_element(p, e);
+ }
+
+ /* terminate the packed string representation
+ with the null character */
+ *p = '\0';
+
+ /* return the packed representation */
+ return packed;
+}
+
+/**
+ Pack an element.
+*/
+char* pack_element(char* buffer, element e)
+{
+ /* an undefined element will not be packed
+ - return the buffer as it is */
+ if (e->type == BCP_PACKAGE_TYPE_UNDEFINED) return buffer;
+
+ /* the rest of the header depends on the element type */
+ switch (e->type) {
+
+ case BCP_PACKAGE_TYPE_INT:
+
+ /* integer are coded as part of the header
+ example: 123 is coded as "#i123\n" */
+
+ /* add the integer element */
+ buffer += sprintf(buffer, "#i%d\n", e->element.vint);
+
+ /* done */
+ break;
+
+ case BCP_PACKAGE_TYPE_STRING:
+
+ /* the header of a string element
+ contains the lenght of the string.
+ The string value itself followes the header.
+ example: "hallo" is coded as "#s5\nhallo\n"
+ */
+
+ /* write the string header */
+ buffer += sprintf(buffer, "#s%d\n", strlen(e->element.vstr));
+
+ /* write the string itself */
+ buffer += sprintf(buffer, "%s\n", e->element.vstr);
+
+ /* done */
+ break;
+
+ case BCP_PACKAGE_TYPE_COMMAND:
+
+ /* commands are characters coded as part of the header
+ example: 'c' is coded as "#cc\n" */
+
+ /* write the command element */
+ buffer += sprintf(buffer, "#c%c\n", e->element.vcmd);
+
+ /* done */
+ break;
+
+ default:
+ fprintf(stderr, "Found a bcp_package element with an unknown type!\n");
+ exit(ERROR_UNKNOWN_TYPE);
+ }
+
+ /* return a pointer to the next unwritten caracter */
+ return buffer;
+}
+
+/**
+ Unpack the elements in the string `packed'
+ and return the result package.
+*/
+bcp_package bcp_package_unpack(char* packed)
+{
+ /* make a new empty package */
+ bcp_package package;
+ package = bcp_package_new();
+
+ /* unpack all elements */
+ char** p = &packed;
+ char type;
+
+ do {
+ type = unpack_element(package, p);
+ } while (*p != NULL);
+
+ /* return the new package */
+ return package;
+}
+
+/**
+ Unpack the first element in `packed'.
+ A pointer to the next element
+ - or NULL if the current element was the last one -
+ is returned.
+*/
+char unpack_element(bcp_package p, char** packed)
+{
+ /* set return *packed to NULL and
+ return BCP_PACKAGE_TYPE_EMPTY
+ if there are no more elements to parse */
+ if (**packed == '\0') {
+ *packed = NULL; /* NULL to signal that there are no more elements */
+ return BCP_PACKAGE_TYPE_EMPTY; /* return BCP_PACKAGE_TYPE_EMPTY
+ to signal that there are no more elements */
+ }
+
+ /* unpack element type */
+ char type;
+ type = parse_type(packed);
+ /* DEBUG: printf("type: %c, rest: \"%s\"\n", type, *packed); */
+
+ /* print value */
+ int integer;
+ char* str;
+ char command;
+ switch (type) {
+
+ case BCP_PACKAGE_TYPE_UNDEFINED:
+ /* do nothing */
+ break;
+
+ case BCP_PACKAGE_TYPE_INT:
+
+ /* unpack integer */
+ integer = parse_int_element(packed);
+
+ /* add the integer */
+ bcp_package_add_int(p, integer);
+
+ break;
+
+ case BCP_PACKAGE_TYPE_STRING:
+
+ /* unpack string */
+ str = parse_string_element(packed);
+
+ /* add string */
+ bcp_package_add_string(p, str);
+
+ break;
+
+ case BCP_PACKAGE_TYPE_COMMAND:
+
+ /* unpack command */
+ command = parse_command_element(packed);
+
+ /* add a command */
+ bcp_package_add_command(p, command);
+
+ break;
+
+ default:
+ fprintf(stderr, "Found a bcp_package element with an unknown type!\n");
+ exit(ERROR_UNKNOWN_TYPE);
+ }
+
+ /* return type of parsed element */
+ return type;
+}
+
+/**
+ Parse a caracter from the beginning of string `*s'
+ and return it.
+*/
+char parse_char(char** s)
+{
+ /* parse character */
+ char c;
+ int parsed;
+ parsed = sscanf(*s, "%c", &c);
+
+ /* check if the item could be parsed */
+ if (parsed != 1) {
+ fprintf(stderr, "ERROR: Couldn't parse caracter: %s\n", *s);
+ exit(ERROR_PARSER);
+ }
+
+ /* advance to the next caracters */
+ (*s)++;
+
+ /* return parsed char */
+ return c;
+}
+
+/**
+ Parse an integer from the beginning of string `s'
+ and return it.
+*/
+int parse_int(char** s)
+{
+ /* parse character */
+ int i;
+ int parsed;
+ parsed = sscanf(*s, "%d", &i);
+
+ /* check if the item could be parsed */
+ if (parsed != 1) {
+ fprintf(stderr, "ERROR: Couldn't parse integer: %s\n", *s);
+ exit(ERROR_PARSER);
+ }
+
+ /* calculate length of parsed integer string */
+ int length;
+ length = intlen(i);
+
+ /* advance to the next caracters */
+ *s += length;
+
+ /* return the parsed integer */
+ return i;
+}
+
+/**
+ Parse a type from the beginning of string `*s'
+ and return the it.
+*/
+char parse_type(char** s)
+{
+ /* parse number sign (#) */
+ char number_sign;
+ number_sign = parse_char(s);
+
+ /* check if the item could be parsed */
+ if (number_sign != '#') {
+ fprintf(stderr, "ERROR: Couldn't parse type: %s\n", *s);
+ exit(ERROR_PARSER);
+ }
+
+ /* parse the type caracter */
+ char type;
+ type = parse_char(s);
+
+ /* return parsed type */
+ return type;
+}
+
+/**
+ Parse a newline caracter from the beginning of string `*s'.
+*/
+void parse_newline(char** s)
+{
+ /* parse character */
+ char newline;
+ newline = parse_char(s);
+
+ /* check if the item could be parsed */
+ if (newline != '\n') {
+ fprintf(stderr, "ERROR: Couldn't parse newline: %s\n", *s);
+ exit(ERROR_PARSER);
+ }
+}
+
+/**
+ Parse an integer element
+ and return it.
+*/
+int parse_int_element(char** s)
+{
+ /* extract the integer */
+ int i;
+ i = parse_int(s);
+
+ /* parse the newline terminating the header */
+ parse_newline(s);
+
+ /* return parsed integer */
+ return i;
+}
+
+/**
+ Parse a string
+ and return a pointer to it.
+*/
+char* parse_string(char** s)
+{
+ /* extract the length of the string */
+ int length;
+ length = parse_int(s);
+
+ /* parse the newline terminating the header */
+ parse_newline(s);
+
+ /* store pointer to found string */
+ char* str;
+ str = *s;
+
+ /* calculate the position of the newline caracter
+ which terminates the string */
+ *s = *s + length;
+
+ /* overwrite the newline character at the end of the string
+ with a string terminator / null caracter */
+ **s = '\0';
+
+ /* calculate the position of the next packed element */
+ (*s)++;
+
+ /* return pointer to the found string */
+ return str;
+}
+
+/**
+ Parse a string element
+ and return a pointer to it.
+*/
+char* parse_string_element(char** s)
+{
+ /* extract the integer */
+ char* str;
+ str = parse_string(s);
+
+ /* return pointer to parsed string */
+ return str;
+}
+
+/**
+ Parse a command element
+ and return a pointer to it.
+*/
+char parse_command_element(char** s)
+{
+ /* parse character */
+ char command;
+ command = parse_char(s);
+
+ /* calculate the position of the next packed element */
+ (*s)++;
+
+ /* return the parsed command */
+ return command;
+}
+
+/* =========================================================
+ * BCP package enumerator functions
+ * ---------------------------------------------------------
+ */
+
+/**
+ package enumerator type struct
+*/
+typedef struct bcp_package_enumerator_struct {
+ bcp_package package;
+ element next;
+} bcp_package_enumerator_struct;
+
+/**
+ Make a new enumerator.
+*/
+bcp_package_enumerator bcp_package_enumerator_new(bcp_package p)
+{
+ bcp_package_enumerator enumerator;
+ enumerator = (bcp_package_enumerator) malloc(sizeof(bcp_package_enumerator_struct));
+
+ if (enumerator == NULL) {
+ fprintf(stderr, "Couldn't allocate memory for new bcp_package_enumerator!\n");
+ exit(ERROR_MEMORY);
+ }
+
+ enumerator->package = p;
+ enumerator->next = p->first;
+
+ return enumerator;
+}
+
+/**
+ Delete a package enumerator.
+*/
+void bcp_package_enumerator_delete(bcp_package_enumerator enumerator)
+{
+ /* free enumerator structure */
+ free(enumerator);
+}
+
+/**
+ Reset enumerator.
+*/
+void bcp_package_enumerator_reset(bcp_package_enumerator e)
+{
+ e->next = e->package->first;
+}
+
+/**
+ Get next element in package.
+*/
+void* bcp_package_enumerator_get_next_element(bcp_package_enumerator e, char* type)
+{
+ /* get next element */
+ element elem = e->next;
+
+ /* if there is no next element
+ set type to BCP_PACKAGE_TYPE_EMPTY to indicate that there is no further element
+ and return NULL
+ */
+ if (elem == NULL) {
+ *type = BCP_PACKAGE_TYPE_EMPTY;
+ return NULL;
+ }
+
+ /* set enumerators `next' pointer to `elem's next element */
+ e->next = elem->next;
+
+ /* get type of found element */
+ *type = elem->type;
+
+ /* return pointer to value */
+ switch (*type) {
+
+ case BCP_PACKAGE_TYPE_UNDEFINED:
+ return (void*) NULL;
+ break;
+
+ case BCP_PACKAGE_TYPE_INT:
+ return (void*) &(elem->element.vint);
+ break;
+
+ case BCP_PACKAGE_TYPE_STRING:
+ return (void*) elem->element.vstr;
+ break;
+
+ case BCP_PACKAGE_TYPE_COMMAND:
+ return (void*) &(elem->element.vcmd);
+ break;
+
+ default:
+ fprintf(stderr, "Found a bcp_package element with an unknown type!\n");
+ exit(ERROR_UNKNOWN_TYPE);
+ }
+}
+
+/* =========================================================
+ * Test functions
+ * ---------------------------------------------------------
+ */
+
+#ifdef BCP_PACKAGE_TEST
+
+void bcp_package_test()
+{
+ /* stuff needed for the tests */
+ char buffers[BUFFER_SIZE][BUFFER_SIZE];
+
+ /* test */
+ printf("[test] Make a package, add elements, delete package:\n");
+ printf("\n");
+
+ /* make a new package */
+ bcp_package package;
+ package = bcp_package_new();
+
+ /* add some elements */
+ int i;
+ int j = 1;
+ for (i = 0; i < 3; i++) {
+
+ /* add an integer */
+ bcp_package_add_int(package, j);
+
+ /* add a string */
+ sprintf(buffers[i], "Hi, number %d :)", j);
+ bcp_package_add_string(package, buffers[i]);
+
+ /* add a command */
+ char command = 'a' + i;
+ bcp_package_add_command(package, command);
+
+ /* calculate a new example integer */
+ j *= j * 100;
+ }
+
+ /* dump */
+ printf(">>> dumping the original package:\n");
+ dump_package(package);
+ printf("\n");
+
+ /* DEBUG - for a more detailed dump uncomment the following: */
+ /*
+ dump_packed_package(package);
+ printf("\n");
+ */
+
+ /* pack */
+ char* packed;
+ packed = bcp_package_pack_allocate(package);
+
+ /* print packed package */
+ printf(">>> the packed package:\n");
+ printf(">>>%s<<<\n", packed);
+ printf("\n");
+
+ /* delete package */
+ bcp_package_delete(package);
+
+ /* unpack the string `packed' */
+ bcp_package package2;
+ package2 = bcp_package_unpack(packed);
+
+ /* dump */
+ printf(">>> dumping the unpacked package:\n");
+ dump_package(package2);
+ printf("\n");
+
+ /* DEBUG - for a more detailed dump uncomment the following: */
+ /*
+ dump_packed_package(package);
+ printf("\n");
+ */
+
+ /* test the enumerator functions */
+ printf(">>> testing enumerator functions:\n");
+ printf("\n");
+
+ /* make new package enumerator */
+ bcp_package_enumerator enumerator;
+ enumerator = bcp_package_enumerator_new(package2);
+
+ /* header */
+ printf(" listing elements:\n");
+
+ /* print element */
+ i = 0;
+ void* elem;
+ char type;
+ while (1) {
+
+ /* get next element */
+ elem = bcp_package_enumerator_get_next_element(enumerator, &type);
+
+ /* if there are no more elements - exit */
+ if (type == BCP_PACKAGE_TYPE_EMPTY) break;
+
+ /* print index and type of element */
+ printf(" %3d. (%c): ", i, type);
+
+ /* print value */
+ switch (type) {
+
+ case BCP_PACKAGE_TYPE_UNDEFINED:
+ printf("<empty>");
+ break;
+
+ case BCP_PACKAGE_TYPE_INT:
+ printf("%d", *((int*) elem));
+ break;
+
+ case BCP_PACKAGE_TYPE_STRING:
+ printf("\"%s\"", (char*) elem);
+ break;
+
+ case BCP_PACKAGE_TYPE_COMMAND:
+ printf("%c", *((char*) elem));
+ break;
+
+ default:
+ fprintf(stderr, "Found a bcp_package element with an unknown type!\n");
+ exit(ERROR_UNKNOWN_TYPE);
+ }
+
+ printf("\n");
+
+ /* increment element index */
+ i++;
+ }
+
+ /* all elements have been printed */
+ printf(" done.\n");
+
+ /* delete the package enumerator */
+ bcp_package_enumerator_delete(enumerator);
+
+ printf("\n");
+
+ /* delete package */
+ bcp_package_delete(package2);
+
+ /* free the packed string representation */
+ free(packed);
+ packed = NULL;
+
+ /* done :) */
+ printf("bye :)\n");
+ printf("\n");
+}
+
+/**
+ Dump all elements in a package.
+
+ example:
+
+ (package): {
+ 0. (c): 'a'
+ 1. (i): 124,
+ 2. (s): "laber",
+ }
+
+*/
+void dump_package(bcp_package p)
+{
+ /* print first line: type and length of the package */
+ printf(" (package,%d): {\n", length_packed(p));
+
+ /* print elements */
+ int i = 0;
+ element e = p->first;
+ for( ; e != NULL; i++, e = e->next) {
+
+ /* print number, type and value of the ith element */
+ printf(" %3d. (%c): ", i, e->type);
+ print_element(e);
+ printf(",\n");
+ }
+
+ /* print last line */
+ printf(" }\n");
+}
+
+/**
+ Dump an element.
+*/
+void print_element(element e)
+{
+ /* print value */
+ switch (e->type) {
+
+ case BCP_PACKAGE_TYPE_UNDEFINED:
+ printf("<empty>");
+ break;
+
+ case BCP_PACKAGE_TYPE_INT:
+ printf("%d", e->element.vint);
+ break;
+
+ case BCP_PACKAGE_TYPE_STRING:
+ printf("\"%s\"", e->element.vstr);
+ break;
+
+ case BCP_PACKAGE_TYPE_COMMAND:
+ printf("%c", e->element.vcmd);
+ break;
+
+ default:
+ fprintf(stderr, "Found a bcp_package element with an unknown type!\n");
+ exit(ERROR_UNKNOWN_TYPE);
+ }
+}
+
+/**
+ Dump all elements in a package
+ together with their packed representation.
+*/
+void dump_packed_package(bcp_package p)
+{
+ /* print first line: type and length of the package */
+ printf(" package:\n");
+ printf("\n");
+ printf(" - length: %d\n", length_packed(p));
+ printf(" - elements:\n");
+ printf("\n");
+
+ /* print elements */
+ int i = 0;
+ element e = p->first;
+ for( ; e != NULL; i++, e = e->next) {
+
+ /* print ith element */
+ printf(" - element %d:\n", i);
+ dump_packed_element(e);
+ printf("\n");
+ }
+
+ /* print last line */
+ printf("\n");
+}
+
+/**
+ Dump an element
+ together with its packed representation.
+*/
+void dump_packed_element(element e)
+{
+ /* calculate length */
+ int length = length_packed_element(e);
+
+ /* allocate memory for the packed string representation */
+ char* packed = (char*) malloc((length + 1) * sizeof(char));
+ if (packed == NULL) {
+ fprintf(stderr, "Couldn't allocate memory to pack an element!\n");
+ exit(ERROR_MEMORY);
+ }
+
+ /* write the element to the buffer */
+ pack_element(packed, e);
+
+ /* terminate the packed string representation
+ with the null character */
+ packed[length] = '\0';
+
+ /* print element type, value,
+ length of packed representation
+ and the packed representation itself */
+ printf(" - type: %c\n", e->type);
+ printf(" - value: "); print_element(e); printf("\n");
+ printf(" - packed representation:\n");
+ printf(" - calculated length: %d\n", length);
+ printf(" - packed: \"%s\"\n", packed);
+ printf(" - length: %d\n", strlen(packed));
+
+ /* free the allocated memory */
+ free (packed);
+}
+
+/**
+ Dump an element header.
+*/
+void dump_element_header(char* header)
+{
+ /* dump header */
+ char* p = header;
+ for( ; *p != '\0'; p++) {
+ printf("%X ", *p);
+ }
+ printf("%X", *p);
+}
+
+#endif /* BCP_PACKAGE_TEST */
+
+/* fin */
Index: source/blender/commandport/utilities/src/hexdump_string.c
===================================================================
--- source/blender/commandport/utilities/src/hexdump_string.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/hexdump_string.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,360 @@
+/*
+ * $Id: hexdump_string.c, v 1.0 2007/05/30, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Hexdump functions to debug the Blender Command Port...
+ *
+ * header file: ../include/hexdump_string.h
+ *
+ */
+
+#include <stdio.h>
+
+#include "hexdump_string.h"
+
+/* declaration of locally used functions */
+char* to_hex(char* buffer, char code);
+char to_printable(char c);
+
+/**
+ Print ascii code table.
+*/
+void print_ascii_code_table()
+{
+ printf(" +---+----------------------------------------------------------------+\n"
+ " | \\ | 0 1 2 3 4 5 6 7 8 9 A B C D E F |\n"
+ " +---+----------------------------------------------------------------+\n"
+ " | 0 | NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI |\n"
+ " | 1 | DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US |\n"
+ " | 2 | SP ! \" # $ %% & ' ( ) * + , - . / |\n"
+ " | 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |\n"
+ " | 4 | @ A B C D E F G H I J K L M N O |\n"
+ " | 5 | P Q R S T U V W X Y Z [ \\ ] ^ _ |\n"
+ " | 6 | ` a b c d e f g h i j k l m n o |\n"
+ " | 7 | p q r s t u v w x y z { | } ~ DEL |\n"
+ " +---+----------------------------------------------------------------+\n"
+ );
+}
+
+
+/**
+ Print the printable code table
+ used in the `| printable repr.|' column of `hexdump_string()'.
+*/
+void print_printable_dump_code_table()
+{
+ printf(" +---+----------------------------------------------------------------+\n"
+ " | \\ | 0 1 2 3 4 5 6 7 8 9 A B C D E F |\n"
+ " +---+----------------------------------------------------------------+\n"
+ " | 0 | 0 ? ? ? ? ? ? ? ? > ^ ? ? ? ? ? |\n"
+ " | 1 | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |\n"
+ " | 2 | SP ! \" # $ %% & ' ( ) * + , - . / |\n"
+ " | 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |\n"
+ " | 4 | @ A B C D E F G H I J K L M N O |\n"
+ " | 5 | P Q R S T U V W X Y Z [ \\ ] ^ _ |\n"
+ " | 6 | ` a b c d e f g h i j k l m n o |\n"
+ " | 7 | p q r s t u v w x y z { | } ~ ? |\n"
+ " +---+----------------------------------------------------------------+\n"
+ );
+}
+
+
+/**
+ Dump the hex codes a string is made of.
+
+ Nicer formatting than the `simple' one - example:
+*/
+void hexdump_string(char* prefix, char* string)
+{
+ char* c; /* pointer to current char in string */
+ c = string;
+
+ /* print a header */
+ printf("%s==============================================================================\n", prefix);
+ printf("%saddr 0 1 2 3 4 5 6 7 8 9 A B C D E F | printable repr.|\n", prefix);
+ printf("%s------------------------------------------------------------+----------------+\n", prefix);
+
+ /* string buffer to print the hex values into */
+ char hexbuf[50]; /* ex: */
+ hexbuf[0] = '\0'; /* "65 69 6e 73 20 7a 77 65 69 20 64 72 65 69 20 76 " */
+ char* ihex; /* >1234567890123456789012345678901234567890123456789< + \0 */
+ ihex = hexbuf;
+
+ /* string buffer to print the printable chars into */
+ char charbuf[17]; /* ex: */
+ charbuf[0] = '\0'; /* "eins zwei drei v" */
+ char* ichar; /* >1234567890123456< + \0 */
+ ichar = charbuf;
+
+ int ifirst = 0;
+ int iline = 0;
+ int hex_per_line = 16;
+
+ while (1) {
+
+ /* hex column separator between 8th and 9th hex column */
+ if (iline == (hex_per_line / 2) ) { /* an extra space between the 8th and 9th column */
+ sprintf(ihex, " "); /* to make the grouping easier to grap for the eyes */
+ ihex++;
+ }
+
+ /* every dump line dumps 16 bytes */
+ if (iline == hex_per_line) { /* every 16 characters ... */
+
+ // printf("%s%0.8x %-50s|%s|\n", prefix, ifirst, hexbuf, charbuf); /* ...print line */
+ printf("%s%.8x %-50s|%s|\n", prefix, ifirst, hexbuf, charbuf); /* ...print line */
+ /* and start a new line */
+
+ ihex = hexbuf; /* reset ihex, ichar and iline */
+ ichar = charbuf;
+ hexbuf[0] = '\0';
+ charbuf[0] = '\0';
+ iline = 0;
+
+ ifirst += hex_per_line; /* set the string index */
+ /* to the first character of the new line */
+ }
+
+ /* hex code */
+ to_hex(ihex, *c); /* print hex code of char */
+ ihex += 3;
+
+ /* character representation */
+ sprintf(ichar, "%c", to_printable(*c)); /* print character representation of char */
+ ichar += 1;
+
+ if (*c == '\0') break;
+
+ /* increment char index and counter */
+ c++;
+ iline++;
+ }
+
+ /* print remaining bytes */
+ // printf("%s%0.8x %-50s|%s|\n", prefix, ifirst, hexbuf, charbuf); /* print everything not printed yet */
+ printf("%s%.8x %-50s|%s|\n", prefix, ifirst, hexbuf, charbuf); /* print everything not printed yet */
+
+ /* ... and a footer */
+ printf("%s==============================================================================\n", prefix);
+}
+
+/**
+ The char code `code' is formatted
+ - as "00" and "7f" if between 00 and 127 - and
+ - as "?!" if outside of this range...
+
+ Returns the pointer `buffer' to the buffer it is given.
+*/
+char* to_hex(char* buffer, char code)
+{
+ if ((0x00 <= code) && (code <= 0x7f)) { /* redundand predicates - */
+ /* they are always true due to the range of char... */
+ // sprintf(buffer, "%0.2x ", code);
+ sprintf(buffer, "%.2x ", code);
+ } else {
+ sprintf(buffer, "?!");
+ }
+
+ return buffer;
+}
+
+
+/**
+ Return a simple printable representation of ascii codes.
+ Return a simple printable representation of ascii codes.
+
+ - printables - as they are
+ - '>' for tab (0x09 - ascii: HT = Horizontal Tab)
+ - '^' for newline (0x0a - ascii: LF = Line Feed)
+ - '0' for the null character (0x00 - ascii: NUL = Null char.)
+ - '?' for things which might cause problems - and ? itself :)
+
+ In form of a table:
+ +---+----------------------------------------------------------------+
+ | \ | 0 1 2 3 4 5 6 7 8 9 A B C D E F |
+ +---+----------------------------------------------------------------+
+ | 0 | 0 ? ? ? ? ? ? ? ? > ^ ? ? ? ? ? |
+ | 1 | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? |
+ | 2 | SP ! " # $ % & ' ( ) * + , - . / |
+ | 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
+ | 4 | @ A B C D E F G H I J K L M N O |
+ | 5 | P Q R S T U V W X Y Z [ \ ] ^ _ |
+ | 6 | ` a b c d e f g h i j k l m n o |
+ | 7 | p q r s t u v w x y z { | } ~ ? |
+ +---+-----------------------------------------------------------------+
+
+ ascii table:
+ +---+----------------------------------------------------------------+
+ | \ | 0 1 2 3 4 5 6 7 8 9 A B C D E F |
+ +---+----------------------------------------------------------------+
+ | 0 | NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI |
+ | 1 | DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US |
+ | 2 | SP ! " # $ % & ' ( ) * + , - . / |
+ | 3 | 0 1 2 3 4 5 6 7 8 9 : ; < = > ? |
+ | 4 | @ A B C D E F G H I J K L M N O |
+ | 5 | P Q R S T U V W X Y Z [ \ ] ^ _ |
+ | 6 | ` a b c d e f g h i j k l m n o |
+ | 7 | p q r s t u v w x y z { | } ~ DEL |
+ +---+----------------------------------------------------------------+
+*/
+char to_printable(char c)
+{
+ /* print:
+
+ - tab as '>'
+ - newline as '^'
+ - nullchar as '0'
+ - all printables as they are
+ - all others as '?'...
+ */
+ char* special_chars = "\t\n";
+ char tab = special_chars[0];
+ char newline = special_chars[1];
+ char nullchar = special_chars[2];
+
+ if (c == tab) {
+ return '>';
+ } else if (c == newline) {
+ return '^';
+ } else if (c == nullchar) {
+ return '0';
+ } else if ((0x20 <= c) && (c <= 0x7e)) {
+ return c;
+ } else {
+ return '?';
+ }
+}
+
+
+/**
+ Dump the hex codes a string is made of.
+*/
+void simple_hexdump_string(char* string)
+{
+ char* c;
+ c = string;
+
+ int i = 0;
+ while (1) {
+
+ if ((i > 0) && (i % 8) == 0) printf(" ");
+ if ((i > 0) && (i % 16) == 0) printf("\n");
+
+ // printf("%0.2x ", *c);
+ printf("%.2x ", *c);
+
+ if (*c == '\0') break;
+
+ c++;
+ i++;
+ }
+
+ printf("\n");
+}
+
+
+/**
+ Test the hexdump functions.
+*/
+void hexdump_string_test()
+{
+ /* print a header */
+ printf("# ==========================================================\n");
+ printf("# Test: Hexdump String Functions:\n");
+ printf("# ----------------------------------------------------------\n");
+ printf("\n");
+
+ /* print the ascii code table */
+ printf(" ASCII Code Table:\n");
+ print_ascii_code_table();
+ printf("\n");
+
+ /* print the printable codes used in `hexdump_string()' */
+ printf(" Printabel Code Table -\n");
+ printf(" as used in the last column by `hexdump_string()':\n");
+ print_printable_dump_code_table();
+ printf("\n");
+
+ /* example string */
+ /* simple example: char* example_str = "eins zwei drei vier fuenf sechs sieben."; */
+ /* slightly more complicated: */
+ char* example_str =
+ "eins zwei drei vier fuenf sechs sieben, "
+ "tab: '\t', newline: '\n' and - to terminate the string - the nullchar: ";
+
+ /* prefix to indent the dumps */
+ char* prefix = " ";
+
+ /* print example text */
+ printf(" Dumping the following string:\n");
+ printf(" \"\%s\"\n", example_str);
+ printf("\n");
+
+ /* test the dump function */
+ printf(" String hex-dump using `hexdump_string()':\n");
+ hexdump_string(prefix, example_str);
+ printf("\n");
+
+ /* test the simple dump function */
+ printf("Simple string hex-dump using `simple_hexdump_string()':\n");
+ simple_hexdump_string(example_str);
+ printf("\n");
+
+ /* dumping all ASCII between 0 and 127 */
+ printf(" A dump of all ASCII between 01 and 7F - and the 00-char at the end:\n");
+
+ /* making a code buffer with all ASCII between 0 and 127 */
+ char hexbuf[0x7f + 1];
+ char* c = hexbuf;
+ char code;
+ *c++ = ' '; /* The first char is a blank... */
+ for (code = 1; 1 /* 0 <= code <= 0x7f */; code++, c++) {
+ /* fill the buffer with ASCII char codes */
+ /* Note: (code <= 0x7f) is always true */
+ /* as `code' is of type char... */
+ *c = code;
+ if (code == 0x7f) break; /* !!! code is a char and will turn negetive */
+ /* !!! if bigger incremented beyond 0x7e */
+ }
+ code = 0;
+ c++;
+ *c = code; /* 0x00 terminates the string */
+
+ /* dumping the code buffer */
+ hexdump_string(prefix, hexbuf);
+ printf("\n");
+
+ /* ... and a footer */
+ printf("# ==========================================================\n");
+ printf("# ==========================================================\n");
+ printf("\n");
+ printf("# fin :)\n");
+ printf("\n");
+}
+
+/* fin */
Index: source/blender/commandport/utilities/src/message_handler.c
===================================================================
--- source/blender/commandport/utilities/src/message_handler.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/message_handler.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,275 @@
+/*
+ * $Id: message_handler.c, v 1.0 2007/06/13, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * The message handler class implements the protocol used by the
+ * commandport for exchanging text messages via a socket connection.
+ * A message is defined as a string of an arbitrary length terminated
+ * with a '\0' character.
+ *
+ * header file: ../include/message_handler.h
+ *
+ */
+
+/* fin */
+
+/* Note:
+ for debugging the message handler, uncomment `#define DEBUG'.
+*/
+
+#include <stdio.h> /* for printf() and fprintf() */
+#include <string.h> /* for strlen() */
+#include <stdlib.h>
+#include <sys/socket.h> /* for recv() and send() */
+#include <unistd.h> /* for close() */
+
+#include "error_codes.h" /* error codes */
+#include "string_buffer.h"
+
+#include "message_handler.h"
+
+/* #define DEBUG */
+
+#ifdef DEBUG
+
+#define RCVBUFSIZE 5 /* DEBUG: make receive buffer small */
+#define IF_DEBUG(x) x
+
+#else
+
+#define RCVBUFSIZE 1024 /* Size of receive buffer */
+#define IF_DEBUG(x)
+
+#endif
+
+/* data structures */
+
+typedef struct message_handler_data {
+ int socket; /* socket id */
+ char* socket_buffer; /* internal receive buffer */
+ string_buffer message_buffer; /* a message might be send in different chunks -
+ this buffer is used to store the message chunks.
+ If more than one message is received in one chunk,
+ the remaining messages are also stored in this buffer. */
+ int chars_remaining; /* number of chars remaining in the internal receive buffer.
+ if `chars_remaining' is 0, the process will wait on
+ the socket for the next message;
+ if `chars_remaining' is bigger than 0, some bytes of
+ the next message already have been received */
+} message_handler_data;
+
+/* declarations */
+
+int scan_for_0_char(char* buffer, int length);
+void dump_message_chunk(char* buffer, int length);
+
+/* definitions */
+
+/**
+ */
+message_handler message_handler_new(int socket)
+{
+ /* allocate message handler data struct */
+ message_handler handler;
+ handler = (message_handler) malloc( sizeof(message_handler_data) );
+
+ /* init message handler data struct */
+ handler->socket = socket; /* socket id */
+ handler->socket_buffer = (char*) malloc( (RCVBUFSIZE + 1) * sizeof(char) );
+ /* internal receive buffer */
+ handler->socket_buffer[RCVBUFSIZE] = '\0'; /* the receive buffer always has to end on '\0'
+ to work with the string functions */
+ handler->message_buffer = string_buffer_new(); /* buffer to store the received message chunks */
+ handler->chars_remaining = 0; /* the internal message receive buffer is empty */
+
+ /* return the message handler data struct */
+ return handler;
+}
+
+/**
+ */
+void message_handler_delete(message_handler handler)
+{
+ /* free the members of the message handler data struct */
+ free(handler->socket_buffer);
+ string_buffer_delete(handler->message_buffer);
+
+ /* finally free the message handler data struct itself */
+ free(handler);
+}
+
+/**
+ Send a message.
+*/
+void message_handler_send_message(message_handler handler, char* message)
+{
+ int length;
+ length = strlen(message); /* length of message */
+ message[length] = '\0'; /* make sure that message ends on '\0' */
+
+ /* Send message */
+ length++; /* include the end-of-string / end-of-message marker '\0' */
+ if (send(handler->socket, message, length, 0) != length) {
+ fprintf(stderr, "Couldn't send message \"%s\"!\n", message);
+ exit(ERROR_SEND);
+ }
+}
+
+/**
+ */
+char* message_handler_receive_message_allocate(message_handler handler)
+{
+ /* empty the message buffer */
+ string_buffer_make_empty(handler->message_buffer);
+
+ /* get first chunk of message */
+ int received_chars; /* Size of chunk */
+ if (handler->chars_remaining) { /* first message chunk is still / already
+ in internal receive buffer - start with it */
+ received_chars = handler->chars_remaining;
+
+ } else {
+
+ /* receive first message chunk from socket */
+ if ((received_chars = recv(handler->socket, handler->socket_buffer, RCVBUFSIZE, 0)) < 0) {
+ fprintf(stderr, "Couldn't receive message!\n");
+ exit(ERROR_RECEIVE);
+ }
+ }
+
+ /* get rest of message */
+ while (1) {
+
+ /* a chunk size of 0 signals the end of the client connection */
+ if (received_chars == 0) return NULL;
+
+ /* printf(">>> %s", handler->socket_buffer); */
+ string_buffer_append(handler->message_buffer, handler->socket_buffer);
+
+ /* scan received buffer for the end-of-message character '\0'
+ `scan_for_0_char(handler->socket_buffer, RCVBUFSIZE)' returns
+ - received_chars if no '\0' was found and
+ - the position of '\0' in `buffer' if '\0' was found.
+ */
+ int length = scan_for_0_char(handler->socket_buffer, received_chars);
+
+ /* If '\0' was found (length != received_chars)
+ this is the last chunk of the current message
+ => set the `last_chunk_flag' */
+ int last_chunk_flag = (length != received_chars);
+
+ /* If the chunk size is one longer than the number of receive chars
+ (bytes + '\0') no bytes from the next message are received.
+ => If the number of received chars is bigger
+ set the `chars_remaining_flag' */
+ int chars_remaining_flag = ((length+1) < received_chars);
+
+ /* DEBUG: dump the received message chunk */
+ IF_DEBUG(dump_message_chunk(handler->socket_buffer, length);
+ printf("length: %d, received_chars: %d, "
+ "last_flag: %d, chars_remaining_flag: %d\n",
+ length, received_chars,
+ last_chunk_flag, chars_remaining_flag);
+ );
+
+ if (last_chunk_flag) { /* last chunk of message */
+
+ /* store the beginning of the next message (if existing) */
+ if (chars_remaining_flag) { /* more chars received than
+ number of chars still part of current message
+ +1 for the end-of-message marker '\n'
+ => these chars are part of the next message.
+ */
+
+ /* store the received chars in the message buffer */
+
+ /* calculate start of next message */
+ char* nextMessage = (handler->socket_buffer + (length+1 * sizeof(char)));
+
+ /* calculate number of chars remaining */
+ handler->chars_remaining = received_chars - (length+1);
+
+ /* move the remaining chars to begin of buffer */
+ memcpy(handler->socket_buffer, nextMessage, handler->chars_remaining);
+ /* terminate with '\0' for the `string_buffer' functions */
+ handler->socket_buffer[handler->chars_remaining] = '\0';
+
+ IF_DEBUG(printf("DEBUG: %d chars remaining in internal receive buffer: \"%s\"\n",
+ handler->chars_remaining, handler->socket_buffer);
+ );
+ } else {
+
+ handler->chars_remaining = 0; /* no chars remaining */
+ IF_DEBUG( printf("DEBUG: no chars remaining in internal receive buffer.\n"); );
+ }
+
+ /* get the message:
+ allocate a char array in the length of the received message
+ and store the message in the array
+ */
+ int length; /* length of the message */
+ char* message = string_buffer_to_char_array_allocate(handler->message_buffer, &length);
+
+ /* empty the message buffer */
+ string_buffer_make_empty(handler->message_buffer);
+ return message;
+ }
+
+ /* See if there is more data to receive */
+ if ((received_chars = recv(handler->socket, handler->socket_buffer, RCVBUFSIZE, 0)) < 0) {
+ fprintf(stderr, "Couldn't receive message!\n");
+ exit(ERROR_RECEIVE);
+ }
+ }
+}
+
+/**
+ */
+int scan_for_0_char(char* buffer, int length)
+{
+ int i;
+ for(i = 0; i < length; i++) if (buffer[i] == '\0') return i;
+ return i;
+}
+
+/**
+ Internal function only used for debugging:
+ Dump the first 'length' bytes of 'buffer'.
+*/
+void dump_message_chunk(char* buffer, int length)
+{
+ printf("DEBUG: received %d bytes: [ ", length);
+ int i;
+ for(i = 0; i < length; i++) {
+ if (i > 0) printf(", ");
+ printf("`%c' (%u)", buffer[i], buffer[i]);
+ }
+ printf(" ]\n");
+}
+
+/* fin */
Index: source/blender/commandport/utilities/src/message_client.c
===================================================================
--- source/blender/commandport/utilities/src/message_client.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/message_client.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,277 @@
+/*
+ * $Id: message_client.c, v 1.0 2007/06/13, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * The message client class is the central part of a Blender Command
+ * Port client written in c. It implements the functionality for
+ * connecting and disconnecting to / from a Blender Server and for
+ * sending and receiving text messages.
+ *
+ * header file: ../include/message_client.h
+ *
+ */
+
+#include <stdio.h> /* for printf() and fprintf() */
+#include <arpa/inet.h> /* for sockaddr_in and inet_addr() */
+#include <stdlib.h> /* for atoi() and exit() */
+#include <string.h> /* for memset() */
+#include <unistd.h> /* for close() */
+
+#include "message_handler.h" /* message handler to send and receive messages */
+
+#include "message_client.h"
+#include "fsleep.h"
+
+typedef struct message_client_struct {
+ char* server_IP_address; /* The IP address of the server to connect to */
+ unsigned short server_port; /* Port of the server */
+ struct sockaddr_in* server_address; /* server address structure */
+ int socket; /* socket descriptor */
+ message_handler handler; /* message handler to send and receive messages */
+} message_client_struct;
+
+/* utility function declarations */
+
+char* string_copy_allocate(char* str);
+struct sockaddr_in* make_server_address_structure_allocate(char* IP_address,
+ unsigned short server_port);
+void free_server_address_structure(struct sockaddr_in* server_address);
+int server_connect(message_client client);
+int server_connect_wait(message_client client, int retries, float retry_sleeptime);
+void server_disconnect(int socket_descriptor);
+
+/* function definitions */
+
+/**
+ */
+message_client message_client_new(char *server_IP_address, unsigned short server_port)
+{
+ /* try only once to connect */
+ int retries = 0;
+ float retry_sleeptime = 0.0;
+ return message_client_new_wait(server_IP_address, server_port, retries, retry_sleeptime);
+}
+
+/**
+ */
+message_client message_client_new_wait(char *server_IP_address, unsigned short server_port,
+ int retries, float retry_sleeptime)
+{
+ /* allocate memory for message client structure */
+ message_client client;
+ client = (message_client) malloc( sizeof(message_client_struct) );
+
+ /* check for errors */
+ if (client == NULL) {
+ fprintf(stderr, "Couldn't allocate memory for new message_client!\n");
+ exit(ERROR_MEMORY);
+ }
+
+ /* init members */
+ client->server_IP_address
+ = string_copy_allocate(server_IP_address); /* server_IP_address */
+ client->server_port = server_port; /* server_port */
+ client->server_address
+ = make_server_address_structure_allocate(server_IP_address, server_port);
+ /* server address structure */
+
+ /* connect to the server */
+ client->socket = server_connect_wait(client, retries, retry_sleeptime);
+
+ /* message handler */
+ client->handler = message_handler_new(client->socket);
+
+ /* return message client structure */
+ return client;
+}
+
+/**
+ Delete a message client.
+*/
+void message_client_delete(message_client client)
+{
+ /* disconnect from server */
+ server_disconnect(client->socket);
+
+ /* free members */
+ free(client->server_IP_address);
+ free_server_address_structure(client->server_address);
+ message_handler_delete(client->handler);
+
+ /* free message client structure */
+ free(client);
+}
+
+/**
+ Send a message.
+*/
+void message_client_send(message_client client, char* message)
+{
+ /* send message via the message handler */
+ message_handler_send_message(client->handler, message);
+}
+
+/**
+ Receive a message.
+ The return value NULL signals the end of the client connection.
+*/
+char* message_client_receive_allocate(message_client client)
+{
+ /* receive message via the message handler */
+ return message_handler_receive_message_allocate(client->handler);
+}
+
+/**
+ Send a message and return the answer.
+*/
+char* message_client_send_receive_allocate(message_client client, char* message)
+{
+ /* send the message */
+ message_client_send(client, message);
+
+ /* return the reply */
+ return message_client_receive_allocate(client);
+}
+
+/* utility functions */
+
+char* string_copy_allocate(char* str)
+{
+ int length = strlen(str);
+ char* copy = (char*) malloc( (length + 1) * sizeof(char) );
+ memcpy(copy, str, length);
+ copy[length]= '\0';
+ return copy;
+}
+
+/**
+ Allocates the memory for a server address structure
+ and initializes its members with the given parameters.
+*/
+struct sockaddr_in* make_server_address_structure_allocate(char* IP_address,
+ unsigned short server_port)
+{
+ /* allocate memory for server address structure */
+ struct sockaddr_in* server_address;
+ server_address = (struct sockaddr_in*) malloc( sizeof(struct sockaddr_in) );
+
+ /* Construct the server address structure */
+ memset(server_address, 0, sizeof(struct sockaddr_in)); /* zero out structure */
+ server_address->sin_family = AF_INET; /* internet address family */
+ server_address->sin_addr.s_addr = inet_addr(IP_address); /* server IP address */
+ server_address->sin_port = htons(server_port); /* server port */
+
+ /* return the socket address structure */
+ return server_address;
+}
+
+/**
+ Frees a server address structure.
+*/
+void free_server_address_structure(struct sockaddr_in* server_address)
+{
+ free(server_address);
+}
+
+/**
+ Connect to server.
+ Returns the socket descriptor.
+*/
+int server_connect(message_client client)
+{
+ /* try only once to connect */
+ int retries = 0;
+ float retry_sleeptime = 0.0;
+ return server_connect_wait(client, retries, retry_sleeptime);
+}
+
+/**
+ Connect to server.
+ Returns the socket descriptor.
+*/
+int server_connect_wait(message_client client, int retries, float retry_sleeptime)
+{
+ /* socket descriptor */
+ int socket_descriptor;
+
+ /* Create reliable stream socket using TCP */
+ if ((socket_descriptor = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ fprintf(stderr, "Couldn't create socket!\n");
+ exit(ERROR_SOCKET);
+ }
+
+ /* Try to establish a connection to the echo server -
+ retry `retries' times and sleep `retry_sleeptime' seconds in between.
+ */
+ int connected = -1; /* when a connection could be established, this should be 0 and -1 otherwise */
+ int i;
+ for (i = 0; i <= retries; i++) {
+
+ /* sleep `retry_sleeptime' seconds between attempts to connect to the server */
+ if (i > 0) fsleep(retry_sleeptime);
+
+ /* try to connect */
+ connected = connect(socket_descriptor,
+ (struct sockaddr*) client->server_address,
+ sizeof(*client->server_address));
+
+ /* if connection could be established, break */
+ if (connected == 0) break;
+
+ /* print a dot to signal that something is done */
+ if (i > 0) printf(".");
+ fflush(stdout);
+ }
+
+ /* check if connection could be established */
+ if (connected == 0) {
+ fprintf(stdout, "Connection to Blender Server established. (IP address: %s, port: %d)\n",
+ client->server_IP_address,
+ (int) client->server_port);
+ } else {
+ fprintf(stderr, "Couldn't connect to Blender Server (IP address: %s, port: %d)!\n",
+ client->server_IP_address,
+ (int) client->server_port);
+ exit(ERROR_CONNECTION);
+ }
+
+ /* return the socket descriptor */
+ return socket_descriptor;
+}
+
+/**
+ Disonnect from a server
+ by sending an empty message.
+*/
+void server_disconnect(int socket_descriptor)
+{
+ /* close the socket */
+ close(socket_descriptor);
+}
+
+/* fin */
Index: source/blender/commandport/utilities/src/SConscript
===================================================================
--- source/blender/commandport/utilities/src/SConscript (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/SConscript (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,42 @@
+# -*- mode: python -*-
+#
+# $Id: SConscript, v 1.0 2007/05/30, dietrich, tokyo $
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2007 by the Blender Foundation.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Author: Dietrich Bollmann
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+# Build file for directory: blender/source/blender/commandport/utilities/src/
+
+Import ('env')
+
+sources = env.Glob('*.c')
+
+incs = '../include'
+
+env.BlenderLib ( 'blender_commandport_utilities', sources, Split(incs), [],
+ libtype=['blender', 'blash'], priority=[0,0] )
+
+# fin.
Index: source/blender/commandport/utilities/src/bcp_debug.c
===================================================================
--- source/blender/commandport/utilities/src/bcp_debug.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/bcp_debug.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,72 @@
+/*
+ * $Id: bcp_debug.c, v 1.0 2007/05/30, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Module for initializing, storing and querying
+ * the Blender command port debug level.
+ *
+ * The command port can be made to print debug messages in different
+ * verbosity levels via the command line option `--debug bcp:<level>'.
+ * `<level>' can be one of 1, 2, 3, 4.
+ *
+ * For more information see the debug help text defined in function
+ * `print_help_debug()' in file `../../blender/src/bcp_handle_client.c'
+ * or call Blender with the option `-hd' / `--help=debug'.
+ *
+ * For the command port debug code search sources for `debug("bcp")'
+ * and `bcp_debug()'.
+ *
+ * header file: ../../../blenkernel/intern/debug.c
+ *
+ */
+
+#include <stdio.h>
+#include "bcp_debug.h"
+
+/* global BCP debug flag */
+int g_bcp_debug_flag = 0;
+
+/**
+ Set BCP debug level.
+*/
+void bcp_set_debug_level(int level)
+{
+ extern int g_bcp_debug_flag;
+ g_bcp_debug_flag = level;
+}
+
+/**
+ Returns the debug level for the Blender command port.
+*/
+int bcp_debug()
+{
+ extern int g_bcp_debug_flag;
+ return g_bcp_debug_flag;
+}
+
+/* fin */
Index: source/blender/commandport/utilities/src/bcp_shell.c
===================================================================
--- source/blender/commandport/utilities/src/bcp_shell.c (.../vendor/blender/working/current/blender) (revision 0)
+++ source/blender/commandport/utilities/src/bcp_shell.c (.../blender/working/branches/bcp/blender) (revision 79)
@@ -0,0 +1,785 @@
+/*
+ * $Id: bcp_shell.c, v 1.0 2007/05/31, dietrich, tokyo $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 by the Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Author: Dietrich Bollmann
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ *
+ * Defines the interactive shell called by blash's `main()' function.
+ *
+ * header file: ../include/bcp_shell.h
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h> /* for exit() */
+#include <string.h>
+
+#include "string_buffer.h"
+#include "message_client.h"
+#include "bcp_debug.h"
+#include "bcp_meta_commands.h"
+#include "bcp_package.h"
+
+#include "bcp_shell.h"
+
+#define MAXLINE 1024
+#define SHELL_SINGLE_FILE_INPUT_PROMPT "SF> "
+#define EVAL_MODE_PROMPT "EM> "
+#define FILE_MODE_PROMPT "FM> "
+#define SINGLE_MODE_PROMPT ">>> "
+#define INPUT_CONTINUE_PROMPT "... "
+
+/* function declarations */
+int process_shell_meta_command(message_client client, string_buffer command, int *mode);
+int read_command(string_buffer buffer, int mode);
+void print_help_text();
+void process_python_single_input_loop(message_client client, string_buffer command, int mode);
+int blender_process_python_input(message_client client, string_buffer command, int mode);
+int print_blender_result(char* result);
+char mode_to_bcp_meta_command(int mode);
+
+/**
+ blash help text:
+
+ Printed by `print_help_text()' after entering the command `help'
+*/
+static char* g_blash_help_text = "\nThis is blash - The BLender-Again SHell :)\n\nCOMMANDS:\n\ntodo\n\n";
+
+/**
+ Open a new Blender command port shell.
+*/
+void bcp_shell(char* server_IP_address, unsigned short server_port, int mode)
+{
+ /* try only once to connect */
+ int retries = 0;
+ float retry_sleeptime = 0.0;
+ bcp_shell_wait(server_IP_address, server_port, mode, retries, retry_sleeptime);
+}
+
+/**
+ Open a new Blender command port shell.
+
+ If the connection to the Blender server could not been established immediately,
+ retry up to `retries' times. Sleep `retry_sleeptime' seconds before trying again.
+*/
+void bcp_shell_wait(char* server_IP_address, unsigned short server_port, int mode,
+ int retries, float retry_sleeptime)
+{
+ /* get debug message level */
+ int debug = bcp_debug();
+
+ string_buffer command = NULL;
+ message_client client = NULL;
+ int length;
+ int ok;
+
+ /* make a new message client
+ to handle the communication with the server
+ */
+ client = message_client_new_wait(server_IP_address, server_port,
+ retries, retry_sleeptime);
+
+ /* error checking */
+ if (client == NULL) {
+ fprintf(stderr, "ERROR - Couldn't connect to the Blender server!");
+ exit(1);
+ }
+
+ /* a string buffer to read the commands from stdin */
+ command = string_buffer_new();
+
+ /* error checking */
+ if (command == NULL) {
+ fprintf(stderr, "ERROR - Couldn't allocate command text buffer!");
+ exit(1);
+ }
+
+ /* init the prompts to use */
+ string_buffer_set_line_prompt( command, SINGLE_MODE_PROMPT );
+ string_buffer_set_text_prompt( command, FILE_MODE_PROMPT );
+ string_buffer_set_text_coninue_prompt( command, INPUT_CONTINUE_PROMPT );
+
+ /* the shell loop */
+ while (1) {
+
+ /* read input from shell
+ - if in line mode read a line;
+ - if in text mode read a text.
+
+ if length < 0 there was a problem while reading the input
+ - probably because CTRL-D was hit. => exit...
+ */
+ length = read_command(command, mode);
+
+ /* process the command:
+ - check for shell meta commands and process them
+ - if no shell meta command was found, process the
+ command in the currently active shell mode
+ */
+
+ /* process shell command */
+ if (length < 0 ||
+ !string_buffer_compare_to_string(command, "bye") ||
+ !string_buffer_compare_to_string(command, "quit") ||
+ !string_buffer_compare_to_string(command, "exit") ||
+ !string_buffer_compare_to_string(command, "bye\n") ||
+ !string_buffer_compare_to_string(command, "quit\n") ||
+ !string_buffer_compare_to_string(command, "exit\n")
+ ) {
+
+ /* exit the shell loop */
+ break;
+
+ } else if (!string_buffer_compare_to_string(command, "help") ||
+ !string_buffer_compare_to_string(command, "help\n")
+ ) {
+
+ /* print help text */
+ print_help_text();
+
+ } else if (string_buffer_starts_with_prefix(command, ".")) {
+
+ /* the command starts with a dot ('.')
+ and is interpreted as shell meta command.
+ Process the shell meta command
+ */
+ ok = process_shell_meta_command(client, command, &mode);
+
+ /* if !ok,
+ process_shell_meta_command() probably tried to read from the shell
+ without result - probably because CTRL-D was hit.
+ exit
+ */
+ if (!ok) {
+ /* exit the shell loop */
+ break;
+ }
+
+
+ } else if (string_buffer_is_empty_or_white_space_string(command)) {
+
+ /* the command is an empty line
+ or a line made only from white space
+ */
+ /* ignore the input line... */
+
+ } else {
+
+ /* A Blender Python command:
+ Send command to blender for evaluation in the given evaluation mode
+ and print the result.
+ */
+ process_python_single_input_loop(client, command, mode);
+ }
+
+ /* empty the command buffer */
+ string_buffer_make_empty(command);
+ }
+
+ /* shell exited - cleanup */
+
+ /* delete the command buffer */
+ if (debug) printf("[DEBUG] bcp_shell: string_buffer_delete(command);\n");
+ string_buffer_delete(command);
+
+ /* delete the message client */
+ if (debug) printf("[DEBUG] bcp_shell: message_client_delete(client);\n");
+ message_client_delete(client);
+}
+
+/**
+ Process a shell meta command.
+ Shell meta commands are commands starting with a dot caracter ('.').
+
+ The following meta commands are defined:
+
+ - . The next input is interpreted as a multi line command,
+ terminated with another dot.
+ Multi line command are evaluated in file mode.
+ - .shell / .single Switch to shell/single input mode.
+ - .eval Switch to eval input mode.
+ - .file Switch to file input mode.
+*/
+int process_shell_meta_command(message_client client, string_buffer command, int *mode)
+{
+ /* process the shell meta command */
+ if (!string_buffer_compare_to_string(command, ".")) {
+
+ /* read a single multi line command from stdin,
+ process it in file mode and
+ continue with the shell mode in the same mode as before
+ */
+ printf("...single text\n");
+ string_buffer_make_empty(command); /* empty command buffer */
+
+ /* read a single multi line command (text) from stdin
+ using the appropriate prompt
+ */
+
+ /* store current prompt */
+ char* prompt = NULL;
+ prompt = string_buffer_get_text_prompt_allocate(command);
+ if (prompt == NULL) {
+ fprintf(stderr, "ERROR while trying to copy a string buffer line input prompt!\n");
+ exit(1);
+ }
+
+ /* (temporarily) set text prompt */
+ string_buffer_set_text_prompt(command, SHELL_SINGLE_FILE_INPUT_PROMPT);
+
+ /* read a multi line command (text) from stdin */
+ int length;
+ length = string_buffer_read_text_from_stdin(command);
+
+ /* if -1 was returned, exit: there was either an input problem or CTRL-D was hit */
+ if (length < 0) {
+ /* return -1 without doing anything */
+ string_buffer_make_empty(command); /* empty command buffer */
+ return 0;
+ }
+
+ /* restore prompt */
+ string_buffer_set_text_prompt(command, prompt);
+ free(prompt);
+
+ /* Send command to blender for evaluation in BCP_FILE_MODE
+ and print the result.
+ */
+
+ int bcp_return_code;
+ bcp_return_code = blender_process_python_input(client, command, BCP_FILE_MODE);
+
+ } else if (!string_buffer_compare_to_string(command, ".shell") ||
+ !string_buffer_compare_to_string(command, ".single") ||
+ !string_buffer_compare_to_string(command, ".s") ||
+ !string_buffer_compare_to_string(command, ".shell\n") ||
+ !string_buffer_compare_to_string(command, ".single\n") ||
+ !string_buffer_compare_to_string(command, ".s\n")
+ ) {
+
+ printf("...shell/single mode\n");
+
+ /* switch to single mode */
+ string_buffer_set_text_prompt(command, SINGLE_MODE_PROMPT); /* set prompt */
+ *mode = BCP_SINGLE_MODE;
+
+ } else if (!string_buffer_compare_to_string(command, ".eval") ||
+ !string_buffer_compare_to_string(command, ".e") ||
+ !string_buffer_compare_to_string(command, ".eval\n") ||
+ !string_buffer_compare_to_string(command, ".e\n")
+ ) {
+
+ printf("...eval mode\n");
+
+ /* switch to eval mode */
+ string_buffer_set_text_prompt(command, EVAL_MODE_PROMPT); /* set prompt */
+ *mode = BCP_EVAL_MODE;
+
+ } else if (!string_buffer_compare_to_string(command, ".file") ||
+ !string_buffer_compare_to_string(command, ".f") ||
+ !string_buffer_compare_to_string(command, ".file\n") ||
+ !string_buffer_compare_to_string(command, ".f\n")
+ ) {
+
+ printf("...file mode\n");
+
+ /* switch to file mode */
+ string_buffer_set_text_prompt(command, FILE_MODE_PROMPT); /* set prompt */
+ *mode = BCP_FILE_MODE;
+
+ } else {
+
+ /* Unknown shell meta command */
+
+ /* make it a string */
+ char* command_string = NULL;
+ command_string = string_buffer_to_char_array_allocate(command, NULL);
+ if (command_string == NULL) {
+ fprintf(stderr, "ERROR: Couldn't convert a string buffer to a string!");
+ exit(1);
+ }
+
+ /* print warning */
+ printf("WARNING: Ignoring unknown shell meta command: %s...\n", command_string);
+ free(command_string);
+
+ /* do nothing - ignore command */
+ }
+
+ /* empty command buffer */
+ string_buffer_make_empty(command);
+
+ /* success */
+ return 1;
+}
+
+/**
+ Read command from shell
+ - if in line mode read a line;
+ - if in text mode read a text.
+*/
+int read_command(string_buffer command, int mode)
+{
+ int length; /* return the length of the read input */
+
+ switch (mode) {
+
+ case BCP_SINGLE_MODE:
+
+ /* read a single line from stdin */
+ length = string_buffer_read_line_from_stdin(command);
+ break;
+
+ case BCP_EVAL_MODE:
+ case BCP_FILE_MODE:
+
+ /* read a multi line command (text) from stdin */
+ length = string_buffer_read_text_from_stdin(command);
+ break;
+
+ default :
+ /* ERROR: undefined mode: */
+ fprintf(stderr, "ERROR: Undefined shell input mode!");
+ exit(1);
+ break;
+ }
+
+ /* return length */
+ return length;
+}
+
+/**
+ Print blash help text.
+*/
+void print_help_text()
+{
+ extern char* g_blash_help_text;
+
+ printf(g_blash_help_text);
+}
+
+/**
+ Process a shell meta command.
+ Shell meta commands are commands starting with a dot caracter ('.').
+
+ The following meta commands are defined:
+
+ - . The next input is interpreted as a multi line command,
+ terminated with another dot.
+ Multi line command are evaluated in file mode.
+ - .shell / .single Switch to shell/single input mode.
+ - .eval Switch to eval input mode.
+ - .file Switch to file input mode.
+*/
+void process_python_single_input_loop(message_client client, string_buffer command, int mode)
+{
+ /* get debug message level */
+ int debug = bcp_debug();
+
+ int bcp_return_code;
+
+ /* read input lines
+ until command is entered completely
+ or an input error is detected
+ */
+ while (1) {
+
+ /* send next command line to blender */
+ bcp_return_code = blender_process_python_input(client, command, mode);
+
+ /* react corresponding to the return code */
+ switch (bcp_return_code) {
+
+ case BCP_RESULT_CODE_SUCCESS:
+
+ /* a complete python command was entered
+ and executed successfully
+
+ continue with the shell loop
+ */
+
+ /* DEBUG */
+ if (debug) printf("[DEBUG] return code: BCP_RESULT_CODE_SUCCESS\n");
+
+ /* continue with the shell loop */
+ break;
+
+ case BCP_RESULT_CODE_INCOMPLETE_INPUT:
+
+ /* the entered command is still incomplete
+
+ set the "input continue prompt" ('... ')
+ read next line
+ and continue with the loop
+ */
+
+ /* DEBUG */
+ if (debug) printf("[DEBUG] return code: BCP_RESULT_CODE_INCOMPLETE_INPUT\n");
+
+ /* empty the command buffer */
+ string_buffer_make_empty(command);
+
+ /* set the line prompt to "... "
+ to indicate an uncomplete python input
+ */
+ string_buffer_set_line_prompt(command, INPUT_CONTINUE_PROMPT);
+
+ /* read next input line from shell */
+ read_command(command, mode);
+
+ /* continue with loop */
+ continue;
+
+ /* never reached */
+ break;
+
+ case BCP_RESULT_CODE_ERROR:
+
+ /* there was an error
+ while reading or executing the input already entered
+
+ a python error should have been printed already by `blender_process_python_input()'
+ continue with the shell loop
+ */
+
+ /* DEBUG */
+ if (debug) printf("[DEBUG] return code: BCP_RESULT_CODE_ERROR\n");
+
+ break;
+
+ case BCP_RESULT_CODE_UNDEFINED:
+
+ /* the evaluatino of the input resulted in an unexpected result
+ ...this should never happen...
+
+ print an error
+ and exit the shell
+ */
+
+ /* DEBUG */
+ if (debug) printf("[DEBUG] return code: BCP_RESULT_CODE_UNDEFINED\n");
+
+ /* print error message */
+ fprintf(stderr, "ERROR in BCP protocol: Blender reported an unexpected result!\n");
+ exit(ERROR_BCP_PYTHON);
+
+ break;
+
+ case BCP_RESULT_CODE_EMPTY_INPUT:
+
+ /* the input was empty
+ this should never happen
+ as empty input lines are handled by the shell
+
+ print an error
+ and exit
+ */
+
+ /* DEBUG */
+ if (debug) printf("[DEBUG] return code: BCP_RESULT_CODE_EMPTY_INPUT\n");
+
+ /* print error message */
+ fprintf(stderr, "ERROR in BCP protocol: Blender complained about an empty input!\n");
+ exit(ERROR_IN_BCP_PROTOCOL);
+
+ break;
+
+ default:
+
+ /* an unknown return code was returned
+ this should never happen
+ and results an error in the BCP protocol...
+
+ print an error and exit
+ */
+
+ /* DEBUG */
+ if (debug) printf("[DEBUG] return code: ERROR - unknown result code!\n");
+
+ /* print error message */
+ fprintf(stderr, "ERROR in BCP protocol: Blender returned an unknown return code!\n");
+ exit(ERROR_IN_BCP_PROTOCOL);
+
+ /* never reached */
+ break;
+ }
+
+ /* a complete command was entered and executed
+ or an error occurred
+
+ continue with the shell loop
+ */
+ break;
+
+ }
+
+ /* restore the normal python line prompt ('>>> ')
+ to indicate that a complete python command was read in
+ */
+ string_buffer_set_line_prompt(command, SINGLE_MODE_PROMPT);
+}
+
+/**
+ Send command to blender for evaluation in the given evaluation mode
+ and print the result.
+*/
+int blender_process_python_input(message_client client, string_buffer command, int mode)
+{
+ /* pack
+ - the mode code and
+ - the command
+ into a bcp_package
+ */
+
+ /* get debug message level */
+ int debug = bcp_debug();
+ int debug2 = (debug >= 2);
+
+ /* make a package */
+ bcp_package command_package;
+ command_package = bcp_package_new();
+
+ /* add the code for the mode */
+ char mode_command;
+ mode_command = mode_to_bcp_meta_command(mode);
+ bcp_package_add_command(command_package, mode_command);
+
+ /* add the command string */
+ char* command_string = NULL;
+ command_string = string_buffer_to_char_array_allocate(command, NULL);
+ bcp_package_add_string(command_package, command_string);
+
+ /* pack the buffer into a newly allocated string */
+ char* packed_command;
+ packed_command = bcp_package_pack_allocate(command_package);
+
+ /* debug: print the packed package */
+ if (debug2) {
+ printf(">>> the packed command package:\n>>>");
+ printf("%s", packed_command);
+ printf("<<<\n");
+ }
+
+ /* delete package */
+ bcp_package_delete(command_package);
+
+ /* free the command string */
+ free(command_string);
+ command_string = NULL;
+
+ /* ================= */
+ /* process the input */
+ /* ----------------- */
+
+ /* send the command to the server and wait for the reply */
+ char* result = NULL;
+ result = message_client_send_receive_allocate(client, packed_command);
+
+ /* free the packed command */
+ free(packed_command);
+ packed_command = NULL;
+
+ /* error checking */
+ if (result == NULL) {
+ fprintf(stderr, "ERROR - Couldn't get a result from the Blender server!\n");
+ fflush(stderr);
+ exit(1);
+ }
+
+ /* print the result */
+ int bcp_return_code;
+ bcp_return_code = print_blender_result(result);
+
+ /* free the packed string representation */