diff --git a/urjtag/ChangeLog b/urjtag/ChangeLog index 273aecec..d1355419 100644 --- a/urjtag/ChangeLog +++ b/urjtag/ChangeLog @@ -1,3 +1,8 @@ +2009-05-05 Rutger Hofman + + * src/flash/, src/svf/, src/tap/*.c, src/tap/parallel/, src/tap/usbconn: + replace calls to printf() with calls to urj_log() and urj_error_set() + 2009-05-07 Arnim Laeuger * src/tap/cable/wiggler2.c: [ 2782581 ] TRST, TMS and TDI incorrectly marked diff --git a/urjtag/include/urjtag/bsdl.h b/urjtag/include/urjtag/bsdl.h index d9fc5594..289b71fa 100644 --- a/urjtag/include/urjtag/bsdl.h +++ b/urjtag/include/urjtag/bsdl.h @@ -41,6 +41,11 @@ typedef struct bsdl.debug = 0; \ } while (0) +/** @return + * < 0 : Error occured, parse/syntax problems or out of memory + * = 0 : No errors, idcode not checked or mismatching + * > 0 : No errors, idcode checked and matched + */ int urj_bsdl_read_file (urj_chain_t *, const char *, int, const char *); void urj_bsdl_set_path (urj_chain_t *, const char *); int urj_bsdl_scan_files (urj_chain_t *, const char *, int); diff --git a/urjtag/include/urjtag/error.h b/urjtag/include/urjtag/error.h index 2bfd4a68..f9bcee45 100644 --- a/urjtag/include/urjtag/error.h +++ b/urjtag/include/urjtag/error.h @@ -75,7 +75,7 @@ extern urj_error_state_t urj_error_state; /** * Descriptive string for error type */ -extern const char *urj_error_string(urj_error_t error); +extern const char *urj_error_string (urj_error_t error); /** * Set error state. @@ -94,10 +94,10 @@ extern const char *urj_error_string(urj_error_t error); __VA_ARGS__); \ if (0 && urj_log_state.level < URJ_LOG_LEVEL_SILENT) \ { \ - urj_log(URJ_LOG_LEVEL_ERROR, "%s:%d %s() %s: ", __FILE__, \ - __LINE__, __func__, urj_error_string(e)); \ - urj_log(URJ_LOG_LEVEL_ERROR, __VA_ARGS__); \ - urj_log(URJ_LOG_LEVEL_ERROR, "\n"); \ + urj_log (URJ_LOG_LEVEL_ERROR, "%s:%d %s() %s: ", __FILE__, \ + __LINE__, __func__, urj_error_string (e)); \ + urj_log (URJ_LOG_LEVEL_ERROR, __VA_ARGS__); \ + urj_log (URJ_LOG_LEVEL_ERROR, "\n"); \ } \ } while (0) diff --git a/urjtag/include/urjtag/parse.h b/urjtag/include/urjtag/parse.h index 76a976fd..c2b4abb3 100644 --- a/urjtag/include/urjtag/parse.h +++ b/urjtag/include/urjtag/parse.h @@ -30,11 +30,11 @@ #include "types.h" /** - * @return -1 on failure; see urj_parse_line() otherwise + * @return -1 on error; see urj_parse_line() otherwise */ int urj_parse_file (urj_chain_t *chain, const char *filename); /** - * @return 1 on failure; urj_cmd_run() otherwise + * @return URJ_STATUS_FAIL on error; urj_cmd_run() otherwise */ int urj_parse_line (urj_chain_t *chain, char *line); /** @@ -42,5 +42,18 @@ int urj_parse_line (urj_chain_t *chain, char *line); */ int urj_parse_stream (urj_chain_t *chain, FILE *f); +/** + * Include a file. Autodetects whether it is a bsdl file or a UrJTAG command + * shell script. + * + * @param filename if begins with a slash, or dots followed by a slash, ignore + * the search path + * @param ignore_path ignore the search path anyway + * + * @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error + */ +int urj_parse_include (urj_chain_t *chain, const char *filename, + int ignore_path); + #endif /* URJ_PARSE_H */ diff --git a/urjtag/include/urjtag/part.h b/urjtag/include/urjtag/part.h index 23faab6e..353b87b8 100644 --- a/urjtag/include/urjtag/part.h +++ b/urjtag/include/urjtag/part.h @@ -25,8 +25,6 @@ #ifndef URJ_PART_H #define URJ_PART_H -#include - #include "types.h" #define URJ_PART_MANUFACTURER_MAXLEN 25 @@ -52,25 +50,28 @@ struct urj_part urj_part_t *urj_part_alloc (const urj_tap_register_t *id); void urj_part_free (urj_part_t *p); -urj_part_t *read_part (FILE *f, urj_tap_register_t *idr); +/* @return instruction pointer on success; NULL if not found but does not set + * urj_error; NULL on error */ urj_part_instruction_t *urj_part_find_instruction (urj_part_t *p, const char *iname); +/* @return data register pointer on success; NULL if not found but does not set + * urj_error; NULL on error */ urj_data_register_t *urj_part_find_data_register (urj_part_t *p, const char *drname); +/* @return signal pointer on success; NULL if not found but does not set + * urj_error; NULL on error */ urj_part_signal_t *urj_part_find_signal (urj_part_t *p, const char *signalname); void urj_part_set_instruction (urj_part_t *p, const char *iname); -/** - * @return URJ_STATUS_FAIL on error; URJ_STATUS_OK on success - */ +/** @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error */ int urj_part_set_signal (urj_part_t *p, urj_part_signal_t *s, int out, int val); -/** - * @return -1 on error; >= 0 for success - */ +/** @return -1 on error; signal number >= 0 for success */ int urj_part_get_signal (urj_part_t *p, urj_part_signal_t *s); -void urj_part_print (urj_part_t *p); +/* @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error */ +int urj_part_print (urj_part_t *p); /** * Set the length of the instructions of a part + * @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error */ int urj_part_instruction_length_set (urj_part_t *part, int length); /** @@ -98,8 +99,11 @@ struct urj_parts urj_parts_t *urj_part_parts_alloc (void); void urj_part_parts_free (urj_parts_t *ps); +/* @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error */ int urj_part_parts_add_part (urj_parts_t *ps, urj_part_t *p); -void urj_part_parts_set_instruction (urj_parts_t *ps, const char *iname); -void urj_part_parts_print (urj_parts_t *ps); +/* @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error */ +int urj_part_parts_set_instruction (urj_parts_t *ps, const char *iname); +/* @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error */ +int urj_part_parts_print (urj_parts_t *ps); #endif /* URJ_PART_H */ diff --git a/urjtag/src/cmd/cmd_addpart.c b/urjtag/src/cmd/cmd_addpart.c index d38d94cb..26ad8499 100644 --- a/urjtag/src/cmd/cmd_addpart.c +++ b/urjtag/src/cmd/cmd_addpart.c @@ -59,6 +59,7 @@ cmd_addpart_run (urj_chain_t *chain, char *params[]) chain->parts = NULL; } + /* @@@@ RFHH check result */ urj_part_parts_set_instruction (chain->parts, "BYPASS"); /* @@@@ RFHH check result */ urj_tap_chain_shift_instructions (chain); diff --git a/urjtag/src/cmd/cmd_include.c b/urjtag/src/cmd/cmd_include.c index b59a3582..4e311128 100644 --- a/urjtag/src/cmd/cmd_include.c +++ b/urjtag/src/cmd/cmd_include.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -40,9 +41,8 @@ static int cmd_include_or_script_run (urj_chain_t *chain, int is_include, char *params[]) { - int go = 0, i, j = 1; - char *path; - int len; + int i; + unsigned int j = 1; if (urj_cmd_params (params) < 2) return -1; @@ -52,67 +52,28 @@ cmd_include_or_script_run (urj_chain_t *chain, int is_include, char *params[]) printf (_("Please use the 'include' command instead of 'script'\n")); } - /* If "params[1]" begins with a slash, or dots followed by a slash, - * assume that user wants to ignore the search path */ - - path = params[1]; -#ifdef __MINGW32__ - if (isalpha (*path) && path[1] == ':') - path += 2; -#endif - while (*path == '.') - path++; - if (*path == '/' || *path == '\\' || !is_include) - { - path = strdup (params[1]); - } - else + if (urj_cmd_params (params) > 2) { - const char *jtag_data_dir = urj_get_data_dir (); - path = malloc (len = strlen (jtag_data_dir) + strlen (params[1]) + 2); - if (path != NULL) + /* loop n times option */ + if (urj_cmd_get_number (params[2], &j)) { - snprintf (path, len, "%s/%s", jtag_data_dir, params[1]); + printf (_("%s: unable to get number from '%s'\n"), + "include/script", params[2]); + return -1; } } - if (path == NULL) - { - printf (_("Out of memory\n")); - return 1; - } - -#ifdef ENABLE_BSDL - /* perform a test read to check for BSDL syntax */ - if (urj_bsdl_read_file (chain, path, URJ_BSDL_MODE_INCLUDE1, NULL) >= 0) - { - /* it seems to be a proper BSDL file, so re-read and execute */ - go = urj_bsdl_read_file (chain, path, URJ_BSDL_MODE_INCLUDE2, NULL); - - free (path); - return 1; - } -#endif - - if (urj_cmd_params (params) > 2) - { - sscanf (params[2], "%d", &j); /* loop n times option */ - } for (i = 0; i < j; i++) { - go = urj_parse_file (chain, path); - - if (go < 0) + if (urj_parse_include (chain, params[1], ! is_include) != URJ_STATUS_OK) { - if (go != -99) - printf (_("Unable to open file `%s go=%d'!\n"), path, go); + printf ("error: %s\n", urj_error_describe ()); + urj_error_reset (); break; } } - free (path); - - return go ? 1 : 0; + return 1; } static void diff --git a/urjtag/src/flash/flash.c b/urjtag/src/flash/flash.c index 026cdffa..adba7f21 100644 --- a/urjtag/src/flash/flash.c +++ b/urjtag/src/flash/flash.c @@ -524,7 +524,9 @@ urj_flasherase (urj_bus_t *bus, uint32_t addr, int number) urj_log (URJ_LOG_LEVEL_NORMAL, _("\nErasing (partially) Failed.\n")); /* BYPASS */ + /* @@@@ RFHH check result */ // urj_part_parts_set_instruction( ps, "BYPASS" ); + /* @@@@ RFHH check result */ // urj_tap_chain_shift_instructions( chain ); return status; diff --git a/urjtag/src/global/parse.c b/urjtag/src/global/parse.c index 68ea580b..92e8bf8c 100644 --- a/urjtag/src/global/parse.c +++ b/urjtag/src/global/parse.c @@ -38,6 +38,7 @@ #include #include #include +#include #define MAXINPUTLINE 100 /* Maximum input line length */ @@ -52,10 +53,16 @@ urj_parse_line (urj_chain_t *chain, char *line) char *sline; if (line == NULL) - return 1; + { + urj_error_set (URJ_ERROR_INVALID, "NULL line"); + return URJ_STATUS_FAIL; + } l = strlen (line); if (l == 0) + { + urj_error_set (URJ_ERROR_INVALID, "zero-length line"); return 1; + } /* allocate as many chars as in the input line; this will be enough in all cases */ sline = malloc (l + 1); @@ -92,6 +99,7 @@ urj_parse_line (urj_chain_t *chain, char *line) if (tcnt == 0) { free (sline); + urj_error_set (URJ_ERROR_INVALID, "empty line"); return 1; } @@ -172,7 +180,8 @@ urj_parse_file (urj_chain_t *chain, const char *filename) f = fopen (filename, "r"); if (!f) { - urj_error_set(URJ_ERROR_IO, "Cannot open file '%s' to parse: %s", filename, strerror(errno)); + urj_error_set(URJ_ERROR_IO, "Cannot open file '%s' to parse: %s", + filename, strerror(errno)); errno = 0; return -1; } @@ -184,3 +193,64 @@ urj_parse_file (urj_chain_t *chain, const char *filename) return go; } + +int +urj_parse_include (urj_chain_t *chain, const char *filename, int ignore_path) +{ + char *path = NULL; + int r = URJ_STATUS_OK; + + if (! ignore_path) + { + /* If "filename" begins with a slash, or dots followed by a slash, + * assume that user wants to ignore the search path after all */ + const char *slashdots = filename; + +#ifdef __MINGW32__ + if (isalpha (*slashdots) && slashdots[1] == ':') + slashdots += 2; +#endif + while (*slashdots == '.') + slashdots++; + ignore_path = (*slashdots == '/' || *slashdots == '\\'); + } + + if (! ignore_path) + { + const char *jtag_data_dir = urj_get_data_dir (); + size_t len; + + path = malloc (len = strlen (jtag_data_dir) + strlen (filename) + 2); + if (path == NULL) + { + printf (_("Out of memory\n")); + urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "malloc(%zd) fails", len); + return URJ_STATUS_FAIL; + } + snprintf (path, len, "%s/%s", jtag_data_dir, filename); + + filename = path; + } + +#ifdef ENABLE_BSDL + /* perform a test read to check for BSDL syntax */ + if (urj_bsdl_read_file (chain, filename, URJ_BSDL_MODE_INCLUDE1, NULL) >= 0) + { + /* it seems to be a proper BSDL file, so re-read and execute */ + if (urj_bsdl_read_file (chain, filename, URJ_BSDL_MODE_INCLUDE2, + NULL) < 0) + // retain errno + r = URJ_STATUS_FAIL; + } + else +#endif + { + if (urj_parse_file (chain, filename) == -1) + r = URJ_STATUS_FAIL; + } + + free (path); + + return r; +} + diff --git a/urjtag/src/part/part.c b/urjtag/src/part/part.c index 1e029a26..79789b5e 100644 --- a/urjtag/src/part/part.c +++ b/urjtag/src/part/part.c @@ -48,6 +48,7 @@ urj_part_alloc (const urj_tap_register_t *id) } p->alias = NULL; /* djf */ + /* @@@@ RFHH check result */ p->id = urj_tap_register_duplicate (id); p->manufacturer[0] = '\0'; p->part[0] = '\0'; @@ -124,7 +125,10 @@ urj_part_find_instruction (urj_part_t *p, const char *iname) urj_part_instruction_t *i; if (!p || !iname) + { + urj_error_set (URJ_ERROR_INVALID, "NULL part or instruction name"); return NULL; + } i = p->instructions; while (i) @@ -143,7 +147,10 @@ urj_part_find_data_register (urj_part_t *p, const char *drname) urj_data_register_t *dr; if (!p || !drname) + { + urj_error_set (URJ_ERROR_INVALID, "NULL part or data register name"); return NULL; + } dr = p->data_registers; while (dr) @@ -163,7 +170,10 @@ urj_part_find_signal (urj_part_t *p, const char *signalname) urj_part_salias_t *sa; if (!p || !signalname) + { + urj_error_set (URJ_ERROR_INVALID, "NULL part or signal name"); return NULL; + } s = p->signals; while (s) @@ -198,7 +208,7 @@ urj_part_set_signal (urj_part_t *p, urj_part_signal_t *s, int out, int val) if (!p || !s) { - urj_error_set (URJ_ERROR_INVALID, "part or signal is NULL"); + urj_error_set (URJ_ERROR_INVALID, "NULL part or signal"); return URJ_STATUS_FAIL; } @@ -251,7 +261,7 @@ urj_part_get_signal (urj_part_t *p, urj_part_signal_t *s) if (!p || !s) { - urj_error_set (URJ_ERROR_INVALID, "part or signal is NULL"); + urj_error_set (URJ_ERROR_INVALID, "NULL part or signal"); return -1; } @@ -274,7 +284,7 @@ urj_part_get_signal (urj_part_t *p, urj_part_signal_t *s) return bsr->out->data[s->input->bit]; } -void +int urj_part_print (urj_part_t *p) { const char *instruction = NULL; @@ -282,7 +292,10 @@ urj_part_print (urj_part_t *p) char format[100]; if (!p) - return; + { + urj_error_set (URJ_ERROR_INVALID, "NULL part"); + return URJ_STATUS_FAIL; + } snprintf (format, 100, _("%%-%ds %%-%ds %%-%ds %%-%ds %%-%ds\n"), URJ_PART_MANUFACTURER_MAXLEN, URJ_PART_PART_MAXLEN, @@ -301,6 +314,8 @@ urj_part_print (urj_part_t *p) dr = _("(none)"); urj_log (URJ_LOG_LEVEL_NORMAL, format, p->manufacturer, p->part, p->stepping, instruction, dr); + + return URJ_STATUS_OK; } @@ -373,7 +388,11 @@ urj_part_parts_alloc (void) { urj_parts_t *ps = malloc (sizeof *ps); if (!ps) + { + urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "malloc(%zd) fails", + sizeof *ps); return NULL; + } ps->len = 0; ps->parts = NULL; @@ -402,34 +421,46 @@ urj_part_parts_add_part (urj_parts_t *ps, urj_part_t *p) urj_part_t **np = realloc (ps->parts, (ps->len + 1) * sizeof *ps->parts); if (!np) - return 0; + { + urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "realloc(%s,%zd) fails", + "ps->parts", (ps->len + 1) * sizeof *ps->parts); + return URJ_STATUS_FAIL; + } ps->parts = np; ps->parts[ps->len++] = p; - return 1; + return URJ_STATUS_OK; } -void +int urj_part_parts_set_instruction (urj_parts_t *ps, const char *iname) { int i; if (!ps) - return; + { + urj_error_set (URJ_ERROR_INVALID, "NULL parts"); + return URJ_STATUS_FAIL; + } for (i = 0; i < ps->len; i++) ps->parts[i]->active_instruction = urj_part_find_instruction (ps->parts[i], iname); + + return URJ_STATUS_OK; } -void +int urj_part_parts_print (urj_parts_t *ps) { int i; if (!ps) - return; + { + urj_error_set (URJ_ERROR_INVALID, "NULL parts"); + return URJ_STATUS_FAIL; + } for (i = 0; i < ps->len; i++) { @@ -441,4 +472,6 @@ urj_part_parts_print (urj_parts_t *ps) urj_log (URJ_LOG_LEVEL_NORMAL, _(" %3d "), i); urj_part_print (p); } + + return URJ_STATUS_OK; } diff --git a/urjtag/src/tap/detect.c b/urjtag/src/tap/detect.c index 8b06f3c8..e81c1a67 100644 --- a/urjtag/src/tap/detect.c +++ b/urjtag/src/tap/detect.c @@ -43,6 +43,7 @@ #include #include #include +#include #include struct id_record @@ -203,7 +204,6 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) int i; char data_path[1024]; - char *cmd[3] = { "include", data_path, NULL }; char manufacturer[URJ_PART_MANUFACTURER_MAXLEN + 1]; char partname[URJ_PART_PART_MAXLEN + 1]; char stepping[URJ_PART_STEPPING_MAXLEN + 1]; @@ -286,6 +286,7 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) part = urj_part_alloc (did); if (part == NULL) + // @@@@ RFHH what about this error? Shouldn't we bail out? break; urj_part_parts_add_part (ps, part); @@ -302,10 +303,11 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) /* find JTAG declarations for a part with id */ - strcpy (data_path, db_path); /* FIXME: Buffer overrun */ + data_path[0] = '\0'; + strncat (data_path, db_path, sizeof data_path); /* FIXME: Buffer overrun */ /* manufacturers */ - strcat (data_path, "/MANUFACTURERS"); + strncat (data_path, "/MANUFACTURERS", sizeof data_path); key = urj_tap_register_alloc (11); memcpy (key->data, &id->data[1], key->len); @@ -321,9 +323,8 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) idr.fullname); if (strlen (idr.fullname) > URJ_PART_MANUFACTURER_MAXLEN) urj_warning (_("Manufacturer too long\n")); - strncpy (manufacturer, idr.fullname, - URJ_PART_MANUFACTURER_MAXLEN); - manufacturer[URJ_PART_MANUFACTURER_MAXLEN] = '\0'; + manufacturer[0] = '\0'; + strncat (manufacturer, idr.fullname, sizeof manufacturer); /* parts */ p = strrchr (data_path, '/'); @@ -331,8 +332,8 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) p[1] = '\0'; else data_path[0] = '\0'; - strcat (data_path, idr.name); - strcat (data_path, "/PARTS"); + strncat (data_path, idr.name, sizeof data_path); + strncat (data_path, "/PARTS", sizeof data_path); key = urj_tap_register_alloc (16); memcpy (key->data, &id->data[12], key->len); @@ -348,8 +349,8 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) chain->active_part, idr.fullname); if (strlen (idr.fullname) > URJ_PART_PART_MAXLEN) urj_warning (_("Part too long\n")); - strncpy (partname, idr.fullname, URJ_PART_PART_MAXLEN); - partname[URJ_PART_PART_MAXLEN] = '\0'; + partname[0] ='\0'; + strncat (partname, idr.fullname, sizeof partname); /* steppings */ p = strrchr (data_path, '/'); @@ -357,8 +358,8 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) p[1] = '\0'; else data_path[0] = '\0'; - strcat (data_path, idr.name); - strcat (data_path, "/STEPPINGS"); + strncat (data_path, idr.name, sizeof data_path); + strncat (data_path, "/STEPPINGS", sizeof data_path); key = urj_tap_register_alloc (4); memcpy (key->data, &id->data[28], key->len); @@ -374,8 +375,8 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) idr.fullname); if (strlen (idr.fullname) > URJ_PART_STEPPING_MAXLEN) urj_warning (_("Stepping too long\n")); - strncpy (stepping, idr.fullname, URJ_PART_STEPPING_MAXLEN); - stepping[URJ_PART_STEPPING_MAXLEN] = '\0'; + stepping[0] = '\0'; + strncat (stepping, idr.fullname, sizeof stepping); /* part definition file */ p = strrchr (data_path, '/'); @@ -383,7 +384,7 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) p[1] = '\0'; else data_path[0] = '\0'; - strcat (data_path, idr.name); + strncat (data_path, idr.name, sizeof data_path); urj_log (URJ_LOG_LEVEL_NORMAL, _(" Filename: %s\n"), data_path); @@ -392,7 +393,12 @@ urj_tap_detect_parts (urj_chain_t *chain, const char *db_path) strcpy (part->manufacturer, manufacturer); strcpy (part->part, partname); strcpy (part->stepping, stepping); - urj_cmd_run (chain, cmd); + if (urj_parse_include (chain, data_path, 0) == URJ_STATUS_FAIL) + { + urj_log (URJ_LOG_LEVEL_NORMAL, "Error: %s\n", + urj_error_describe()); + urj_error_reset(); + } #ifdef ENABLE_BSDL } #endif diff --git a/urjtag/src/tap/tap.c b/urjtag/src/tap/tap.c index 019c8ac4..34e80760 100644 --- a/urjtag/src/tap/tap.c +++ b/urjtag/src/tap/tap.c @@ -61,6 +61,7 @@ urj_tap_reset_bypass (urj_chain_t *chain) urj_tap_shift_register (chain, ir, NULL, URJ_CHAIN_EXITMODE_IDLE); urj_tap_register_free (ir); + /* @@@@ RFHH check result */ urj_part_parts_set_instruction (chain->parts, "BYPASS"); }