Nife version Beta
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

7 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
8 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
8 лет назад
10 лет назад
8 лет назад
10 лет назад
8 лет назад
10 лет назад
8 лет назад
10 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
9 лет назад
10 лет назад
10 лет назад
8 лет назад
10 лет назад
8 лет назад
10 лет назад
10 лет назад
10 лет назад
8 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
10 лет назад
8 лет назад
10 лет назад
8 лет назад
10 лет назад
8 лет назад
10 лет назад
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  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. }