/* * m_cmd.c: built-in commands */ #include "m.h" #include #define HELPDIR "/opt/m/help/" #ifndef MAXPATHLEN # define MAXPATHLEN BUFSIZ #endif void m_history( void) { FILE *fout; char *fname = NULL; char *mode = NULL; int i, n = 10000, narg = (int) *pc++; npop(narg); for( i = 0; i < narg; ++i) { if( !sp[i]) error("null argument",""); if( sp[i] == <sym) { ++i; continue; } else if( sp[i] == >sym) { ++i; mode = "w"; } else if( sp[i] == >GTsym) { ++i; mode = "a"; } else { n_check( sp[i], "history"); n = fabs(VAL(sp[i])); continue; } if( !sp[i]) error("null argument",""); fname = sp[i]->name ? sp[i]->name : STR(sp[i]); } if( !fname) { history( n, stdout); return; } if( !mode) mode = "w"; if( (fout = fopen( fname, mode)) == NULL) { perror(fname); error("can't open ",fname); } history( n, fout); fclose(fout); } void m_cd( void) { char *dir; int narg = (int) *pc++; npop( narg); if( narg > 1) error("cd takes at most one argument",""); if( narg == 1) { if( !sp[0]) error("null argument",""); if( sp[0]->name ) dir = sp[0]->name; else /* must be a STRING */ dir = STR(sp[0]); } else if( (dir = getenv( "HOME")) == NULL) { yyerror("getenv(\"HOME\") failed"); return; } if( chdir( dir)) { yyerror("can't change directory"); perror(dir); } } void m_pwd( void) { int narg = (int) *pc++; char *p, cwd[MAXPATHLEN]; npop( narg); /* #ifdef __unix__ p = getwd(cwd); #else p = getcwd( cwd, MAXPATHLEN); #endif */ p = getcwd( cwd, MAXPATHLEN); if( p) dprint( "%s\n", cwd); } void m_echo( void) { int narg = (int) *pc++; npop( narg); if( narg == 0) { dprint( "echo is %s\n", echo ? "on" : "off"); return; } if( sp[0] ) { if( strcmp( sp[0]->name, "on") == 0) echo = 1; else if( strcmp( sp[0]->name, "off") == 0) echo = 0; else yyerror("echo expects `on' or `off' as argument"); } } static void pr_help( char *topic) { FILE *fp; char line[BUFSIZ]; (void) strcat( strcpy( line, HELPDIR), topic); if( (fp = fopen( line, "r")) == NULL) perror(line); else { dprint("\n"); while( fgets( line, sizeof(line), fp)) dprint( "%s", line); fclose( fp); } } void m_help( void) { int i, narg = (int) *pc++; npop(narg); if( narg == 0) pr_help( "help"); else for( i = 0; i < narg; ++i) if( sp[i]) pr_help( sp[i]->name ? sp[i]->name : STR(sp[i]) ); } void m_what( void) { int narg = (int) *pc++; npop(narg); what(); } void m_who( void) { int narg = (int) *pc++; npop(narg); who(); } #ifdef DEBUG void m_disasm( void) { int i, j; Symbolptr s; Instptr f; int narg = (int) *pc++; npop(narg); for( i = 0; i < narg; i++) { s = sp[i]; if( !s) continue; if( s->type != PROCEDURE && s->type != FUNCTION) display(s,""); else { dprint( "%s %s(", str_class(s->class), s->name); f = s->u.fptr + 1; for( j = 0; j < NARG(s); ++j) dprint( " %s%s", str_type( (int)*f++), ju.fptr + SIZE(s)); } } } #endif void m_clear( void) { int i; int narg = (int) *pc++; npop(narg); if( narg == 0) clear_all(); else for( i = 0; i < narg; i++) if( sp[i] && sp[i]->name) clear(sp[i]); } void m_list( void) { int i; int narg = (int) *pc++; npop(narg); for( i = 0; i < narg; i++) if( sp[i]) { if( sp[i]->type != PROCEDURE && sp[i]->type != FUNCTION) display(sp[i],""); else if( *sp[i]->u.fptr) dprint( "%s", (char *) i2d(*sp[i]->u.fptr)); } } void m_quit( void) { npop( (int) *pc++); (void) exit(SUCCESS); } static void m_load_read( int binary) { char fname[BUFSIZ]; int i, narg; narg = (int) *pc++; npop(narg); if( narg == 0) { if( binary) readfile( "matlab.mat"); else addfile( "save.m"); } else for( i = 0; i < narg; ++i) { if( !sp[i]) error("null argument",""); if( sp[i] == <sym) ++i; else if( sp[i] == >sym || sp[i] == >GTsym) { ++i; continue; } if( !sp[i]) error("null argument",""); if( sp[i]->name ) { strcpy( fname, sp[i]->name); strcat( fname, binary ? ".mat" : ".m"); if( binary) readfile( fname); else addfile( fname); } else { /* must be a STRING */ if( binary) readfile( fname); else addfile( STR(sp[i])); } } if( !binary && fin == stdin) fin = nextfile(); } void m_load( void) { m_load_read( 0); /* not binary */ } void m_read( void) { m_load_read( 1); /* binary */ } static void m_save_write( int binary) { FILE *fout; char fname[BUFSIZ]; int i, count = 0, narg = (int) *pc++; char *mode = NULL; npop(narg); for( i = 0; i < narg; ++i) { if( !sp[i]) error("null argument",""); if( sp[i] == <sym) { ++i; continue; } else if( sp[i] == >sym) { ++i; mode = binary ? "wb" : "w"; } else if( sp[i] == >GTsym) { ++i; mode = binary ? "ab" : "a"; } else { ++count; continue; } if( !sp[i]) error("null argument",""); if( sp[i]->name ) { strcpy( fname, sp[i]->name); strcat( fname, ".m"); } else /* must be a STRING */ strcpy( fname, STR(sp[i])); } if( !mode) /* b needs to be added to mode above for binary */ { if( binary) { mode = "wb"; strcpy( fname, "matlab.mat"); } else { mode = "w"; strcpy( fname, "save.m"); } } if( (fout = fopen( fname, mode)) == NULL) { perror(fname); error("can't open ",fname); } #ifdef DEBUG if( prog_debug) dprint( "save: opened file %s, mode = %s\n", fname, mode); #endif if( count == 0) save_all(fout, binary); else for( i = 0; i < narg; ++i) { if( sp[i] == <sym || sp[i] == >sym || sp[i] == >GTsym) ++i; else if( sp[i]->name) save( fout, sp[i], binary); } fclose(fout); } void m_save( void) { m_save_write( 0); /* not binary */ } void m_write( void) { m_save_write( 1); /* binary */ } void m_diary( void) { char *fname = NULL; char *mode = NULL; int on = 0, off = 0; int i, narg = (int) *pc++; npop(narg); for( i = 0; i < narg; ++i) { if( !sp[i]) error("null argument",""); if( sp[i] == <sym) { ++i; continue; } else if( sp[i] == >sym) { ++i; mode = "w"; } else if( sp[i] == >GTsym) { ++i; mode = "a"; } else if( strcmp( sp[i]->name, "on") == 0) { on = 1; continue; } else if( strcmp( sp[i]->name, "off") == 0) { off = 1; continue; } else { yyerror( "invalid argument to diary"); continue; } if( !sp[i]) error("null argument",""); fname = sp[i]->name ? sp[i]->name : STR(sp[i]); } if( on && off) { yyerror("can't specify both `on' and `off' for diary!"); return; } if( !fname && !on && !off) { dprint( "diary is %s\n", diary ? "on" : "off"); return; } if( !fname && fdiary) { /* got just `on' or `off' */ diary = on ? 1 : 0; if( !diary) fflush( fdiary); return; } if( !on && !off) /* opening new diary file */ on = 1; if( !fname) fname = "diary"; if( !mode) mode = "w"; if( fdiary) fclose(fdiary); if( (fdiary = fopen( fname, mode)) == NULL) { perror(fname); diary = 0; fdiary = NULL; return; } diary = on ? 1 : 0; #ifdef DEBUG if( prog_debug) { dprint( "diary: opened file %s, mode = %s\n", fname, mode); dprint( "diary: is %s\n", diary ? "on" : "off"); } #endif }