2 * Copyright (c) 2003 Stephen Williams (steve@icarus.com)
4 * This source code is free software; you can redistribute it
5 * and/or modify it in source code form under the terms of the GNU
6 * General Public License as published by the Free Software
7 * Foundation; either version 2 of the License, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20 #ident "$Id: sys_fileio.c,v 1.10 2007/03/14 04:05:51 steve Exp $"
23 # include "vpi_user.h"
24 # include "sys_priv.h"
30 #define IS_MCD(mcd) !((mcd)>>31&1)
34 * Implement the $fopen system function.
36 static PLI_INT32
sys_fopen_compiletf(PLI_BYTE8
*name
)
38 vpiHandle sys
= vpi_handle(vpiSysTfCall
, 0);
39 vpiHandle argv
= vpi_iterate(vpiArgument
, sys
);
43 vpi_printf("%s: file name argument missing.\n", name
);
44 vpi_sim_control(vpiFinish
, -1);
48 item
= vpi_scan(argv
);
50 vpi_printf("%s: file name argument missing.\n", name
);
51 vpi_sim_control(vpiFinish
, -1);
55 item
= vpi_scan(argv
);
57 /* The mode argument is optional. It is OK for it
58 to be missing. In this case, there are no more
59 arguments, and we're done. */
63 if (! is_constant(item
)) {
64 vpi_printf("ERROR: %s mode argument must be a constant\n", name
);
65 vpi_sim_control(vpiFinish
, -1);
68 if (vpi_get(vpiConstType
, item
) != vpiStringConst
) {
69 vpi_printf("ERROR: %s mode argument must be a string.\n", name
);
70 vpi_sim_control(vpiFinish
, -1);
73 item
= vpi_scan(argv
);
75 /* There should be no more arguments. */
79 vpi_free_object(argv
);
80 vpi_printf("%s: Too many arguments to system function.\n", name
);
84 static PLI_INT32
sys_fopen_calltf(PLI_BYTE8
*name
)
87 char *mode_string
= 0;
89 vpiHandle call_handle
= vpi_handle(vpiSysTfCall
, 0);
90 vpiHandle argv
= vpi_iterate(vpiArgument
, call_handle
);
91 vpiHandle item
= vpi_scan(argv
);
92 vpiHandle mode
= vpi_scan(argv
);
97 value
.format
= vpiStringVal
;
98 vpi_get_value(mode
, &value
);
99 mode_string
= strdup(value
.value
.str
);
101 vpi_free_object(argv
);
104 /* Get the string form of the file name from the file name
106 value
.format
= vpiStringVal
;
107 vpi_get_value(item
, &value
);
109 if ((value
.format
!= vpiStringVal
) || !value
.value
.str
) {
110 vpi_printf("ERROR: %s: File name argument (type=%d)"
111 " does not have a string value\n",
112 name
, vpi_get(vpiType
, item
));
113 if (mode
) free(mode_string
);
117 value
.format
= vpiIntVal
;
119 value
.value
.integer
= vpi_fopen(value
.value
.str
, mode_string
);
122 value
.value
.integer
= vpi_mcd_open(value
.value
.str
);
124 vpi_put_value(call_handle
, &value
, 0, vpiNoDelay
);
129 static PLI_INT32
sys_fopen_sizetf(PLI_BYTE8
*x
)
135 * Implement $fclose system function
137 static PLI_INT32
sys_fclose_calltf(PLI_BYTE8
*name
)
143 vpiHandle sys
= vpi_handle(vpiSysTfCall
, 0);
144 vpiHandle argv
= vpi_iterate(vpiArgument
, sys
);
145 vpiHandle item
= vpi_scan(argv
);
148 vpi_printf("%s: mcd parameter missing.\n", name
);
151 type
= vpi_get(vpiType
, item
);
158 vpi_printf("ERROR: %s mcd parameter must be of integral type",
160 vpi_printf(", got vpiType=%d\n", type
);
161 vpi_free_object(argv
);
165 value
.format
= vpiIntVal
;
166 vpi_get_value(item
, &value
);
167 mcd
= value
.value
.integer
;
173 static PLI_INT32
sys_fflush_calltf(PLI_BYTE8
*name
)
180 static PLI_INT32
sys_fputc_calltf(PLI_BYTE8
*name
)
185 s_vpi_value value
, xvalue
;
186 vpiHandle sys
= vpi_handle(vpiSysTfCall
, 0);
187 vpiHandle argv
= vpi_iterate(vpiArgument
, sys
);
188 vpiHandle item
= vpi_scan(argv
);
192 vpi_printf("%s: mcd parameter missing.\n", name
);
196 type
= vpi_get(vpiType
, item
);
203 vpi_printf("ERROR: %s mcd parameter must be of integral", name
);
204 vpi_printf(", got vpiType=%d\n", type
);
205 vpi_free_object(argv
);
209 value
.format
= vpiIntVal
;
210 vpi_get_value(item
, &value
);
211 mcd
= value
.value
.integer
;
213 if (IS_MCD(mcd
)) return EOF
;
215 item
= vpi_scan(argv
);
217 xvalue
.format
= vpiIntVal
;
218 vpi_get_value(item
, &xvalue
);
219 x
= xvalue
.value
.integer
;
221 fp
= vpi_get_file(mcd
);
227 static PLI_INT32
sys_fgetc_calltf(PLI_BYTE8
*name
)
231 s_vpi_value value
, rval
;
232 vpiHandle sys
= vpi_handle(vpiSysTfCall
, 0);
233 vpiHandle argv
= vpi_iterate(vpiArgument
, sys
);
234 vpiHandle item
= vpi_scan(argv
);
238 vpi_printf("%s: mcd parameter missing.\n", name
);
242 type
= vpi_get(vpiType
, item
);
249 vpi_printf("ERROR: %s mcd parameter must be of integral", name
);
250 vpi_printf(", got vpiType=%d\n", type
);
251 vpi_free_object(argv
);
255 value
.format
= vpiIntVal
;
256 vpi_get_value(item
, &value
);
257 mcd
= value
.value
.integer
;
259 rval
.format
= vpiIntVal
;
261 fp
= vpi_get_file(mcd
);
262 if (!fp
|| IS_MCD(mcd
))
263 rval
.value
.integer
= EOF
;
265 rval
.value
.integer
= fgetc(fp
);
267 vpi_put_value(sys
, &rval
, 0, vpiNoDelay
);
272 static PLI_INT32
sys_fgetc_sizetf(PLI_BYTE8
*x
)
277 static PLI_INT32
sys_fgets_compiletf(PLI_BYTE8
*name
)
279 vpiHandle sys
= vpi_handle(vpiSysTfCall
, 0);
280 vpiHandle argv
= vpi_iterate(vpiArgument
, sys
);
281 vpiHandle item
= vpi_scan(argv
);
285 vpi_printf("%s: string parameter missing.\n", name
);
289 type
= vpi_get(vpiType
, item
);
291 if (type
!= vpiReg
) {
292 vpi_printf("%s: string parameter must be a reg.\n", name
);
293 vpi_free_object(argv
);
297 item
= vpi_scan(argv
);
299 vpi_printf("%s: mcd parameter missing.\n", name
);
303 /* That should be all the arguments. */
304 item
= vpi_scan(argv
);
310 static PLI_INT32
sys_fgets_calltf(PLI_BYTE8
*name
)
314 s_vpi_value value
, rval
;
319 vpiHandle sys
= vpi_handle(vpiSysTfCall
, 0);
320 vpiHandle argv
= vpi_iterate(vpiArgument
, sys
);
321 vpiHandle str
= vpi_scan(argv
);
322 vpiHandle mch
= vpi_scan(argv
);
324 value
.format
= vpiIntVal
;
325 vpi_get_value(mch
, &value
);
326 mcd
= value
.value
.integer
;
328 fd
= vpi_get_file(mcd
);
329 if (!fd
|| IS_MCD(mcd
)) {
330 rval
.format
= vpiIntVal
;
331 rval
.value
.integer
= 0;
332 vpi_put_value(sys
, &rval
, 0, vpiNoDelay
);
336 txt_len
= vpi_get(vpiSize
, str
) / 8;
337 txt
= malloc(txt_len
+ 1);
339 if (fgets(txt
, txt_len
+1, fd
) == 0) {
340 rval
.format
= vpiIntVal
;
341 rval
.value
.integer
= 0;
342 vpi_put_value(sys
, &rval
, 0, vpiNoDelay
);
347 rval
.format
= vpiIntVal
;
348 rval
.value
.integer
= strlen(txt
);
349 vpi_put_value(sys
, &rval
, 0, vpiNoDelay
);
351 value
.format
= vpiStringVal
;
352 value
.value
.str
= txt
;
353 vpi_put_value(str
, &value
, 0, vpiNoDelay
);
360 static PLI_INT32
sys_ungetc_compiletf(PLI_BYTE8
*name
)
363 vpiHandle sys
= vpi_handle(vpiSysTfCall
, 0);
364 vpiHandle argv
= vpi_iterate(vpiArgument
, sys
);
365 vpiHandle item
= vpi_scan(argv
);
368 vpi_printf("%s: mcd parameter missing.\n", name
);
372 type
= vpi_get(vpiType
, item
);
379 vpi_printf("ERROR: %s mcd parameter must be of integral", name
);
380 vpi_printf(", got vpiType=%d\n", type
);
381 vpi_free_object(argv
);
388 static PLI_INT32
sys_ungetc_calltf(PLI_BYTE8
*name
)
392 s_vpi_value value
, xvalue
, rval
;
393 vpiHandle sys
= vpi_handle(vpiSysTfCall
, 0);
394 vpiHandle argv
= vpi_iterate(vpiArgument
, sys
);
395 vpiHandle item
= vpi_scan(argv
);
398 rval
.format
= vpiIntVal
;
402 value
.format
= vpiIntVal
;
403 vpi_get_value(item
, &value
);
404 mcd
= value
.value
.integer
;
407 rval
.value
.integer
= EOF
;
408 vpi_put_value(sys
, &rval
, 0, vpiNoDelay
);
412 item
= vpi_scan(argv
);
414 xvalue
.format
= vpiIntVal
;
415 vpi_get_value(item
, &xvalue
);
416 x
= xvalue
.value
.integer
;
418 fp
= vpi_get_file(mcd
);
420 rval
.value
.integer
= EOF
;
421 vpi_put_value(sys
, &rval
, 0, vpiNoDelay
);
427 rval
.value
.integer
= 0;
428 vpi_put_value(sys
, &rval
, 0, vpiNoDelay
);
432 static PLI_INT32
sys_ungetc_sizetf(PLI_BYTE8
*x
)
439 void sys_fileio_register()
441 s_vpi_systf_data tf_data
;
443 //============================== fopen
444 tf_data
.type
= vpiSysFunc
;
445 tf_data
.tfname
= "$fopen";
446 tf_data
.calltf
= sys_fopen_calltf
;
447 tf_data
.compiletf
= sys_fopen_compiletf
;
448 tf_data
.sizetf
= sys_fopen_sizetf
;
449 tf_data
.user_data
= "$fopen";
450 vpi_register_systf(&tf_data
);
452 //============================== fclose
453 tf_data
.type
= vpiSysTask
;
454 tf_data
.tfname
= "$fclose";
455 tf_data
.calltf
= sys_fclose_calltf
;
456 tf_data
.compiletf
= 0;
458 tf_data
.user_data
= "$fclose";
459 vpi_register_systf(&tf_data
);
461 //============================== fflush
462 tf_data
.type
= vpiSysTask
;
463 tf_data
.tfname
= "$fflush";
464 tf_data
.calltf
= sys_fflush_calltf
;
465 tf_data
.compiletf
= 0;
467 tf_data
.user_data
= "$fflush";
468 vpi_register_systf(&tf_data
);
470 //============================== fputc
471 tf_data
.type
= vpiSysTask
;
472 tf_data
.tfname
= "$fputc";
473 tf_data
.calltf
= sys_fputc_calltf
;
474 tf_data
.compiletf
= 0;
476 tf_data
.user_data
= "$fputc";
477 vpi_register_systf(&tf_data
);
479 //============================== fgetc
480 tf_data
.type
= vpiSysFunc
;
481 tf_data
.sysfunctype
= vpiSysFuncInt
;
482 tf_data
.tfname
= "$fgetc";
483 tf_data
.calltf
= sys_fgetc_calltf
;
484 tf_data
.compiletf
= 0;
485 tf_data
.sizetf
= sys_fgetc_sizetf
;
486 tf_data
.user_data
= "$fgetc";
487 vpi_register_systf(&tf_data
);
489 //============================== fgets
490 tf_data
.type
= vpiSysFunc
;
491 tf_data
.sysfunctype
= vpiSysFuncInt
;
492 tf_data
.tfname
= "$fgets";
493 tf_data
.calltf
= sys_fgets_calltf
;
494 tf_data
.compiletf
= sys_fgets_compiletf
;
496 tf_data
.user_data
= "$fgets";
497 vpi_register_systf(&tf_data
);
499 //============================== ungetc
500 tf_data
.type
= vpiSysFunc
;
501 tf_data
.sysfunctype
= vpiSysFuncInt
;
502 tf_data
.tfname
= "$ungetc";
503 tf_data
.calltf
= sys_ungetc_calltf
;
504 tf_data
.compiletf
= sys_ungetc_compiletf
;
505 tf_data
.sizetf
= sys_ungetc_sizetf
;
506 tf_data
.user_data
= "$ungetc";
507 vpi_register_systf(&tf_data
);
512 * $Log: sys_fileio.c,v $
513 * Revision 1.10 2007/03/14 04:05:51 steve
514 * VPI tasks take PLI_BYTE* by the standard.
516 * Revision 1.9 2006/10/30 22:45:37 steve
517 * Updates for Cygwin portability (pr1585922)
519 * Revision 1.8 2006/08/03 05:02:46 steve
520 * Use compiletf to check arguments.
522 * Revision 1.7 2005/09/20 18:34:01 steve
523 * Clean up compiler warnings.
525 * Revision 1.6 2005/01/09 20:12:22 steve
526 * Merge $fopen robustness fix from 0.8
528 * Revision 1.5.2.1 2005/01/01 20:07:41 steve
529 * More robust handling of file name argument to $fopen.
531 * Revision 1.5 2004/08/24 16:16:23 steve
532 * Fix read count passed to fgets.
534 * Revision 1.4 2004/02/20 03:20:04 steve
535 * unused variable warning.
537 * Revision 1.3 2004/02/19 21:33:13 steve
538 * Add the $fgets function.
540 * Revision 1.2 2003/11/07 19:40:05 steve
541 * Implement basic fflush.
543 * Revision 1.1 2003/10/30 03:43:20 steve
544 * Rearrange fileio functions, and add ungetc.