diff --git a/src/avrftdi.c b/src/avrftdi.c index f0c07a6a..315f23e8 100644 --- a/src/avrftdi.c +++ b/src/avrftdi.c @@ -651,7 +651,7 @@ static int avrftdi_pin_setup(PROGRAMMER * pgm) static int avrftdi_open(PROGRAMMER * pgm, char *port) { int vid, pid, interface, index, err; - char * serial, *desc; + const char *serial, *desc; avrftdi_t* pdata = to_pdata(pgm); diff --git a/src/avrpart.c b/src/avrpart.c index 4fc6304f..970dfde8 100644 --- a/src/avrpart.c +++ b/src/avrpart.c @@ -672,6 +672,7 @@ void avr_mem_display(const char * prefix, FILE * f, AVRMEM * m, AVRPART * p, AVRPART * avr_new_part(void) { AVRPART * p; + char *nulp = cache_string(""); p = (AVRPART *)malloc(sizeof(AVRPART)); if (p == NULL) { @@ -686,8 +687,8 @@ AVRPART * avr_new_part(void) p->reset_disposition = RESET_DEDICATED; p->retry_pulse = PIN_AVR_SCK; p->flags = AVRPART_SERIALOK | AVRPART_PARALLELOK | AVRPART_ENABLEPAGEPROGRAMMING; - p->parent_id = NULL; - p->config_file = NULL; + p->parent_id = nulp; + p->config_file = nulp; p->lineno = 0; memset(p->signature, 0xFF, 3); p->ctl_stack_type = CTL_STACK_NONE; diff --git a/src/config.h b/src/config.h index a20af733..a7d2563d 100644 --- a/src/config.h +++ b/src/config.h @@ -101,8 +101,6 @@ void pyytext(void); char * dup_string(const char * str); -char * cache_string(const char * file); - #ifdef __cplusplus } #endif diff --git a/src/config_gram.y b/src/config_gram.y index ce11b924..552832ec 100644 --- a/src/config_gram.y +++ b/src/config_gram.y @@ -532,8 +532,7 @@ prog_parm_conntype_id: prog_parm_usb: K_USBDEV TKN_EQUAL TKN_STRING { { - strncpy(current_prog->usbdev, $3->value.string, PGM_USBSTRINGLEN); - current_prog->usbdev[PGM_USBSTRINGLEN-1] = 0; + current_prog->usbdev = cache_string($3->value.string); free_token($3); } } | @@ -546,22 +545,19 @@ prog_parm_usb: K_USBPID TKN_EQUAL usb_pid_list | K_USBSN TKN_EQUAL TKN_STRING { { - strncpy(current_prog->usbsn, $3->value.string, PGM_USBSTRINGLEN); - current_prog->usbsn[PGM_USBSTRINGLEN-1] = 0; + current_prog->usbsn = cache_string($3->value.string); free_token($3); } } | K_USBVENDOR TKN_EQUAL TKN_STRING { { - strncpy(current_prog->usbvendor, $3->value.string, PGM_USBSTRINGLEN); - current_prog->usbvendor[PGM_USBSTRINGLEN-1] = 0; + current_prog->usbvendor = cache_string($3->value.string); free_token($3); } } | K_USBPRODUCT TKN_EQUAL TKN_STRING { { - strncpy(current_prog->usbproduct, $3->value.string, PGM_USBSTRINGLEN); - current_prog->usbproduct[PGM_USBSTRINGLEN-1] = 0; + current_prog->usbproduct = cache_string($3->value.string); free_token($3); } } diff --git a/src/developer_opts.c b/src/developer_opts.c index f80f5537..8aea0bb2 100644 --- a/src/developer_opts.c +++ b/src/developer_opts.c @@ -436,7 +436,7 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) { dev_info("#------------------------------------------------------------\n"); dev_info("# %s\n", p->desc); dev_info("#------------------------------------------------------------\n"); - if(p->parent_id) + if(p->parent_id && *p->parent_id) dev_info("\npart parent \"%s\"\n", p->parent_id); else dev_info("\npart\n"); @@ -597,9 +597,7 @@ static void dev_part_strct(AVRPART *p, bool tsv, AVRPART *base) { } - - -// -p */[cdosw*] +// -p */[dASsrcow*t] void dev_output_part_defs(char *partdesc) { bool cmdok, waits, opspi, descs, astrc, strct, cmpst, raw, all, tsv; char *flags; @@ -693,7 +691,7 @@ void dev_output_part_defs(char *partdesc) { dev_part_strct(p, tsv, astrc? NULL: strct? nullpart: - p->parent_id? locate_part(part_list, p->parent_id): nullpart); + p->parent_id && *p->parent_id? locate_part(part_list, p->parent_id): nullpart); if(raw) dev_part_raw(p); @@ -891,3 +889,119 @@ void dev_output_part_defs(char *partdesc) { } } } + + +static void dev_pgm_raw(PROGRAMMER *pgm) { + PROGRAMMER dp; + + memcpy(&dp, pgm, sizeof dp); + dev_raw_dump((unsigned char *) &dp, sizeof dp, pgm->desc, "pgm", 0); +} + + +static void dev_pgm_strct(PROGRAMMER *pgm, bool tsv, PROGRAMMER *base) { + if(!tsv) { + int firstid = 1; + + dev_info("#------------------------------------------------------------\n"); + dev_info("# "); + for(LNODEID ln=lfirst(pgm->id); ln; ln=lnext(ln)) { + if(!firstid) + dev_info("/"); + firstid = 0; + dev_info("%s", ldata(ln)); + } + dev_info("\n"); + dev_info("#------------------------------------------------------------\n"); + if(pgm->parent_id && *pgm->parent_id) + dev_info("\nprogrammer parent \"%s\"\n", pgm->parent_id); + else + dev_info("\nprogrammer\n"); + } + + if(!tsv) + dev_info(";\n"); +} + + +// -c */[ASsrt] +void dev_output_pgm_defs(char *pgmid) { + bool astrc, strct, cmpst, raw, tsv; + char *flags; + int nprinted; + PROGRAMMER *nullpgm = pgm_new(); + + if((flags = strchr(pgmid, '/'))) + *flags++ = 0; + + if(!flags && !strcmp(pgmid, "*")) // treat -c * as if it was -c */A + flags = "A"; + + if(!*flags || !strchr("ASsrt", *flags)) { + dev_info("%s: flags for developer option -c / not recognised\n", progname); + dev_info( + "Wildcard examples (these need protecting in the shell through quoting):\n" + " * all known programmers\n" + " avrftdi just this programmer\n" + " jtag*pdi matches jtag2pdi, jtag3pdi, jtag3updi and jtag2updi\n" + " jtag?pdi matches jtag2pdi and jtag3pdi\n" + "Flags (one or more of the characters below):\n" + " A show entries of avrdude.conf programmers with all values\n" + " S show entries of avrdude.conf programmers with necessary values\n" + " s show short entries of avrdude.conf programmers using parent\n" + " r show entries of avrdude.conf programmers as raw dump\n" + " t use tab separated values as much as possible\n" + "Examples:\n" + " $ avrdude -c usbasp/s\n" + " $ avrdude -c */st | grep baudrate\n" + " $ avrdude -c */r | sort\n" + "Notes:\n" + " -c * is the same as -c */A\n" + " This help message is printed using any unrecognised flag, eg, -c/h\n" + " Leaving no space after -c can be an OK substitute for quoting in shells\n" + " /s, /S and /A outputs are designed to be used as input in avrdude.conf\n" + " Sorted /r output should stay invariant when rearranging avrdude.conf\n" + " These options are just to help development, so not further documented\n" + ); + return; + } + + // redirect stderr to stdout + fflush(stderr); fflush(stdout); dup2(1, 2); + + astrc = !!strchr(flags, 'A'); + strct = !!strchr(flags, 'S'); + cmpst = !!strchr(flags, 's'); + raw = !!strchr(flags, 'r'); + tsv = !!strchr(flags, 't'); + + nprinted = dev_nprinted; + + LNODEID ln1, ln2; + for(ln1=lfirst(programmers); ln1; ln1=lnext(ln1)) { + PROGRAMMER *pgm = ldata(ln1); + int matched = 0; + for(ln2=lfirst(pgm->id); ln2; ln2=lnext(ln2)) { + if(part_match(pgmid, ldata(ln2))) { + matched = 1; + break; + } + } + if(!matched) + continue; + + if(dev_nprinted > nprinted) { + dev_info("\n"); + nprinted = dev_nprinted; + } + + if(astrc || strct || cmpst) + dev_pgm_strct(pgm, tsv, + astrc? NULL: + strct? nullpgm: + pgm->parent_id && *pgm->parent_id? locate_programmer(programmers, pgm->parent_id): nullpgm); + + if(raw) + dev_pgm_raw(pgm); + } +} diff --git a/src/developer_opts.h b/src/developer_opts.h index 6c4b3b71..2079c109 100644 --- a/src/developer_opts.h +++ b/src/developer_opts.h @@ -20,5 +20,6 @@ #define developer_opts_h void dev_output_part_defs(char *partdesc); +void dev_output_pgm_defs(char *programmer); #endif diff --git a/src/ft245r.c b/src/ft245r.c index 874167ac..04790143 100644 --- a/src/ft245r.c +++ b/src/ft245r.c @@ -851,7 +851,7 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) { avrdude_message(MSG_NOTICE, "%s: ft245r_open(): no device identifier in portname, using default\n", progname); - pgm->usbsn[0] = 0; + pgm->usbsn = cache_string(""); devnum = 0; } else { if (strlen(device) == 8 ){ // serial number @@ -863,7 +863,7 @@ static int ft245r_open(PROGRAMMER * pgm, char * port) { device); } // copy serial number to pgm struct - strcpy(pgm->usbsn, device); + pgm->usbsn = cache_string(device); // and use first device with matching serial (should be unique) devnum = 0; } diff --git a/src/libavrdude.h b/src/libavrdude.h index 23905953..7dcab3c2 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -217,7 +217,7 @@ typedef struct opcode { typedef struct avrpart { char desc[AVR_DESCLEN]; /* long part name */ char id[AVR_IDLEN]; /* short part name */ - char * parent_id; /* parent id if set, for -p.../s */ + const char * parent_id; /* parent id if set, for -p.../s */ char family_id[AVR_FAMILYIDLEN+1]; /* family id in the SIB (avr8x) */ int hvupdi_variant; /* HV pulse on UPDI pin, no pin or RESET pin */ int stk500_devcode; /* stk500 device code */ @@ -280,7 +280,7 @@ typedef struct avrpart { LISTID mem; /* avr memory definitions */ LISTID mem_alias; /* memory alias definitions */ - char *config_file; /* config file where defined */ + const char * config_file; /* config file where defined */ int lineno; /* config file line number */ } AVRPART; @@ -640,7 +640,6 @@ extern struct serial_device usbhid_serdev; #define PGM_DESCLEN 80 #define PGM_PORTLEN PATH_MAX #define PGM_TYPELEN 32 -#define PGM_USBSTRINGLEN 256 typedef enum { EXIT_VCC_UNSPEC, @@ -672,7 +671,7 @@ typedef struct programmer_t { char desc[PGM_DESCLEN]; char type[PGM_TYPELEN]; char port[PGM_PORTLEN]; - char *parent_id; + const char *parent_id; void (*initpgm)(struct programmer_t * pgm); unsigned int pinno[N_PINS]; struct pindef_t pin[N_PINS]; @@ -685,8 +684,7 @@ typedef struct programmer_t { int baudrate; int usbvid; LISTID usbpid; - char usbdev[PGM_USBSTRINGLEN], usbsn[PGM_USBSTRINGLEN]; - char usbvendor[PGM_USBSTRINGLEN], usbproduct[PGM_USBSTRINGLEN]; + const char *usbdev, *usbsn, *usbvendor, *usbproduct; double bitclock; /* JTAG ICE clock period in microseconds */ int ispdelay; /* ISP clock delay */ union filedescriptor fd; @@ -740,7 +738,7 @@ typedef struct programmer_t { int (*parseextparams) (struct programmer_t * pgm, LISTID xparams); void (*setup) (struct programmer_t * pgm); void (*teardown) (struct programmer_t * pgm); - char *config_file; /* config file where defined */ + const char *config_file; /* config file where defined */ int lineno; /* config file line number */ void *cookie; /* for private use by the programmer */ char flag; /* for private use of the programmer */ @@ -989,6 +987,8 @@ void cleanup_config(void); int read_config(const char * file); +char *cache_string(const char *file); + #ifdef __cplusplus } #endif diff --git a/src/main.c b/src/main.c index 9f72847f..83bde3e9 100644 --- a/src/main.c +++ b/src/main.c @@ -754,7 +754,7 @@ int main(int argc, char * argv []) avrdude_message(MSG_NOTICE, "\n"); - // developer option -p /[*codws] prints various aspects of part descriptions and exits + // Developer option -p /[dASsrcow*t] prints part description(s) and exits if(partdesc && (strcmp(partdesc, "*") == 0 || strchr(partdesc, '/'))) { dev_output_part_defs(partdesc); exit(1); @@ -770,6 +770,12 @@ int main(int argc, char * argv []) } } + // Developer option -c /[ASsrt] prints programmer description(s) and exits + if(programmer && (strcmp(programmer, "*") == 0 || strchr(programmer, '/'))) { + dev_output_pgm_defs(programmer); + exit(1); + } + if (programmer) { if (strcmp(programmer, "?") == 0) { avrdude_message(MSG_INFO, "\n"); diff --git a/src/pgm.c b/src/pgm.c index dd38552f..a4e0ed54 100644 --- a/src/pgm.c +++ b/src/pgm.c @@ -65,6 +65,7 @@ PROGRAMMER * pgm_new(void) { int i; PROGRAMMER * pgm; + char *nulp = cache_string(""); pgm = (PROGRAMMER *)malloc(sizeof(*pgm)); if (pgm == NULL) { @@ -79,13 +80,18 @@ PROGRAMMER * pgm_new(void) pgm->usbpid = lcreat(NULL, 0); pgm->desc[0] = 0; pgm->type[0] = 0; - pgm->parent_id = NULL; - pgm->config_file = NULL; + pgm->parent_id = nulp; + pgm->config_file = nulp; pgm->lineno = 0; pgm->baudrate = 0; pgm->initpgm = NULL; pgm->hvupdi_support = lcreat(NULL, 0); + pgm->usbdev = nulp; + pgm->usbsn = nulp; + pgm->usbvendor = nulp; + pgm->usbproduct = nulp; + for (i=0; ipinno[i] = 0; pin_clear_all(&(pgm->pin[i])); @@ -146,7 +152,7 @@ void pgm_free(PROGRAMMER * const p) ldestroy_cb(p->usbpid, free); p->id = NULL; p->usbpid = NULL; - /* do not free p->parent_id nor p->config_file */ + /* do not free p->parent_id, p->config_file, p->usbdev, p->usbsn, p->usbvendor or p-> usbproduct */ /* p->cookie is freed by pgm_teardown */ free(p); } diff --git a/src/ser_avrdoper.c b/src/ser_avrdoper.c index a8414403..e459f921 100644 --- a/src/ser_avrdoper.c +++ b/src/ser_avrdoper.c @@ -65,8 +65,8 @@ static int avrdoperRxPosition = 0; /* amount of bytes already consu /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ -static int usbOpenDevice(union filedescriptor *fdp, int vendor, char *vendorName, - int product, char *productName, int doReportIDs) +static int usbOpenDevice(union filedescriptor *fdp, int vendor, const char *vendorName, + int product, const char *productName, int doReportIDs) { hid_device *dev; diff --git a/src/usbasp.c b/src/usbasp.c index 250c8a22..2b4c4831 100644 --- a/src/usbasp.c +++ b/src/usbasp.c @@ -160,9 +160,9 @@ static int usbasp_transmit(PROGRAMMER * pgm, unsigned char receive, unsigned char functionid, const unsigned char *send, unsigned char *buffer, int buffersize); #ifdef USE_LIBUSB_1_0 -static int usbOpenDevice(libusb_device_handle **device, int vendor, char *vendorName, int product, char *productName); +static int usbOpenDevice(libusb_device_handle **device, int vendor, const char *vendorName, int product, const char *productName); #else -static int usbOpenDevice(usb_dev_handle **device, int vendor, char *vendorName, int product, char *productName); +static int usbOpenDevice(usb_dev_handle **device, int vendor, const char *vendorName, int product, const char *productName); #endif // interface - prog. static int usbasp_open(PROGRAMMER * pgm, char * port); @@ -337,7 +337,7 @@ static int usbasp_transmit(PROGRAMMER * pgm, */ #ifdef USE_LIBUSB_1_0 static int usbOpenDevice(libusb_device_handle **device, int vendor, - char *vendorName, int product, char *productName) + const char *vendorName, int product, const char *productName) { libusb_device_handle *handle = NULL; int errorCode = USB_ERROR_NOTFOUND; @@ -412,7 +412,7 @@ static int usbOpenDevice(libusb_device_handle **device, int vendor, } #else static int usbOpenDevice(usb_dev_handle **device, int vendor, - char *vendorName, int product, char *productName) + const char *vendorName, int product, const char *productName) { struct usb_bus *bus; struct usb_device *dev;