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.
 
 
 
 

506 lines
11 KiB

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