patch #7688: Implement parent programmers feature
* avrdude.conf.in: updated documentation comment and some programmers have now parents * config_gram.y: initpgm will now called at first use of programmer in main. parser sets only the function pointer in the pgm structure. Pin and pin lists definitions can now be empty to remove the parents setting. * doc/avrdude.texi: updated documentation * main.c: added call to pgm->initpgm after locate_programmer * pgm.[hc]: added field initpgm in structure, added function pgm_dup git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@1045 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
parent
0e14a476f5
commit
d72a56ef01
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
2012-01-22 Rene Liebscher <R.Liebscher@gmx.de>
|
||||||
|
|
||||||
|
patch #7688: Implement parent programmers feature
|
||||||
|
* avrdude.conf.in: updated documentation comment and some programmers
|
||||||
|
have now parents
|
||||||
|
* config_gram.y: initpgm will now called at first use of programmer
|
||||||
|
in main. parser sets only the function pointer in the pgm structure.
|
||||||
|
Pin and pin lists definitions can now be empty to remove the parents
|
||||||
|
setting.
|
||||||
|
* doc/avrdude.texi: updated documentation
|
||||||
|
* main.c: added call to pgm->initpgm after locate_programmer
|
||||||
|
* pgm.[hc]: added field initpgm in structure, added function pgm_dup
|
||||||
|
|
||||||
2012-01-21 Rene Liebscher <R.Liebscher@gmx.de>
|
2012-01-21 Rene Liebscher <R.Liebscher@gmx.de>
|
||||||
|
|
||||||
bug #21797: AT90PWM316: New part description
|
bug #21797: AT90PWM316: New part description
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
# Possible entry formats are:
|
# Possible entry formats are:
|
||||||
#
|
#
|
||||||
# programmer
|
# programmer
|
||||||
|
# parent <id> # optional parent
|
||||||
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
# id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||||
# desc = <description> ; # quoted string
|
# desc = <description> ; # quoted string
|
||||||
# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic |
|
# type = par | stk500 | stk500v2 | stk500pp | stk500hvsp | stk500generic |
|
||||||
|
@ -454,22 +455,13 @@ programmer
|
||||||
# http://armwerks.com/catalog/o-link-debugger-copy/
|
# http://armwerks.com/catalog/o-link-debugger-copy/
|
||||||
# or just have a look at ebay ...
|
# or just have a look at ebay ...
|
||||||
# It is basically the same entry as jtagkey with different usb ids.
|
# It is basically the same entry as jtagkey with different usb ids.
|
||||||
programmer
|
programmer parent "jtagkey"
|
||||||
id = "o-link";
|
id = "o-link";
|
||||||
desc = "O-Link, OpenJTAG from www.100ask.net";
|
desc = "O-Link, OpenJTAG from www.100ask.net";
|
||||||
type = avrftdi;
|
|
||||||
usbvid = 0x1457;
|
usbvid = 0x1457;
|
||||||
usbpid = 0x5118;
|
usbpid = 0x5118;
|
||||||
usbdev = "A";
|
|
||||||
usbvendor = "www.100ask.net";
|
usbvendor = "www.100ask.net";
|
||||||
usbproduct = "USB<=>JTAG&RS232";
|
usbproduct = "USB<=>JTAG&RS232";
|
||||||
usbsn = "";
|
|
||||||
# for pin connections see jtagkey
|
|
||||||
reset = 4;
|
|
||||||
sck = 1;
|
|
||||||
mosi = 2;
|
|
||||||
miso = 3;
|
|
||||||
buff = 5;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer
|
||||||
|
@ -490,10 +482,8 @@ programmer
|
||||||
type = stk500v2;
|
type = stk500v2;
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer parent "avrispmkII"
|
||||||
id = "avrisp2";
|
id = "avrisp2";
|
||||||
desc = "Atmel AVR ISP mkII";
|
|
||||||
type = stk500v2;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer
|
||||||
|
@ -641,10 +631,8 @@ programmer
|
||||||
type = butterfly_mk;
|
type = butterfly_mk;
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer parent "mkbutterfly"
|
||||||
id = "butterfly_mk";
|
id = "butterfly_mk";
|
||||||
desc = "Mikrokopter.de Butterfly";
|
|
||||||
type = butterfly_mk;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer
|
||||||
|
@ -655,19 +643,14 @@ programmer
|
||||||
;
|
;
|
||||||
|
|
||||||
# easier to type
|
# easier to type
|
||||||
programmer
|
programmer parent "jtagmkI"
|
||||||
id = "jtag1";
|
id = "jtag1";
|
||||||
desc = "Atmel JTAG ICE (mkI)";
|
|
||||||
baudrate = 115200; # default is 115200
|
|
||||||
type = jtagmki;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
# easier to type
|
# easier to type
|
||||||
programmer
|
programmer parent "jtag1"
|
||||||
id = "jtag1slow";
|
id = "jtag1slow";
|
||||||
desc = "Atmel JTAG ICE (mkI)";
|
|
||||||
baudrate = 19200;
|
baudrate = 19200;
|
||||||
type = jtagmki;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer
|
||||||
|
@ -678,27 +661,19 @@ programmer
|
||||||
;
|
;
|
||||||
|
|
||||||
# easier to type
|
# easier to type
|
||||||
programmer
|
programmer parent "jtagmkII"
|
||||||
id = "jtag2slow";
|
id = "jtag2slow";
|
||||||
desc = "Atmel JTAG ICE mkII";
|
|
||||||
baudrate = 19200; # default is 19200
|
|
||||||
type = jtagmkii;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
# JTAG ICE mkII @ 115200 Bd
|
# JTAG ICE mkII @ 115200 Bd
|
||||||
programmer
|
programmer parent "jtag2slow"
|
||||||
id = "jtag2fast";
|
id = "jtag2fast";
|
||||||
desc = "Atmel JTAG ICE mkII";
|
|
||||||
baudrate = 115200;
|
baudrate = 115200;
|
||||||
type = jtagmkii;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
# make the fast one the default, people will love that
|
# make the fast one the default, people will love that
|
||||||
programmer
|
programmer parent "jtag2fast"
|
||||||
id = "jtag2";
|
id = "jtag2";
|
||||||
desc = "Atmel JTAG ICE mkII";
|
|
||||||
baudrate = 115200;
|
|
||||||
type = jtagmkii;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
# JTAG ICE mkII in ISP mode
|
# JTAG ICE mkII in ISP mode
|
||||||
|
@ -825,15 +800,9 @@ programmer
|
||||||
# except that there is a LED indicating that the
|
# except that there is a LED indicating that the
|
||||||
# programming is currently in progress.
|
# programming is currently in progress.
|
||||||
|
|
||||||
programmer
|
programmer parent "stk200"
|
||||||
id = "pony-stk200";
|
id = "pony-stk200";
|
||||||
desc = "Pony Prog STK200";
|
desc = "Pony Prog STK200";
|
||||||
type = par;
|
|
||||||
buff = 4, 5;
|
|
||||||
sck = 6;
|
|
||||||
mosi = 7;
|
|
||||||
reset = 9;
|
|
||||||
miso = 10;
|
|
||||||
pgmled = 8;
|
pgmled = 8;
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -847,14 +816,9 @@ programmer
|
||||||
miso = 11;
|
miso = 11;
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer parent "dt006"
|
||||||
id = "bascom";
|
id = "bascom";
|
||||||
desc = "Bascom SAMPLE programming cable";
|
desc = "Bascom SAMPLE programming cable";
|
||||||
type = par;
|
|
||||||
reset = 4;
|
|
||||||
sck = 5;
|
|
||||||
mosi = 2;
|
|
||||||
miso = 11;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
programmer
|
programmer
|
||||||
|
@ -979,16 +943,11 @@ programmer
|
||||||
|
|
||||||
# It is almost same as pony-stk200, except vcc on pin 5 to auto
|
# It is almost same as pony-stk200, except vcc on pin 5 to auto
|
||||||
# disconnect port (download on http://electropol.free.fr)
|
# disconnect port (download on http://electropol.free.fr)
|
||||||
programmer
|
programmer parent "pony-stk200"
|
||||||
id = "frank-stk200";
|
id = "frank-stk200";
|
||||||
desc = "Frank STK200";
|
desc = "Frank STK200";
|
||||||
type = par;
|
buff = ; # delete buff pin assignment
|
||||||
vcc = 5;
|
vcc = 5;
|
||||||
sck = 6;
|
|
||||||
mosi = 7;
|
|
||||||
reset = 9;
|
|
||||||
miso = 10;
|
|
||||||
pgmled = 8;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
# The AT98ISP Cable is a simple parallel dongle for AT89 family.
|
# The AT98ISP Cable is a simple parallel dongle for AT89 family.
|
||||||
|
@ -1040,14 +999,9 @@ programmer
|
||||||
# Same as above, different name
|
# Same as above, different name
|
||||||
# reset=!txd sck=rts mosi=dtr miso=cts
|
# reset=!txd sck=rts mosi=dtr miso=cts
|
||||||
|
|
||||||
programmer
|
programmer parent "ponyser"
|
||||||
id = "siprog";
|
id = "siprog";
|
||||||
desc = "Lancos SI-Prog <http://www.lancos.com/siprogsch.html>";
|
desc = "Lancos SI-Prog <http://www.lancos.com/siprogsch.html>";
|
||||||
type = serbb;
|
|
||||||
reset = ~3;
|
|
||||||
sck = 7;
|
|
||||||
mosi = 4;
|
|
||||||
miso = 8;
|
|
||||||
;
|
;
|
||||||
|
|
||||||
# unknown (dasa in uisp)
|
# unknown (dasa in uisp)
|
||||||
|
|
|
@ -298,7 +298,7 @@ prog_def :
|
||||||
progname, infile, lineno);
|
progname, infile, lineno);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if (current_prog->type[0] == 0) {
|
if (current_prog->initpgm == NULL) {
|
||||||
fprintf(stderr, "%s: error at %s:%d: programmer type not specified\n",
|
fprintf(stderr, "%s: error at %s:%d: programmer type not specified\n",
|
||||||
progname, infile, lineno);
|
progname, infile, lineno);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -325,6 +325,21 @@ prog_decl :
|
||||||
strcpy(current_prog->config_file, infile);
|
strcpy(current_prog->config_file, infile);
|
||||||
current_prog->lineno = lineno;
|
current_prog->lineno = lineno;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
K_PROGRAMMER K_PARENT TKN_STRING
|
||||||
|
{
|
||||||
|
struct programmer_t * pgm = locate_programmer(programmers, $3->value.string);
|
||||||
|
if (pgm == NULL) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: error at %s:%d: parent programmer %s not found\n",
|
||||||
|
progname, infile, lineno, $3->value.string);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
current_prog = pgm_dup(pgm);
|
||||||
|
strcpy(current_prog->config_file, infile);
|
||||||
|
current_prog->lineno = lineno;
|
||||||
|
free_token($3);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -469,37 +484,37 @@ prog_parm_type:
|
||||||
;
|
;
|
||||||
|
|
||||||
prog_parm_type_id:
|
prog_parm_type_id:
|
||||||
K_PAR { par_initpgm(current_prog); } |
|
K_PAR { current_prog->initpgm = par_initpgm; } |
|
||||||
K_SERBB { serbb_initpgm(current_prog); } |
|
K_SERBB { current_prog->initpgm = serbb_initpgm; } |
|
||||||
K_STK500 { stk500_initpgm(current_prog); } |
|
K_STK500 { current_prog->initpgm = stk500_initpgm; } |
|
||||||
K_STK500V2 { stk500v2_initpgm(current_prog); } |
|
K_STK500V2 { current_prog->initpgm = stk500v2_initpgm; } |
|
||||||
K_WIRING { wiring_initpgm(current_prog); } |
|
K_WIRING { current_prog->initpgm = wiring_initpgm; } |
|
||||||
K_STK500HVSP { stk500hvsp_initpgm(current_prog); } |
|
K_STK500HVSP { current_prog->initpgm = stk500hvsp_initpgm; } |
|
||||||
K_STK500PP { stk500pp_initpgm(current_prog); } |
|
K_STK500PP { current_prog->initpgm = stk500pp_initpgm; } |
|
||||||
K_STK500GENERIC { stk500generic_initpgm(current_prog); } |
|
K_STK500GENERIC { current_prog->initpgm = stk500generic_initpgm; } |
|
||||||
K_ARDUINO { arduino_initpgm(current_prog); } |
|
K_ARDUINO { current_prog->initpgm = arduino_initpgm; } |
|
||||||
K_AVRFTDI { avrftdi_initpgm(current_prog); } |
|
K_AVRFTDI { current_prog->initpgm = avrftdi_initpgm; } |
|
||||||
K_BUSPIRATE { buspirate_initpgm(current_prog); } |
|
K_BUSPIRATE { current_prog->initpgm = buspirate_initpgm; } |
|
||||||
K_STK600 { stk600_initpgm(current_prog); } |
|
K_STK600 { current_prog->initpgm = stk600_initpgm; } |
|
||||||
K_STK600HVSP { stk600hvsp_initpgm(current_prog); } |
|
K_STK600HVSP { current_prog->initpgm = stk600hvsp_initpgm; } |
|
||||||
K_STK600PP { stk600pp_initpgm(current_prog); } |
|
K_STK600PP { current_prog->initpgm = stk600pp_initpgm; } |
|
||||||
K_AVR910 { avr910_initpgm(current_prog); } |
|
K_AVR910 { current_prog->initpgm = avr910_initpgm; } |
|
||||||
K_USBASP { usbasp_initpgm(current_prog); } |
|
K_USBASP { current_prog->initpgm = usbasp_initpgm; } |
|
||||||
K_USBTINY { usbtiny_initpgm(current_prog); } |
|
K_USBTINY { current_prog->initpgm = usbtiny_initpgm; } |
|
||||||
K_BUTTERFLY { butterfly_initpgm(current_prog); } |
|
K_BUTTERFLY { current_prog->initpgm = butterfly_initpgm; } |
|
||||||
K_BUTTERFLY_MK { butterfly_mk_initpgm(current_prog); } |
|
K_BUTTERFLY_MK { current_prog->initpgm = butterfly_mk_initpgm; } |
|
||||||
K_JTAG_MKI { jtagmkI_initpgm(current_prog); } |
|
K_JTAG_MKI { current_prog->initpgm = jtagmkI_initpgm; } |
|
||||||
K_JTAG_MKII { jtagmkII_initpgm(current_prog); } |
|
K_JTAG_MKII { current_prog->initpgm = jtagmkII_initpgm; } |
|
||||||
K_JTAG_MKII_AVR32 { jtagmkII_avr32_initpgm(current_prog); } |
|
K_JTAG_MKII_AVR32 { current_prog->initpgm = jtagmkII_avr32_initpgm; } |
|
||||||
K_JTAG_MKII_DW { jtagmkII_dw_initpgm(current_prog); } |
|
K_JTAG_MKII_DW { current_prog->initpgm = jtagmkII_dw_initpgm; } |
|
||||||
K_JTAG_MKII_ISP { stk500v2_jtagmkII_initpgm(current_prog); } |
|
K_JTAG_MKII_ISP { current_prog->initpgm = stk500v2_jtagmkII_initpgm; } |
|
||||||
K_JTAG_MKII_PDI { jtagmkII_pdi_initpgm(current_prog); } |
|
K_JTAG_MKII_PDI { current_prog->initpgm = jtagmkII_pdi_initpgm; } |
|
||||||
K_DRAGON_DW { jtagmkII_dragon_dw_initpgm(current_prog); } |
|
K_DRAGON_DW { current_prog->initpgm = jtagmkII_dragon_dw_initpgm; } |
|
||||||
K_DRAGON_HVSP { stk500v2_dragon_hvsp_initpgm(current_prog); } |
|
K_DRAGON_HVSP { current_prog->initpgm = stk500v2_dragon_hvsp_initpgm; } |
|
||||||
K_DRAGON_ISP { stk500v2_dragon_isp_initpgm(current_prog); } |
|
K_DRAGON_ISP { current_prog->initpgm = stk500v2_dragon_isp_initpgm; } |
|
||||||
K_DRAGON_JTAG { jtagmkII_dragon_initpgm(current_prog); } |
|
K_DRAGON_JTAG { current_prog->initpgm = jtagmkII_dragon_initpgm; } |
|
||||||
K_DRAGON_PDI { jtagmkII_dragon_pdi_initpgm(current_prog); } |
|
K_DRAGON_PDI { current_prog->initpgm = jtagmkII_dragon_pdi_initpgm; } |
|
||||||
K_DRAGON_PP { stk500v2_dragon_pp_initpgm(current_prog); }
|
K_DRAGON_PP { current_prog->initpgm = stk500v2_dragon_pp_initpgm; }
|
||||||
;
|
;
|
||||||
|
|
||||||
prog_parm_usb:
|
prog_parm_usb:
|
||||||
|
@ -549,6 +564,8 @@ pin_number:
|
||||||
TKN_NUMBER { assign_pin(pin_name, $1, 0); }
|
TKN_NUMBER { assign_pin(pin_name, $1, 0); }
|
||||||
|
|
|
|
||||||
TKN_TILDE TKN_NUMBER { assign_pin(pin_name, $2, 1); }
|
TKN_TILDE TKN_NUMBER { assign_pin(pin_name, $2, 1); }
|
||||||
|
|
|
||||||
|
/* empty */ { current_prog->pinno[pin_name] = 0; }
|
||||||
;
|
;
|
||||||
|
|
||||||
pin_list:
|
pin_list:
|
||||||
|
@ -568,6 +585,10 @@ pin_list:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
/* empty */ {
|
||||||
|
current_prog->pinno[pin_name] = 0;
|
||||||
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
prog_parm_pins:
|
prog_parm_pins:
|
||||||
|
|
|
@ -1432,6 +1432,7 @@ The format of the programmer definition is as follows:
|
||||||
|
|
||||||
@smallexample
|
@smallexample
|
||||||
programmer
|
programmer
|
||||||
|
parent <id> # <id> is a quoted string
|
||||||
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
id = <id1> [, <id2> [, <id3>] ...] ; # <idN> are quoted strings
|
||||||
desc = <description> ; # quoted string
|
desc = <description> ; # quoted string
|
||||||
type = par | stk500 | ... ; # programmer type (see below for a list)
|
type = par | stk500 | ... ; # programmer type (see below for a list)
|
||||||
|
@ -1455,6 +1456,10 @@ programmer
|
||||||
;
|
;
|
||||||
@end smallexample
|
@end smallexample
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
If a parent is specified, all settings of it (except its ids) are used for the new
|
||||||
|
programmer. These values can be changed by new setting them for the new programmer.
|
||||||
|
|
||||||
@noindent
|
@noindent
|
||||||
To invert a bit in the pin definitions, use @code{= ~ <num>}.
|
To invert a bit in the pin definitions, use @code{= ~ <num>}.
|
||||||
|
|
||||||
|
|
9
main.c
9
main.c
|
@ -727,6 +727,15 @@ int main(int argc, char * argv [])
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pgm->initpgm) {
|
||||||
|
pgm->initpgm(pgm);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"\n%s: Can't initialize the programmer.\n\n",
|
||||||
|
progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
if (pgm->setup) {
|
if (pgm->setup) {
|
||||||
pgm->setup(pgm);
|
pgm->setup(pgm);
|
||||||
}
|
}
|
||||||
|
|
20
pgm.c
20
pgm.c
|
@ -82,6 +82,7 @@ PROGRAMMER * pgm_new(void)
|
||||||
pgm->config_file[0] = 0;
|
pgm->config_file[0] = 0;
|
||||||
pgm->lineno = 0;
|
pgm->lineno = 0;
|
||||||
pgm->baudrate = 0;
|
pgm->baudrate = 0;
|
||||||
|
pgm->initpgm = NULL;
|
||||||
|
|
||||||
for (i=0; i<N_PINS; i++)
|
for (i=0; i<N_PINS; i++)
|
||||||
pgm->pinno[i] = 0;
|
pgm->pinno[i] = 0;
|
||||||
|
@ -147,6 +148,25 @@ void pgm_free(PROGRAMMER * const p)
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROGRAMMER * pgm_dup(const PROGRAMMER const * src)
|
||||||
|
{
|
||||||
|
PROGRAMMER * pgm;
|
||||||
|
|
||||||
|
pgm = (PROGRAMMER *)malloc(sizeof(*pgm));
|
||||||
|
if (pgm == NULL) {
|
||||||
|
fprintf(stderr, "%s: out of memory allocating programmer structure\n",
|
||||||
|
progname);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(pgm, src, sizeof(*pgm));
|
||||||
|
|
||||||
|
pgm->id = lcreat(NULL, 0);
|
||||||
|
|
||||||
|
return pgm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void pgm_default(void)
|
static void pgm_default(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: programmer operation not supported\n", progname);
|
fprintf(stderr, "%s: programmer operation not supported\n", progname);
|
||||||
|
|
2
pgm.h
2
pgm.h
|
@ -61,6 +61,7 @@ typedef struct programmer_t {
|
||||||
char desc[PGM_DESCLEN];
|
char desc[PGM_DESCLEN];
|
||||||
char type[PGM_TYPELEN];
|
char type[PGM_TYPELEN];
|
||||||
char port[PGM_PORTLEN];
|
char port[PGM_PORTLEN];
|
||||||
|
void (*initpgm)(struct programmer_t * pgm);
|
||||||
unsigned int pinno[N_PINS];
|
unsigned int pinno[N_PINS];
|
||||||
exit_vcc_t exit_vcc;
|
exit_vcc_t exit_vcc;
|
||||||
exit_reset_t exit_reset;
|
exit_reset_t exit_reset;
|
||||||
|
@ -131,6 +132,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PROGRAMMER * pgm_new(void);
|
PROGRAMMER * pgm_new(void);
|
||||||
|
PROGRAMMER * pgm_dup(const PROGRAMMER const * src);
|
||||||
void pgm_free(PROGRAMMER * const p);
|
void pgm_free(PROGRAMMER * const p);
|
||||||
|
|
||||||
void programmer_display(PROGRAMMER * pgm, const char * p);
|
void programmer_display(PROGRAMMER * pgm, const char * p);
|
||||||
|
|
Loading…
Reference in New Issue