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.
 
 
 
 

481 lines
10 KiB

  1. /* Copyright (C) 2011-2014 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-2014\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)
  135. {
  136. char *mot, *d, *f, *w;
  137. d=b; f=b+strlen(d);
  138. #ifdef DEBUG
  139. printf("traiteLigne : <%s>\n",d);
  140. #endif
  141. while (d<f) {
  142. if (noErr()) break;
  143. /* recherche du 1er mot */
  144. if (stringEnCours) {
  145. mot = d;
  146. while (1) {
  147. if((d = strchr(d,'"')) == NULL) {
  148. d=mot+strlen(mot);
  149. break;
  150. }
  151. if (*(d-1) == '\\') {
  152. w = d-1;
  153. while (*w != '\0') {
  154. *w = *(w+1);
  155. w++;
  156. }
  157. continue;
  158. }
  159. d++;
  160. if (!isSepa(*d,1)) continue;
  161. break;
  162. }
  163. } else {
  164. /* on ignore les commentaires */
  165. if ((mot = strchr(d, (int)'#')) != NULL) {
  166. *mot = '\0';
  167. f = mot;
  168. }
  169. while (isSepa(*d,0)) d++; /* on avance tant que separateurs */
  170. mot = d;
  171. while (!isSepa(*d,1)) d++; /* on avance si nonSepa ET non \0 */
  172. }
  173. *d++ = '\0'; /* fin de la commande */
  174. if (strlen(mot)>0)
  175. if (traiteMot(mot)) break; /* abort if error */
  176. }
  177. }
  178. void compileFile(char * f)
  179. {
  180. FILE *F;
  181. int i=0;
  182. if ((F = fopen(f,"r")) != NULL) {
  183. while (fgets(bufP, LBUF,F)) {
  184. if (noErr()) {
  185. printf("In file %s line %d !\n",f,i);
  186. break;
  187. }
  188. traiteLigne(bufP);
  189. i++;
  190. }
  191. fclose(F);
  192. }
  193. }
  194. struct DumpEnt {
  195. double V;
  196. char L[8];
  197. uint32_t Scs;
  198. };
  199. /* Dump and Restore Nblf : Nife Binary Linkable Format */
  200. #define LENT 20
  201. #define LMARK 3
  202. char * DumpRest_ext(char * L)
  203. {
  204. void * M;
  205. char *F;
  206. if ((M = malloc(strlen(L)+5)) == NULL) stopErr("DumpRest_ext","malloc");
  207. F = (char*)M;
  208. sprintf(F,"%s.nblf",L);
  209. return F;
  210. }
  211. void dump_marque(int fd, char C)
  212. {
  213. char b[LMARK+1];
  214. sprintf(b,"<%c>",C);
  215. if ((write (fd, (void*)b, LMARK)) != LMARK)
  216. stopErr("dump","marque");
  217. }
  218. void restore_marque(int fd, char C)
  219. {
  220. char b[LMARK+1];
  221. /* printf("Restore %c ! \n", C); */
  222. if ((read(fd, (void*)b, LMARK)) == LMARK)
  223. if (b[1] == C) return;
  224. stopErr("restore","marque");
  225. }
  226. void rest_links_pr(int i, char *O, char *C)
  227. {
  228. if (i) {
  229. printf("Linking %d %s", i, O);
  230. if (i > 1) printf("s");
  231. printf(" to %s stack.\n",C);
  232. }
  233. }
  234. void dump_rest_pr(int T, int N, char * L) /* T=0 dump, T=1 restore */
  235. {
  236. if (T==0) printf("Dump ");
  237. printf("%d elt",N);
  238. if (N>1) printf("s");
  239. printf(" for %s stack",L);
  240. if (T) printf(" restored");
  241. printf(".\n");
  242. }
  243. static void restoreFic(char *L)
  244. {
  245. int fd;
  246. struct DumpEnt E;
  247. char * F;
  248. dropTrSuite();
  249. F = DumpRest_ext(L);
  250. if ((fd = open(F,O_RDONLY)) == -1) {
  251. perror(F);
  252. messErr(43);
  253. } else {
  254. if (read(fd,(void*)&E, LENT) != LENT) {
  255. printf("File too small !\n");
  256. messErr(59);
  257. } else {
  258. if (strncmp(E.L,"Nblf010", 7) == 0) {
  259. if (E.Scs == (long)getScs()) {
  260. if (E.V == atof(VERSION)) {
  261. restore_marque(fd, 'N');
  262. restore_stackN(fd);
  263. restore_marque(fd, 'C');
  264. restore_stackC(fd);
  265. restore_marque(fd, 'L');
  266. restore_stackL(fd);
  267. restore_marque(fd, 'V');
  268. restore_stackV(fd);
  269. restore_links_stackN();
  270. restore_marque(fd, 'F');
  271. restore_stackF(fd);
  272. restore_marque(fd, 'X');
  273. restore_links_stackV();
  274. } else printf("This file is just available for Nife v %g !\n",E.V);
  275. } else printf("This file have another SCS !\n");
  276. } else printf("Not a NBLF File !\n");
  277. close(fd);
  278. }
  279. }
  280. free((void*)F);
  281. }
  282. static void dumpFic(char *L)
  283. {
  284. int fd;
  285. struct DumpEnt E;
  286. char * F;
  287. dropTrSuite();
  288. F = DumpRest_ext(L);
  289. if ((fd = open(F,O_CREAT|O_WRONLY,0600)) == -1) {
  290. perror(F);
  291. messErr(58);
  292. } else {
  293. strncpy(E.L,"Nblf010", 7);
  294. E.V=atof(VERSION);
  295. E.Scs=(long)getScs();
  296. if ((write(fd,(void*)&E, LENT)) == LENT) {
  297. dump_marque(fd, 'N');
  298. dump_stackN(fd);
  299. dump_marque(fd, 'C');
  300. dump_stackC(fd);
  301. dump_marque(fd, 'L');
  302. dump_stackL(fd);
  303. dump_marque(fd, 'V');
  304. dump_stackV(fd);
  305. dump_marque(fd, 'F');
  306. dump_stackF(fd);
  307. dump_marque(fd, 'X');
  308. close(fd);
  309. } else messErr(58);
  310. }
  311. free((void*)F);
  312. }
  313. static void lectFic(char *L)
  314. {
  315. int fd;
  316. dropTrSuite();
  317. if ((fd = open(L,O_RDONLY)) == -1) {
  318. perror(L);
  319. messErr(16);
  320. } else addFD(fd,L);
  321. }
  322. void IF_LoadCS(void)
  323. {
  324. char * f;
  325. f = getString();
  326. if (f != NULL) {
  327. compileFile(f);
  328. free((void*)f);
  329. }
  330. }
  331. void IF_ExecCS(void)
  332. {
  333. char * f;
  334. f = getString();
  335. if (f != NULL) {
  336. if (strlen(f)>0) traiteLigne(f);
  337. free((void*)f);
  338. }
  339. }
  340. void * makeFunction(char * f)
  341. {
  342. void *M;
  343. if ((M = malloc(strlen(f)+8)) == NULL) stopErr("makeFunction","malloc");
  344. sprintf((char*)M,": _f %s ;",f);
  345. traiteLigne((char*)M);
  346. free(M);
  347. if (noErr() == 0) {
  348. M = fctByName("_f");
  349. return M;
  350. }
  351. messErr(48);
  352. return VIDE;
  353. }
  354. void IF_ExecCSf(void)
  355. {
  356. char * f;
  357. void *C;
  358. f = getString();
  359. if (f != NULL) {
  360. C = VIDE;
  361. if (strlen(f)>0) C = makeFunction(f);
  362. free((void*)f);
  363. if (C != VIDE) {
  364. IF_execFct("_f");
  365. rmLastFct();
  366. }
  367. }
  368. }
  369. void IF_Dump(void)
  370. {
  371. putTrSuite(dumpFic);
  372. }
  373. void IF_Restore(void)
  374. {
  375. putTrSuite(restoreFic);
  376. }
  377. void IF_Load(void)
  378. {
  379. putTrSuite(lectFic);
  380. }
  381. int main(int N, char *P[])
  382. {
  383. int n;
  384. char *dirW = ".nife";
  385. if (N > 2) {
  386. fprintf(stderr,"nife [nif-file]\n");
  387. return(1);
  388. }
  389. if ((sizeof(void*) != sizeof(long)) ||
  390. (sizeof(double) != sizeof(long long))) {
  391. fprintf(stderr,"Nife open-source don't runs on these machine !\n");
  392. return(2);
  393. }
  394. signal(SIGQUIT,SIG_IGN);
  395. signal(SIGABRT,SIG_IGN);
  396. signal(SIGUSR1,SIG_IGN);
  397. signal(SIGCONT,SIG_IGN);
  398. signal(SIGSTOP,SIG_IGN);
  399. signal(SIGTSTP,SIG_IGN);
  400. signal(SIGINT,Interrupt);
  401. signal(SIGTERM,Interrupt);
  402. signal(SIGPIPE,Interrupt);
  403. signal(SIGCHLD,Interrupt);
  404. signal(SIGQUIT,Interrupt);
  405. signal(SIGSEGV,Interrupt);
  406. signal(SIGFPE,Interrupt);
  407. signal(SIGALRM,Interrupt);
  408. /* work in ./.nife for facilities of debugging !! */
  409. if (chdir(dirW) != 0) {
  410. if (mkdir(dirW, 0755) == -1) {
  411. perror("mkdir"); return 1;
  412. }
  413. if (chdir(dirW) != 0) {
  414. perror("chdir"); return 1;
  415. }
  416. }
  417. termInit(); /* may stop if no term found */
  418. TH_init();
  419. initLib();
  420. D_Reset();
  421. if (N==2) {
  422. IF_Load();
  423. lectFic(P[1]);
  424. } else {
  425. printf("Welcome to Nife : Just stack it !\n");
  426. IF_helpS();
  427. }
  428. while (RUN) {
  429. if ((FD_IN+iTERM) == 0) {
  430. printf("> ");
  431. fflush(stdout);
  432. }
  433. razErr();
  434. if ((n=lireLigne(FD_IN,bufP,bufP2,LBUF)) == -1)
  435. printf("Line too long!\n");
  436. else
  437. if (n>0) traiteLigne(bufP);
  438. }
  439. IF_delAllGP();
  440. IF_netStopS();
  441. IF_netOff();
  442. termReset();
  443. printf("Bye !\n");
  444. return 0;
  445. }