* callback.c (default_callback): Initialize target_endian.
[deliverable/binutils-gdb.git] / sim / common / callback.c
1 /* Remote target callback routines.
2 Copyright 1995, 1996, 1997, 2000, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Cygnus Solutions.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free Software
20 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21
22 /* This file provides a standard way for targets to talk to the host OS
23 level. */
24
25 #ifdef HAVE_CONFIG_H
26 #include "cconfig.h"
27 #endif
28 #include "ansidecl.h"
29 #ifdef ANSI_PROTOTYPES
30 #include <stdarg.h>
31 #else
32 #include <varargs.h>
33 #endif
34 #include <stdio.h>
35 #ifdef HAVE_STDLIB_H
36 #include <stdlib.h>
37 #endif
38 #ifdef HAVE_STRING_H
39 #include <string.h>
40 #else
41 #ifdef HAVE_STRINGS_H
42 #include <strings.h>
43 #endif
44 #endif
45 #include <errno.h>
46 #include <fcntl.h>
47 #include <time.h>
48 #include <sys/types.h>
49 #include <sys/stat.h>
50 #include "gdb/callback.h"
51 #include "targ-vals.h"
52
53 #ifdef HAVE_UNISTD_H
54 #include <unistd.h>
55 #endif
56
57 /* ??? sim_cb_printf should be cb_printf, but until the callback support is
58 broken out of the simulator directory, these are here to not require
59 sim-utils.h. */
60 void sim_cb_printf PARAMS ((host_callback *, const char *, ...));
61 void sim_cb_eprintf PARAMS ((host_callback *, const char *, ...));
62
63 extern CB_TARGET_DEFS_MAP cb_init_syscall_map[];
64 extern CB_TARGET_DEFS_MAP cb_init_errno_map[];
65 extern CB_TARGET_DEFS_MAP cb_init_open_map[];
66
67 extern int system PARAMS ((const char *));
68
69 static int os_init PARAMS ((host_callback *));
70 static int os_shutdown PARAMS ((host_callback *));
71 static int os_unlink PARAMS ((host_callback *, const char *));
72 static long os_time PARAMS ((host_callback *, long *));
73 static int os_system PARAMS ((host_callback *, const char *));
74 static int os_rename PARAMS ((host_callback *, const char *, const char *));
75 static int os_write_stdout PARAMS ((host_callback *, const char *, int));
76 static void os_flush_stdout PARAMS ((host_callback *));
77 static int os_write_stderr PARAMS ((host_callback *, const char *, int));
78 static void os_flush_stderr PARAMS ((host_callback *));
79 static int os_write PARAMS ((host_callback *, int, const char *, int));
80 static int os_read_stdin PARAMS ((host_callback *, char *, int));
81 static int os_read PARAMS ((host_callback *, int, char *, int));
82 static int os_open PARAMS ((host_callback *, const char *, int));
83 static int os_lseek PARAMS ((host_callback *, int, long, int));
84 static int os_isatty PARAMS ((host_callback *, int));
85 static int os_get_errno PARAMS ((host_callback *));
86 static int os_close PARAMS ((host_callback *, int));
87 static void os_vprintf_filtered PARAMS ((host_callback *, const char *, va_list));
88 static void os_evprintf_filtered PARAMS ((host_callback *, const char *, va_list));
89 static void os_error PARAMS ((host_callback *, const char *, ...));
90 static int fdmap PARAMS ((host_callback *, int));
91 static int fdbad PARAMS ((host_callback *, int));
92 static int wrap PARAMS ((host_callback *, int));
93
94 /* Set the callback copy of errno from what we see now. */
95
96 static int
97 wrap (p, val)
98 host_callback *p;
99 int val;
100 {
101 p->last_errno = errno;
102 return val;
103 }
104
105 /* Make sure the FD provided is ok. If not, return non-zero
106 and set errno. */
107
108 static int
109 fdbad (p, fd)
110 host_callback *p;
111 int fd;
112 {
113 if (fd < 0 || fd > MAX_CALLBACK_FDS || p->fd_buddy[fd] < 0)
114 {
115 p->last_errno = EINVAL;
116 return -1;
117 }
118 return 0;
119 }
120
121 static int
122 fdmap (p, fd)
123 host_callback *p;
124 int fd;
125 {
126 return p->fdmap[fd];
127 }
128
129 static int
130 os_close (p, fd)
131 host_callback *p;
132 int fd;
133 {
134 int result;
135 int i, next;
136
137 result = fdbad (p, fd);
138 if (result)
139 return result;
140 /* If this file descripter has one or more buddies (originals /
141 duplicates from a dup), just remove it from the circular list. */
142 for (i = fd; (next = p->fd_buddy[i]) != fd; )
143 i = next;
144 if (fd != i)
145 p->fd_buddy[i] = p->fd_buddy[fd];
146 else
147 result = wrap (p, close (fdmap (p, fd)));
148 p->fd_buddy[fd] = -1;
149
150 return result;
151 }
152
153
154 /* taken from gdb/util.c:notice_quit() - should be in a library */
155
156
157 #if defined(__GO32__) || defined (_MSC_VER)
158 static int
159 os_poll_quit (p)
160 host_callback *p;
161 {
162 #if defined(__GO32__)
163 int kbhit ();
164 int getkey ();
165 if (kbhit ())
166 {
167 int k = getkey ();
168 if (k == 1)
169 {
170 return 1;
171 }
172 else if (k == 2)
173 {
174 return 1;
175 }
176 else
177 {
178 sim_cb_eprintf (p, "CTRL-A to quit, CTRL-B to quit harder\n");
179 }
180 }
181 #endif
182 #if defined (_MSC_VER)
183 /* NB - this will not compile! */
184 int k = win32pollquit();
185 if (k == 1)
186 return 1;
187 else if (k == 2)
188 return 1;
189 #endif
190 return 0;
191 }
192 #else
193 #define os_poll_quit 0
194 #endif /* defined(__GO32__) || defined(_MSC_VER) */
195
196 static int
197 os_get_errno (p)
198 host_callback *p;
199 {
200 return cb_host_to_target_errno (p, p->last_errno);
201 }
202
203
204 static int
205 os_isatty (p, fd)
206 host_callback *p;
207 int fd;
208 {
209 int result;
210
211 result = fdbad (p, fd);
212 if (result)
213 return result;
214 result = wrap (p, isatty (fdmap (p, fd)));
215
216 return result;
217 }
218
219 static int
220 os_lseek (p, fd, off, way)
221 host_callback *p;
222 int fd;
223 long off;
224 int way;
225 {
226 int result;
227
228 result = fdbad (p, fd);
229 if (result)
230 return result;
231 result = lseek (fdmap (p, fd), off, way);
232 return result;
233 }
234
235 static int
236 os_open (p, name, flags)
237 host_callback *p;
238 const char *name;
239 int flags;
240 {
241 int i;
242 for (i = 0; i < MAX_CALLBACK_FDS; i++)
243 {
244 if (p->fd_buddy[i] < 0)
245 {
246 int f = open (name, cb_target_to_host_open (p, flags), 0644);
247 if (f < 0)
248 {
249 p->last_errno = errno;
250 return f;
251 }
252 p->fd_buddy[i] = i;
253 p->fdmap[i] = f;
254 return i;
255 }
256 }
257 p->last_errno = EMFILE;
258 return -1;
259 }
260
261 static int
262 os_read (p, fd, buf, len)
263 host_callback *p;
264 int fd;
265 char *buf;
266 int len;
267 {
268 int result;
269
270 result = fdbad (p, fd);
271 if (result)
272 return result;
273 result = wrap (p, read (fdmap (p, fd), buf, len));
274 return result;
275 }
276
277 static int
278 os_read_stdin (p, buf, len)
279 host_callback *p;
280 char *buf;
281 int len;
282 {
283 return wrap (p, read (0, buf, len));
284 }
285
286 static int
287 os_write (p, fd, buf, len)
288 host_callback *p;
289 int fd;
290 const char *buf;
291 int len;
292 {
293 int result;
294 int real_fd;
295
296 result = fdbad (p, fd);
297 if (result)
298 return result;
299 real_fd = fdmap (p, fd);
300 switch (real_fd)
301 {
302 default:
303 result = wrap (p, write (real_fd, buf, len));
304 break;
305 case 1:
306 result = p->write_stdout (p, buf, len);
307 break;
308 case 2:
309 result = p->write_stderr (p, buf, len);
310 break;
311 }
312 return result;
313 }
314
315 static int
316 os_write_stdout (p, buf, len)
317 host_callback *p ATTRIBUTE_UNUSED;
318 const char *buf;
319 int len;
320 {
321 return fwrite (buf, 1, len, stdout);
322 }
323
324 static void
325 os_flush_stdout (p)
326 host_callback *p ATTRIBUTE_UNUSED;
327 {
328 fflush (stdout);
329 }
330
331 static int
332 os_write_stderr (p, buf, len)
333 host_callback *p ATTRIBUTE_UNUSED;
334 const char *buf;
335 int len;
336 {
337 return fwrite (buf, 1, len, stderr);
338 }
339
340 static void
341 os_flush_stderr (p)
342 host_callback *p ATTRIBUTE_UNUSED;
343 {
344 fflush (stderr);
345 }
346
347 static int
348 os_rename (p, f1, f2)
349 host_callback *p;
350 const char *f1;
351 const char *f2;
352 {
353 return wrap (p, rename (f1, f2));
354 }
355
356
357 static int
358 os_system (p, s)
359 host_callback *p;
360 const char *s;
361 {
362 return wrap (p, system (s));
363 }
364
365 static long
366 os_time (p, t)
367 host_callback *p;
368 long *t;
369 {
370 return wrap (p, time (t));
371 }
372
373
374 static int
375 os_unlink (p, f1)
376 host_callback *p;
377 const char *f1;
378 {
379 return wrap (p, unlink (f1));
380 }
381
382 static int
383 os_stat (p, file, buf)
384 host_callback *p;
385 const char *file;
386 struct stat *buf;
387 {
388 /* ??? There is an issue of when to translate to the target layout.
389 One could do that inside this function, or one could have the
390 caller do it. It's more flexible to let the caller do it, though
391 I'm not sure the flexibility will ever be useful. */
392 return wrap (p, stat (file, buf));
393 }
394
395 static int
396 os_fstat (p, fd, buf)
397 host_callback *p;
398 int fd;
399 struct stat *buf;
400 {
401 if (fdbad (p, fd))
402 return -1;
403 /* ??? There is an issue of when to translate to the target layout.
404 One could do that inside this function, or one could have the
405 caller do it. It's more flexible to let the caller do it, though
406 I'm not sure the flexibility will ever be useful. */
407 return wrap (p, fstat (fdmap (p, fd), buf));
408 }
409
410 static int
411 os_lstat (p, file, buf)
412 host_callback *p;
413 const char *file;
414 struct stat *buf;
415 {
416 /* NOTE: hpn/2004-12-12: Same issue here as with os_fstat. */
417 return wrap (p, lstat (file, buf));
418 }
419
420 static int
421 os_ftruncate (p, fd, len)
422 host_callback *p;
423 int fd;
424 long len;
425 {
426 int result;
427
428 result = fdbad (p, fd);
429 if (result)
430 return result;
431 result = wrap (p, ftruncate (fdmap (p, fd), len));
432 return result;
433 }
434
435 static int
436 os_truncate (p, file, len)
437 host_callback *p;
438 const char *file;
439 long len;
440 {
441 return wrap (p, truncate (file, len));
442 }
443
444 static int
445 os_shutdown (p)
446 host_callback *p;
447 {
448 int i, next, j;
449 for (i = 0; i < MAX_CALLBACK_FDS; i++)
450 {
451 int do_close = 1;
452
453 next = p->fd_buddy[i];
454 if (next < 0)
455 continue;
456 do
457 {
458 j = next;
459 if (j == MAX_CALLBACK_FDS)
460 do_close = 0;
461 next = p->fd_buddy[j];
462 p->fd_buddy[j] = -1;
463 /* At the initial call of os_init, we got -1, 0, 0, 0, ... */
464 if (next < 0)
465 {
466 p->fd_buddy[i] = -1;
467 do_close = 0;
468 break;
469 }
470 }
471 while (j != i);
472 if (do_close)
473 close (p->fdmap[i]);
474 }
475 return 1;
476 }
477
478 static int
479 os_init (p)
480 host_callback *p;
481 {
482 int i;
483
484 os_shutdown (p);
485 for (i = 0; i < 3; i++)
486 {
487 p->fdmap[i] = i;
488 p->fd_buddy[i] = i - 1;
489 }
490 p->fd_buddy[0] = MAX_CALLBACK_FDS;
491 p->fd_buddy[MAX_CALLBACK_FDS] = 2;
492
493 p->syscall_map = cb_init_syscall_map;
494 p->errno_map = cb_init_errno_map;
495 p->open_map = cb_init_open_map;
496
497 return 1;
498 }
499
500 /* DEPRECATED */
501
502 /* VARARGS */
503 static void
504 #ifdef ANSI_PROTOTYPES
505 os_printf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
506 #else
507 os_printf_filtered (p, va_alist)
508 host_callback *p;
509 va_dcl
510 #endif
511 {
512 va_list args;
513 #ifdef ANSI_PROTOTYPES
514 va_start (args, format);
515 #else
516 char *format;
517
518 va_start (args);
519 format = va_arg (args, char *);
520 #endif
521
522 vfprintf (stdout, format, args);
523 va_end (args);
524 }
525
526 /* VARARGS */
527 static void
528 #ifdef ANSI_PROTOTYPES
529 os_vprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
530 #else
531 os_vprintf_filtered (p, format, args)
532 host_callback *p;
533 const char *format;
534 va_list args;
535 #endif
536 {
537 vprintf (format, args);
538 }
539
540 /* VARARGS */
541 static void
542 #ifdef ANSI_PROTOTYPES
543 os_evprintf_filtered (host_callback *p ATTRIBUTE_UNUSED, const char *format, va_list args)
544 #else
545 os_evprintf_filtered (p, format, args)
546 host_callback *p;
547 const char *format;
548 va_list args;
549 #endif
550 {
551 vfprintf (stderr, format, args);
552 }
553
554 /* VARARGS */
555 static void
556 #ifdef ANSI_PROTOTYPES
557 os_error (host_callback *p ATTRIBUTE_UNUSED, const char *format, ...)
558 #else
559 os_error (p, va_alist)
560 host_callback *p;
561 va_dcl
562 #endif
563 {
564 va_list args;
565 #ifdef ANSI_PROTOTYPES
566 va_start (args, format);
567 #else
568 char *format;
569
570 va_start (args);
571 format = va_arg (args, char *);
572 #endif
573
574 vfprintf (stderr, format, args);
575 fprintf (stderr, "\n");
576
577 va_end (args);
578 exit (1);
579 }
580
581 host_callback default_callback =
582 {
583 os_close,
584 os_get_errno,
585 os_isatty,
586 os_lseek,
587 os_open,
588 os_read,
589 os_read_stdin,
590 os_rename,
591 os_system,
592 os_time,
593 os_unlink,
594 os_write,
595 os_write_stdout,
596 os_flush_stdout,
597 os_write_stderr,
598 os_flush_stderr,
599
600 os_stat,
601 os_fstat,
602 os_lstat,
603
604 os_ftruncate,
605 os_truncate,
606
607 os_poll_quit,
608
609 os_shutdown,
610 os_init,
611
612 os_printf_filtered, /* deprecated */
613
614 os_vprintf_filtered,
615 os_evprintf_filtered,
616 os_error,
617
618 0, /* last errno */
619
620 { 0, }, /* fdmap */
621 { -1, }, /* fd_buddy */
622
623 0, /* syscall_map */
624 0, /* errno_map */
625 0, /* open_map */
626 0, /* signal_map */
627 0, /* stat_map */
628
629 /* Defaults expected to be overridden at initialization, where needed. */
630 BFD_ENDIAN_UNKNOWN, /* target_endian */
631
632 HOST_CALLBACK_MAGIC,
633 };
634 \f
635 /* Read in a file describing the target's system call values.
636 E.g. maybe someone will want to use something other than newlib.
637 This assumes that the basic system call recognition and value passing/
638 returning is supported. So maybe some coding/recompilation will be
639 necessary, but not as much.
640
641 If an error occurs, the existing mapping is not changed. */
642
643 CB_RC
644 cb_read_target_syscall_maps (cb, file)
645 host_callback *cb;
646 const char *file;
647 {
648 CB_TARGET_DEFS_MAP *syscall_map, *errno_map, *open_map, *signal_map;
649 const char *stat_map;
650 FILE *f;
651
652 if ((f = fopen (file, "r")) == NULL)
653 return CB_RC_ACCESS;
654
655 /* ... read in and parse file ... */
656
657 fclose (f);
658 return CB_RC_NO_MEM; /* FIXME:wip */
659
660 /* Free storage allocated for any existing maps. */
661 if (cb->syscall_map)
662 free (cb->syscall_map);
663 if (cb->errno_map)
664 free (cb->errno_map);
665 if (cb->open_map)
666 free (cb->open_map);
667 if (cb->signal_map)
668 free (cb->signal_map);
669 if (cb->stat_map)
670 free ((PTR) cb->stat_map);
671
672 cb->syscall_map = syscall_map;
673 cb->errno_map = errno_map;
674 cb->open_map = open_map;
675 cb->signal_map = signal_map;
676 cb->stat_map = stat_map;
677
678 return CB_RC_OK;
679 }
680
681 /* Translate the target's version of a syscall number to the host's.
682 This isn't actually the host's version, rather a canonical form.
683 ??? Perhaps this should be renamed to ..._canon_syscall. */
684
685 int
686 cb_target_to_host_syscall (cb, target_val)
687 host_callback *cb;
688 int target_val;
689 {
690 CB_TARGET_DEFS_MAP *m;
691
692 for (m = &cb->syscall_map[0]; m->target_val != -1; ++m)
693 if (m->target_val == target_val)
694 return m->host_val;
695
696 return -1;
697 }
698
699 /* FIXME: sort tables if large.
700 Alternatively, an obvious improvement for errno conversion is
701 to machine generate a function with a large switch(). */
702
703 /* Translate the host's version of errno to the target's. */
704
705 int
706 cb_host_to_target_errno (cb, host_val)
707 host_callback *cb;
708 int host_val;
709 {
710 CB_TARGET_DEFS_MAP *m;
711
712 for (m = &cb->errno_map[0]; m->host_val; ++m)
713 if (m->host_val == host_val)
714 return m->target_val;
715
716 /* ??? Which error to return in this case is up for grabs.
717 Note that some missing values may have standard alternatives.
718 For now return 0 and require caller to deal with it. */
719 return 0;
720 }
721
722 /* Given a set of target bitmasks for the open system call,
723 return the host equivalent.
724 Mapping open flag values is best done by looping so there's no need
725 to machine generate this function. */
726
727 int
728 cb_target_to_host_open (cb, target_val)
729 host_callback *cb;
730 int target_val;
731 {
732 int host_val = 0;
733 CB_TARGET_DEFS_MAP *m;
734
735 for (m = &cb->open_map[0]; m->host_val != -1; ++m)
736 {
737 switch (m->target_val)
738 {
739 /* O_RDONLY can be (and usually is) 0 which needs to be treated
740 specially. */
741 case TARGET_O_RDONLY :
742 case TARGET_O_WRONLY :
743 case TARGET_O_RDWR :
744 if ((target_val & (TARGET_O_RDONLY | TARGET_O_WRONLY | TARGET_O_RDWR))
745 == m->target_val)
746 host_val |= m->host_val;
747 /* Handle the host/target differentiating between binary and
748 text mode. Only one case is of importance */
749 #if ! defined (TARGET_O_BINARY) && defined (O_BINARY)
750 host_val |= O_BINARY;
751 #endif
752 break;
753 default :
754 if ((m->target_val & target_val) == m->target_val)
755 host_val |= m->host_val;
756 break;
757 }
758 }
759
760 return host_val;
761 }
762
763 /* Utility for e.g. cb_host_to_target_stat to store values in the target's
764 stat struct. */
765
766 void
767 cb_store_target_endian (cb, p, size, val)
768 host_callback *cb;
769 char *p;
770 int size;
771 long val; /* ??? must be as big as target word size */
772 {
773 if (cb->target_endian == BFD_ENDIAN_BIG)
774 {
775 p += size;
776 while (size-- > 0)
777 {
778 *--p = val;
779 val >>= 8;
780 }
781 }
782 else
783 {
784 while (size-- > 0)
785 {
786 *p++ = val;
787 val >>= 8;
788 }
789 }
790 }
791
792 /* Translate a host's stat struct into a target's.
793 If HS is NULL, just compute the length of the buffer required,
794 TS is ignored.
795
796 The result is the size of the target's stat struct,
797 or zero if an error occurred during the translation. */
798
799 int
800 cb_host_to_target_stat (cb, hs, ts)
801 host_callback *cb;
802 const struct stat *hs;
803 PTR ts;
804 {
805 const char *m = cb->stat_map;
806 char *p;
807
808 if (hs == NULL)
809 ts = NULL;
810 p = ts;
811
812 while (m)
813 {
814 char *q = strchr (m, ',');
815 int size;
816
817 /* FIXME: Use sscanf? */
818 if (q == NULL)
819 {
820 /* FIXME: print error message */
821 return 0;
822 }
823 size = atoi (q + 1);
824 if (size == 0)
825 {
826 /* FIXME: print error message */
827 return 0;
828 }
829
830 if (hs != NULL)
831 {
832 if (0)
833 ;
834 /* Defined here to avoid emacs indigestion on a lone "else". */
835 #undef ST_x
836 #define ST_x(FLD) \
837 else if (strncmp (m, #FLD, q - m) == 0) \
838 cb_store_target_endian (cb, p, size, hs->FLD)
839
840 #ifdef HAVE_STRUCT_STAT_ST_DEV
841 ST_x (st_dev);
842 #endif
843 #ifdef HAVE_STRUCT_STAT_ST_INO
844 ST_x (st_ino);
845 #endif
846 #ifdef HAVE_STRUCT_STAT_ST_MODE
847 ST_x (st_mode);
848 #endif
849 #ifdef HAVE_STRUCT_STAT_ST_NLINK
850 ST_x (st_nlink);
851 #endif
852 #ifdef HAVE_STRUCT_STAT_ST_UID
853 ST_x (st_uid);
854 #endif
855 #ifdef HAVE_STRUCT_STAT_ST_GID
856 ST_x (st_gid);
857 #endif
858 #ifdef HAVE_STRUCT_STAT_ST_RDEV
859 ST_x (st_rdev);
860 #endif
861 #ifdef HAVE_STRUCT_STAT_ST_SIZE
862 ST_x (st_size);
863 #endif
864 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
865 ST_x (st_blksize);
866 #endif
867 #ifdef HAVE_STRUCT_STAT_ST_BLOCKS
868 ST_x (st_blocks);
869 #endif
870 #ifdef HAVE_STRUCT_STAT_ST_ATIME
871 ST_x (st_atime);
872 #endif
873 #ifdef HAVE_STRUCT_STAT_ST_MTIME
874 ST_x (st_mtime);
875 #endif
876 #ifdef HAVE_STRUCT_STAT_ST_CTIME
877 ST_x (st_ctime);
878 #endif
879 #undef ST_x
880 /* FIXME:wip */
881 else
882 /* Unsupported field, store 0. */
883 cb_store_target_endian (cb, p, size, 0);
884 }
885
886 p += size;
887 m = strchr (q, ':');
888 if (m)
889 ++m;
890 }
891
892 return p - (char *) ts;
893 }
894 \f
895 /* Cover functions to the vfprintf callbacks.
896
897 ??? If one thinks of the callbacks as a subsystem onto itself [or part of
898 a larger "remote target subsystem"] with a well defined interface, then
899 one would think that the subsystem would provide these. However, until
900 one is allowed to create such a subsystem (with its own source tree
901 independent of any particular user), such a critter can't exist. Thus
902 these functions are here for the time being. */
903
904 void
905 sim_cb_printf (host_callback *p, const char *fmt, ...)
906 {
907 va_list ap;
908
909 va_start (ap, fmt);
910 p->vprintf_filtered (p, fmt, ap);
911 va_end (ap);
912 }
913
914 void
915 sim_cb_eprintf (host_callback *p, const char *fmt, ...)
916 {
917 va_list ap;
918
919 va_start (ap, fmt);
920 p->evprintf_filtered (p, fmt, ap);
921 va_end (ap);
922 }
This page took 0.049566 seconds and 5 git commands to generate.