Nife version Beta
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

502 lines
11 KiB

  1. /* Copyright (C) 2011-2016 Patrick H. E. Foubet - S.E.R.I.A.N.E.
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or any
  5. later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>
  12. *******************************************************************/
  13. /* nife.c */
  14. #include "conf.h"
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <signal.h>
  19. #include <sys/types.h>
  20. #include <sys/wait.h>
  21. #include <sys/stat.h>
  22. #include <fcntl.h>
  23. #include <unistd.h>
  24. #include "nife.h"
  25. #include "mth.h"
  26. #include "err.h"
  27. #include "lib.h"
  28. #include "stackC.h"
  29. #include "stackV.h"
  30. #include "stackF.h"
  31. #include "histo.h"
  32. #include "tasks.h"
  33. #include "debug.h"
  34. #include "help.h"
  35. #include "net.h"
  36. #include "gplot.h"
  37. static char sepa[] = " \t\n";
  38. static int SigOn=0; /* only for interractive task */
  39. void putTrSuite(void (*f)(char*))
  40. {
  41. int i;
  42. i=iTS;
  43. traiteSuite[i++]=f;
  44. _MODIF_iTS_(i);
  45. if (iTS==NBTRSUITE) fprintf(stderr,"traiteSuite limit raise !\n");
  46. }
  47. void dropTrSuite(void)
  48. {
  49. int i;
  50. i=iTS-1;
  51. _MODIF_iTS_(i);
  52. if (iTS < 0) fprintf(stderr,"traiteSuite index negative !\n");
  53. }
  54. PFC getTrSuite(void)
  55. {
  56. if (iTS<1) return (PFC)NULL;
  57. else return(traiteSuite[iTS-1]);
  58. }
  59. void interInfos(char *F, char*P)
  60. {
  61. fprintf(stderr, " Error in %s ( %s ) !!\n",F,P);
  62. if (errno) perror(F);
  63. if (inSonProc) {
  64. sleep(2); exit(1);
  65. }
  66. }
  67. void Interrupt(int S)
  68. {
  69. int status;
  70. switch(S) {
  71. case SIGCHLD :
  72. if(WAITPID) return;
  73. while (waitpid(-1, &status, WNOHANG) > 0);
  74. return;
  75. break;
  76. case SIGSEGV :
  77. printf("Segmentation Error !!\n");
  78. termReset();
  79. _exit(1);
  80. break;
  81. case SIGPIPE :
  82. printf("Pipe is broken");
  83. break;
  84. case SIGFPE :
  85. printf("Floating Point");
  86. break;
  87. case SIGALRM :
  88. printf("Compilation");
  89. break;
  90. case SIGINT :
  91. if (!SigOn) return;
  92. default :
  93. printf("Signal %d !\n",S);
  94. break;
  95. }
  96. siglongjmp(ENV_INT,1);
  97. }
  98. void IF_about(void)
  99. {
  100. char Lib[8];
  101. *Lib='\0';
  102. #ifdef _MULTI_THREADING_
  103. strcpy(Lib,"mt-");
  104. #endif
  105. printf("nife (Networking Industrial Forth-like Environment) - version %s%s-%ld/%ld\n\t (c) S.E.R.I.A.N.E. 2009-2015\n",Lib,VERSION,sizeof(long)*8,sizeof(double)*8);
  106. }
  107. int isSepa(char c, int m)
  108. {
  109. unsigned int i;
  110. if (m == 1) /* '\0 fait partie du lot */
  111. if (c == (char)'\0') return 1;
  112. for (i=0; i<strlen(sepa);i++)
  113. if (c == sepa[i]) return 1;
  114. return 0;
  115. }
  116. int traiteMot(char *M)
  117. {
  118. int Err=0;
  119. PFC tS;
  120. if (sigsetjmp(ENV_INT,1)) {
  121. interInfos("traiteMot",M);
  122. return 1;
  123. }
  124. if (!ITASK) SigOn=1;
  125. /* printf("traiteMot <%s> iTS=%d\n",M,iTS); */
  126. tS = getTrSuite();
  127. if (tS != (PFC)NULL) tS(M);
  128. else
  129. if (! execLib(M)) { Err=1; messErr2(10,M); }
  130. if (ITASK) exit(0); /* non interpretation in task ! */
  131. if (!ITASK) SigOn=0;
  132. return Err;
  133. }
  134. static void traiteLigne(char *b, int Ctx)
  135. {
  136. char *mot, *d, *f, *w;
  137. /* case of sh command : ! */
  138. if (*b=='!') {
  139. runCommandT(b+1);
  140. return;
  141. }
  142. d=b; f=b+strlen(d);
  143. #ifdef DEBUG
  144. printf("traiteLigne : <%s>\n",d);
  145. #endif
  146. switch(Ctx) {
  147. case 1 : /* compileFile */
  148. D_Trace(" #");
  149. break;
  150. case 2 : /* IF_ExecCS */
  151. D_Trace("# ExecCS:");
  152. break;
  153. case 3 : /* makeFunction */
  154. D_Trace("# makeFunction:");
  155. break;
  156. default : /* 0 */
  157. if (getiFD()) D_Trace(" #");
  158. }
  159. D_Tracenl(b);
  160. while (d<f) {
  161. if (noErr()) break;
  162. /* recherche du 1er mot */
  163. if (stringEnCours) {
  164. mot = d;
  165. while (1) {
  166. if((d = strchr(d,'"')) == NULL) {
  167. d=mot+strlen(mot);
  168. break;
  169. }
  170. if (*(d-1) == '\\') {
  171. w = d-1;
  172. while (*w != '\0') {
  173. *w = *(w+1);
  174. w++;
  175. }
  176. continue;
  177. }
  178. d++;
  179. if (!isSepa(*d,1)) continue;
  180. break;
  181. }
  182. } else {
  183. /* on ignore les commentaires */
  184. if ((mot = strchr(d, (int)'#')) != NULL) {
  185. *mot = '\0';
  186. f = mot;
  187. }
  188. while (isSepa(*d,0)) d++; /* on avance tant que separateurs */
  189. mot = d;
  190. while (!isSepa(*d,1)) d++; /* on avance si nonSepa ET non \0 */
  191. }
  192. *d++ = '\0'; /* fin de la commande */
  193. if (strlen(mot)>0)
  194. if (traiteMot(mot)) break; /* abort if error */
  195. }
  196. }
  197. void compileFile(char * f)
  198. {
  199. FILE *F;
  200. int i=0;
  201. if ((F = fopen(f,"r")) != NULL) {
  202. while (fgets(bufP, LBUF,F)) {
  203. if (noErr()) {
  204. printf("In file %s line %d !\n",f,i);
  205. break;
  206. }
  207. traiteLigne(bufP,1);
  208. i++;
  209. }
  210. fclose(F);
  211. }
  212. }
  213. struct DumpEnt {
  214. double V;
  215. char L[8];
  216. uint32_t Scs;
  217. };
  218. /* Dump and Restore Nblf : Nife Binary Linkable Format */
  219. #define LENT 20
  220. #define LMARK 3
  221. char * DumpRest_ext(char * L)
  222. {
  223. void * M;
  224. char *F;
  225. if ((M = malloc(strlen(L)+5)) == NULL) stopErr("DumpRest_ext","malloc");
  226. F = (char*)M;
  227. sprintf(F,"%s.nblf",L);
  228. return F;
  229. }
  230. void dump_marque(int fd, char C)
  231. {
  232. char b[LMARK+1];
  233. sprintf(b,"<%c>",C);
  234. if ((write (fd, (void*)b, LMARK)) != LMARK)
  235. stopErr("dump","marque");
  236. }
  237. void restore_marque(int fd, char C)
  238. {
  239. char b[LMARK+1];
  240. /* printf("Restore %c ! \n", C); */
  241. if ((read(fd, (void*)b, LMARK)) == LMARK)
  242. if (b[1] == C) return;
  243. stopErr("restore","marque");
  244. }
  245. void rest_links_pr(int i, char *O, char *C)
  246. {
  247. if (i) {
  248. printf("Linking %d %s", i, O);
  249. if (i > 1) printf("s");
  250. printf(" to %s stack.\n",C);
  251. }
  252. }
  253. void dump_rest_pr(int T, int N, char * L) /* T=0 dump, T=1 restore */
  254. {
  255. if (T==0) printf("Dump ");
  256. printf("%d elt",N);
  257. if (N>1) printf("s");
  258. printf(" for %s stack",L);
  259. if (T) printf(" restored");
  260. printf(".\n");
  261. }
  262. static void restoreFic(char *L)
  263. {
  264. int fd;
  265. struct DumpEnt E;
  266. char * F;
  267. dropTrSuite();
  268. F = DumpRest_ext(L);
  269. if ((fd = open(F,O_RDONLY)) == -1) {
  270. perror(F);
  271. messErr(43);
  272. } else {
  273. if (read(fd,(void*)&E, LENT) != LENT) {
  274. printf("File too small !\n");
  275. messErr(59);
  276. } else {
  277. if (strncmp(E.L,"Nblf010", 7) == 0) {
  278. if (E.Scs == (long)getScs()) {
  279. if (E.V == atof(VERSION)) {
  280. restore_marque(fd, 'N');
  281. restore_stackN(fd);
  282. restore_marque(fd, 'C');
  283. restore_stackC(fd);
  284. restore_marque(fd, 'L');
  285. restore_stackL(fd);
  286. restore_marque(fd, 'V');
  287. restore_stackV(fd);
  288. restore_links_stackN();
  289. restore_marque(fd, 'F');
  290. restore_stackF(fd);
  291. restore_marque(fd, 'X');
  292. restore_links_stackV();
  293. } else printf("This file is just available for Nife v %g !\n",E.V);
  294. } else printf("This file have another SCS !\n");
  295. } else printf("Not a NBLF File !\n");
  296. close(fd);
  297. }
  298. }
  299. free((void*)F);
  300. }
  301. static void dumpFic(char *L)
  302. {
  303. int fd;
  304. struct DumpEnt E;
  305. char * F;
  306. dropTrSuite();
  307. F = DumpRest_ext(L);
  308. if ((fd = open(F,O_CREAT|O_WRONLY,0600)) == -1) {
  309. perror(F);
  310. messErr(58);
  311. } else {
  312. strncpy(E.L,"Nblf010", 7);
  313. E.V=atof(VERSION);
  314. E.Scs=(long)getScs();
  315. if ((write(fd,(void*)&E, LENT)) == LENT) {
  316. dump_marque(fd, 'N');
  317. dump_stackN(fd);
  318. dump_marque(fd, 'C');
  319. dump_stackC(fd);
  320. dump_marque(fd, 'L');
  321. dump_stackL(fd);
  322. dump_marque(fd, 'V');
  323. dump_stackV(fd);
  324. dump_marque(fd, 'F');
  325. dump_stackF(fd);
  326. dump_marque(fd, 'X');
  327. close(fd);
  328. } else messErr(58);
  329. }
  330. free((void*)F);
  331. }
  332. static void lectFic(char *L)
  333. {
  334. int fd;
  335. dropTrSuite();
  336. if ((fd = open(L,O_RDONLY)) == -1) {
  337. perror(L);
  338. messErr(16);
  339. } else addFD(fd,L);
  340. }
  341. void IF_LoadCS(void)
  342. {
  343. char * f;
  344. f = getString();
  345. if (f != NULL) {
  346. compileFile(f);
  347. free((void*)f);
  348. }
  349. }
  350. void IF_ExecCS(void)
  351. {
  352. char * f;
  353. f = getString();
  354. if (f != NULL) {
  355. if (strlen(f)>0) traiteLigne(f,2);
  356. free((void*)f);
  357. }
  358. }
  359. void * makeFunction(char * f)
  360. {
  361. void *M;
  362. if ((M = malloc(strlen(f)+8)) == NULL) stopErr("makeFunction","malloc");
  363. sprintf((char*)M,": _f %s ;",f);
  364. traiteLigne((char*)M,3);
  365. free(M);
  366. if (noErr() == 0) {
  367. M = fctByName("_f");
  368. return M;
  369. }
  370. messErr(48);
  371. return VIDE;
  372. }
  373. void IF_ExecCSf(void)
  374. {
  375. char * f;
  376. void *C;
  377. f = getString();
  378. if (f != NULL) {
  379. C = VIDE;
  380. if (strlen(f)>0) C = makeFunction(f);
  381. free((void*)f);
  382. if (C != VIDE) {
  383. IF_execFct("_f");
  384. rmLastFct();
  385. }
  386. }
  387. }
  388. void IF_Dump(void)
  389. {
  390. putTrSuite(dumpFic);
  391. }
  392. void IF_Restore(void)
  393. {
  394. putTrSuite(restoreFic);
  395. }
  396. void IF_Load(void)
  397. {
  398. putTrSuite(lectFic);
  399. }
  400. int main(int N, char *P[])
  401. {
  402. int n,Ctx;
  403. char *dirW = ".nife";
  404. if (N > 2) {
  405. fprintf(stderr,"nife [nif-file]\n");
  406. return(1);
  407. }
  408. if ((sizeof(void*) != sizeof(long)) ||
  409. (sizeof(double) != sizeof(long long))) {
  410. fprintf(stderr,"Nife open-source don't runs on these machine !\n");
  411. return(2);
  412. }
  413. signal(SIGQUIT,SIG_IGN);
  414. signal(SIGABRT,SIG_IGN);
  415. signal(SIGUSR1,SIG_IGN);
  416. signal(SIGCONT,SIG_IGN);
  417. signal(SIGSTOP,SIG_IGN);
  418. signal(SIGTSTP,SIG_IGN);
  419. signal(SIGINT,Interrupt);
  420. signal(SIGTERM,Interrupt);
  421. signal(SIGPIPE,Interrupt);
  422. signal(SIGCHLD,Interrupt);
  423. signal(SIGQUIT,Interrupt);
  424. signal(SIGSEGV,Interrupt);
  425. signal(SIGFPE,Interrupt);
  426. signal(SIGALRM,Interrupt);
  427. /* work in ./.nife for facilities of debugging !! */
  428. if (chdir(dirW) != 0) {
  429. if (mkdir(dirW, 0755) == -1) {
  430. perror("mkdir"); return 1;
  431. }
  432. if (chdir(dirW) != 0) {
  433. perror("chdir"); return 1;
  434. }
  435. }
  436. termInit(); /* may stop if no term found */
  437. TH_init();
  438. initLib();
  439. D_Reset();
  440. if (N==2) {
  441. IF_Load();
  442. lectFic(P[1]);
  443. } else {
  444. printf("Welcome to Nife : Just stack it !\n");
  445. IF_helpS();
  446. }
  447. while (RUN) {
  448. if ((FD_IN+iTERM) == 0) {
  449. printf("> ");
  450. fflush(stdout);
  451. Ctx=0;
  452. } else Ctx=1;
  453. razErr();
  454. if ((n=lireLigne(FD_IN,bufP,bufP2,LBUF)) == -1)
  455. printf("Line too long!\n");
  456. else
  457. if (n>0) traiteLigne(bufP,0);
  458. }
  459. IF_delAllGP();
  460. IF_netStopS();
  461. IF_netOff();
  462. D_Close();
  463. termReset();
  464. printf("Bye !\n");
  465. return 0;
  466. }