33 void RecordingMacro::write_dated_comment(
const char *what)
const {
42 : stop_action_name(strdup(stop_action_name_)),
43 application_id(strdup(application_id_)),
48 path = (filename[0] ==
'/')
63 if (expand_existing) {
65 char *close = strstr(content,
"ARB::close");
66 if (close) close[0] = 0;
72 out = fopen(path,
"w");
76 write_dated_comment(expand_existing ?
"recording resumed" :
"recording started");
87 void RecordingMacro::write_as_perl_string(
const char *value)
const {
88 const char SQUOTE =
'\'';
90 for (
int i = 0; value[i]; ++i) {
104 bool handled =
false;
110 static int MACRO_START_LEN = strlen(MACRO_ACTION_START);
111 const char *sub_action = action_name+MACRO_START_LEN;
113 int playbackType = 0;
121 write(
"BIO::macro_execute(");
122 write_as_perl_string(macroName);
124 write(
'0'+(playbackType-1));
136 write(
"BIO::remote_action($gb_main");
137 write(
','); write_as_perl_string(app_id);
138 write(
','); write_as_perl_string(action_name);
144 write(
"BIO::remote_awar($gb_main");
145 write(
','); write_as_perl_string(app_id);
146 write(
','); write_as_perl_string(awar_name);
147 write(
','); write_as_perl_string(content);
158 else if (action_id[0] ==
'$') {
161 else if (strcmp(action_id, stop_action_name) != 0) {
183 write_dated_comment(
"recording stopped");
184 write(
"ARB::close($gb_main);\n");
201 const char *found = strchr(str, qchar);
203 if (found[-1] ==
'\\') {
215 while (isspace(line[0])) ++
line;
216 if (line[0] ==
'\"' || line[0] ==
'\'') {
220 line = other_quote+1;
221 while (isspace(line[0])) ++
line;
235 while (isspace(line[0])) ++
line;
237 const char cmd[] =
"BIO::remote_awar($gb_main,";
240 if (strncmp(line, cmd, cmd_len) == 0) {
244 bool app_id_differs = strcmp(app_id,
id) != 0;
246 if (app_id_differs)
return NULp;
251 if (line[0] ==
',') {
262 return strcmp(line,
"BIO::remote_action($gb_main,\'ARB_NT\',\'macros\');") == 0;
266 return strcmp(line,
"ARB::close($gb_main);") == 0;
271 while (isspace(line[i])) ++i;
272 return line[i] ==
'#';
275 void RecordingMacro::post_process() {
279 error = macro.has_error();
281 StrArray&
line = macro.lines();
284 for (
size_t i = 0; i<line.size(); ++i) {
288 for (
size_t n = i+1; n<line.size(); ++n) {
292 if (strcmp(mod_awar, mod_next_awar) == 0) {
309 bool isLastCommand =
true;
310 for (
size_t n = i+1; n<line.size() && isLastCommand; ++n) {
312 isLastCommand =
false;
321 error = macro.save();
333 #define TEST_PARSE_QUOTED_STRING(in,res_exp,out_exp) do { \
334 const char *line = (in); \
335 char *res =parse_quoted_string(line); \
336 TEST_EXPECT_EQUAL(res, res_exp); \
337 TEST_EXPECT_EQUAL(line, out_exp); \
341 #define TEST_MODIFIES_AWAR(cmd,app_exp,awar_exp,app_in) do { \
342 char *app = app_in; \
343 char *awar = modifies_awar(cmd, app); \
344 TEST_EXPECTATION(all().of(that(awar).is_equal_to(awar_exp), \
345 that(app).is_equal_to(app_exp))); \
351 const char *null =
NULp;
352 TEST_PARSE_QUOTED_STRING(
"", null,
"");
353 TEST_PARSE_QUOTED_STRING(
"\"str\"",
"str",
"");
354 TEST_PARSE_QUOTED_STRING(
"\"part\", rest",
"part",
", rest");
355 TEST_PARSE_QUOTED_STRING(
"\"\"",
"",
"");
356 TEST_PARSE_QUOTED_STRING(
"\"\"rest",
"",
"rest");
357 TEST_PARSE_QUOTED_STRING(
"\"unmatched", null,
"\"unmatched");
359 TEST_MODIFIES_AWAR(
"# BIO::remote_awar($gb_main,\"app\", \"awar_name\", \"value\");", null, null,
NULp);
360 TEST_MODIFIES_AWAR(
"BIO::remote_awar($gb_main,\"app\", \"awar_name\", \"value\");",
"app",
"awar_name",
NULp);
361 TEST_MODIFIES_AWAR(
"BIO::remote_awar($gb_main,\"app\", \"awar_name\", \"value\");",
"app",
"awar_name", strdup(
"app"));
362 TEST_MODIFIES_AWAR(
"BIO::remote_awar($gb_main,\"app\", \"awar_name\", \"value\");",
"diff", null, strdup(
"diff"));
364 TEST_MODIFIES_AWAR(
" \t BIO::remote_awar($gb_main,\"app\", \"awar_name\", \"value\");",
"app",
"awar_name",
NULp);
367 void TEST_post_process() {
369 const char *source =
"general/pp.amc";
370 const char *dest =
"general/pp_out.amc";
371 const char *expected =
"general/pp_exp.amc";
void track_action(const char *action_id)
#define implicated(hypothesis, conclusion)
void track_awar_change(AW_awar *awar)
long GB_mode_of_file(const char *path)
RecordingMacro(const char *filename, const char *application_id_, const char *stop_action_name_, bool expand_existing)
GB_ERROR GB_IO_error(const char *action, const char *filename)
const char * ARB_date_string()
const char * GBS_global_string(const char *templat,...)
char * AW_get_selected_fullname(AW_root *awr, const char *awar_prefix)
char * ARB_strpartdup(const char *start, const char *end)
int GB_unlink(const char *path)
char * parse_quoted_string(const char *&line)
#define ARRAY_ELEMS(array)
GB_ERROR GB_await_error()
static AW_root * SINGLETON
#define TEST_EXPECT(cond)
static void error(const char *msg)
GB_CSTR GB_path_in_ARBHOME(const char *relative_path)
bool opens_macro_dialog(const char *line)
char * read_as_string() const
#define TEST_EXPECT_ZERO_OR_SHOW_ERRNO(iocond)
const char * GBT_relativeMacroname(const char *macro_name)
void write_awar_change(const char *app_id, const char *awar_name, const char *content)
GB_CSTR GB_path_in_ARBLIB(const char *relative_path)
GB_ERROR GB_set_mode_of_file(const char *path, long mode)
GB_CSTR GB_concat_path(GB_CSTR anypath_left, GB_CSTR anypath_right)
const char * closing_quote(const char *str, char qchar)
void write_action(const char *app_id, const char *action_name)
#define TEST_EXPECT_NO_ERROR(call)
bool is_end_of_macro(const char *line)
void aw_message(const char *msg)
bool GB_is_readablefile(const char *filename)
bool ARB_strBeginsWith(const char *str, const char *with)
#define TEST_EXPECT_TEXTFILE_DIFFLINES(fgot, fwant, diff)
bool is_comment(const char *line)
void warn_unrecordable(const char *what)
#define MACRO_PLAYBACK_MARKED_ID
GB_CSTR GB_getenvARBMACROHOME(void)
static const char * action_name[]
#define MACRO_PLAYBACK_ID
char * modifies_awar(const char *line, char *&app_id)
char * GBS_global_string_copy(const char *templat,...)
char * GB_read_file(const char *path)