Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33d9ca87c0 | ||
|
|
4983647ad1 | ||
|
|
dea729767e | ||
|
|
aa61937a20 | ||
|
|
01113671ec | ||
|
|
68d3311b01 | ||
|
|
55ad7180e1 | ||
|
|
a2505eabf7 | ||
|
|
2ad1bada78 | ||
|
|
8460963bc3 | ||
|
|
4cbc937c45 | ||
|
|
f60884882c | ||
|
|
2a07637008 | ||
|
|
6f207a7ed4 | ||
|
|
2ffcab88b3 | ||
|
|
a3cc520837 | ||
|
|
22de8f85c5 | ||
|
|
7019ea7f8b | ||
|
|
799c7c7548 | ||
|
|
961994d6c7 | ||
|
|
f8f63d87d4 | ||
|
|
3384b0df85 | ||
|
|
fcb62ff71c | ||
|
|
0871ed56fc | ||
|
|
a6f8d2aefa |
No files matched your search
@@ -49,7 +49,7 @@ cat /proc/*/maps et faire des grep pour voir les .so et module chargés par open
|
||||
exec/genw $1.w && exec/lwa $1.wa && rm $1.wa && exec/lw $1
|
||||
```
|
||||
# Site Web
|
||||
https://www.lanisys.fr/wiki/doku.php?id=w
|
||||
https://w.lanisys.fr/
|
||||
|
||||
## LANGAGE W
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/* **********************************************
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
W language is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version (GPL-3.0-or-later).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
********************************************** */
|
||||
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
// for windows compilation and generating/using import library
|
||||
#ifdef WAPIEXPORT
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#endif
|
||||
#ifdef WAPIIMPORT
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllimport)
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
|
||||
#define ARG_DEBUG "d"
|
||||
#define ARG_TRACE "t"
|
||||
#define ARG_DISASM "d"
|
||||
|
||||
void GetArgs(env * e, int argc, char * argv[], Dynamic * arg)
|
||||
{
|
||||
int nbOpt = 0, cpt = 0;
|
||||
dynSetLen(e, arg, 0);
|
||||
for(int a = 1; a < argc; a++)
|
||||
{
|
||||
if(strcmp(argv[a], "-" ARG_DEBUG) == 0)
|
||||
dynStoreSz(e, arg, 1, ++nbOpt, ARG_DEBUG, 1, cFM, cVM);
|
||||
else if(strcmp(argv[a], "-" ARG_TRACE) == 0)
|
||||
dynStoreSz(e, arg, 1, ++nbOpt, ARG_TRACE, 1, cFM, cVM);
|
||||
else if(strncmp(argv[a], "-WBIN:", 6) == 0 && strlen(argv[a]) > 6)
|
||||
dynStoreSz(e, arg, 3, DYN_NONE, &argv[a][6], DYN_LGNONE, cFM, DYN_NONE); // memo (.o .so)
|
||||
else if(strncmp(argv[a], "-WLIB:", 6) == 0 && strlen(argv[a]) > 6)
|
||||
dynStoreSz(e, arg, 5, DYN_NONE, &argv[a][6], DYN_LGNONE, cFM, DYN_NONE); // memo (.wp .wa)
|
||||
else if(strncmp(argv[a], "-WSRC:", 6) == 0 && strlen(argv[a]) > 6)
|
||||
dynStoreSz(e, arg, 4, DYN_NONE, &argv[a][6], DYN_LGNONE, cFM, DYN_NONE); // memo (.w)
|
||||
else if(strncmp(argv[a], "-", 1) == 0)
|
||||
; // argument inconnu, ignorer
|
||||
else
|
||||
{
|
||||
// premier argument ne commencant pas par "-" : nom du prog wp
|
||||
for( ; a < argc; a++)
|
||||
dynStoreSz(e, arg, 2, ++cpt, argv[a], DYN_LGNONE, cFM, cVM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(dynExtractPos(e, arg, 3, DYN_NONE, cFM, DYN_NONE) <= 0)
|
||||
{
|
||||
dynStoreSz(e, arg, 3, DYN_NONE, getenv("WBIN"), DYN_LGNONE, cFM, DYN_NONE); // si absent en ligne de cmd, lire de la var d'env
|
||||
if(dynExtractPos(e, arg, 3, DYN_NONE, cFM, DYN_NONE) <= 0)
|
||||
dynStoreSz(e, arg, 3, DYN_NONE, getenv("LD_LIBRARY_PATH"), DYN_LGNONE, cFM, DYN_NONE); // dernier recours...
|
||||
}
|
||||
//
|
||||
if(dynExtractPos(e, arg, 5, DYN_NONE, cFM, DYN_NONE) <= 0)
|
||||
dynStoreSz(e, arg, 5, DYN_NONE, getenv("WLIB"), DYN_LGNONE, cFM, DYN_NONE); // si absent en ligne de cmd, lire de la var d'env
|
||||
//
|
||||
if(dynExtractPos(e, arg, 4, DYN_NONE, cFM, DYN_NONE) <= 0)
|
||||
dynStoreSz(e, arg, 4, DYN_NONE, getenv("WSRC"), DYN_LGNONE, cFM, DYN_NONE); // si absent en ligne de cmd, lire de la var d'env
|
||||
/*
|
||||
arg<1> = options en MV
|
||||
arg<2> = prog et parametres en MV
|
||||
arg<3> = WBIN (.o .so) => invoke, LD_LIBRARY_PATH
|
||||
arg<4> = WSRC (.w) => lwc
|
||||
arg<5> = WLIB (.wp .wa) => call, lwa lwc
|
||||
*/
|
||||
}
|
||||
+188
-173
@@ -31,6 +31,7 @@
|
||||
#include "langage.h"
|
||||
#include "dynamic.h"
|
||||
#include "instr.h"
|
||||
#include "arg.c"
|
||||
|
||||
env e;
|
||||
|
||||
@@ -85,10 +86,23 @@ void decodeString(env * e, Dynamic * this)
|
||||
dynChange(e, this, "#20", " ", DYN_ALL);
|
||||
}
|
||||
|
||||
Dynamic pcode;
|
||||
ent64s posOffset;
|
||||
|
||||
void PCODE(int x)
|
||||
{
|
||||
dynConcatSz(&e,&pcode,"0",1);
|
||||
pcode.ptr[pcode.mLg-1]=((octet)x);
|
||||
}
|
||||
void PCODEP(int x)
|
||||
{
|
||||
pcode.ptr[posOffset++]=((octet)x);
|
||||
}
|
||||
|
||||
int assembler(env * e, char * fichier, int * cptLig)
|
||||
{
|
||||
#define PCODE(x) {dynConcatSz(e,&pcode,"0",1);pcode.ptr[pcode.mLg-1]=((octet)x);}
|
||||
#define PCODEP(x) pcode.ptr[pcode.mLg++]=((octet)x);
|
||||
//#define PCODE(x) {dynConcatSz(e,&pcode,"0",1);pcode.ptr[pcode.mLg-1]=((octet)x);}
|
||||
//#define PCODEP(x) pcode.ptr[pcode.mLg++]=((octet)x);
|
||||
//
|
||||
dynInit(e, &e->int_dynamic, DYN_LGMIN);
|
||||
//
|
||||
@@ -96,8 +110,8 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
if(dynRead(e, &e->int_dynamic, fichier) != OK)
|
||||
return -1;
|
||||
// traiter chaque ligne
|
||||
Dynamic ligne, tmp, pcode, varsys, trav;
|
||||
int ret = OK, i, sav, offset, instr, debutSub;
|
||||
Dynamic ligne, tmp, varsys, trav;
|
||||
int ret = OK, i, sav, offset, instr, debutSub; // precInstr = -1;
|
||||
int premiere_instr = 1, derniere_instr = 0;
|
||||
long pos; // pour locate
|
||||
ent64s num;
|
||||
@@ -153,13 +167,13 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
debutSub = debutSub + 2 + pcode.ptr[debutSub + 1];
|
||||
offset = pcode.mLg + 1 - debutSub;
|
||||
// maj offset
|
||||
sav = pcode.mLg;
|
||||
//sav = pcode.mLg;
|
||||
dynField(e, &adrLabel, &trav, 5, iLabel, cFM, cVM, 1);
|
||||
pcode.mLg = dynToNum(e, &trav, DYN_FALSE, 0);
|
||||
PCODEP((offset >> 16) & 255)
|
||||
PCODEP((offset >> 8 ) & 255)
|
||||
PCODEP(offset & 255)
|
||||
pcode.mLg = sav;
|
||||
posOffset = dynToNum(e, &trav, DYN_FALSE, 0);
|
||||
PCODEP((offset >> 16) & 255);
|
||||
PCODEP((offset >> 8 ) & 255);
|
||||
PCODEP(offset & 255);
|
||||
//pcode.mLg = sav;
|
||||
dynDel(e, &adrLabel, 4, iLabel, cFM, cVM, 1);
|
||||
dynDel(e, &adrLabel, 5, iLabel, cFM, cVM, 1);
|
||||
}
|
||||
@@ -212,8 +226,8 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
num = dynToNum(e, &tmp, 0, 3) & 255;
|
||||
if(tmp.mInternal == DYN_ERR) ret = -3; // erreur conversion
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
break;
|
||||
case IN_JUMP:
|
||||
case IN_JMPF:
|
||||
@@ -224,7 +238,7 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
pos = dynLocateSz(e, &adrLabel, tmp.mPtr, cVM, 1, cFM);
|
||||
if(pos > 0)
|
||||
{
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
dynField(e, &adrLabel, &trav, 2, pos, cFM, cVM, 1); // adresse debut loop
|
||||
offset = dynToNum(e, &trav, DYN_FALSE, 8);
|
||||
dynField(e, &adrLabel, &trav, 3, subNiv, cFM, cVM, 1); // adresse debut sub en cours
|
||||
@@ -232,19 +246,19 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
if(subNiv > 1)
|
||||
debutSub = debutSub + 2 + pcode.ptr[debutSub + 1];
|
||||
offset = offset + 1 - debutSub; // ad debut loop - debut du prog/sub en cours
|
||||
PCODEP((offset >> 16) & 255)
|
||||
PCODEP((offset >> 8 ) & 255)
|
||||
PCODEP(offset & 255)
|
||||
PCODE((offset >> 16) & 255); // 23/11/2025 - verif PCODE ok a la place de PCODEP
|
||||
PCODE((offset >> 8 ) & 255); // 23/11/2025 - verif PCODE ok a la place de PCODEP
|
||||
PCODE(offset & 255); // 23/11/2025 - verif PCODE ok a la place de PCODEP
|
||||
}
|
||||
else
|
||||
{
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
// memoriser l'endroit ou on veut mettre l'offset du jump a faire adrLabel<4> et <5>
|
||||
dynIns(e, &adrLabel, 4, 1, &tmp, cFM, cVM);
|
||||
dynInsSz(e, &adrLabel, 5, 1, Int32ToSz(pcode.mLg, DYN_FALSE, 0), DYN_LGNONE, cFM, cVM);
|
||||
PCODE(0)
|
||||
PCODE(0)
|
||||
PCODE(0)
|
||||
PCODE(0);
|
||||
PCODE(0);
|
||||
PCODE(0);
|
||||
}
|
||||
break;
|
||||
case IN_DECL:
|
||||
@@ -255,20 +269,20 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(tmp.mLg < 1 || tmp.mLg > 255) { ret = -4; break; } // erreur longueur nom variable
|
||||
num = tmp.mLg;
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_SRCL:
|
||||
// SRCL
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
num = dynToNum(e, &tmp, 0, 8) & 0xFFFFFF;
|
||||
if(tmp.mInternal == DYN_ERR) ret = -3; // erreur conversion
|
||||
PCODE(instr)
|
||||
PCODE((num >> 16) & 255)
|
||||
PCODE((num >> 8) & 255)
|
||||
PCODE(num & 255)
|
||||
PCODE(instr);
|
||||
PCODE((num >> 16) & 255);
|
||||
PCODE((num >> 8) & 255);
|
||||
PCODE(num & 255);
|
||||
break;
|
||||
case IN_PHDS:
|
||||
case IN_PIDS:
|
||||
@@ -280,13 +294,13 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
num = tmp.mLg;
|
||||
if(num == 1 && tmp.mPtr[0] == '_') // assembler SUBR _ pour avoir lg = 0
|
||||
num = 0;
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(0)
|
||||
PCODE(0)
|
||||
PCODE(0)
|
||||
PCODE(tmp.mPtr[p]);
|
||||
PCODE(0);
|
||||
PCODE(0);
|
||||
PCODE(0);
|
||||
/* nouvelle methode */
|
||||
dynStoreSz(e, &adrLabel, 3, ++subNiv, Int32ToSz(sav, DYN_FALSE, 0), DYN_LGNONE, cFM, cVM);
|
||||
break;
|
||||
@@ -295,28 +309,28 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
if(subNiv < 2) { ret = -8; break; } // erreur descente de niveau incorrecte
|
||||
dynField(e, &adrLabel, &trav, 3, subNiv--, cFM, cVM, 1);
|
||||
debutSub = dynToNum(e, &trav, DYN_FALSE, 8);
|
||||
sav = pcode.mLg;
|
||||
pcode.mLg = debutSub + 2 + pcode.ptr[debutSub + 1];
|
||||
offset = sav + 1 - debutSub;
|
||||
PCODEP((offset >> 16) & 255)
|
||||
PCODEP((offset >> 8 ) & 255)
|
||||
PCODEP(offset & 255)
|
||||
pcode.mLg = sav;
|
||||
PCODE(instr)
|
||||
//sav = pcode.mLg;
|
||||
posOffset = debutSub + 2 + pcode.ptr[debutSub + 1];
|
||||
offset = pcode.mLg + 1 - debutSub;
|
||||
PCODEP((offset >> 16) & 255);
|
||||
PCODEP((offset >> 8 ) & 255);
|
||||
PCODEP(offset & 255);
|
||||
//pcode.mLg = sav;
|
||||
PCODE(instr);
|
||||
break;
|
||||
case IN_BEXC:
|
||||
// BEXC
|
||||
// memoriser la position pour renseigner l'offset plus tard => idem adrLabel<3> : BEXC juste apres PROG et SUBR !
|
||||
PCODE(instr)
|
||||
PCODE(0)
|
||||
PCODE(0)
|
||||
PCODE(0)
|
||||
PCODE(instr);
|
||||
PCODE(0);
|
||||
PCODE(0);
|
||||
PCODE(0);
|
||||
break;
|
||||
case IN_EXCE:
|
||||
// EXCE
|
||||
// debut du bloc except : ecrire l'adresse dans l'instruction BEXC
|
||||
PCODE(instr)
|
||||
sav = pcode.mLg;
|
||||
PCODE(instr);
|
||||
//sav = pcode.mLg;
|
||||
/* nouvelle methode */
|
||||
dynField(e, &adrLabel, &trav, 3, subNiv, cFM, cVM, 1); // adresse debut sub en cours
|
||||
debutSub = dynToNum(e, &trav, DYN_FALSE, 8);
|
||||
@@ -324,31 +338,31 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
{
|
||||
debutSub = debutSub + 2 + pcode.ptr[debutSub + 1] + 3;
|
||||
offset = pcode.mLg - debutSub;
|
||||
pcode.mLg = debutSub + 1;
|
||||
posOffset = debutSub + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset = pcode.mLg - debutSub;
|
||||
pcode.mLg = debutSub + 1;
|
||||
posOffset = debutSub + 1;
|
||||
}
|
||||
PCODEP((offset >> 16) & 255)
|
||||
PCODEP((offset >> 8 ) & 255)
|
||||
PCODEP(offset & 255)
|
||||
pcode.mLg = sav;
|
||||
PCODEP((offset >> 16) & 255);
|
||||
PCODEP((offset >> 8 ) & 255);
|
||||
PCODEP(offset & 255);
|
||||
//pcode.mLg = sav;
|
||||
break;
|
||||
case IN_CATC:
|
||||
// CATC
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
break;
|
||||
case IN_THRW:
|
||||
// THRW
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
num = dynToNum(e, &tmp, 0, 8) & 0xFFFFFF;
|
||||
if(tmp.mInternal == DYN_ERR) ret = -3; // erreur conversion
|
||||
PCODE(instr)
|
||||
PCODE((num >> 16) & 255)
|
||||
PCODE((num >> 8) & 255)
|
||||
PCODE(num & 255)
|
||||
PCODE(instr);
|
||||
PCODE((num >> 16) & 255);
|
||||
PCODE((num >> 8) & 255);
|
||||
PCODE(num & 255);
|
||||
break;
|
||||
case IN_PART:
|
||||
// PART
|
||||
@@ -357,22 +371,19 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
num = dynToNum(e, &tmp, 0, 3) & 255;
|
||||
if(tmp.mInternal == DYN_ERR) ret = -3; // erreur conversion
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
break;
|
||||
case IN_RETN:
|
||||
case IN_RETT:
|
||||
// RETN / RETT
|
||||
PCODE(instr)
|
||||
break;
|
||||
case IN_CRAZ:
|
||||
// CRAZ
|
||||
PCODE(instr)
|
||||
// RETN / RETT / CRAZ
|
||||
PCODE(instr);
|
||||
break;
|
||||
case IN_CLIB:
|
||||
case IN_CALL:
|
||||
// CLIB / CALL
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
//dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
//num = dynToNum(e, &tmp, 0, 3) & 255;
|
||||
//if(tmp.mInternal == DYN_ERR) { ret = -3; break; } // erreur conversion
|
||||
@@ -381,13 +392,13 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
num = tmp.mLg;
|
||||
if(num == 1 && tmp.mPtr[0] == '_')
|
||||
{
|
||||
PCODE(0)
|
||||
PCODE(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
PCODE(num)
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
}
|
||||
break;
|
||||
case IN_PVAT:
|
||||
@@ -397,7 +408,7 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
case IN_RNXT:
|
||||
case IN_CPHA:
|
||||
// PVAT / TYPO / PSHT / SELE / RNXT / CPHA
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
break;
|
||||
case IN_CPSH:
|
||||
case IN_PARM:
|
||||
@@ -419,33 +430,33 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(tmp.mLg < 1 || tmp.mLg > 255) { ret = -4; break; } // erreur longueur nom variable
|
||||
num = tmp.mLg;
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_COMP:
|
||||
// COMP
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(strcmp(tmp.mPtr, "EQ") == 0)
|
||||
PCODE(CMP_EQ)
|
||||
PCODE(CMP_EQ);
|
||||
else if(strcmp(tmp.mPtr, "NE") == 0)
|
||||
PCODE(CMP_NE)
|
||||
PCODE(CMP_NE);
|
||||
else if(strcmp(tmp.mPtr, "LT") == 0)
|
||||
PCODE(CMP_LT)
|
||||
PCODE(CMP_LT);
|
||||
else if(strcmp(tmp.mPtr, "GT") == 0)
|
||||
PCODE(CMP_GT)
|
||||
PCODE(CMP_GT);
|
||||
else if(strcmp(tmp.mPtr, "LE") == 0)
|
||||
PCODE(CMP_LE)
|
||||
PCODE(CMP_LE);
|
||||
else if(strcmp(tmp.mPtr, "GE") == 0)
|
||||
PCODE(CMP_GE)
|
||||
PCODE(CMP_GE);
|
||||
else if(strcmp(tmp.mPtr, "AND") == 0)
|
||||
PCODE(CMP_AND)
|
||||
PCODE(CMP_AND);
|
||||
else if(strcmp(tmp.mPtr, "OR") == 0)
|
||||
PCODE(CMP_OR)
|
||||
PCODE(CMP_OR);
|
||||
else if(strcmp(tmp.mPtr, "NOT") == 0)
|
||||
PCODE(CMP_NOT)
|
||||
PCODE(CMP_NOT);
|
||||
else
|
||||
ret = -9; // code comparaison inconnu
|
||||
break;
|
||||
@@ -531,32 +542,32 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
// DESV
|
||||
case IN_DEZV:
|
||||
// DEZV
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
break;
|
||||
case IN_MODL:
|
||||
// MODL
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(tmp.mLg < 3 || tmp.mLg > 45) { ret = -4; break; } // erreur longueur nom module
|
||||
num = tmp.mLg;
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_PSHC:
|
||||
// PSHC
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
num = dynToNum(e, &tmp, 1, 19);
|
||||
if(tmp.mInternal == DYN_ERR) ret = -3; // erreur conversion
|
||||
PCODE(instr)
|
||||
PCODE((num >> 56) & 255)
|
||||
PCODE((num >> 48) & 255)
|
||||
PCODE((num >> 40) & 255)
|
||||
PCODE((num >> 32) & 255)
|
||||
PCODE((num >> 24) & 255)
|
||||
PCODE((num >> 16) & 255)
|
||||
PCODE((num >> 8) & 255)
|
||||
PCODE(num & 255)
|
||||
PCODE(instr);
|
||||
PCODE((num >> 56) & 255);
|
||||
PCODE((num >> 48) & 255);
|
||||
PCODE((num >> 40) & 255);
|
||||
PCODE((num >> 32) & 255);
|
||||
PCODE((num >> 24) & 255);
|
||||
PCODE((num >> 16) & 255);
|
||||
PCODE((num >> 8) & 255);
|
||||
PCODE(num & 255);
|
||||
break;
|
||||
case IN_PSH0:
|
||||
case IN_PSH1:
|
||||
@@ -579,7 +590,7 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
// WRIT
|
||||
case IN_WRLN:
|
||||
// WRLN
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
break;
|
||||
case IN_PSHA:
|
||||
// PSHA d1 : transco chaine / numero
|
||||
@@ -589,8 +600,8 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
dynField(e, &varsys, &tmp, 2, pos, ';', ',', 1);
|
||||
num = dynToNum(e, &tmp, 0, 3) & 255;
|
||||
if(tmp.mInternal == DYN_ERR) ret = -3; // erreur conversion
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
break;
|
||||
case IN_DSET:
|
||||
// DSET - TODO decoder la chaine, cas des \xx en hexa (recalcul lg : fn qui met a jour directement tmp et maj lg)
|
||||
@@ -598,10 +609,10 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
decodeString(e, &tmp);
|
||||
if(tmp.mLg < 0 || tmp.mLg > 255) { ret = -4; break; } // erreur longueur nom
|
||||
num = tmp.mLg;
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_DEXH:
|
||||
// DEXH
|
||||
@@ -626,103 +637,103 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
num = tmp.mLg;
|
||||
if(num == 1 && tmp.mPtr[0] == '_') // assembler DEXF/DEXV/VLET/DCAT _ pour avoir lg = 0
|
||||
num = 0;
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_CLAS:
|
||||
// CLAS
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(tmp.mLg < 1 || tmp.mLg > 255) { ret = -4; break; } // erreur longueur nom var
|
||||
num = tmp.mLg;
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(tmp.mLg < 1 || tmp.mLg > 255) { ret = -4; break; } // erreur longueur nom var
|
||||
num = tmp.mLg;
|
||||
if(num == 1 && tmp.mPtr[0] == '_') // assembler CLAS lg1 nom1 _ pour avoir lg2 = 0
|
||||
num = 0;
|
||||
PCODE(num)
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_DCMP:
|
||||
// DCMP
|
||||
//dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(strcmp(tmp.mPtr, "EQ") == 0)
|
||||
PCODE(CMP_EQ)
|
||||
PCODE(CMP_EQ);
|
||||
else if(strcmp(tmp.mPtr, "NE") == 0)
|
||||
PCODE(CMP_NE)
|
||||
PCODE(CMP_NE);
|
||||
else if(strcmp(tmp.mPtr, "LT") == 0)
|
||||
PCODE(CMP_LT)
|
||||
PCODE(CMP_LT);
|
||||
else if(strcmp(tmp.mPtr, "GT") == 0)
|
||||
PCODE(CMP_GT)
|
||||
PCODE(CMP_GT);
|
||||
else if(strcmp(tmp.mPtr, "LE") == 0)
|
||||
PCODE(CMP_LE)
|
||||
PCODE(CMP_LE);
|
||||
else if(strcmp(tmp.mPtr, "GE") == 0)
|
||||
PCODE(CMP_GE)
|
||||
PCODE(CMP_GE);
|
||||
else
|
||||
ret = -9; // code comparaison inconnu
|
||||
//
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(tmp.mLg < 1 || tmp.mLg > 255) { ret = -4; break; } // erreur longueur nom var
|
||||
num = tmp.mLg;
|
||||
PCODE(num)
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_INCL:
|
||||
// INCL (lg=0 possible si rien)
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(tmp.mLg < 0 || tmp.mLg > 255) { ret = -4; break; } // erreur longueur nom variable
|
||||
num = tmp.mLg;
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_PNAM:
|
||||
// PNAM (lg=0 possible si rien)
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
if(tmp.mLg < 0 || tmp.mLg > 255) { ret = -4; break; } // erreur longueur nom ident
|
||||
num = tmp.mLg;
|
||||
PCODE(instr)
|
||||
PCODE(num)
|
||||
PCODE(instr);
|
||||
PCODE(num);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_PROG:
|
||||
case IN_BACK:
|
||||
case IN_LIBR:
|
||||
// debut de programme executable directement (normal et demon) et debut library, non executable directement
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
/* nouvelle methode */
|
||||
dynStoreSz(e, &adrLabel, 3, ++subNiv, Int32ToSz(pcode.mLg, DYN_FALSE, 0), DYN_LGNONE, cFM, cVM);
|
||||
break;
|
||||
case IN_SDBG:
|
||||
dynField(e, &ligne, &tmp, i++, 0, ' ', 0, 1);
|
||||
num = tmp.mLg;
|
||||
PCODE(instr)
|
||||
PCODE((num >> 16) & 255)
|
||||
PCODE((num >> 8) & 255)
|
||||
PCODE(num & 255)
|
||||
PCODE(instr);
|
||||
PCODE((num >> 16) & 255);
|
||||
PCODE((num >> 8) & 255);
|
||||
PCODE(num & 255);
|
||||
for(int p = 0; p < num; p++)
|
||||
PCODE(tmp.mPtr[p])
|
||||
PCODE(tmp.mPtr[p]);
|
||||
break;
|
||||
case IN_TEST:
|
||||
// TEST
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
break;
|
||||
case IN_ENDL:
|
||||
case IN_ENDP:
|
||||
// ENDL / ENDP : fin de librairie / prog directement executable
|
||||
if(subNiv != 1) { ret = -8; break; } // erreur descente de niveau incorrecte
|
||||
PCODE(instr)
|
||||
PCODE(instr);
|
||||
derniere_instr = 1;
|
||||
break;
|
||||
default:
|
||||
@@ -744,27 +755,12 @@ int assembler(env * e, char * fichier, int * cptLig)
|
||||
if(tmp.mLg != 0 && tmp.mPtr[0] != ';') { ret = -6; printf("tmp *%s*\n", tmp.mPtr);} // erreur en fin d'instruction
|
||||
}
|
||||
}
|
||||
//precInstr = instr;
|
||||
}
|
||||
//
|
||||
if(!ret)
|
||||
{
|
||||
// si pas d'erreur : copier dans le repertoire WBIN en renommant "xxx.wa" en "xxx.wp"
|
||||
//char * wbin = getenv("WBIN");
|
||||
//if(wbin == NULL)
|
||||
// wbin = getenv("LD_LIBRARY_PATH");
|
||||
//if(wbin == NULL)
|
||||
//{
|
||||
// ret = -11;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// dynLet(e, &tmp, wbin, DYN_LGNONE);
|
||||
// dynConcatSz(e, &tmp, e->path_sep, DYN_LGNONE);
|
||||
// dynConcatSz(e, &tmp, fichier, DYN_LGNONE);
|
||||
// tmp.mPtr[tmp.mLg - 1] = 'p';
|
||||
// dynWrite(e, &pcode, tmp.mPtr);
|
||||
//}
|
||||
// ecrire au meme endroit que le .w et .wa
|
||||
// si pas d'erreur, ecrire au meme endroit que le .wa (=> dans WLIB)
|
||||
dynLet(e, &tmp, fichier, DYN_LGNONE);
|
||||
tmp.mPtr[tmp.mLg - 1] = 'p';
|
||||
dynWrite(e, &pcode, tmp.mPtr);
|
||||
@@ -1255,13 +1251,14 @@ int disassembler(env * e, char * fichier)
|
||||
dynFree(e, &tmp);
|
||||
dynFree(e, &varsys);
|
||||
dynFree(e, &niv);
|
||||
return 0;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* ***************************************************************************************************** */
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
int cr = 0;
|
||||
int cr = OK;
|
||||
Dynamic arg, wlib, fichier;
|
||||
/* */
|
||||
/* avis de licence */
|
||||
printf("W language Copyright 2024,2025 lanisys.fr\n");
|
||||
@@ -1269,7 +1266,7 @@ int main(int argc, char * argv[])
|
||||
/* argument : fichier a assembler/desassembler (si -d) */
|
||||
if(argc < 2)
|
||||
{
|
||||
printf("Usage: lwa [-d] <fichier>\n");
|
||||
printf("Usage: lwa [-d] [-WLIB:<chemin>] <fichier.wa|fichier.wp>\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* */
|
||||
@@ -1279,40 +1276,58 @@ int main(int argc, char * argv[])
|
||||
lap = ts.tv_sec * 1000000 + (ts.tv_nsec / 1000);
|
||||
/* */
|
||||
init_env(&e);
|
||||
dynInit(&e, &arg, 0);
|
||||
dynInit(&e, &wlib, 0);
|
||||
dynInit(&e, &fichier, 0);
|
||||
/* */
|
||||
if(strcmp(argv[1], "-d") == 0)
|
||||
GetArgs(&e, argc, argv, &arg);
|
||||
dynExtractField(&e, &arg, 5, &wlib);
|
||||
dynExtractSubField(&e, &arg, 2, 1, &fichier); // fichier = .wa a assembler / .wp a desassembler
|
||||
/* */
|
||||
if(fichier.mLg < 4)
|
||||
{
|
||||
if(argc >= 3)
|
||||
{
|
||||
#ifndef UNIX
|
||||
cr = disassembler(&e, argv[2]);
|
||||
#else
|
||||
cr = disassembler(&e, argv[2]);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
printf("Usage: lwa -d <fichier>\n");
|
||||
printf("Nom de fichier incorrect\n");
|
||||
cr = -14;
|
||||
}
|
||||
else if(wlib.mLg == 0)
|
||||
{
|
||||
printf("Variable d'environnement WLIB non definie\n");
|
||||
cr = -15;
|
||||
}
|
||||
else
|
||||
{
|
||||
int numLig = 0;
|
||||
#ifndef UNIX
|
||||
if((cr = assembler(&e, argv[1], &numLig)) != OK)
|
||||
#else
|
||||
if((cr = assembler(&e, argv[1], &numLig)) != OK)
|
||||
#endif
|
||||
if(wlib.mPtr[wlib.mLg - 1] != e.path_sep[0])
|
||||
dynConcatSz(&e, &wlib, e.path_sep, 1);
|
||||
dynConcat(&e, &wlib, &fichier);
|
||||
if(dynLocateSz(&e, &arg, ARG_DISASM, cVM, 1, cFM) > 0)
|
||||
{
|
||||
printf("Erreur %d a la ligne %d\n", cr, numLig);
|
||||
#ifndef UNIX
|
||||
cr = disassembler(&e, wlib.mPtr);
|
||||
#else
|
||||
cr = disassembler(&e, wlib.mPtr);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Result : OK, lines=%d\n", numLig);
|
||||
int numLig = 0;
|
||||
#ifndef UNIX
|
||||
if((cr = assembler(&e, wlib.mPtr, &numLig)) != OK)
|
||||
#else
|
||||
if((cr = assembler(&e, wlib.mPtr, &numLig)) != OK)
|
||||
#endif
|
||||
{
|
||||
printf("Erreur %d a la ligne %d\n", cr, numLig);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Result : OK, lines=%d\n", numLig);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* */
|
||||
if(clock_gettime_monotonic(&ts) != -1)
|
||||
lap = ts.tv_sec * 1000000 + (ts.tv_nsec / 1000) - lap;
|
||||
printf("exit:%u ", cr);
|
||||
printf("exit:%d ", cr);
|
||||
if(lap < 1500)
|
||||
printf("(%llu µs)\n", lap);
|
||||
else if(lap < 1500000)
|
||||
|
||||
@@ -29,7 +29,30 @@
|
||||
#include "buffer.h"
|
||||
#include "dynamic.h"
|
||||
|
||||
void buffer_read(env * e, var * varbuf, var * v)
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
/*
|
||||
Dans le contexte des IPC, memoire partagee, contenant un buffer (donc partagé), le champ "ptr" pointe forcement a la suite de l'entete,
|
||||
car un malloc ne fonctionne pas en inter process.
|
||||
Contrairement à la création avec "var_init", destiné a ne pas etre partage, ptr est créé par un malloc
|
||||
La macro BUFPTR permet de gerer ces 2 cas : si le buffer est en memoire partagee, le champ ptr = NULL et il suffit alors d'aller juste apres l'entete
|
||||
pour trouver les donnees. Si le buffer est cree avec var_init, il faut utiliser la valeur de ptr directement.
|
||||
*/
|
||||
|
||||
//#define BUFPTR(x) (pointeur)(x->ptr == NULL ? (pointeur)(x + sizeof(var)) : x->ptr)
|
||||
pointeur BUFPTR(var * x)
|
||||
{
|
||||
return (pointeur)(x->ptr == NULL ? (pointeur)(x + sizeof(var)) : x->ptr);
|
||||
}
|
||||
|
||||
WAPIDECL void buffer_read(env * e, var * varbuf, var * v)
|
||||
{
|
||||
ent16 lg, lgfin; /* taille max d'un element dans un buffer : 64 Ko */
|
||||
ent64 p;
|
||||
@@ -56,9 +79,9 @@ void buffer_read(env * e, var * varbuf, var * v)
|
||||
return; /* buffer vide : var dynamic vide aussi */
|
||||
/* */
|
||||
p = varbuf->read;
|
||||
lg = *(octet *)(varbuf->ptr + p++) * 256;
|
||||
lg = *(octet *)(BUFPTR(varbuf) + p++) * 256;
|
||||
if(p >= varbuf->lgmax) p = 0;
|
||||
lg += *(octet *)(varbuf->ptr + p++);
|
||||
lg += *(octet *)(BUFPTR(varbuf) + p++);
|
||||
if(p >= varbuf->lgmax) p = 0;
|
||||
if(lg > 0)
|
||||
{
|
||||
@@ -68,7 +91,7 @@ void buffer_read(env * e, var * varbuf, var * v)
|
||||
if(lg <= (lgfin = varbuf->lgmax - p))
|
||||
{
|
||||
/* copier un seul bloc */
|
||||
memcopie(v->ptr, varbuf->ptr + p, lg);
|
||||
memcopie(v->ptr, BUFPTR(varbuf) + p, lg);
|
||||
//memcpy(v->ptr, varbuf->ptr + p, lg);
|
||||
v->lg = lg;
|
||||
*(v->ptr + lg) = 0; /* \0 de fin de chaine */
|
||||
@@ -80,9 +103,9 @@ void buffer_read(env * e, var * varbuf, var * v)
|
||||
else
|
||||
{
|
||||
/* 2 blocs */
|
||||
memcopie(v->ptr, varbuf->ptr + p, lgfin);
|
||||
memcopie(v->ptr, BUFPTR(varbuf) + p, lgfin);
|
||||
//memcpy(v->ptr, varbuf->ptr + p, lgfin);
|
||||
memcopie(v->ptr + lgfin, varbuf->ptr, lg - lgfin);
|
||||
memcopie(v->ptr + lgfin, BUFPTR(varbuf), lg - lgfin);
|
||||
//memcpy(v->ptr + lgfin, varbuf->ptr, lg - lgfin);
|
||||
varbuf->read = lg - lgfin;
|
||||
}
|
||||
@@ -91,7 +114,7 @@ void buffer_read(env * e, var * varbuf, var * v)
|
||||
varbuf->read = p;
|
||||
}
|
||||
|
||||
void buffer_write(env * e, var * varbuf, var * v)
|
||||
WAPIDECL void buffer_write(env * e, var * varbuf, var * v)
|
||||
{
|
||||
ent64 p, lgfin;
|
||||
if(varbuf == NULL || v == NULL)
|
||||
@@ -101,7 +124,7 @@ void buffer_write(env * e, var * varbuf, var * v)
|
||||
if(varbuf->type != VAR_BUFFER || v->type != VAR_DYNAMIC)
|
||||
return;
|
||||
/* uniquement ecriture d'une VAR_DYNAMIC */
|
||||
if(v->lg > (v->lgmax / 16)) // pour pouvoir ecrire au moins 16 items dans le buffer
|
||||
if(v->lg > (varbuf->lgmax / 2)) // pour pouvoir ecrire au moins 2 items dans le buffer
|
||||
{
|
||||
e->exception = EX_BUFOVF; /* trop grand a ecrire */
|
||||
return;
|
||||
@@ -117,11 +140,11 @@ void buffer_write(env * e, var * varbuf, var * v)
|
||||
}
|
||||
/* */
|
||||
p = varbuf->write;
|
||||
*(varbuf->ptr + p) = (v->lg & 65535) >> 8;
|
||||
*(BUFPTR(varbuf) + p) = (v->lg & 65535) >> 8;
|
||||
p++;
|
||||
*(varbuf->ptr + p) = v->lg & 255;
|
||||
*(BUFPTR(varbuf) + p) = v->lg & 255;
|
||||
p++;
|
||||
memcopie(varbuf->ptr + p, v->ptr, v->lg);
|
||||
memcopie(BUFPTR(varbuf) + p, v->ptr, v->lg);
|
||||
//memcpy(varbuf->ptr + p, v->ptr, v->lg);
|
||||
varbuf->write = p + v->lg;
|
||||
}
|
||||
@@ -133,12 +156,11 @@ void buffer_write(env * e, var * varbuf, var * v)
|
||||
e->exception = EX_BUFOVF; /* pas assez de place */
|
||||
return;
|
||||
}
|
||||
/* */
|
||||
p = varbuf->write;
|
||||
*(varbuf->ptr + p) = (v->lg & 65535) >> 8;
|
||||
*(BUFPTR(varbuf) + p) = (v->lg & 65535) >> 8;
|
||||
p++;
|
||||
if(p >= varbuf->lgmax) p = 0;
|
||||
*(varbuf->ptr + p) = v->lg & 255;
|
||||
*(BUFPTR(varbuf) + p) = v->lg & 255;
|
||||
p++;
|
||||
if(p >= varbuf->lgmax) p = 0;
|
||||
if(v->lg == 0)
|
||||
@@ -149,7 +171,7 @@ void buffer_write(env * e, var * varbuf, var * v)
|
||||
if(v->lg <= (lgfin = varbuf->lgmax - p))
|
||||
{
|
||||
/* copier en une fois */
|
||||
memcopie(varbuf->ptr + p, v->ptr, v->lg);
|
||||
memcopie(BUFPTR(varbuf) + p, v->ptr, v->lg);
|
||||
//memcpy(varbuf->ptr + p, v->ptr, v->lg);
|
||||
if(p + v->lg >= varbuf->lgmax)
|
||||
varbuf->write = 0; /* pas plus cas sinon il y aurait eu copie en 2 fois */
|
||||
@@ -159,16 +181,16 @@ void buffer_write(env * e, var * varbuf, var * v)
|
||||
else
|
||||
{
|
||||
/* en 2 fois */
|
||||
memcopie(varbuf->ptr + p, v->ptr, lgfin);
|
||||
memcopie(BUFPTR(varbuf) + p, v->ptr, lgfin);
|
||||
//memcpy(varbuf->ptr + p, v->ptr, lgfin);
|
||||
memcopie(varbuf->ptr, v->ptr + lgfin, v->lg - lgfin);
|
||||
memcopie(BUFPTR(varbuf), v->ptr + lgfin, v->lg - lgfin);
|
||||
//memcpy(varbuf->ptr, v->ptr + lgfin, v->lg - lgfin);
|
||||
varbuf->write = v->lg - lgfin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void buffer_clear(env * e, var * varbuf)
|
||||
WAPIDECL void buffer_clear(env * e, var * varbuf)
|
||||
{
|
||||
if(varbuf == NULL)
|
||||
return;
|
||||
@@ -176,10 +198,10 @@ void buffer_clear(env * e, var * varbuf)
|
||||
return;
|
||||
varbuf->read = 0;
|
||||
varbuf->write = 0;
|
||||
memset(varbuf->ptr, 0, varbuf->lgmax);
|
||||
memset(BUFPTR(varbuf), 0, varbuf->lgmax);
|
||||
}
|
||||
|
||||
void buffer_printdebug(env * e, var * varbuf, ent32 lg)
|
||||
WAPIDECL void buffer_printdebug(env * e, var * varbuf, ent32 lg)
|
||||
{
|
||||
if(varbuf == NULL)
|
||||
return;
|
||||
@@ -189,5 +211,5 @@ void buffer_printdebug(env * e, var * varbuf, ent32 lg)
|
||||
if(lg == 0)
|
||||
lg = varbuf->lgmax;
|
||||
/* affichage brut en hexa */
|
||||
hex2((char *)varbuf->ptr, lg, 32);
|
||||
hex2((char *)BUFPTR(varbuf), lg, 32);
|
||||
}
|
||||
@@ -23,11 +23,13 @@
|
||||
#ifndef BUFFER_H
|
||||
#define BUFFER_H
|
||||
|
||||
void buffer_read(env * e, var * varbuf, var * v);
|
||||
void buffer_write(env * e, var * varbuf, var * v);
|
||||
void buffer_clear(env * e, var * varbuf);
|
||||
#include "apidecl.h"
|
||||
|
||||
void buffer_printdebug(env * e, var * varbuf, ent32 lg);
|
||||
WAPIDECL void buffer_read(env * e, var * varbuf, var * v);
|
||||
WAPIDECL void buffer_write(env * e, var * varbuf, var * v);
|
||||
WAPIDECL void buffer_clear(env * e, var * varbuf);
|
||||
|
||||
WAPIDECL void buffer_printdebug(env * e, var * varbuf, ent32 lg);
|
||||
|
||||
/* ********************************************** */
|
||||
#endif
|
||||
@@ -1,14 +1,18 @@
|
||||
BUILD=`date +%Y%m%d%H%M%S`
|
||||
echo BUILD $BUILD
|
||||
|
||||
echo 0. Compilation pour shared lib
|
||||
gcc -c w_src/dynamic.c -s -Wall -DUNIX -m64 -fPIC -o exec/dynamic.o -Wno-unused-value
|
||||
gcc -c w_src/var.c -s -Wall -DUNIX -m64 -fPIC -o exec/var.o
|
||||
gcc -c w_src/hashtable.c -s -Wall -DUNIX -m64 -fPIC -o exec/hashtable.o
|
||||
gcc -c w_src/buffer.c -s -Wall -DUNIX -m64 -fPIC -o exec/buffer.o
|
||||
gcc -c w_src/global.c -s -Wall -DUNIX -m64 -fPIC -o exec/global.o
|
||||
gcc -c w_src/rep.c -s -Wall -DUNIX -m64 -fPIC -o exec/rep.o
|
||||
gcc -shared -s exec/dynamic.o exec/var.o exec/hashtable.o exec/global.o exec/rep.o -o exec/libw.so
|
||||
rm -f exec/dynamic.o exec/var.o exec/hashtable.o exec/global.o exec/rep.o
|
||||
gcc -shared -s exec/dynamic.o exec/var.o exec/hashtable.o exec/global.o exec/rep.o exec/buffer.o -o exec/libw.so
|
||||
rm -f exec/dynamic.o exec/var.o exec/hashtable.o exec/global.o exec/rep.o exec/buffer.o
|
||||
|
||||
echo 1. Compilation de modeleMod.c
|
||||
gcc -shared -s -o exec/modele.o w_src/modeleMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
echo 1. Compilation de templateMod.c
|
||||
gcc -shared -s -o exec/template.o w_src/templateMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
|
||||
echo 2. Compilation de fileMod.c
|
||||
gcc -shared -s -o exec/file.o w_src/fileMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
@@ -16,21 +20,25 @@ gcc -shared -s -o exec/file.o w_src/fileMod.c -m64 -DUNIX -Wall -fPIC -L./exec -
|
||||
echo 3. Compilation de sockMod.c
|
||||
gcc -shared -s -o exec/sock.o w_src/sockMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
|
||||
echo 4. Compilation de dbMod.c et dbpgsql.c
|
||||
gcc -shared -s -o exec/db.o w_src/dbMod.c -m64 -DUNIX -Wall -ldl -fPIC -L./exec -l:libw.so
|
||||
#echo 4. Compilation de dbMod.c et dbpgsql.c
|
||||
#gcc -shared -s -o exec/db.o w_src/dbMod.c -m64 -DUNIX -Wall -ldl -fPIC -L./exec -l:libw.so
|
||||
#gcc -shared -s -o exec/pgsql.o w_src/dbpgsql.c -m64 -DUNIX -Wall -I/usr/include/postgresql -fPIC -L./exec -l:libw.so
|
||||
|
||||
echo 5. Compilation de lzwMod.c
|
||||
gcc -shared -s -o exec/lzw_lib.o w_src/lzw_lib.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
gcc -shared -s -o exec/lzw.o w_src/lzwMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so -l:lzw_lib.o
|
||||
gcc -shared -s -o exec/lzw_lib.so w_src/lzw_lib.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
gcc -shared -s -o exec/lzw.o w_src/lzwMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so -l:lzw_lib.so
|
||||
|
||||
echo 5. Compilation de pdfMod.c
|
||||
gcc -shared -s -o exec/pdf_lib.o w_src/pdf_lib.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
#gcc -shared -s -o exec/pdf.o w_src/pdfMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so -l:pdf_lib.o
|
||||
gcc -shared -s -o exec/pdf_lib.so w_src/pdf_lib.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
gcc -shared -s -o exec/pdf.o w_src/pdfMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so -l:pdf_lib.so -l:lzw_lib.so
|
||||
|
||||
echo 6. Compilation de jsonMod.c
|
||||
gcc -shared -s -o exec/json_lib.o w_src/json_lib.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
gcc -shared -s -o exec/json.o w_src/jsonMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so -l:json_lib.o
|
||||
gcc -shared -s -o exec/json_lib.so w_src/json_lib.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
gcc -shared -s -o exec/json.o w_src/jsonMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so -l:json_lib.so
|
||||
|
||||
echo 6. Compilation de shmMod.c
|
||||
gcc -shared -s -o exec/shm_lib.so w_src/shm_lib.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
gcc -shared -s -o exec/shm.o w_src/shmMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so -l:shm_lib.so
|
||||
|
||||
echo 7. Compilation de timeMod.c
|
||||
gcc -shared -s -o exec/time.o w_src/timeMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
@@ -45,7 +53,7 @@ echo 10. Compilation de randomMod.c
|
||||
gcc -shared -s -o exec/random.o w_src/randomMod.c -m64 -DUNIX -Wall -fPIC -L./exec -l:libw.so
|
||||
|
||||
echo 11. Compilation et link de langage.c
|
||||
gcc w_src/langage.c -s -o exec/lw -ldl -m64 -DUNIX -Wall -Wno-stringop-truncation -L./exec -l:libw.so
|
||||
gcc w_src/langage.c -s -o exec/lw -ldl -m64 -DUNIX -DBUILD=$BUILD -Wall -Wno-stringop-truncation -L./exec -l:libw.so -l:shm_lib.so
|
||||
|
||||
echo 12. Compilation et link de assembler.c
|
||||
gcc w_src/assembler.c -s -o exec/lwa -ldl -m64 -DUNIX -Wall -Wno-stringop-truncation -L./exec -l:libw.so
|
||||
@@ -60,6 +68,6 @@ echo 15. Generation de l\'analyseur de source w \(compilateur w\)
|
||||
gcc w_src/genw.c -s -o exec/lwc -Wall -m64 -DUNIX -Wno-stringop-truncation -L./exec -l:libw.so
|
||||
|
||||
echo "test_utf => gcc test_utf.c -s -o utf -Wall -m64 -DUNIX -L./exec -l:libw.so"
|
||||
echo "test_pdf => gcc test_pdf.c -s -o pdf -Wall -m64 -DUNIX -L./exec -l:libw.so -l:pdf_lib.o -l:lzw_lib.o"
|
||||
echo "test_pdf => gcc test_pdf.c -s -o pdf -Wall -m64 -DUNIX -L./exec -l:libw.so -l:pdf_lib.so -l:lzw_lib.so"
|
||||
|
||||
echo "package => dpkg-deb --build wlanguage"
|
||||
+46
-60
@@ -5,81 +5,67 @@ call vcvars64.bat
|
||||
|
||||
cd "C:\Users\Poupougne42\source\repos\win_w_src"
|
||||
|
||||
echo 0. Compilation pour static lib
|
||||
cl /c /Foexec\dynamic.obj w_src\dynamic.c
|
||||
cl /c /Foexec\var.obj w_src\var.c
|
||||
cl /c /Foexec\hashtable.obj w_src\hashtable.c
|
||||
cl /c /Foexec\global.obj w_src\global.c
|
||||
cl /c /Foexec\rep.obj w_src\rep.c
|
||||
echo ------------------------------------------------------------------------------------------
|
||||
echo 0. Compilation pour dynamic lib DLL
|
||||
cl /LD /DWINLIB /DWAPIEXPORT /Feexec\libw.dll w_src\dynamic.c w_src\var.c w_src\hashtable.c w_src\buffer.c w_src\global.c w_src\rep.c
|
||||
|
||||
echo 1a. Compilation de templateMod.c
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\template.dll w_src\templateMod.c exec\libw.lib
|
||||
|
||||
lib /OUT:exec\libw.lib exec\dynamic.obj exec\var.obj exec\hashtable.obj exec\global.obj exec\rep.obj
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 1a. Compilation de modeleMod.c
|
||||
cl w_src\modeleMod.c exec\libw.lib /Foexec\modeleMod.obj /DWINLIB /link /DLL /OUT:exec\modele.dll
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 1b. Compilation de fileMod.c
|
||||
cl w_src\fileMod.c exec\libw.lib /Foexec\fileMod.obj /DWINLIB /link /DLL /OUT:exec\file.dll
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\file.dll w_src\fileMod.c exec\libw.lib
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 1c. Compilation de jsonMod.c
|
||||
cl /c /Foexec\json_lib.obj w_src\json_lib.c
|
||||
lib /OUT:exec\json_lib.lib exec\json_lib.obj
|
||||
cl w_src\jsonMod.c exec\libw.lib exec\json_lib.lib /Foexec\jsonMod.obj /DWINLIB /link /DLL /OUT:exec\json.dll
|
||||
echo 1c. Compilation de timeMod.c
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\time.dll w_src\timeMod.c exec\libw.lib
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 1d. Compilation de timeMod.c
|
||||
cl w_src\timeMod.c exec\libw.lib /Foexec\timeMod.obj /DWINLIB /link /DLL /OUT:exec\time.dll
|
||||
echo 1d. Compilation de hashMod.c
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\hash.dll w_src\hashMod.c exec\libw.lib
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 1e. Compilation de hashMod.c
|
||||
cl w_src\hashMod.c exec\libw.lib /Foexec\hashMod.obj /DWINLIB /link /DLL /OUT:exec\hash.dll
|
||||
echo 1e. Compilation de systemMod.c (ws2_32.lib pour socket)
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\system.dll w_src\systemMod.c exec\libw.lib ws2_32.lib
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 1f. Compilation de systemMod.c
|
||||
cl w_src\systemMod.c exec\libw.lib ws2_32.lib /Foexec\systemMod.obj /DWINLIB /link /DLL /OUT:exec\system.dll
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 1g. Compilation de randomMod.c
|
||||
cl w_src\randomMod.c exec\libw.lib /Foexec\randomMod.obj /DWINLIB /link /DLL /OUT:exec\random.dll
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 1h. Compilation de lzwMod.c
|
||||
cl /c /Foexec\lzw_lib.obj w_src\lzw_lib.c
|
||||
lib /OUT:exec\lzw_lib.lib exec\lzw_lib.obj
|
||||
cl w_src\lzwMod.c exec\libw.lib exec\lzw_lib.lib /Foexec\lzwMod.obj /DWINLIB /link /DLL /OUT:exec\lzw.dll
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 1h. Compilation de pdfMod.c
|
||||
cl /c /Foexec\pdf_lib.obj w_src\pdf_lib.c
|
||||
lib /OUT:exec\pdf_lib.lib exec\pdf_lib.obj
|
||||
rem cl w_src\pdfMod.c exec\libw.lib exec\pdf_lib.lib /Foexec\pdfMod.obj /DWINLIB /link /DLL /OUT:exec\pdf.dll
|
||||
echo 1f. Compilation de randomMod.c
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\random.dll w_src\randomMod.c exec\libw.lib
|
||||
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 2. Compilation langage lw (ws2_32.lib pour socket)
|
||||
cl w_src\langage.c exec\libw.lib ws2_32.lib /Foexec\langage.obj /DWINLIB /link /OUT:exec\lw.exe
|
||||
echo ------------------------------------------------------------------------------------------
|
||||
echo 2a. Compilation de jsonMod.c
|
||||
cl /LD /DWINLIB /DWAPIEXPORT /Feexec\json_lib.dll w_src\json_lib.c exec\libw.lib
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\json.dll w_src\jsonMod.c exec\libw.lib exec\json_lib.lib
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 3. Compilation assembleur lwa
|
||||
cl w_src\assembler.c exec\libw.lib /Foexec\assembler.obj /DWINLIB /link /OUT:exec\lwa.exe
|
||||
echo 2b. Compilation de shmMod.c
|
||||
cl /LD /DWINLIB /DWAPIEXPORT /Feexec\shm_lib.dll w_src\shm_lib.c exec\libw.lib
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\shm.dll w_src\shmMod.c exec\libw.lib exec\shm_lib.lib
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 4. Compilation du compilateur W (generateur d'assembleur)
|
||||
cl w_src\genw.c exec\libw.lib /Foexec\genw.obj /DWINLIB /link /OUT:exec\lwc.exe
|
||||
echo 2c. Compilation de lzwMod.c
|
||||
cl /LD /DWINLIB /DWAPIEXPORT /Feexec\lzw_lib.dll w_src\lzw_lib.c exec\libw.lib
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\lzw.dll w_src\lzwMod.c exec\libw.lib exec\lzw_lib.lib
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 5. Compilation formatteur de code w
|
||||
cl w_src\format.c exec\libw.lib /Foexec\format.obj /DWINLIB /link /OUT:exec\lwf.exe
|
||||
echo 2d. Compilation de pdfMod.c
|
||||
cl /LD /DWINLIB /DWAPIEXPORT /Feexec\pdf_lib.dll w_src\pdf_lib.c exec\libw.lib exec\lzw_lib.lib
|
||||
cl /LD /DWINLIB /DWAPIIMPORT /Feexec\pdf.dll w_src\pdfMod.c exec\libw.lib exec\pdf_lib.lib
|
||||
|
||||
echo ------------------------------------------------------------------------
|
||||
echo 6. Generation du generateur de fichier lex
|
||||
cl w_src\genlex.c exec\libw.lib /Foexec\genlex.obj /DWINLIB /link /OUT:exec\wlex.exe
|
||||
echo ------------------------------------------------------------------------------------------
|
||||
echo 3a. Generation lw.exe
|
||||
cl w_src\langage.c /DWINLIB /DWAPIIMPORT /Feexec\lw.exe exec\libw.lib exec\shm_lib.lib /link
|
||||
|
||||
rem purge des .obj
|
||||
echo 3b. Generation lwa.exe
|
||||
cl w_src\assembler.c /DWINLIB /DWAPIIMPORT /Feexec\lwa.exe exec\libw.lib /link
|
||||
|
||||
echo 3c. Generation lwc.exe
|
||||
cl w_src\genw.c /DWINLIB /DWAPIIMPORT /Feexec\lwc.exe exec\libw.lib /link
|
||||
|
||||
echo 3d. Generation lwf.exe
|
||||
cl w_src\format.c /DWINLIB /DWAPIIMPORT /Feexec\lwf.exe exec\libw.lib /link
|
||||
|
||||
echo 3d. Generation wlex.exe
|
||||
cl w_src\genlex.c /DWINLIB /DWAPIIMPORT /Feexec\wlex.exe exec\libw.lib /link
|
||||
|
||||
echo ------------------------------------------------------------------------------------------
|
||||
echo 4. Purge
|
||||
del .\*.obj
|
||||
del exec\*.obj
|
||||
del exec\*.lib
|
||||
del exec\*.exp
|
||||
dir exec
|
||||
exit
|
||||
@@ -2,7 +2,7 @@
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024 lanisys.fr
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
@@ -86,7 +86,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(strncmp(e->fn, "init", 4) == 0)
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
@@ -102,14 +102,14 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
p_etat->fnDb = NULL;
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
// liberation specifique au module avant arret process
|
||||
if(p_etat != NULL)
|
||||
memfree(e, p_etat);
|
||||
//*** code specifique ici
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param->type == VAR_DYNAMIC)
|
||||
@@ -119,7 +119,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
else if(strncmp(e->fn, "error", 5) == 0)
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
@@ -133,7 +133,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "conn", 4) == 0)
|
||||
else if(modFnIs(e, "conn", 4))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -182,7 +182,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "disc", 4) == 0)
|
||||
else if(modFnIs(e, "disc", 4))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -208,7 +208,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "info", 4) == 0)
|
||||
else if(modFnIs(e, "info", 4))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
|
||||
+9
-9
@@ -221,7 +221,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
// -----------------------------------------------------------
|
||||
if(strncmp(e->fn, "read", 4) == 0)
|
||||
if(modFnIs(e, "read", 4))
|
||||
{
|
||||
// param<1> = no fichier ; param<2> = cle
|
||||
dynRemove(e, param, &p_etat->mTmp, cFM, DYN_TRUE);
|
||||
@@ -319,11 +319,11 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
return EX_DB_ELSE; // pas d'erreur : mettre le code pour "non trouve" ELSE
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "write", 4) == 0)
|
||||
else if(modFnIs(e, "write", 5))
|
||||
{
|
||||
//
|
||||
}
|
||||
else if(strncmp(e->fn, "open", 4) == 0)
|
||||
else if(modFnIs(e, "open", 4))
|
||||
{
|
||||
// param<1> = nom table ; si ok renvoie en retour param<1> = id fichier (indice du tableau)
|
||||
int lgSav = p_etat->mBase.mLg;
|
||||
@@ -376,7 +376,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
dynSetLen(e, &p_etat->mBase, lgSav);
|
||||
}
|
||||
else if(strncmp(e->fn, "create", 5) == 0)
|
||||
else if(modFnIs(e, "create", 5))
|
||||
{
|
||||
// cree la table : param<1> nom ; modulo param<2> ; separateur param<3>
|
||||
fileHeader info;
|
||||
@@ -421,7 +421,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "close", 5) == 0)
|
||||
else if(modFnIs(e, "close", 5))
|
||||
{
|
||||
// param<1> = no fichier
|
||||
int pos = dynToNum(e, param, 0, 6);
|
||||
@@ -437,7 +437,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
// sinon, fichier deja ferme : RAS
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "setup", 5) == 0)
|
||||
else if(modFnIs(e, "setup", 5))
|
||||
{
|
||||
// sortir si mId deja present (!=0) : une base est deja ouverte
|
||||
// param<1> = repertoire de base => sa cle d'acces = mKey
|
||||
@@ -488,7 +488,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "init", 4) == 0)
|
||||
else if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// si init deja fait, ras
|
||||
if(p_etat == NULL)
|
||||
@@ -502,7 +502,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
dynInit(e, &p_etat->mEntry, DYN_LGMIN);
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
struct shmid_ds attrs = {0};
|
||||
// liberation specifique au module avant arret process
|
||||
@@ -534,7 +534,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
memfree(e, p_etat);
|
||||
*etat = NULL;
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
dynLet(e, param, "100", 3); // version 1.00 ici
|
||||
|
||||
@@ -60,13 +60,17 @@ char * strerr[] = {
|
||||
"EX_REMOVE_KO remove field error"
|
||||
};
|
||||
|
||||
long rg(env * e, Dynamic * regles, char * nom, Dynamic * tmp)
|
||||
enum {
|
||||
cLF = 10
|
||||
};
|
||||
|
||||
long rg(env * e, Dynamic * regles, char * nom, Dynamic * tmp)
|
||||
{
|
||||
// renvoie le numero de la regle a partir de son nom, 0 si non trouvee ou erreur conversion en numerique
|
||||
long pos = dynLocateSz(e, regles, nom, ',', 1, 10);
|
||||
long pos = dynLocateSz(e, regles, nom, ',', 1, cLF);
|
||||
if(pos > 0)
|
||||
{
|
||||
dynField(e, regles, tmp, 1, pos + 1, 10, ',', 1);
|
||||
dynField(e, regles, tmp, 1, pos + 1, cLF, ',', 1);
|
||||
pos = dynToNum(e, tmp, DYN_FALSE, 5); // pas de signe et num regle sur 16 bits : 5 chiffres
|
||||
if(tmp->mInternal != DYN_OK)
|
||||
pos = 0;
|
||||
@@ -92,58 +96,191 @@ void init_reg(env * e, Dynamic * regles, Dynamic * tmp)
|
||||
r.reste = rg(e, regles, "reste", tmp);
|
||||
}
|
||||
|
||||
void print_var(env * e, var * v, Dynamic * tmp)
|
||||
void print_var(env * e, var * v, Dynamic * tmp, int prettyPrint)
|
||||
{
|
||||
if(v->type == VAR_PARAM)
|
||||
v = (var *)v->ptr; /* travailler avec la var pointee */
|
||||
switch(v->type)
|
||||
{
|
||||
// "0XNSPDHOB"
|
||||
case VAR_NULL:
|
||||
printf("Var %c\n",e->var_car[v->type]); // X
|
||||
break;
|
||||
case VAR_NUMBER:
|
||||
long lg;
|
||||
NumberToSz(e, v->num, tmp->mPtr, &lg);
|
||||
printf("Var %c : %s\n",e->var_car[v->type], tmp->mPtr); // N
|
||||
break;
|
||||
case VAR_DYNAMIC:
|
||||
if(strncmp(e->nom, "_stack", 6) == 0)
|
||||
printf("Var %c(%lld) : %s (ret: %p)\n",e->var_car[v->type], v->mLg, v->mPtr, *(pointeur *)(v->mPtr)); // D
|
||||
else
|
||||
printf("Var %c(%lld) : %s\n",e->var_car[v->type], v->mLg, v->mPtr); // D
|
||||
break;
|
||||
case VAR_BUFFER:
|
||||
printf("Var %c\n",e->var_car[v->type]); // B
|
||||
break;
|
||||
case VAR_HASHTABLE:
|
||||
printf("Var %c\n",e->var_car[v->type]); // H
|
||||
hashtable_printdebug(e, v, 1);
|
||||
break;
|
||||
case VAR_OBJECT:
|
||||
printf("Var %c\n",e->var_car[v->type]); // O
|
||||
hashtable_printdebug(e, v, 1);
|
||||
break;
|
||||
case VAR_SUBROUTINE:
|
||||
printf("Var %c : %p (-> %p)\n",e->var_car[v->type], v, v->ptr); // S
|
||||
break;
|
||||
case VAR_PARAM:
|
||||
printf("Var %c\n",e->var_car[v->type]); // P : mais ne peut pas arriver ici
|
||||
break;
|
||||
}
|
||||
//
|
||||
char * var_str[9] = {"0","X","N","S","P","D","H","O","B"};
|
||||
if(e->demon)
|
||||
switch(v->type)
|
||||
{
|
||||
// "0XNSPDHOB"
|
||||
case VAR_NULL:
|
||||
dynPrintfSz(e, "Var " PRINTF_MARK "\n", var_str[v->type]); // X
|
||||
break;
|
||||
case VAR_NUMBER:
|
||||
dynPrintfSz(e, "Var " PRINTF_MARK " : ", var_str[v->type]);
|
||||
dynPrintfSz(e, PRINTF_MARK "\n", NumberToSz(e, v->num, NULL, NULL)); // N
|
||||
break;
|
||||
case VAR_DYNAMIC:
|
||||
if(strncmp(e->nom, GUV_BINADDR, 8) == 0)
|
||||
{
|
||||
dynPrintfSz(e, "=> begin end counter\n", NULL);
|
||||
dynPrintfSz(e, "=> ", NULL);
|
||||
dynPrintfConcatHexSz(e, v->mPtr, v->mLg);
|
||||
dynPrintfSz(e, "\n", NULL);
|
||||
}
|
||||
else if(strncmp(e->nom, GUV_STACK, 6) == 0)
|
||||
{
|
||||
dynPrintfSz(e, "=> prevLocal si begin end EXCE except\n", NULL);
|
||||
dynPrintfSz(e, "=> ", NULL);
|
||||
dynPrintfConcatHexSz(e, v->mPtr, v->mLg);
|
||||
dynPrintfSz(e, "\n", NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
dynPrintfSz(e, "Var " PRINTF_MARK "(", var_str[v->type]); // X
|
||||
dynPrintfInt64(e, PRINTF_MARK ") : \n", v->mLg, 0);
|
||||
if(prettyPrint)
|
||||
{
|
||||
dynSetAs(e, tmp, v);
|
||||
dynReplace(e, tmp, cFM, cLF);
|
||||
dynReplace(e, tmp, cVM, '|');
|
||||
dynPrintfSz(e, PRINTF_MARK "\n", tmp->mPtr);
|
||||
}
|
||||
else
|
||||
dynPrintfSz(e, PRINTF_MARK "\n", v->mPtr);
|
||||
}
|
||||
break;
|
||||
case VAR_BUFFER:
|
||||
dynPrintfSz(e, "Var " PRINTF_MARK "\n", var_str[v->type]); // B
|
||||
break;
|
||||
case VAR_HASHTABLE:
|
||||
dynPrintfSz(e, "Var " PRINTF_MARK "\n", var_str[v->type]); // H
|
||||
hashtable_printdebug(e, v, 1);
|
||||
break;
|
||||
case VAR_OBJECT:
|
||||
dynPrintfSz(e, "Var " PRINTF_MARK "\n", var_str[v->type]); // O
|
||||
hashtable_printdebug(e, v, 1);
|
||||
break;
|
||||
case VAR_SUBROUTINE:
|
||||
dynPrintfSz(e, "Var " PRINTF_MARK " : ", var_str[v->type]); // X
|
||||
dynPrintfHex(e, PRINTF_MARK " (-> ", (ent64)v, 0);
|
||||
dynPrintfHex(e, PRINTF_MARK ")\n", (ent64)v->ptr, 0); // S
|
||||
break;
|
||||
case VAR_PARAM:
|
||||
dynPrintfSz(e, "Var " PRINTF_MARK "\n", var_str[v->type]); // P : mais ne peut pas arriver ici
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch(v->type)
|
||||
{
|
||||
// "0XNSPDHOB"
|
||||
case VAR_NULL:
|
||||
printf("Var %c\n",e->var_car[v->type]); // X
|
||||
break;
|
||||
case VAR_NUMBER:
|
||||
printf("Var %c : %s\n",e->var_car[v->type], NumberToSz(e, v->num, NULL, NULL)); // N
|
||||
break;
|
||||
case VAR_DYNAMIC:
|
||||
if(strncmp(e->nom, GUV_STACK, 6) == 0)
|
||||
{
|
||||
printf("=> prevLocal si begin end EXCE except\n");
|
||||
hex3(v->mPtr, v->mLg);
|
||||
}
|
||||
else if(strncmp(e->nom, GUV_BINADDR, 8) == 0)
|
||||
{
|
||||
printf("=> begin end counter\n");
|
||||
hex3(v->mPtr, v->mLg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(prettyPrint)
|
||||
{
|
||||
dynSetAs(e, tmp, v);
|
||||
dynReplace(e, tmp, cFM, cLF);
|
||||
dynReplace(e, tmp, cVM, '|');
|
||||
printf("Var %c(%lld) : \n%s\n",e->var_car[v->type], tmp->mLg, tmp->mPtr); // D
|
||||
}
|
||||
else
|
||||
printf("Var %c(%lld) : %s\n",e->var_car[v->type], v->mLg, v->mPtr); // D
|
||||
}
|
||||
break;
|
||||
case VAR_BUFFER:
|
||||
printf("Var %c\n",e->var_car[v->type]); // B
|
||||
break;
|
||||
case VAR_HASHTABLE:
|
||||
printf("Var %c\n",e->var_car[v->type]); // H
|
||||
hashtable_printdebug(e, v, 1);
|
||||
break;
|
||||
case VAR_OBJECT:
|
||||
printf("Var %c\n",e->var_car[v->type]); // O
|
||||
hashtable_printdebug(e, v, 1);
|
||||
break;
|
||||
case VAR_SUBROUTINE:
|
||||
printf("Var %c : %p (-> %p)\n",e->var_car[v->type], v, v->ptr); // S
|
||||
break;
|
||||
case VAR_PARAM:
|
||||
printf("Var %c\n",e->var_car[v->type]); // P : mais ne peut pas arriver ici
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* gestion du mode "debug" dans tous les type d'execution : p-code, compile, script... */
|
||||
|
||||
void initDebugCtxShm(env * e)
|
||||
{
|
||||
if( ! e->debugCtxShm)
|
||||
e->debugCtxShm = memalloc(e, sizeof(modContextShm));
|
||||
if( ! e->debugCtxShm)
|
||||
e->debug = 0; // erreur alloc : pas de debug
|
||||
else
|
||||
{
|
||||
*((ent64 *)(((modContextShm *)e->debugCtxShm)->nom)) = 0;
|
||||
*(((ent64 *)(((modContextShm *)e->debugCtxShm)->nom)) + 1) = 0;
|
||||
*(((ent64 *)(((modContextShm *)e->debugCtxShm)->nom)) + 2) = 0;
|
||||
strncpy(((modContextShm *)e->debugCtxShm)->nom, "dbg", 3);
|
||||
strcpy(((modContextShm *)e->debugCtxShm)->nom + 3, Int64ToSz(e, getpid(), DYN_FALSE, 0));
|
||||
((modContextShm *)e->debugCtxShm)->taille = 16000;
|
||||
initShm(e, e->debugCtxShm);
|
||||
((modContextShm *)e->debugCtxShm)->message = &e->printf;
|
||||
*((ent64 *)(((modContextShm *)e->debugCtxShm)->desti)) = 0;
|
||||
*(((ent64 *)(((modContextShm *)e->debugCtxShm)->desti)) + 1) = 0;
|
||||
*(((ent64 *)(((modContextShm *)e->debugCtxShm)->desti)) + 2) = 0;
|
||||
//
|
||||
if( ! ((modContextShm *)e->debugCtxShm)->buffer)
|
||||
e->debug = 0; // erreur init : pas de debug
|
||||
}
|
||||
}
|
||||
|
||||
/* gestion du mode "debug" */
|
||||
void debug(env * e)
|
||||
{
|
||||
/* mode debug quand background
|
||||
sur le client qui debugge, utilisation du mod shm, en ciblant dbg<pid>, et donne son nom pour la reponse (prog w a faire, attente 1s apres signal + demander user retry)
|
||||
le background (<pid>) que l'on veut debugger utilise shm_lib.c en se nommant dbg<pid> : ouverture du shm a reception du signal (cf. var ctx_env_debug)
|
||||
*/
|
||||
int arret = FALSE;
|
||||
if(ctx_env_debug)
|
||||
{
|
||||
if(e->debug == 0) e->debug = 1; else e->debug = 0;
|
||||
/* si activation debug, mode 1 = pas a pas */
|
||||
ctx_env_debug = 0;
|
||||
// managing background process debug
|
||||
if(e->debug && e->demon)
|
||||
{
|
||||
initDebugCtxShm(e);
|
||||
}
|
||||
if( (! e->debug) && e->demon)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(e->debug != 0 && e->demon && ! e->debugCtxShm)
|
||||
{
|
||||
// demarrage process directement en mode debug
|
||||
initDebugCtxShm(e);
|
||||
}
|
||||
//
|
||||
if(e->debug == 0 || e->debugreglelex.mLg == 0 || ctx_env_kill) // pas de debug ou erreur a la lecture des regles lex de debug ou signal kill recu
|
||||
{
|
||||
if(e->demon && e->debugCtxShm && ((modContextShm *)e->debugCtxShm)->buffer)
|
||||
{
|
||||
dynSetLen(e, &e->printf, 0);
|
||||
dynPrintfSz(e, "%", NULL);
|
||||
writeShm(e, (modContextShm *)e->debugCtxShm); // envoi message au client, signifiant l'arret du mode debug
|
||||
}
|
||||
return;
|
||||
}
|
||||
/* gestion mode debug : si 1, mode pas a pas */
|
||||
if(e->debug == 1)
|
||||
arret = TRUE;
|
||||
@@ -155,73 +292,123 @@ void debug(env * e)
|
||||
if(!arret)
|
||||
return;
|
||||
/* */
|
||||
// attente message du client donnant son identifiant, si pas deja recu !
|
||||
if(e->demon && ((modContextShm *)e->debugCtxShm)->desti[0] == 0)
|
||||
{
|
||||
while( ! ctx_env_kill)
|
||||
{
|
||||
dynSetLen(e, &e->printf, 0);
|
||||
readShm(e, (modContextShm *)e->debugCtxShm);
|
||||
if(e->printf.mLg > 0)
|
||||
break;
|
||||
#ifdef WINLIB
|
||||
Sleep(500); // 1/2 sec.
|
||||
#else
|
||||
usleep(500000); // 1/2 sec.
|
||||
#endif
|
||||
}
|
||||
if(ctx_env_kill)
|
||||
return;
|
||||
*((ent64 *)(((modContextShm *)e->debugCtxShm)->desti)) = 0;
|
||||
*(((ent64 *)(((modContextShm *)e->debugCtxShm)->desti)) + 1) = 0;
|
||||
*(((ent64 *)(((modContextShm *)e->debugCtxShm)->desti)) + 2) = 0;
|
||||
if(e->printf.mLg < 24 && e->printf.mPtr[0] == '%')
|
||||
strncpy(((modContextShm *)e->debugCtxShm)->desti, e->printf.mPtr + 1, e->printf.mLg);
|
||||
}
|
||||
/* */
|
||||
var * v;
|
||||
Dynamic tmp, dyn;
|
||||
Dynamic tmp, file;
|
||||
dynInit(e, &tmp, 0);
|
||||
dynInit(e, &dyn, 0);
|
||||
dynInit(e, &file, 0);
|
||||
int prettyPrint = FALSE;
|
||||
ent16 tok, tok2; /* token lu par la macro ci-dessous "ntok" */
|
||||
long n; /* indice en cours dans les token (parametre de la macro "ntok") base 1 */
|
||||
//#define ntok(x) dynExtractSubFieldAsNumber(e, &e->debugvalex, 2, x, &e->debugcmd) // attention aux separateurs !
|
||||
#define ntok(x) dynFieldAsNumber(e, &e->debugvalex, 2, x, cFM, cVM)
|
||||
//
|
||||
long localLineNum = e->ligsrc; // pour la lecture du source a la bonne ligne
|
||||
//
|
||||
// afficher source et ligne en cours
|
||||
dynSetLen(e, &e->printf, 0);
|
||||
long srcFound = FALSE;
|
||||
e->nom64[0] = 0;
|
||||
e->nom64[1] = 0;
|
||||
e->nom64[2] = 0;
|
||||
strncpy(e->nom, "_srcdbg", 7);
|
||||
hashtable_do(e, HASH_READ, &e->g, e->nom, &v);
|
||||
hashtable_do(e, HASH_READ, &e->g, copy_nom(e, GUV_SRCDBG), &v);
|
||||
if(v != NULL)
|
||||
{
|
||||
// v = liste des noms/fichiers source vs numero de ligne
|
||||
GetFile(e, e->ligsrc, v, e->bin_indice, &tmp);
|
||||
e->nom64[0] = 0;
|
||||
e->nom64[1] = 0;
|
||||
e->nom64[2] = 0;
|
||||
strncpy(e->nom, "_wdir", 5);
|
||||
hashtable_do(e, HASH_READ, &e->g, e->nom, &v);
|
||||
if(tmp.mLg > 0 && v != NULL)
|
||||
GetFile(e, e->ligsrc, v, e->bin_indice, &file, &localLineNum);
|
||||
hashtable_do(e, HASH_READ, &e->g, copy_nom(e, GUV_WDIR), &v); // permet de savoir si wsrc gere lors de cette execution
|
||||
if(file.mLg > 0 && v != NULL)
|
||||
{
|
||||
//
|
||||
long nb,dup;
|
||||
dynSetLen(e, &dyn, 0);
|
||||
ScanDirectory(e, NULL, v, tmp.mPtr, &dyn, &nb, &dup);
|
||||
if(nb >= 1)
|
||||
if(dynRead(e, &e->tmp_dynamic, dyn.mPtr) == OK)
|
||||
if(dynRead(e, &e->tmp_dynamic, file.mPtr) == OK)
|
||||
{
|
||||
dynField(e, &e->tmp_dynamic, &tmp, localLineNum, DYN_NONE, cLF, DYN_NONE, 1);
|
||||
if(e->demon)
|
||||
{
|
||||
dynField(e, &e->tmp_dynamic, &e->int_dynamic, nb, DYN_NONE, cFM, DYN_NONE, 1); // on prend le permier fichier trouve
|
||||
dynField(e, &e->int_dynamic, &dyn, e->ligsrc, DYN_NONE, 10, DYN_NONE, 1);
|
||||
printf("%s:%lld: %s\n", tmp.mPtr, e->ligsrc, dyn.mPtr);
|
||||
srcFound = TRUE;
|
||||
dynSetAs(e, &e->printf, &file);
|
||||
dynConcatSz(e, &e->printf, ":", 1);
|
||||
dynConcatNumber(e, &e->printf, localLineNum);
|
||||
dynConcatSz(e, &e->printf, ": ", 2);
|
||||
dynConcat(e, &e->printf, &tmp);
|
||||
dynConcatSz(e, &e->printf, "\n", 1);
|
||||
}
|
||||
else
|
||||
printf("%s:%ld: %s\n", file.mPtr, localLineNum, tmp.mPtr);
|
||||
srcFound = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
for(;;)
|
||||
{
|
||||
// prompt
|
||||
if(srcFound)
|
||||
printf("W%d> ", VERSION);
|
||||
else
|
||||
printf("W%d:%lld> ", VERSION, e->ligsrc);
|
||||
e->debugcmd.mLg = 0;
|
||||
int c;
|
||||
char cmd[2];
|
||||
cmd[1] = 0;
|
||||
while((c = getchar()) != EOF && !ctx_env_kill) // EOF = -1 ; verifier signal ctx_env_kill
|
||||
if(c == 10)
|
||||
break;
|
||||
else
|
||||
if(e->demon)
|
||||
{
|
||||
dynPrintfInt64(e, "W" PRINTF_MARK, VERSION, 0);
|
||||
if( ! srcFound)
|
||||
dynPrintfInt64(e, ":" PRINTF_MARK, e->ligsrc, 0);
|
||||
dynPrintfSz(e, "> ", NULL);
|
||||
writeShm(e, (modContextShm *)e->debugCtxShm);
|
||||
//
|
||||
// attente de la commande
|
||||
while( ! ctx_env_kill)
|
||||
{
|
||||
cmd[0] = c;
|
||||
dynConcatSz(e, &e->debugcmd, cmd, 1);
|
||||
dynSetLen(e, &e->printf, 0);
|
||||
readShm(e, (modContextShm *)e->debugCtxShm);
|
||||
if(e->printf.mLg > 0)
|
||||
break;
|
||||
#ifdef WINLIB
|
||||
Sleep(500); // 1/2 sec.
|
||||
#else
|
||||
usleep(500000); // 1/2 sec.
|
||||
#endif
|
||||
}
|
||||
//printf("\n");
|
||||
dynSetAs(e, &e->debugcmd, &e->printf);
|
||||
dynSetLen(e, &e->printf, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// prompt
|
||||
if(srcFound)
|
||||
printf("W%d> ", VERSION);
|
||||
else
|
||||
printf("W%d:%lld> ", VERSION, e->ligsrc);
|
||||
dynSetLen(e, &e->debugcmd, 0);
|
||||
int c;
|
||||
char cmd[2];
|
||||
cmd[1] = 0;
|
||||
while((c = getchar()) != EOF && !ctx_env_kill) // EOF = -1 ; verifier signal ctx_env_kill
|
||||
if(c == cLF)
|
||||
break;
|
||||
else
|
||||
{
|
||||
cmd[0] = c;
|
||||
dynConcatSz(e, &e->debugcmd, cmd, 1);
|
||||
}
|
||||
}
|
||||
//
|
||||
if(ctx_env_kill)
|
||||
{
|
||||
dynFree(e, &tmp);
|
||||
dynFree(e, &dyn);
|
||||
dynFree(e, &file);
|
||||
return;
|
||||
}
|
||||
//
|
||||
@@ -231,20 +418,30 @@ void debug(env * e)
|
||||
//
|
||||
if(e->debugvalex.mLg == 0)
|
||||
continue; // empty line
|
||||
for(n = 1;;n++)
|
||||
{
|
||||
tok = ntok(n);
|
||||
if(tok == r.blanc)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
n = 0;
|
||||
while((tok = ntok(++n)) == r.blanc) ;
|
||||
if(tok == 0)
|
||||
continue; // blank line
|
||||
/* */
|
||||
if(tok == r.aide)
|
||||
{
|
||||
printf("Debug command list :\n"
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Debug command list :\n"
|
||||
"? affiche les commandes de debug\n"
|
||||
"s S infos en cours sur le programme\n"
|
||||
"q Q continuer et arreter le mode debug 0\n"
|
||||
"n N continuer en mode debug pas a pas 1\n"
|
||||
"c C continuer en mode debug 2 arret aux points d'arret uniquement\n"
|
||||
"v V :ident voir le contenu de la variable <ident>\n"
|
||||
"vg VG voir le contenu de la hash globale 'g'\n"
|
||||
"vg VG :ident voir le contenu de la var <ident> a l'interieur de la hash globale 'g'\n"
|
||||
"vl VL voir le contenu de la hash locale courante\n"
|
||||
"b B liste des breakpoints\n"
|
||||
"b B +/- num ajouter ou supprimer un breakpoint ; si pas de nombre, à l'emplacement en cours, sinon numero de ligne source <num>\n"
|
||||
"a A + afficher les infos assembleur (idem trace)\n"
|
||||
"a A - supprimer les infos assembleur\n", NULL);
|
||||
else
|
||||
printf("Debug command list :\n"
|
||||
"? affiche les commandes de debug\n"
|
||||
"s S infos en cours sur le programme\n"
|
||||
"q Q continuer et arreter le mode debug 0\n"
|
||||
@@ -262,7 +459,10 @@ void debug(env * e)
|
||||
}
|
||||
if(tok != r.commande)
|
||||
{
|
||||
printf("Unknown command\n");
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Unknown command\n", NULL);
|
||||
else
|
||||
printf("Unknown command\n");
|
||||
continue;
|
||||
}
|
||||
/* trt cmd ; e->debugcmd sert de variable tmp ici */
|
||||
@@ -271,14 +471,7 @@ void debug(env * e)
|
||||
if(dynCompare(e, &e->debugcmd, CMP_EQ, "vg", 2) || dynCompare(e, &e->debugcmd, CMP_EQ, "VG", 2))
|
||||
{
|
||||
/* voir le contenu d'une variable */
|
||||
for(n++;;n++)
|
||||
{
|
||||
tok = ntok(n);
|
||||
if(tok == r.blanc)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
while((tok = ntok(++n)) == r.blanc) ;
|
||||
if(tok != r.ident)
|
||||
hashtable_printdebug(e, &e->g, 1);
|
||||
else
|
||||
@@ -286,7 +479,12 @@ void debug(env * e)
|
||||
dynField(e, &e->debugvalex, &tmp, 1, n, cFM, cVM, 1);
|
||||
dynIconv(e, &tmp, &e->debugcmd, "X");
|
||||
if(e->debugcmd.mLg < 2 || e->debugcmd.mLg > 24)
|
||||
printf("Incorrect var name\n");
|
||||
{
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Incorrect var name\n", NULL);
|
||||
else
|
||||
printf("Incorrect var name\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
e->nom64[0] = 0;
|
||||
@@ -298,12 +496,15 @@ void debug(env * e)
|
||||
hashtable_do(e, HASH_READ, &e->g, e->nom, &v);
|
||||
if(v != NULL)
|
||||
{
|
||||
print_var(e, v, &tmp);
|
||||
if(strncmp(e->nom, "_binaddr", 8) == 0)
|
||||
hex3(v->mPtr, v->mLg);
|
||||
print_var(e, v, &tmp, prettyPrint);
|
||||
}
|
||||
else
|
||||
printf("Unknown global var\n");
|
||||
{
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Unknown global var\n", NULL);
|
||||
else
|
||||
printf("Unknown global var\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
@@ -313,104 +514,135 @@ void debug(env * e)
|
||||
if(e->local)
|
||||
hashtable_printdebug(e, e->local, 1);
|
||||
else
|
||||
printf("No local hashtable.\n");
|
||||
{
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "No local hashtable.\n", NULL);
|
||||
else
|
||||
printf("No local hashtable.\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(dynCompare(e, &e->debugcmd, CMP_EQ, "s", 1) || dynCompare(e, &e->debugcmd, CMP_EQ, "S", 1))
|
||||
{
|
||||
printf("Statut du programme en cours, pid %lld, pcode version %d, w-exec version %d (%s) :\n", e->pid, e->version, VERSION, (e->endianess == W_BIG_ENDIAN ? "big-endian" : "little-endian"));
|
||||
e->nom64[0] = 0; e->nom64[1] = 0; e->nom64[2] = 0;
|
||||
strncpy(e->nom, "_file", 5);
|
||||
hashtable_do(e, HASH_READ, &e->g, e->nom, &v);
|
||||
if(v != NULL)
|
||||
if(e->demon)
|
||||
{
|
||||
dynLet(e, &dyn, v->mPtr, DYN_LGNONE);
|
||||
dynConvert(e, &dyn, sFM, "/");
|
||||
dynPrintfInt64(e, "Statut du programme en cours, pid " PRINTF_MARK ", pcode version ", e->pid, 0);
|
||||
dynPrintfInt64(e, PRINTF_MARK ", w-exec version ", e->version, 0);
|
||||
dynPrintfInt64(e, PRINTF_MARK " (", VERSION, 0);
|
||||
dynPrintfSz(e, PRINTF_MARK ") :\n", (e->endianess == W_BIG_ENDIAN ? "big-endian" : "little-endian"));
|
||||
}
|
||||
else
|
||||
dynSetLen(e, &dyn, 0);
|
||||
printf("Statut du programme en cours, pid %lld, pcode version %d, w-exec version %d (%s) :\n", e->pid, e->version, VERSION, (e->endianess == W_BIG_ENDIAN ? "big-endian" : "little-endian"));
|
||||
//
|
||||
if(e->except_ex > 0 && e->except_ex <= EXNB)
|
||||
dynLet(e, &e->debugcmd, strerr[e->except_ex - 1], DYN_LGNONE);
|
||||
else
|
||||
dynLet(e, &e->debugcmd, e->except_ex == 0 ? "" : "Unknown", DYN_LGNONE);
|
||||
printf("Source en cours => %s:%lld\n", dyn.mPtr, e->ligsrc);
|
||||
printf("PCode en cours => %p - %p\n", e->debut, e->fin);
|
||||
printf("Part => %d\n", e->part);
|
||||
printf("Precision => %lld\n", e->precision / NUM_FACTEUR);
|
||||
printf("Exception => %lld %s\n", e->except_ex, e->debugcmd.mPtr);
|
||||
printf("Occupation memoire => %lld Ko, %lld blocs\n", e->mem_size/1024, e->mem_numb);
|
||||
if(e->demon)
|
||||
{
|
||||
dynPrintfSz(e, "Source en cours => " PRINTF_MARK ":", file.mPtr);
|
||||
dynPrintfInt64(e, PRINTF_MARK "\nPCode en cours => ", localLineNum, 0);
|
||||
dynPrintfHex(e, PRINTF_MARK " - ", (ent64)e->debut, 0);
|
||||
dynPrintfHex(e, PRINTF_MARK " (", (ent64)e->fin, 0);
|
||||
dynPrintfInt64(e, PRINTF_MARK ")\nPart => ", e->fin - e->debut + 1, 0);
|
||||
dynPrintfInt64(e, PRINTF_MARK "\nPrecision => ", e->part, 0);
|
||||
dynPrintfInt64(e, PRINTF_MARK "\nException => ", e->precision / NUM_FACTEUR, 0);
|
||||
dynPrintfInt64(e, PRINTF_MARK " ", e->except_ex, 0);
|
||||
dynPrintfSz(e, PRINTF_MARK "\nOccupation memoire => ", e->debugcmd.mPtr);
|
||||
dynPrintfInt64(e, PRINTF_MARK " Ko, ", e->mem_size/1024, 0);
|
||||
dynPrintfInt64(e, PRINTF_MARK " blocs\n", e->mem_numb, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Source en cours => %s:%ld\n", file.mPtr, localLineNum);
|
||||
printf("PCode en cours => %p - %p (%d)\n", e->debut, e->fin, (int)(e->fin - e->debut + 1));
|
||||
printf("Part => %d\n", e->part);
|
||||
printf("Precision => %lld\n", e->precision / NUM_FACTEUR);
|
||||
printf("Exception => %lld %s\n", e->except_ex, e->debugcmd.mPtr);
|
||||
printf("Occupation memoire => %lld Ko, %lld blocs\n", e->mem_size/1024, e->mem_numb);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(dynCompare(e, &e->debugcmd, CMP_EQ, "q", 1) || dynCompare(e, &e->debugcmd, CMP_EQ, "Q", 1))
|
||||
{
|
||||
if(e->demon)
|
||||
{
|
||||
dynLet(e, &e->printf, "%", 1); // envoi commande fin debugging au client
|
||||
writeShm(e, (modContextShm *)e->debugCtxShm);
|
||||
}
|
||||
e->debug = 0;
|
||||
dynFree(e, &tmp);
|
||||
dynFree(e, &dyn);
|
||||
dynFree(e, &file);
|
||||
return;
|
||||
}
|
||||
if(dynCompare(e, &e->debugcmd, CMP_EQ, "n", 1) || dynCompare(e, &e->debugcmd, CMP_EQ, "N", 1))
|
||||
{
|
||||
e->debug = 1;
|
||||
dynFree(e, &tmp);
|
||||
dynFree(e, &dyn);
|
||||
dynFree(e, &file);
|
||||
return;
|
||||
}
|
||||
if(dynCompare(e, &e->debugcmd, CMP_EQ, "c", 1) || dynCompare(e, &e->debugcmd, CMP_EQ, "C", 1))
|
||||
{
|
||||
e->debug = 2;
|
||||
dynFree(e, &tmp);
|
||||
dynFree(e, &dyn);
|
||||
dynFree(e, &file);
|
||||
return;
|
||||
}
|
||||
if(dynCompare(e, &e->debugcmd, CMP_EQ, "a", 1) || dynCompare(e, &e->debugcmd, CMP_EQ, "A", 1))
|
||||
{
|
||||
/* gestion des breakpoints */
|
||||
for(n++;;n++)
|
||||
{
|
||||
tok = ntok(n);
|
||||
if(tok == r.blanc)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
/* gestion des traces assembleur */
|
||||
while((tok = ntok(++n)) == r.blanc) ;
|
||||
if(tok == r.ajouter)
|
||||
{
|
||||
e->trace = 1;
|
||||
printf("Trace ON\n");
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Trace ON\n", NULL);
|
||||
else
|
||||
printf("Trace ON\n");
|
||||
}
|
||||
else if(tok == r.supprimer)
|
||||
{
|
||||
e->trace = 0;
|
||||
printf("Trace OFF\n");
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Trace OFF\n", NULL);
|
||||
else
|
||||
printf("Trace OFF\n");
|
||||
}
|
||||
else
|
||||
printf("Syntax error in command\n");
|
||||
{
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Syntax error in command\n", NULL);
|
||||
else
|
||||
printf("Syntax error in command\n");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if(dynCompare(e, &e->debugcmd, CMP_EQ, "b", 1) || dynCompare(e, &e->debugcmd, CMP_EQ, "B", 1))
|
||||
{
|
||||
/* gestion des breakpoints */
|
||||
for(n++;;n++)
|
||||
{
|
||||
tok = ntok(n);
|
||||
if(tok == r.blanc)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
while((tok = ntok(++n)) == r.blanc) ;
|
||||
if(tok == 0)
|
||||
{
|
||||
/* voir les breakpoints */
|
||||
dynLet(e, &tmp, e->debugbrkpoint.mPtr, e->debugbrkpoint.mLg);
|
||||
dynReplace(e, &tmp, cFM, ',');
|
||||
printf("brkpoints: %s\n", tmp.mPtr);
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "brkpoints: " PRINTF_MARK "\n", tmp.mPtr);
|
||||
else
|
||||
printf("brkpoints: %s\n", tmp.mPtr);
|
||||
}
|
||||
else if(tok == r.ajouter || tok == r.supprimer)
|
||||
{
|
||||
n++;
|
||||
tok2 = ntok(n);
|
||||
if(tok2 != r.nombre)
|
||||
printf("Syntax error in command\n");
|
||||
{
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Syntax error in command\n", NULL);
|
||||
else
|
||||
printf("Syntax error in command\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
dynField(e, &e->debugvalex, &tmp, 1, n, cFM, cVM, 1);
|
||||
@@ -420,17 +652,28 @@ void debug(env * e)
|
||||
if(pos < 0 && tok == r.ajouter)
|
||||
{
|
||||
dynInsSz(e, &e->debugbrkpoint, abs(pos), DYN_NONE, Int64ToSz(e, numLigne, FALSE, 9), DYN_LGNONE, cFM, DYN_NONE);
|
||||
printf("Brkpoint added in line %ld\n", numLigne);
|
||||
if(e->demon)
|
||||
dynPrintfInt64(e, "Breakpoint added in line " PRINTF_MARK "\n", numLigne, 0);
|
||||
else
|
||||
printf("Breakpoint added in line %ld\n", numLigne);
|
||||
}
|
||||
if(pos > 0 && tok == r.supprimer)
|
||||
{
|
||||
dynDel(e, &e->debugbrkpoint, pos, DYN_NONE, cFM, DYN_NONE, 1);
|
||||
printf("Brkpoint in line %ld deleted\n", numLigne);
|
||||
if(e->demon)
|
||||
dynPrintfInt64(e, "Breakpoint in line " PRINTF_MARK " deleted\n", numLigne, 0);
|
||||
else
|
||||
printf("Breakpoint in line %ld deleted\n", numLigne);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("Syntax error in command\n");
|
||||
{
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Syntax error in command\n", NULL);
|
||||
else
|
||||
printf("Syntax error in command\n");
|
||||
}
|
||||
//
|
||||
continue;
|
||||
}
|
||||
@@ -438,22 +681,25 @@ void debug(env * e)
|
||||
if(dynCompare(e, &e->debugcmd, CMP_EQ, "v", 1) || dynCompare(e, &e->debugcmd, CMP_EQ, "V", 1))
|
||||
{
|
||||
/* voir le contenu d'une variable */
|
||||
for(n++;;n++)
|
||||
{
|
||||
tok = ntok(n);
|
||||
if(tok == r.blanc)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
while((tok = ntok(++n)) == r.blanc) ;
|
||||
if(tok != r.ident)
|
||||
printf("Syntax error in command\n");
|
||||
{
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Syntax error in command\n", NULL);
|
||||
else
|
||||
printf("Syntax error in command\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
dynField(e, &e->debugvalex, &tmp, 1, n, cFM, cVM, 1);
|
||||
dynIconv(e, &tmp, &e->debugcmd, "X");
|
||||
if(e->debugcmd.mLg < 2 || e->debugcmd.mLg > 24)
|
||||
printf("Incorrect var name\n");
|
||||
{
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Incorrect var name\n", NULL);
|
||||
else
|
||||
printf("Incorrect var name\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
e->nom64[0] = 0;
|
||||
@@ -473,58 +719,37 @@ void debug(env * e)
|
||||
hashtable_do(e, HASH_READ, &e->g, e->nom, &v);
|
||||
}
|
||||
if(v != NULL)
|
||||
{
|
||||
//var_printdebug(e, v, e->debugcmd.mPtr + 1);
|
||||
// renvoyer la valeur lue, selon le type de la var
|
||||
if(v->type == VAR_PARAM)
|
||||
v = (var *)v->ptr; /* travailler avec la var pointee */
|
||||
switch(v->type)
|
||||
{
|
||||
// "0XNSPDHOB"
|
||||
case VAR_NULL:
|
||||
printf("Var %c\n",e->var_car[v->type]); // X
|
||||
break;
|
||||
case VAR_NUMBER:
|
||||
long lg;
|
||||
NumberToSz(e, v->num, tmp.mPtr, &lg);
|
||||
printf("Var %c : %s\n",e->var_car[v->type], tmp.mPtr); // N
|
||||
break;
|
||||
case VAR_DYNAMIC:
|
||||
if(strncmp(e->nom, "_stack", 6) == 0)
|
||||
printf("Var %c(%lld) : %s (ret: %p)\n",e->var_car[v->type], v->mLg, v->mPtr, *(pointeur *)(v->mPtr)); // D
|
||||
else
|
||||
printf("Var %c(%lld) : %s\n",e->var_car[v->type], v->mLg, v->mPtr); // D
|
||||
break;
|
||||
case VAR_BUFFER:
|
||||
printf("Var %c\n",e->var_car[v->type]); // B
|
||||
break;
|
||||
case VAR_HASHTABLE:
|
||||
printf("Var %c\n",e->var_car[v->type]); // H
|
||||
hashtable_printdebug(e, v, 1);
|
||||
break;
|
||||
case VAR_OBJECT:
|
||||
printf("Var %c\n",e->var_car[v->type]); // O
|
||||
hashtable_printdebug(e, v, 1);
|
||||
break;
|
||||
case VAR_SUBROUTINE:
|
||||
printf("Var %c : %p (-> %p)\n",e->var_car[v->type], v, v->ptr); // S
|
||||
break;
|
||||
case VAR_PARAM:
|
||||
printf("Var %c\n",e->var_car[v->type]); // P : mais ne peut pas arriver ici
|
||||
break;
|
||||
}
|
||||
}
|
||||
print_var(e, v, &tmp, prettyPrint);
|
||||
else
|
||||
printf("Unknown var\n");
|
||||
{
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Unknown var\n", NULL);
|
||||
else
|
||||
printf("Unknown var\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* */
|
||||
printf("Unknown command\n");
|
||||
if(dynCompare(e, &e->debugcmd, CMP_EQ, "pp", 2) || dynCompare(e, &e->debugcmd, CMP_EQ, "PP", 2))
|
||||
{
|
||||
// toggle pretty print switch
|
||||
prettyPrint = ! prettyPrint;
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Pretty print " PRINTF_MARK " (dynamic)\n", prettyPrint ? "ON" : "OFF");
|
||||
else
|
||||
printf("Pretty print %s (dynamic)\n", prettyPrint ? "ON" : "OFF");
|
||||
continue;
|
||||
}
|
||||
/* */
|
||||
if(e->demon)
|
||||
dynPrintfSz(e, "Unknown command\n", NULL);
|
||||
else
|
||||
printf("Unknown command\n");
|
||||
}
|
||||
dynFree(e, &tmp);
|
||||
dynFree(e, &dyn);
|
||||
dynFree(e, &file);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -578,3 +803,4 @@ r.ident = rg(e, regles, "ident", tmp);
|
||||
r.reste = rg(e, regles, "reste", tmp);
|
||||
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
;
|
||||
; for background w process debugging
|
||||
; using shm_lib on buffer "dbg<pid>" for the debugged process
|
||||
; Usage: lw debug <pid2debug>
|
||||
;
|
||||
begin wdebug
|
||||
declare idProc, msg, pid, cmd, ret, capt, again, delay, debugging
|
||||
declare OK, ERROR
|
||||
let debugging = @false
|
||||
let OK = 0
|
||||
let ERROR = neg(1)
|
||||
;
|
||||
sub WriteProcess(id, message, cr)
|
||||
invoke shm&set(id, message)
|
||||
let cr = OK
|
||||
except
|
||||
let cr = ERROR
|
||||
catch
|
||||
endsub
|
||||
;
|
||||
sub ReadProcess(message, cr)
|
||||
invoke shm&get(message)
|
||||
let cr = OK
|
||||
except
|
||||
let cr = ERROR
|
||||
catch
|
||||
endsub
|
||||
; ********************************************************
|
||||
;
|
||||
let pid = field(@arg, @currfm, 2)
|
||||
if pid = '' or type(pid) # @varnumber then
|
||||
let msg = 'Incorrect pid number (':pid:'), abort'
|
||||
echonl msg
|
||||
return
|
||||
endif
|
||||
;
|
||||
let idProc = 'dbg':pid
|
||||
let msg = 'Start debugging process ':pid
|
||||
echonl msg
|
||||
;
|
||||
loop
|
||||
let msg = 'Sending SIGUSR1 signal and wait 1 second'
|
||||
echonl msg
|
||||
let capt = ''
|
||||
let ret = 0
|
||||
let cmd = 'kill -10 ':pid
|
||||
invoke system&execute(cmd, ret, capt)
|
||||
breakon ret # OK
|
||||
; now waiting for shm to init from signaled process
|
||||
let delay = 1
|
||||
invoke system&sleep(delay)
|
||||
;
|
||||
let msg = '%':@prog
|
||||
do WriteProcess(idProc, msg, ret)
|
||||
breakon ret = OK
|
||||
; retry ?
|
||||
let msg = 'Process ':pid:" don't respond to debug start message (":msg:"), try again (Y/N) ? "
|
||||
echo msg
|
||||
input again
|
||||
breakon again # 'y' and again # 'Y'
|
||||
endloop
|
||||
returnon ret # OK
|
||||
;
|
||||
; ok, we can debug background process now
|
||||
; 1. read prompt
|
||||
; 2. get command from user
|
||||
; 3. send command
|
||||
; 4. repeat from step 1
|
||||
let msg = "Ready for debuging... ('q' to end session)"
|
||||
echonl msg
|
||||
let delay = 0.1
|
||||
let debugging = @true
|
||||
loop
|
||||
do ReadProcess(msg, ret)
|
||||
breakon ret # OK or msg = '%'
|
||||
if msg # '' then
|
||||
echo msg
|
||||
loop
|
||||
let cmd = ''
|
||||
input cmd
|
||||
breakon cmd # ''
|
||||
endloop
|
||||
;
|
||||
do WriteProcess(idProc, cmd, ret)
|
||||
breakon ret # OK
|
||||
else
|
||||
invoke system&sleep(delay)
|
||||
endif
|
||||
endloop
|
||||
let msg = "End of debugging"
|
||||
echonl msg
|
||||
;
|
||||
except
|
||||
if debugging then
|
||||
let cmd = '%'
|
||||
do WriteProcess(idProc, cmd, ret)
|
||||
endif
|
||||
let msg = 'Exception ':@except
|
||||
echonl msg
|
||||
end
|
||||
@@ -28,6 +28,15 @@
|
||||
#include "langage.h"
|
||||
#include "dynamic.h"
|
||||
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
// table conversion WIN1252 vers UTF-8 (maxi 4 octets par cars, de 0x80 a 0xFF)
|
||||
char TbleW1252ToU8[128 * 4] = { 0xE2,0x82,0xAC,0, 0,0,0,0, 0xE2,0x80,0x9A,0, 0xC6,0x92,0,0, 0xE2,0x80,0x9E,0, 0xE2,0x80,0xA6,0, 0xE2,0x80,0xA0,0, 0xE2,0x80,0xA1,0,
|
||||
0xCB,0x86,0,0, 0xE2,0x80,0xB0,0, 0xC5,0xA0,0,0, 0xE2,0x80,0xB9,0, 0xC5,0x92,0,0, 0,0,0,0, 0xC5,0xBD,0,0, 0,0,0,0,
|
||||
@@ -63,40 +72,39 @@ char table885915[128 * 4] = { 0xC2,0x80,0,0, 0xC2,0x81,0,0, 0xC2,0x82,0,0, 0xC2,
|
||||
0xC3,0xB0,0,0, 0xC3,0xB1,0,0, 0xC3,0xB2,0,0, 0xC3,0xB3,0,0, 0xC3,0xB4,0,0, 0xC3,0xB5,0,0, 0xC3,0xB6,0,0, 0xC3,0xB7,0,0, /* B0-B7 */
|
||||
0xC3,0xB8,0,0, 0xC3,0xB9,0,0, 0xC3,0xBA,0,0, 0xC3,0xBB,0,0, 0xC3,0xBC,0,0, 0xC3,0xBD,0,0, 0xC3,0xBE,0,0, 0xC3,0xBF,0,0 };
|
||||
|
||||
void NumberToSz(env * e, ent64s valeur, char * resultat, long * lg)
|
||||
WAPIDECL char * NumberToSz(env * e, ent64s valeur, char * resultat, ent64s * lg)
|
||||
{
|
||||
char res[20]; // en 64 bits, maxi 19 chiffres + \0 (en signe mais sans le signe ici)
|
||||
long pos = 19;
|
||||
static char res[22]; /* lg max signe en 64 bits : signe + 19 chiffres + decimale + \0 */
|
||||
ent64s pos = 21;
|
||||
char * p;
|
||||
//
|
||||
*lg = 0;
|
||||
int signe = DYN_FALSE;
|
||||
if(valeur < 0)
|
||||
{
|
||||
valeur = -valeur;
|
||||
*resultat++ = '-';
|
||||
*lg = 1;
|
||||
signe = DYN_TRUE;
|
||||
}
|
||||
res[pos--] = 0;
|
||||
// traitement des 5 decimales + 1er chiffre decimal hors boucle (soit 2 boucles)
|
||||
p = e->tbl_1000 + 2 + (valeur % 1000) * 3;
|
||||
valeur /= 1000;
|
||||
if(pos < 18 || *p != 48)
|
||||
if(pos < 20 || *p != 48)
|
||||
res[pos--] = *p;
|
||||
p--;
|
||||
if(pos < 18 || *p != 48)
|
||||
if(pos < 20 || *p != 48)
|
||||
res[pos--] = *p;
|
||||
p--;
|
||||
if(pos < 18 || *p != 48)
|
||||
if(pos < 20 || *p != 48)
|
||||
res[pos--] = *p;
|
||||
p = e->tbl_1000 + 2 + (valeur % 1000) * 3;
|
||||
valeur /= 1000;
|
||||
if(pos < 18 || *p != 48)
|
||||
if(pos < 20 || *p != 48)
|
||||
res[pos--] = *p;
|
||||
p--;
|
||||
if(pos < 18 || *p != 48)
|
||||
if(pos < 20 || *p != 48)
|
||||
res[pos--] = *p;
|
||||
p--;
|
||||
if(pos < 18)
|
||||
if(pos < 20)
|
||||
res[pos--] = '.';
|
||||
res[pos--] = *p;
|
||||
// maxi 4 boucles pour traiter les eventuels autres chiffres (idem Int64ToSz)
|
||||
@@ -121,15 +129,21 @@ void NumberToSz(env * e, ent64s valeur, char * resultat, long * lg)
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
pos++;
|
||||
// copie chaine + maj longueur
|
||||
strcpy(resultat, res + pos);
|
||||
*lg += 19 - pos;
|
||||
if(signe)
|
||||
res[pos] = '-';
|
||||
else
|
||||
pos++;
|
||||
/* */
|
||||
if(lg)
|
||||
*lg = 21 - pos;
|
||||
if(resultat)
|
||||
strncpy(resultat, res + pos, 21 - pos + 1); // pour copier le zero de fin
|
||||
return res + pos;
|
||||
}
|
||||
|
||||
char * Int64ToSz(env * e, ent64s valeur, long signe, long leftPad)
|
||||
WAPIDECL char * Int64ToSz(env * e, ent64s valeur, long signe, long leftPad)
|
||||
{
|
||||
static char resultat[21] = {0}; /* lg max signe en 64 bits : signe + 19 chiffres + \0 */
|
||||
static char resultat[21]; /* lg max signe en 64 bits : signe + 19 chiffres + \0 */
|
||||
long pos = 20;
|
||||
char * p;
|
||||
/* signe = TRUE si conversion en signee ; leftPad = 0 pas de padding de zeros a gauche, sinon donne la longueur max, zeros compris, max 10 hors signe */
|
||||
@@ -178,7 +192,7 @@ char * Int64ToSz(env * e, ent64s valeur, long signe, long leftPad)
|
||||
return resultat + pos;
|
||||
}
|
||||
|
||||
char * Int32ToSz(ent32s valeur, long signe, long leftPad)
|
||||
WAPIDECL char * Int32ToSz(ent32s valeur, long signe, long leftPad)
|
||||
{
|
||||
// pk pas faire similaire a int64sz ? a cause de "env * e" ?
|
||||
static char resultat[12]; /* lg max signe en 32 bits : signe + 10 chiffres + \0 */
|
||||
@@ -223,7 +237,7 @@ char * Int32ToSz(ent32s valeur, long signe, long leftPad)
|
||||
return resultat + pos;
|
||||
}
|
||||
|
||||
long dynInit(env * e, Dynamic * this, long lgmax)
|
||||
WAPIDECL long dynInit(env * e, Dynamic * this, long lgmax)
|
||||
{
|
||||
long cr = DYN_OK;
|
||||
this->mLg = 0;
|
||||
@@ -238,11 +252,11 @@ long dynInit(env * e, Dynamic * this, long lgmax)
|
||||
this->mPtr[0] = 0;
|
||||
else
|
||||
cr = DYN_ERR;
|
||||
this->codePage = CP_DEFAULT;
|
||||
this->codePage = WCP_DEFAULT;
|
||||
return cr;
|
||||
}
|
||||
|
||||
long dynCopy(env * e, Dynamic * this, Dynamic * aCopier)
|
||||
WAPIDECL long dynCopy(env * e, Dynamic * this, Dynamic * aCopier)
|
||||
{
|
||||
long cr = DYN_OK;
|
||||
this->mLg = aCopier->mLg;
|
||||
@@ -262,14 +276,14 @@ long dynCopy(env * e, Dynamic * this, Dynamic * aCopier)
|
||||
return cr;
|
||||
}
|
||||
|
||||
void dynFree(env * e, Dynamic * this)
|
||||
WAPIDECL void dynFree(env * e, Dynamic * this)
|
||||
{
|
||||
/* liberer la chaine */
|
||||
if(this->mPtr != NULL)
|
||||
memfree(e, this->mPtr);
|
||||
}
|
||||
|
||||
long dynCtrl(env * e, Dynamic * this, long lg, long copier)
|
||||
WAPIDECL long dynCtrl(env * e, Dynamic * this, long lg, long copier)
|
||||
{
|
||||
char * tmp = NULL;
|
||||
long taille;
|
||||
@@ -307,7 +321,7 @@ long dynCtrl(env * e, Dynamic * this, long lg, long copier)
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
void dynSetLen(env * e, Dynamic * this, long lg)
|
||||
WAPIDECL void dynSetLen(env * e, Dynamic * this, long lg)
|
||||
{
|
||||
/* UTF8 lg physique ici */
|
||||
if(lg < this->mLgmax && this->mPtr != NULL)
|
||||
@@ -317,7 +331,7 @@ void dynSetLen(env * e, Dynamic * this, long lg)
|
||||
}
|
||||
}
|
||||
|
||||
long dynLengthUtf8(const char * p, long lg, int separator)
|
||||
WAPIDECL long dynLengthUtf8(const char * p, long lg, int separator)
|
||||
{
|
||||
static octet
|
||||
tableCarNb[256] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
@@ -399,7 +413,7 @@ long dynLengthUtf8(const char * p, long lg, int separator)
|
||||
return len;
|
||||
}
|
||||
|
||||
long dynNextUtf8(char ** p, long lg, long * pos, char * carU8, int separator)
|
||||
WAPIDECL long dynNextUtf8(char ** p, long lg, long * pos, char * carU8, int separator)
|
||||
{
|
||||
static octet
|
||||
tableCarNb[256] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
@@ -489,7 +503,7 @@ long dynNextUtf8(char ** p, long lg, long * pos, char * carU8, int separator)
|
||||
return len;
|
||||
}
|
||||
|
||||
long Win1252ToUTF8(env * e, Dynamic * valeur, Dynamic * resultat)
|
||||
WAPIDECL long Win1252ToUTF8(env * e, Dynamic * valeur, Dynamic * resultat)
|
||||
{
|
||||
// renvoi la longueur "utf8" de la chaine apres conversion
|
||||
long i, utf, pos, len = 0;
|
||||
@@ -524,7 +538,7 @@ long Win1252ToUTF8(env * e, Dynamic * valeur, Dynamic * resultat)
|
||||
return len;
|
||||
}
|
||||
|
||||
long UTF8ToWin1252(env * e, Dynamic * valeur, Dynamic * resultat)
|
||||
WAPIDECL long UTF8ToWin1252(env * e, Dynamic * valeur, Dynamic * resultat)
|
||||
{
|
||||
char * p = valeur->mPtr;
|
||||
long pos = 0, len, lg = valeur->mLg;
|
||||
@@ -556,7 +570,7 @@ long UTF8ToWin1252(env * e, Dynamic * valeur, Dynamic * resultat)
|
||||
return DYN_OK; // len = 0 => fin de chaine
|
||||
}
|
||||
|
||||
void NumberToBin(env * e, ent64s valeur, pointeur resultat, int nbOctet, int signe, int endianess)
|
||||
WAPIDECL void NumberToBin(env * e, ent64s valeur, pointeur resultat, int nbOctet, int signe, int endianess)
|
||||
{
|
||||
// sur 1 a 8 octets max
|
||||
if(endianess == W_DEFAULT_ENDIAN)
|
||||
@@ -602,7 +616,7 @@ void NumberToBin(env * e, ent64s valeur, pointeur resultat, int nbOctet, int sig
|
||||
}
|
||||
}
|
||||
|
||||
void BinToNumber(env * e, pointeur valeur, ent64s * resultat, int nbOctet, int signe, int endianess)
|
||||
WAPIDECL void BinToNumber(env * e, pointeur valeur, ent64s * resultat, int nbOctet, int signe, int endianess)
|
||||
{
|
||||
// sur 1 a 8 octets max
|
||||
if(endianess == W_DEFAULT_ENDIAN)
|
||||
@@ -649,23 +663,23 @@ void BinToNumber(env * e, pointeur valeur, ent64s * resultat, int nbOctet, int s
|
||||
}
|
||||
}
|
||||
|
||||
long dynSetAsNumber(env * e, Dynamic * this, ent64s valeur)
|
||||
WAPIDECL long dynSetAsNumber(env * e, Dynamic * this, ent64s valeur)
|
||||
{
|
||||
return dynLet(e, this, Int64ToSz(e, valeur, DYN_TRUE, 0), DYN_LGNONE);
|
||||
}
|
||||
|
||||
long dynSetAs(env * e, Dynamic * this, Dynamic * valeur)
|
||||
WAPIDECL long dynSetAs(env * e, Dynamic * this, Dynamic * valeur)
|
||||
{
|
||||
return dynLet(e, this, valeur->mPtr, valeur->mLg);
|
||||
}
|
||||
|
||||
long dynSetAsSz(env * e, Dynamic * this, char * chaine)
|
||||
WAPIDECL long dynSetAsSz(env * e, Dynamic * this, char * chaine)
|
||||
{
|
||||
|
||||
return dynLet(e, this, chaine, DYN_LGNONE);
|
||||
}
|
||||
|
||||
long dynLet(env * e, Dynamic * this, char * chaine, long lgChaine)
|
||||
WAPIDECL long dynLet(env * e, Dynamic * this, char * chaine, long lgChaine)
|
||||
{
|
||||
/* UTF8 : lg physique ici */
|
||||
if(this->mPtr == NULL)
|
||||
@@ -691,7 +705,7 @@ long dynLet(env * e, Dynamic * this, char * chaine, long lgChaine)
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynCompare(env * e, Dynamic * this, ent64 comparaison, char * chaine, long lgChaine)
|
||||
WAPIDECL long dynCompare(env * e, Dynamic * this, ent64 comparaison, char * chaine, long lgChaine)
|
||||
{
|
||||
// UTF8 : lg physique ici
|
||||
int cmp; // = 0: egal, < 0: this < chaine, > 0: this > chaine
|
||||
@@ -754,7 +768,7 @@ long dynCompare(env * e, Dynamic * this, ent64 comparaison, char * chaine, long
|
||||
return FALSE; // code condition inconnu
|
||||
}
|
||||
|
||||
long dynRead(env * e, Dynamic * this, char * fichier)
|
||||
WAPIDECL long dynRead(env * e, Dynamic * this, char * fichier)
|
||||
{
|
||||
/* UTF8 lg physique ici */
|
||||
FILE * fic;
|
||||
@@ -783,7 +797,7 @@ long dynRead(env * e, Dynamic * this, char * fichier)
|
||||
cr = DYN_OK;
|
||||
this->mLg = lg;
|
||||
this->mPtr[lg] = 0;
|
||||
this->codePage = CP_DEFAULT;
|
||||
this->codePage = WCP_DEFAULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -792,7 +806,7 @@ long dynRead(env * e, Dynamic * this, char * fichier)
|
||||
return cr;
|
||||
}
|
||||
|
||||
long dynWrite(env * e, Dynamic * this, char * fichier)
|
||||
WAPIDECL long dynWrite(env * e, Dynamic * this, char * fichier)
|
||||
{
|
||||
/* UTF8 lg physique ici */
|
||||
FILE * fic;
|
||||
@@ -813,12 +827,12 @@ long dynWrite(env * e, Dynamic * this, char * fichier)
|
||||
return cr;
|
||||
}
|
||||
|
||||
ent64s dynToNum(env * e, Dynamic * this, long signe, long nbLuMax)
|
||||
WAPIDECL ent64s dynToNum(env * e, Dynamic * this, long signe, long nbLuMax)
|
||||
{
|
||||
return dynSzToNum(e, this->mPtr, signe, nbLuMax, (long *)&this->mInternal);
|
||||
}
|
||||
|
||||
ent64s dynSzToNum(env * e, char * chaine, long signe, long nbLuMax, long * error)
|
||||
WAPIDECL ent64s dynSzToNum(env * e, char * chaine, long signe, long nbLuMax, long * error)
|
||||
{
|
||||
/* si un des caracteres lu n'est pas numerique (ou le '-' si signe), mInternal vaut DYN_ERR, DYN_OK si tous les cars sont ok */
|
||||
char * p = chaine, c;
|
||||
@@ -879,7 +893,7 @@ ent64s dynSzToNum(env * e, char * chaine, long signe, long nbLuMax, long * error
|
||||
return nombre;
|
||||
}
|
||||
|
||||
ent64s dynToNumber(env * e, Dynamic * this)
|
||||
WAPIDECL ent64s dynToNumber(env * e, Dynamic * this)
|
||||
{
|
||||
/* si un des caracteres lu n'est pas numerique (sauf '-' et '.'), mInternal vaut DYN_ERR, DYN_OK si tous les cars sont ok */
|
||||
char * p = this->mPtr, c;
|
||||
@@ -952,12 +966,12 @@ ent64s dynToNumber(env * e, Dynamic * this)
|
||||
return nombre;
|
||||
}
|
||||
|
||||
long dynConvertError(env * e, Dynamic * this)
|
||||
WAPIDECL long dynConvertError(env * e, Dynamic * this)
|
||||
{
|
||||
return (this->mInternal == DYN_ERR ? DYN_TRUE : DYN_FALSE);
|
||||
}
|
||||
|
||||
long dynConcatSz(env * e, Dynamic * this, char * chaine, long lgChaine)
|
||||
WAPIDECL long dynConcatSz(env * e, Dynamic * this, char * chaine, long lgChaine)
|
||||
{
|
||||
/* UTF8 lg physique ici */
|
||||
long lg;
|
||||
@@ -978,18 +992,18 @@ long dynConcatSz(env * e, Dynamic * this, char * chaine, long lgChaine)
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynConcat(env * e, Dynamic * this, Dynamic * valeur)
|
||||
WAPIDECL long dynConcat(env * e, Dynamic * this, Dynamic * valeur)
|
||||
{
|
||||
/* UTF8 lg physique ici */
|
||||
return dynConcatSz(e, this, valeur->mPtr, valeur->mLg);
|
||||
}
|
||||
|
||||
long dynConcatNumber(env * e, Dynamic * this, ent64s valeur)
|
||||
WAPIDECL long dynConcatNumber(env * e, Dynamic * this, ent64s valeur)
|
||||
{
|
||||
return dynConcatSz(e, this, Int64ToSz(e, valeur, DYN_TRUE, 0), DYN_LGNONE);
|
||||
}
|
||||
|
||||
long dynStoreSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char * chaine, long lgChaine, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynStoreSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char * chaine, long lgChaine, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
/* UTF8 lg physique ici ; A REVOIR si separateur # SVM VM FM et > 128 !! */
|
||||
long iPos, iScan, iFin, iCpt, iLg;
|
||||
@@ -1103,17 +1117,17 @@ long dynStoreSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynStore(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * valeur, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynStore(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * valeur, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
return dynStoreSz(e, this, numChamp, numSousChamp, valeur->mPtr, valeur->mLg, separateurChamp, separateurSousChamp);
|
||||
}
|
||||
|
||||
long dynStoreNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, ent64s valeur, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynStoreNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, ent64s valeur, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
return dynStoreSz(e, this, numChamp, numSousChamp, Int64ToSz(e, valeur, DYN_TRUE, 0), DYN_LGNONE, separateurChamp, separateurSousChamp);
|
||||
}
|
||||
|
||||
long dynField(env * e, Dynamic * this, Dynamic * resultat, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp, long nb)
|
||||
WAPIDECL long dynField(env * e, Dynamic * this, Dynamic * resultat, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp, long nb)
|
||||
{
|
||||
/* UTF8 lg physique ici ; a revoir si separateur # SVM VM FM et > 128 !! */
|
||||
long iPos, iScan, iFin, iLg;
|
||||
@@ -1203,7 +1217,7 @@ long dynField(env * e, Dynamic * this, Dynamic * resultat, long numChamp, long n
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
ent64s dynFieldAsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL ent64s dynFieldAsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
long lg = dynExtractPos(e, this, numChamp, numSousChamp, separateurChamp, separateurSousChamp);
|
||||
long posDebut = this->mInternal;
|
||||
@@ -1222,27 +1236,27 @@ ent64s dynFieldAsNumber(env * e, Dynamic * this, long numChamp, long numSousCham
|
||||
return resultat;
|
||||
}
|
||||
|
||||
long dynExtractField(env * e, Dynamic * this, long numChamp, Dynamic * resultat)
|
||||
WAPIDECL long dynExtractField(env * e, Dynamic * this, long numChamp, Dynamic * resultat)
|
||||
{
|
||||
return dynField(e, this, resultat, numChamp, DYN_NONE, e->sep_field, DYN_NONE, 1);
|
||||
}
|
||||
|
||||
long dynExtractSubField(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * resultat)
|
||||
WAPIDECL long dynExtractSubField(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * resultat)
|
||||
{
|
||||
return dynField(e, this, resultat, numChamp, numSousChamp, e->sep_field, e->sep_subfield, 1);
|
||||
}
|
||||
|
||||
ent64s dynExtractFieldAsNumber(env * e, Dynamic * this, long numChamp, Dynamic * resultat)
|
||||
WAPIDECL ent64s dynExtractFieldAsNumber(env * e, Dynamic * this, long numChamp, Dynamic * resultat)
|
||||
{
|
||||
return dynFieldAsNumber(e, this, numChamp, DYN_NONE, e->sep_field, DYN_NONE);
|
||||
}
|
||||
|
||||
ent64s dynExtractSubFieldAsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * resultat)
|
||||
WAPIDECL ent64s dynExtractSubFieldAsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * resultat)
|
||||
{
|
||||
return dynFieldAsNumber(e, this, numChamp, numSousChamp, e->sep_field, e->sep_subfield);
|
||||
}
|
||||
|
||||
long dynInsSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char * chaine, long lgChaine, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynInsSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char * chaine, long lgChaine, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
/* UTF8 lg physique ici ; a revoir si separateur # SVM VM FM et > 128 !! */
|
||||
long iPos, iScan, iCpt, iLg, nSep;
|
||||
@@ -1344,17 +1358,17 @@ long dynInsSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char *
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynIns(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * valeur, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynIns(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * valeur, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
return dynInsSz(e, this, numChamp, numSousChamp, valeur->mPtr, valeur->mLg, separateurChamp, separateurSousChamp);
|
||||
}
|
||||
|
||||
long dynInsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, ent64s valeur, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynInsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, ent64s valeur, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
return dynInsSz(e, this, numChamp, numSousChamp, Int64ToSz(e, valeur, DYN_TRUE, 0), DYN_LGNONE, separateurChamp, separateurSousChamp);
|
||||
}
|
||||
|
||||
long dynDel(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp, long nb)
|
||||
WAPIDECL long dynDel(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp, long nb)
|
||||
{
|
||||
/* UTF8 lg physique ici ; a revoir si separateur # SVM VM FM et > 128 !! */
|
||||
long iPos, iScan, iFin;
|
||||
@@ -1467,7 +1481,7 @@ long dynDel(env * e, Dynamic * this, long numChamp, long numSousChamp, char sepa
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynLocateSz(env * e, Dynamic * this, char * chaine, char separateur, long numChamp, char separateurChamp)
|
||||
WAPIDECL long dynLocateSz(env * e, Dynamic * this, char * chaine, char separateur, long numChamp, char separateurChamp)
|
||||
{
|
||||
/* UTF8 lg physique ici ; a revoir si separateur # SVM VM FM et > 128 !! */
|
||||
char * p, * q, c, d;
|
||||
@@ -1505,7 +1519,7 @@ long dynLocateSz(env * e, Dynamic * this, char * chaine, char separateur, long n
|
||||
}
|
||||
}
|
||||
|
||||
long dynSortLocateSz(env * e, Dynamic * this, char * chaine, char separateur, long tri, long numChamp, char separateurChamp)
|
||||
WAPIDECL long dynSortLocateSz(env * e, Dynamic * this, char * chaine, char separateur, long tri, long numChamp, char separateurChamp)
|
||||
{
|
||||
/* UTF8 lg physique ici ; a revoir si separateur # SVM VM FM et > 128 !! */
|
||||
char * p, * q, c, d, ec;
|
||||
@@ -1546,7 +1560,7 @@ long dynSortLocateSz(env * e, Dynamic * this, char * chaine, char separateur, lo
|
||||
}
|
||||
}
|
||||
|
||||
long dynDcount(env * e, Dynamic * this, char caractere, long numChamp, char separateurChamp)
|
||||
WAPIDECL long dynDcount(env * e, Dynamic * this, char caractere, long numChamp, char separateurChamp)
|
||||
{
|
||||
/* UTF8 lg physique ici ; a revoir si separateur # SVM VM FM et > 128 !! */
|
||||
long nb = 1, iPos = -1, iScan;
|
||||
@@ -1575,17 +1589,17 @@ long dynDcount(env * e, Dynamic * this, char caractere, long numChamp, char sepa
|
||||
return nb;
|
||||
}
|
||||
|
||||
void dynBegin(env * e, Dynamic * this)
|
||||
WAPIDECL void dynBegin(env * e, Dynamic * this)
|
||||
{
|
||||
dynRemove(e, this, NULL, 0, DYN_TRUE);
|
||||
}
|
||||
|
||||
long dynNext(env * e, Dynamic * this, Dynamic * resultat, char separateur)
|
||||
WAPIDECL long dynNext(env * e, Dynamic * this, Dynamic * resultat, char separateur)
|
||||
{
|
||||
return dynRemove(e, this, resultat, separateur, DYN_FALSE);
|
||||
}
|
||||
|
||||
long dynRemove(env * e, Dynamic * this, Dynamic * resultat, char separateur, long raz)
|
||||
WAPIDECL long dynRemove(env * e, Dynamic * this, Dynamic * resultat, char separateur, long raz)
|
||||
{
|
||||
/* UTF8 lg physique ici ; a revoir si separateur # SVM VM FM et > 128 !! */
|
||||
long pos1; // mInternal est l'equivalent de pos2
|
||||
@@ -1619,7 +1633,7 @@ long dynRemove(env * e, Dynamic * this, Dynamic * resultat, char separateur, lon
|
||||
return pos1;
|
||||
}
|
||||
|
||||
long dynExtractPos(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynExtractPos(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
/* A revoir pour UTF8, mais a priori ok car correspond aux positions "physiques" du champ/sous-champ */
|
||||
long iPos, iScan, iFin;
|
||||
@@ -1690,7 +1704,7 @@ long dynExtractPos(env * e, Dynamic * this, long numChamp, long numSousChamp, ch
|
||||
}
|
||||
}
|
||||
|
||||
long dynCount(env * e, Dynamic * this, char caractere, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynCount(env * e, Dynamic * this, char caractere, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
/* a revoir pour UTF8 : cf. dynCountUtf8 */
|
||||
long lg, i, nb = 0;
|
||||
@@ -1704,7 +1718,7 @@ long dynCount(env * e, Dynamic * this, char caractere, long numChamp, long numSo
|
||||
return nb;
|
||||
}
|
||||
|
||||
long dynCountUtf8(env * e, Dynamic * this, char * caractere4, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynCountUtf8(env * e, Dynamic * this, char * caractere4, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
// <caractere4> doit avoir 5 cars mini, padde a droite avec \0, sinon ko
|
||||
if(dynLengthUtf8(caractere4, strlen(caractere4), DYN_TRUE) <= 0)
|
||||
@@ -1727,7 +1741,7 @@ long dynCountUtf8(env * e, Dynamic * this, char * caractere4, long numChamp, lon
|
||||
return nb;
|
||||
}
|
||||
|
||||
long dynSetSubstr(env * e, Dynamic * this, Dynamic * valeur, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynSetSubstr(env * e, Dynamic * this, Dynamic * valeur, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
long debutEx, lgEx;
|
||||
if((lgEx = dynExtractPos(e, this, numChamp, numSousChamp, separateurChamp, separateurSousChamp)) < 0)
|
||||
@@ -1780,7 +1794,7 @@ long dynSetSubstr(env * e, Dynamic * this, Dynamic * valeur, long debut, long le
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynSetSubstrUtf8(env * e, Dynamic * this, Dynamic * valeur, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynSetSubstrUtf8(env * e, Dynamic * this, Dynamic * valeur, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
long lg, pos, lenc, num;
|
||||
/* met a jour la chaine [debut, len] avec le contenu de valeur; si debut/len incoherent, ne fait rien
|
||||
@@ -1862,7 +1876,7 @@ long dynSetSubstrUtf8(env * e, Dynamic * this, Dynamic * valeur, long debut, lon
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynSubstr(env * e, Dynamic * this, Dynamic * resultat, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynSubstr(env * e, Dynamic * this, Dynamic * resultat, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
long lg, pos;
|
||||
/* renvoi dans resultat la chaine [debut, len] ; si debut/len incoherent, renvoie une chaine vide ; debut -1 : partir de la fin en arriere */
|
||||
@@ -1900,7 +1914,7 @@ long dynSubstr(env * e, Dynamic * this, Dynamic * resultat, long debut, long len
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynSubstrUtf8(env * e, Dynamic * this, Dynamic * resultat, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
WAPIDECL long dynSubstrUtf8(env * e, Dynamic * this, Dynamic * resultat, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp)
|
||||
{
|
||||
long lg, pos, lenc, num;
|
||||
/* renvoi dans resultat la chaine [debut, len] ; si debut/len incoherent, renvoie une chaine vide ; debut -1 : partir de la fin en arriere */
|
||||
@@ -1965,7 +1979,7 @@ long dynSubstrUtf8(env * e, Dynamic * this, Dynamic * resultat, long debut, long
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
char ** dynToTabPtr(env * e, Dynamic * this, char separateur)
|
||||
WAPIDECL char ** dynToTabPtr(env * e, Dynamic * this, char separateur)
|
||||
{
|
||||
/* UTF8 lg physique ici ; a revoir si separateur # SVM VM FM et > 128 !! */
|
||||
long nb;
|
||||
@@ -2002,7 +2016,7 @@ char ** dynToTabPtr(env * e, Dynamic * this, char separateur)
|
||||
return tab;
|
||||
}
|
||||
|
||||
long dynConvert(env * e, Dynamic * this, char * from, char * to)
|
||||
WAPIDECL long dynConvert(env * e, Dynamic * this, char * from, char * to)
|
||||
{
|
||||
/* a revoir pour UTF8, cf. dynConvertUtf8 */
|
||||
long lgFrom;
|
||||
@@ -2023,7 +2037,7 @@ long dynConvert(env * e, Dynamic * this, char * from, char * to)
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
void dynReplace(env * e, Dynamic * this, char from, char to)
|
||||
WAPIDECL void dynReplace(env * e, Dynamic * this, char from, char to)
|
||||
{
|
||||
/* pour faire sur utf8, appeler dynConvertUtf8 a la place */
|
||||
if(this->mPtr == NULL)
|
||||
@@ -2035,7 +2049,7 @@ void dynReplace(env * e, Dynamic * this, char from, char to)
|
||||
return;
|
||||
}
|
||||
|
||||
long dynConvertUtf8(env * e, Dynamic * this, char * from, char * to)
|
||||
WAPIDECL long dynConvertUtf8(env * e, Dynamic * this, char * from, char * to)
|
||||
{
|
||||
if(from == NULL || to == NULL || this->mPtr == NULL)
|
||||
return DYN_ERR;
|
||||
@@ -2114,7 +2128,7 @@ long dynConvertUtf8(env * e, Dynamic * this, char * from, char * to)
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
void dynErase(env * e, Dynamic * this, char * car)
|
||||
WAPIDECL void dynErase(env * e, Dynamic * this, char * car)
|
||||
{
|
||||
/* a revoir pour UTF8, cf. dynEraseUtf8 */
|
||||
const char * p;
|
||||
@@ -2142,7 +2156,7 @@ void dynErase(env * e, Dynamic * this, char * car)
|
||||
this->mPtr[this->mLg] = 0;
|
||||
}
|
||||
|
||||
void dynEraseUtf8(env * e, Dynamic * this, char * car)
|
||||
WAPIDECL void dynEraseUtf8(env * e, Dynamic * this, char * car)
|
||||
{
|
||||
// <car> doit avoir 5 cars mini, padde a droite avec \0, sinon ko
|
||||
long lgCar = strlen(car);
|
||||
@@ -2187,7 +2201,7 @@ void dynEraseUtf8(env * e, Dynamic * this, char * car)
|
||||
return;
|
||||
}
|
||||
|
||||
long dynIndexSz(env * e, Dynamic * this, char * chaine, long lgChaine, long occ)
|
||||
WAPIDECL long dynIndexSz(env * e, Dynamic * this, char * chaine, long lgChaine, long occ)
|
||||
{
|
||||
/* a revoir pour utf8, cf. dynIndexSzUtf8 */
|
||||
long pos, i, concorde;
|
||||
@@ -2211,12 +2225,12 @@ long dynIndexSz(env * e, Dynamic * this, char * chaine, long lgChaine, long occ)
|
||||
return -1; /* non trouve */
|
||||
}
|
||||
|
||||
long dynIndex(env * e, Dynamic * this, Dynamic * valeur, long occ)
|
||||
WAPIDECL long dynIndex(env * e, Dynamic * this, Dynamic * valeur, long occ)
|
||||
{
|
||||
return dynIndexSz(e, this, valeur->mPtr, valeur->mLg, occ);
|
||||
}
|
||||
|
||||
long dynIndexSzUtf8(env * e, Dynamic * this, char * chaine, long lgChaine, long occ)
|
||||
WAPIDECL long dynIndexSzUtf8(env * e, Dynamic * this, char * chaine, long lgChaine, long occ)
|
||||
{
|
||||
/* renvoie la position de <chaine> dans le Dynamic, occurence numero <occ> */
|
||||
/* position renvoyee en base 0 (! cars logiques utf8 !) ; -1 si non trouvee */
|
||||
@@ -2257,7 +2271,7 @@ long dynIndexSzUtf8(env * e, Dynamic * this, char * chaine, long lgChaine, long
|
||||
return -1; /* non trouve */
|
||||
}
|
||||
|
||||
long dynChange(env * e, Dynamic * this, char * chaine, char * remplace, long nb)
|
||||
WAPIDECL long dynChange(env * e, Dynamic * this, char * chaine, char * remplace, long nb)
|
||||
{
|
||||
/* a revoir pour UTF8, cf. dynChangeUtf8 */
|
||||
/* nb = 0 pour tout remplacer, sinon les <nb> premieres occurences (par defaut 0 = tout) */
|
||||
@@ -2312,7 +2326,7 @@ long dynChange(env * e, Dynamic * this, char * chaine, char * remplace, long nb)
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynChangeUtf8(env * e, Dynamic * this, char * chaine, char * remplace, long nb)
|
||||
WAPIDECL long dynChangeUtf8(env * e, Dynamic * this, char * chaine, char * remplace, long nb)
|
||||
{
|
||||
/* nb = 0 pour tout remplacer, sinon les <nb> premieres occurences (par defaut 0 = tout) */
|
||||
long lgChaine = strlen(chaine);
|
||||
@@ -2410,8 +2424,17 @@ long dynChangeUtf8(env * e, Dynamic * this, char * chaine, char * remplace, long
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
WAPIDECL char * dynConvertCharToCharHexa(octet c)
|
||||
{
|
||||
static char car[16] = {"0123456789ABCDEF"};
|
||||
static char res[3] = {0};
|
||||
res[0] = car[c / 16];
|
||||
res[1] = car[c % 16];
|
||||
return res;
|
||||
}
|
||||
|
||||
// dynOconv ne sert pas, à gérer ailleurs autrement : faire un module Convert : Hexa, base64 ; horodate a deja son module
|
||||
long dynOconv(env * e, Dynamic * this, Dynamic * resultat, char * format)
|
||||
WAPIDECL long dynOconv(env * e, Dynamic * this, Dynamic * resultat, char * format)
|
||||
{
|
||||
/* a revoir pour UTF8 ? (Base64 ?) oui pour D car d'autres cars utf8 peuvent etre dans la chaine */
|
||||
static char car[64] = {"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_."}; /* sert a la conv hexa et base64 */
|
||||
@@ -2426,11 +2449,19 @@ long dynOconv(env * e, Dynamic * this, Dynamic * resultat, char * format)
|
||||
{
|
||||
struct tm * ptm;
|
||||
/* conversion date/heure : format interne = time_t unix sur 32 bits */
|
||||
time_t tm = dynToNum(e, this, DYN_NONE, 10); /* pas de signe, lg max sur 32 bits = 10 chiffres */
|
||||
if(this->mInternal == DYN_ERR)
|
||||
return DYN_ERR; /* pbm de conversion numerique */
|
||||
time_t tm;
|
||||
if(this->mLg == 0)
|
||||
{
|
||||
tm = time(NULL);
|
||||
ptm = gmtime(&tm);
|
||||
}
|
||||
else
|
||||
{
|
||||
tm = dynToNum(e, this, DYN_NONE, 10); /* pas de signe, lg max sur 32 bits = 10 chiffres */
|
||||
if(this->mInternal == DYN_ERR)
|
||||
return DYN_ERR; /* pbm de conversion numerique */
|
||||
ptm = localtime(&tm);
|
||||
}
|
||||
/* analyse formatage demande */
|
||||
dynLet(e, resultat, NULL, DYN_LGNONE);
|
||||
tmp[1] = 0;
|
||||
@@ -2525,7 +2556,7 @@ long dynOconv(env * e, Dynamic * this, Dynamic * resultat, char * format)
|
||||
}
|
||||
|
||||
// seul dynIconv "X" sert dans w : ç gérer ailleurs et autrement
|
||||
long dynIconv(env * e, Dynamic * this, Dynamic * resultat, char * format)
|
||||
WAPIDECL long dynIconv(env * e, Dynamic * this, Dynamic * resultat, char * format)
|
||||
{
|
||||
/* a revoir pour UTF8 ? (Base64 ?) */
|
||||
static char car[64] = {"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_."}; /* sert a la conv hexa et base64 */
|
||||
@@ -2760,7 +2791,7 @@ long dynIconv(env * e, Dynamic * this, Dynamic * resultat, char * format)
|
||||
}
|
||||
|
||||
// mettre ailleurs ? module convert ?
|
||||
long dynConvertHexaToLong(Dynamic * valeur)
|
||||
WAPIDECL long dynConvertHexaToLong(Dynamic * valeur)
|
||||
{
|
||||
static long hexa[128] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
@@ -2777,7 +2808,7 @@ long dynConvertHexaToLong(Dynamic * valeur)
|
||||
return resultat;
|
||||
}
|
||||
|
||||
long dynConvertCharHexaToChar(char c1, char c2, char * c)
|
||||
WAPIDECL long dynConvertCharHexaToChar(char c1, char c2, char * c)
|
||||
{
|
||||
static char hexa[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
@@ -2801,7 +2832,7 @@ long dynConvertCharHexaToChar(char c1, char c2, char * c)
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynFmt(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char filler, long lg)
|
||||
WAPIDECL long dynFmt(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char filler, long lg)
|
||||
{
|
||||
/* a revoir pour UTF8, cf. dynFmtUtf8 */
|
||||
long nb, ngauche;
|
||||
@@ -2865,8 +2896,7 @@ long dynFmt(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char fill
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
// TODO FDE a tester
|
||||
long dynFmtUtf8(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char * filler, long lg)
|
||||
WAPIDECL long dynFmtUtf8(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char * filler, long lg)
|
||||
{
|
||||
long nb, nbThis, lgFiller;
|
||||
/* filler est un tableau de 5 octets maxi, contenant un seul caractere utf8, padde a droite avec \0 (sinon ko), servant de remplissage lors du formatage */
|
||||
@@ -2948,6 +2978,7 @@ long dynFmtUtf8(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char
|
||||
dynSetLen(e, resultat, this->mLg + nb * lgFiller); /* met le \0 a la fin */
|
||||
break;
|
||||
case 'C':
|
||||
{
|
||||
/* centrer la chaine : nb/2 a gauche et nb/2(+1 si impair) a droite */
|
||||
/* a gauche */
|
||||
long ngauche = nb >> 1;
|
||||
@@ -2964,11 +2995,12 @@ long dynFmtUtf8(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char
|
||||
strncpy(p, filler, lgFiller);
|
||||
dynSetLen(e, resultat, this->mLg + nb * lgFiller); /* met le \0 a la fin */
|
||||
break;
|
||||
}
|
||||
}
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynFmtNumber(env * e, ent64s valeur, Dynamic * resultat, char cadrage, char filler, long lg)
|
||||
WAPIDECL long dynFmtNumber(env * e, ent64s valeur, Dynamic * resultat, char cadrage, char filler, long lg)
|
||||
{
|
||||
/* a revoir pour UTF8 (FDE : ??) */
|
||||
/* ent64s : longueur max = 20 cars (signe + 19 chiffres) */
|
||||
@@ -3026,7 +3058,7 @@ long dynFmtNumber(env * e, ent64s valeur, Dynamic * resultat, char cadrage, char
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynTrim(env * e, Dynamic * this, Dynamic * resultat, char car, long option)
|
||||
WAPIDECL long dynTrim(env * e, Dynamic * this, Dynamic * resultat, char car, long option)
|
||||
{
|
||||
/* a revoir pour UTF8, cf. dynTrimUtf8 */
|
||||
/* car = caractere a "trimer" + option = 1 a gauche, 2 a droite, 3 gauche+droite+milieu => n'est pas utilisee !! */
|
||||
@@ -3079,7 +3111,7 @@ long dynTrim(env * e, Dynamic * this, Dynamic * resultat, char car, long option)
|
||||
return DYN_OK;
|
||||
}
|
||||
|
||||
long dynTrimUtf8(env * e, Dynamic * this, Dynamic * resultat, char * car, long option)
|
||||
WAPIDECL long dynTrimUtf8(env * e, Dynamic * this, Dynamic * resultat, char * car, long option)
|
||||
{
|
||||
/* car est un tableau de 4 octets maxi, contenant un seul caractere utf8, padde a droite avec \0 (sinon ko), a "trimer" */
|
||||
/* option = 1 a gauche, 2 a droite, 3 gauche+droite+milieu => n'est pas utilisee !! */
|
||||
|
||||
@@ -32,19 +32,23 @@
|
||||
#define sSVM "\xFC"
|
||||
#define sTM "\xFB"
|
||||
|
||||
#define DYN_OK 0 // attention, DYN_OK doit etre egal a 0 sinon des tests seront KO...
|
||||
#define DYN_ERR -1
|
||||
enum {
|
||||
DYN_OK = 0, // attention, DYN_OK doit etre egal a 0 sinon des tests seront KO...
|
||||
DYN_ERR = -1,
|
||||
|
||||
#define DYN_FALSE 0
|
||||
#define DYN_TRUE -1
|
||||
DYN_FALSE = 0,
|
||||
DYN_TRUE = -1,
|
||||
|
||||
#define DYN_LGNONE -1 // quand un parametre ne doit pas etre pris en compte, de type "lgChaine"
|
||||
#define DYN_NONE 0 // quand un parametre ne doit pas etre pris en compte, de type "numChamp/numSousChamp separateurChamp/SousChamp"
|
||||
DYN_LGNONE = -1, // quand un parametre ne doit pas etre pris en compte, de type "lgChaine"
|
||||
DYN_NONE = 0, // quand un parametre ne doit pas etre pris en compte, de type "numChamp/numSousChamp separateurChamp/SousChamp"
|
||||
|
||||
#define DYN_ALL 0 // toues les occurences (dynChange...)
|
||||
DYN_ALL = 0, // toues les occurences (dynChange...)
|
||||
|
||||
#define DYN_SORT_ASC 1
|
||||
#define DYN_SORT_DESC 2
|
||||
DYN_SORT_ASC = 1,
|
||||
DYN_SORT_DESC = 2,
|
||||
|
||||
DYN_NOTFOUND = -1 // quand pas trouve (index...)
|
||||
};
|
||||
|
||||
/*typedef struct
|
||||
{
|
||||
@@ -65,83 +69,86 @@ typedef var Dynamic;
|
||||
si erreur de codage/lecture utf8, la norme est de le remplacer par le point de code \uFFFD (EF BF BD) et de continuer (à convertir en 3F ? par exemple en mono byte)
|
||||
*/
|
||||
|
||||
#include "apidecl.h"
|
||||
|
||||
/* ********************************************** */
|
||||
void NumberToSz(env * e, ent64s valeur, char * resultat, long * lg);
|
||||
char * Int64ToSz(env * e, ent64s valeur, long signe, long leftPad);
|
||||
char * Int32ToSz(ent32s valeur, long signe, long leftPad);
|
||||
long dynInit(env * e, Dynamic * this, long lgmax);
|
||||
long dynCopy(env * e, Dynamic * this, Dynamic * aCopier);
|
||||
void dynFree(env * e, Dynamic * this);
|
||||
void dynSetLen(env * e, Dynamic * this, long lg);
|
||||
WAPIDECL char * NumberToSz(env * e, ent64s valeur, char * resultat, ent64s * lg);
|
||||
WAPIDECL char * Int64ToSz(env * e, ent64s valeur, long signe, long leftPad);
|
||||
WAPIDECL char * Int32ToSz(ent32s valeur, long signe, long leftPad);
|
||||
WAPIDECL long dynInit(env * e, Dynamic * this, long lgmax);
|
||||
WAPIDECL long dynCopy(env * e, Dynamic * this, Dynamic * aCopier);
|
||||
WAPIDECL void dynFree(env * e, Dynamic * this);
|
||||
WAPIDECL void dynSetLen(env * e, Dynamic * this, long lg);
|
||||
//long dynCarU8(env * e, Dynamic * this, long * pos);
|
||||
//long dynLgU8(env * e, Dynamic * this);
|
||||
long dynLengthUtf8(const char * p, long lg, int separator);
|
||||
long dynNextUtf8(char ** p, long lg, long * pos, char * carU8, int separator);
|
||||
long dynCtrl(env * e, Dynamic * this, long lg, long copier);
|
||||
long Win1252ToUTF8(env * e, Dynamic * valeur, Dynamic * resultat);
|
||||
long UTF8ToWin1252(env * e, Dynamic * valeur, Dynamic * resultat);
|
||||
void NumberToBin(env * e, ent64s valeur, pointeur resultat, int nbOctet, int signe, int endianess);
|
||||
void BinToNumber(env * e, pointeur valeur, ent64s * resultat, int nbOctet, int signe, int endianess);
|
||||
long dynSetAsNumber(env * e, Dynamic * this, ent64s valeur);
|
||||
long dynSetAs(env * e, Dynamic * this, Dynamic * valeur);
|
||||
long dynSetAsSz(env * e, Dynamic * this, char * chaine);
|
||||
long dynLet(env * e, Dynamic * this, char * chaine, long lgChaine);
|
||||
long dynCompare(env * e, Dynamic * this, ent64 comparaison, char * chaine, long lgChaine);
|
||||
long dynRead(env * e, Dynamic * this, char * fichier);
|
||||
long dynWrite(env * e, Dynamic * this, char * fichier);
|
||||
ent64s dynSzToNum(env * e, char * chaine, long signe, long nbLuMax, long * error);
|
||||
ent64s dynToNum(env * e, Dynamic * this, long signe, long nbLuMax);
|
||||
ent64s dynToNumber(env * e, Dynamic * this);
|
||||
long dynConvertError(env * e, Dynamic * this);
|
||||
long dynConcatSz(env * e, Dynamic * this, char * chaine, long lgChaine);
|
||||
long dynConcat(env * e, Dynamic * this, Dynamic * valeur);
|
||||
long dynConcatNumber(env * e, Dynamic * this, ent64s valeur);
|
||||
long dynStoreSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char * chaine, long lgChaine, char separateurChamp, char separateurSousChamp);
|
||||
long dynStore(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * valeur, char separateurChamp, char separateurSousChamp);
|
||||
long dynStoreNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, ent64s valeur, char separateurChamp, char separateurSousChamp);
|
||||
long dynField(env * e, Dynamic * this, Dynamic * resultat, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp, long nb);
|
||||
ent64s dynFieldAsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
long dynExtractField(env * e, Dynamic * this, long numChamp, Dynamic * resultat);
|
||||
long dynExtractSubField(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * resultat);
|
||||
ent64s dynExtractFieldAsNumber(env * e, Dynamic * this, long numChamp, Dynamic * resultat);
|
||||
ent64s dynExtractSubFieldAsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * resultat);
|
||||
long dynInsSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char * chaine, long lgChaine, char separateurChamp, char separateurSousChamp);
|
||||
long dynIns(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * valeur, char separateurChamp, char separateurSousChamp);
|
||||
long dynInsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, ent64s valeur, char separateurChamp, char separateurSousChamp);
|
||||
long dynDel(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp, long nb);
|
||||
long dynLocateSz(env * e, Dynamic * this, char * chaine, char separateur, long numChamp, char separateurChamp);
|
||||
long dynSortLocateSz(env * e, Dynamic * this, char * chaine, char separateur, long tri, long numChamp, char separateurChamp);
|
||||
long dynDcount(env * e, Dynamic * this, char caractere, long numChamp, char separateurChamp);
|
||||
void dynBegin(env * e, Dynamic * this);
|
||||
long dynNext(env * e, Dynamic * this, Dynamic * resultat, char separateur);
|
||||
long dynRemove(env * e, Dynamic * this, Dynamic * resultat, char separateur, long raz);
|
||||
long dynExtractPos(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
long dynCount(env * e, Dynamic * this, char caractere, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
long dynCountUtf8(env * e, Dynamic * this, char * caractere4, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
long dynSetSubstr(env * e, Dynamic * this, Dynamic * valeur, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
long dynSetSubstrUtf8(env * e, Dynamic * this, Dynamic * valeur, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
long dynSubstr(env * e, Dynamic * this, Dynamic * resultat, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
long dynSubstrUtf8(env * e, Dynamic * this, Dynamic * resultat, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
char ** dynToTabPtr(env * e, Dynamic * this, char separateur);
|
||||
long dynConvert(env * e, Dynamic * this, char * from, char * to);
|
||||
void dynReplace(env * e, Dynamic * this, char from, char to);
|
||||
long dynConvertUtf8(env * e, Dynamic * this, char * from, char * to);
|
||||
void dynErase(env * e, Dynamic * this, char * car);
|
||||
void dynEraseUtf8(env * e, Dynamic * this, char * car);
|
||||
long dynIndexSz(env * e, Dynamic * this, char * chaine, long lgChaine, long occ);
|
||||
long dynIndex(env * e, Dynamic * this, Dynamic * valeur, long occ);
|
||||
long dynIndexSzUtf8(env * e, Dynamic * this, char * chaine, long lgChaine, long occ);
|
||||
long dynChange(env * e, Dynamic * this, char * chaine, char * remplace, long nb);
|
||||
long dynChangeUtf8(env * e, Dynamic * this, char * chaine, char * remplace, long nb);
|
||||
long dynOconv(env * e, Dynamic * this, Dynamic * resultat, char * format);
|
||||
long dynIconv(env * e, Dynamic * this, Dynamic * resultat, char * format);
|
||||
long dynConvertHexaToLong(Dynamic * valeur);
|
||||
long dynConvertCharHexaToChar(char c1, char c2, char * c);
|
||||
long dynFmt(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char filler, long lg);
|
||||
long dynFmtUtf8(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char * filler, long lg);
|
||||
long dynFmtNumber(env * e, ent64s valeur, Dynamic * resultat, char cadrage, char filler, long lg);
|
||||
long dynTrim(env * e, Dynamic * this, Dynamic * resultat, char car, long option);
|
||||
long dynTrimUtf8(env * e, Dynamic * this, Dynamic * resultat, char * car, long option);
|
||||
WAPIDECL long dynLengthUtf8(const char * p, long lg, int separator);
|
||||
WAPIDECL long dynNextUtf8(char ** p, long lg, long * pos, char * carU8, int separator);
|
||||
WAPIDECL long dynCtrl(env * e, Dynamic * this, long lg, long copier);
|
||||
WAPIDECL long Win1252ToUTF8(env * e, Dynamic * valeur, Dynamic * resultat);
|
||||
WAPIDECL long UTF8ToWin1252(env * e, Dynamic * valeur, Dynamic * resultat);
|
||||
WAPIDECL void NumberToBin(env * e, ent64s valeur, pointeur resultat, int nbOctet, int signe, int endianess);
|
||||
WAPIDECL void BinToNumber(env * e, pointeur valeur, ent64s * resultat, int nbOctet, int signe, int endianess);
|
||||
WAPIDECL long dynSetAsNumber(env * e, Dynamic * this, ent64s valeur);
|
||||
WAPIDECL long dynSetAs(env * e, Dynamic * this, Dynamic * valeur);
|
||||
WAPIDECL long dynSetAsSz(env * e, Dynamic * this, char * chaine);
|
||||
WAPIDECL long dynLet(env * e, Dynamic * this, char * chaine, long lgChaine);
|
||||
WAPIDECL long dynCompare(env * e, Dynamic * this, ent64 comparaison, char * chaine, long lgChaine);
|
||||
WAPIDECL long dynRead(env * e, Dynamic * this, char * fichier);
|
||||
WAPIDECL long dynWrite(env * e, Dynamic * this, char * fichier);
|
||||
WAPIDECL ent64s dynSzToNum(env * e, char * chaine, long signe, long nbLuMax, long * error);
|
||||
WAPIDECL ent64s dynToNum(env * e, Dynamic * this, long signe, long nbLuMax);
|
||||
WAPIDECL ent64s dynToNumber(env * e, Dynamic * this);
|
||||
WAPIDECL long dynConvertError(env * e, Dynamic * this);
|
||||
WAPIDECL long dynConcatSz(env * e, Dynamic * this, char * chaine, long lgChaine);
|
||||
WAPIDECL long dynConcat(env * e, Dynamic * this, Dynamic * valeur);
|
||||
WAPIDECL long dynConcatNumber(env * e, Dynamic * this, ent64s valeur);
|
||||
WAPIDECL long dynStoreSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char * chaine, long lgChaine, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynStore(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * valeur, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynStoreNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, ent64s valeur, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynField(env * e, Dynamic * this, Dynamic * resultat, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp, long nb);
|
||||
WAPIDECL ent64s dynFieldAsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynExtractField(env * e, Dynamic * this, long numChamp, Dynamic * resultat);
|
||||
WAPIDECL long dynExtractSubField(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * resultat);
|
||||
WAPIDECL ent64s dynExtractFieldAsNumber(env * e, Dynamic * this, long numChamp, Dynamic * resultat);
|
||||
WAPIDECL ent64s dynExtractSubFieldAsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * resultat);
|
||||
WAPIDECL long dynInsSz(env * e, Dynamic * this, long numChamp, long numSousChamp, char * chaine, long lgChaine, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynIns(env * e, Dynamic * this, long numChamp, long numSousChamp, Dynamic * valeur, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynInsNumber(env * e, Dynamic * this, long numChamp, long numSousChamp, ent64s valeur, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynDel(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp, long nb);
|
||||
WAPIDECL long dynLocateSz(env * e, Dynamic * this, char * chaine, char separateur, long numChamp, char separateurChamp);
|
||||
WAPIDECL long dynSortLocateSz(env * e, Dynamic * this, char * chaine, char separateur, long tri, long numChamp, char separateurChamp);
|
||||
WAPIDECL long dynDcount(env * e, Dynamic * this, char caractere, long numChamp, char separateurChamp);
|
||||
WAPIDECL void dynBegin(env * e, Dynamic * this);
|
||||
WAPIDECL long dynNext(env * e, Dynamic * this, Dynamic * resultat, char separateur);
|
||||
WAPIDECL long dynRemove(env * e, Dynamic * this, Dynamic * resultat, char separateur, long raz);
|
||||
WAPIDECL long dynExtractPos(env * e, Dynamic * this, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynCount(env * e, Dynamic * this, char caractere, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynCountUtf8(env * e, Dynamic * this, char * caractere4, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynSetSubstr(env * e, Dynamic * this, Dynamic * valeur, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynSetSubstrUtf8(env * e, Dynamic * this, Dynamic * valeur, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynSubstr(env * e, Dynamic * this, Dynamic * resultat, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL long dynSubstrUtf8(env * e, Dynamic * this, Dynamic * resultat, long debut, long len, long numChamp, long numSousChamp, char separateurChamp, char separateurSousChamp);
|
||||
WAPIDECL char ** dynToTabPtr(env * e, Dynamic * this, char separateur);
|
||||
WAPIDECL long dynConvert(env * e, Dynamic * this, char * from, char * to);
|
||||
WAPIDECL void dynReplace(env * e, Dynamic * this, char from, char to);
|
||||
WAPIDECL long dynConvertUtf8(env * e, Dynamic * this, char * from, char * to);
|
||||
WAPIDECL void dynErase(env * e, Dynamic * this, char * car);
|
||||
WAPIDECL void dynEraseUtf8(env * e, Dynamic * this, char * car);
|
||||
WAPIDECL long dynIndexSz(env * e, Dynamic * this, char * chaine, long lgChaine, long occ);
|
||||
WAPIDECL long dynIndex(env * e, Dynamic * this, Dynamic * valeur, long occ);
|
||||
WAPIDECL long dynIndexSzUtf8(env * e, Dynamic * this, char * chaine, long lgChaine, long occ);
|
||||
WAPIDECL long dynChange(env * e, Dynamic * this, char * chaine, char * remplace, long nb);
|
||||
WAPIDECL long dynChangeUtf8(env * e, Dynamic * this, char * chaine, char * remplace, long nb);
|
||||
WAPIDECL long dynOconv(env * e, Dynamic * this, Dynamic * resultat, char * format);
|
||||
WAPIDECL long dynIconv(env * e, Dynamic * this, Dynamic * resultat, char * format);
|
||||
WAPIDECL char * dynConvertCharToCharHexa(octet c);
|
||||
WAPIDECL long dynConvertHexaToLong(Dynamic * valeur);
|
||||
WAPIDECL long dynConvertCharHexaToChar(char c1, char c2, char * c);
|
||||
WAPIDECL long dynFmt(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char filler, long lg);
|
||||
WAPIDECL long dynFmtUtf8(env * e, Dynamic * this, Dynamic * resultat, char cadrage, char * filler, long lg);
|
||||
WAPIDECL long dynFmtNumber(env * e, ent64s valeur, Dynamic * resultat, char cadrage, char filler, long lg);
|
||||
WAPIDECL long dynTrim(env * e, Dynamic * this, Dynamic * resultat, char car, long option);
|
||||
WAPIDECL long dynTrimUtf8(env * e, Dynamic * this, Dynamic * resultat, char * car, long option);
|
||||
|
||||
/* ********************************************** */
|
||||
#endif
|
||||
@@ -2,7 +2,7 @@
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024 lanisys.fr
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
@@ -20,30 +20,32 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
********************************************** */
|
||||
enum {
|
||||
/* types de requete FCGI */
|
||||
#define FCGI_BEGIN_REQUEST 1
|
||||
#define FCGI_ABORT_REQUEST 2
|
||||
#define FCGI_END_REQUEST 3
|
||||
#define FCGI_PARAMS 4
|
||||
#define FCGI_STDIN 5
|
||||
#define FCGI_STDOUT 6
|
||||
FCGI_BEGIN_REQUEST = 1,
|
||||
FCGI_ABORT_REQUEST = 2,
|
||||
FCGI_END_REQUEST = 3,
|
||||
FCGI_PARAMS = 4,
|
||||
FCGI_STDIN = 5,
|
||||
FCGI_STDOUT = 6,
|
||||
|
||||
/* demande dans le BEGIN REQUEST */
|
||||
#define FCGI_RESPONDER 1
|
||||
#define FCGI_AUTHORIZER 2
|
||||
#define FCGI_FILTER 3
|
||||
FCGI_RESPONDER = 1,
|
||||
FCGI_AUTHORIZER = 2,
|
||||
FCGI_FILTER = 3,
|
||||
|
||||
/* code du "protocl status" lors du END REQUEST */
|
||||
#define FCGI_REQUEST_COMPLETE 0
|
||||
#define FCGI_CANT_MPX_CONN 1
|
||||
#define FCGI_OVERLOADED 2
|
||||
#define FCGI_UNKNOWN_ROLE 3
|
||||
FCGI_REQUEST_COMPLETE = 0,
|
||||
FCGI_CANT_MPX_CONN = 1,
|
||||
FCGI_OVERLOADED = 2,
|
||||
FCGI_UNKNOWN_ROLE = 3,
|
||||
|
||||
/* codes d'erreurs du module */
|
||||
#define WFC_OK 0 /* continuer a lire */
|
||||
#define WFC_ERR 1
|
||||
#define WFC_KEEPALIVE 2
|
||||
#define WFC_REPONDRE 3
|
||||
WFC_OK = 0, /* continuer a lire */
|
||||
WFC_ERR = 1,
|
||||
WFC_KEEPALIVE = 2,
|
||||
WFC_REPONDRE = 3
|
||||
};
|
||||
|
||||
/* Descritpion du message en cours ; id = 0 si aucun en cours */
|
||||
struct {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024 lanisys.fr
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
@@ -26,10 +26,10 @@
|
||||
#include <string.h>
|
||||
|
||||
#ifdef UNIX
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#else
|
||||
#include "windows.h" // pour les fonctions FindFile...
|
||||
#include "windows.h" // pour les fonctions FindFile...
|
||||
#endif
|
||||
|
||||
#include "langage.h"
|
||||
@@ -51,13 +51,12 @@ static int setError(modEtat * p, int err)
|
||||
return EX_MODERR;
|
||||
}
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
/* TODO : gestion des 3 parametres (au lieu d'un seul) */
|
||||
modEtat * p_etat;
|
||||
@@ -91,7 +90,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(strncmp(e->fn, "init", 4) == 0)
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
@@ -104,7 +103,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//*** code specifique ici
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
//*** code specifique ici
|
||||
// liberation specifique au module avant arret process
|
||||
@@ -113,7 +112,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
memfree(e, p_etat);
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param1->type == VAR_DYNAMIC)
|
||||
@@ -123,7 +122,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
else if(strncmp(e->fn, "error", 5) == 0)
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
@@ -139,7 +138,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "create", 6) == 0)
|
||||
else if(modFnIs(e, "create", 6))
|
||||
{
|
||||
// todo...
|
||||
// test
|
||||
@@ -149,7 +148,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
printf("mod create %d\n", p_etat->error);
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "get", 3) == 0)
|
||||
else if(modFnIs(e, "get", 3))
|
||||
{
|
||||
/* utilisation de dynRead qui fait le travail, param1 : nom, param2 : contenu lu */
|
||||
if(param1 == NULL || param2 == NULL)
|
||||
@@ -163,7 +162,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "set", 3) == 0)
|
||||
else if(modFnIs(e, "set", 3))
|
||||
{
|
||||
/* copie du code de dynWrite, avec modif param1 : nom, param2 : contenu a ecrire */
|
||||
if(param1 == NULL || param2 == NULL)
|
||||
@@ -188,7 +187,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "size", 4) == 0)
|
||||
else if(modFnIs(e, "size", 4))
|
||||
{
|
||||
/* copie du code de dynRead, plus court */
|
||||
FILE * fic;
|
||||
@@ -220,7 +219,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "dir", 3) == 0)
|
||||
else if(modFnIs(e, "dir", 3))
|
||||
{
|
||||
/* copie du code de dynRead, plus court */
|
||||
if(param1 == NULL)
|
||||
|
||||
@@ -181,6 +181,11 @@ void init_reg(env * e, Dynamic * regles, Dynamic * tmp)
|
||||
r.other = rg(e, regles, "other", tmp);
|
||||
}
|
||||
|
||||
enum {
|
||||
TAB_COUNT = 3,
|
||||
COMMENT_EOL = 8
|
||||
};
|
||||
|
||||
static void formatage(Dynamic * s, Dynamic * f, int type)
|
||||
{
|
||||
// s : source ; f : source apres formatage, type : 1 w, 2 pcode
|
||||
@@ -190,8 +195,8 @@ static void formatage(Dynamic * s, Dynamic * f, int type)
|
||||
//#define nreg(x) ((x)*2 > token.mLg ? 0 : *(ent16 *)(token.mPtr + (x)*2 - 2))
|
||||
#define ntok(x) dynExtractSubFieldAsNumber(&e, &valex, 2, x, &tmp)
|
||||
//
|
||||
#define TAB_COUNT 3
|
||||
#define COMMENT_EOL 8
|
||||
//#define TAB_COUNT 3
|
||||
//#define COMMENT_EOL 8
|
||||
//
|
||||
Dynamic trav, tmp, lig; /* variables de travail */
|
||||
Dynamic regles; /* regles lex */
|
||||
|
||||
@@ -33,33 +33,45 @@
|
||||
#include "lex.c"
|
||||
#include "instr.h"
|
||||
#include "rep.h"
|
||||
#include "arg.c"
|
||||
|
||||
#define WVERS 1 /* version du compilateur w et donc du code compile */
|
||||
enum {
|
||||
WVERS = 1, /* version du compilateur w et donc du code compile */
|
||||
|
||||
#define R_EXCEPT 100000 /* permet de savoir si le except a ete fait dans le niveau de code */
|
||||
//R_EXCEPT = 100000, /* permet de savoir si le except a ete fait dans le niveau de code */
|
||||
|
||||
#define TERM_ERR 0
|
||||
#define TERM_NUM 1
|
||||
#define TERM_STR 2
|
||||
#define TERM_VARSYS 3
|
||||
#define TERM_PAR 4
|
||||
#define TERM_ENDPAR 5
|
||||
#define TERM_VAR 6
|
||||
#define TERM_ENDH 7
|
||||
#define TERM_ENDS 8
|
||||
#define TERM_FN 256 /* terme fn() : > 256 */
|
||||
TERM_ERR = 0,
|
||||
TERM_NUM = 1,
|
||||
TERM_STR = 2,
|
||||
TERM_VARSYS = 3,
|
||||
TERM_PAR = 4,
|
||||
TERM_ENDPAR = 5,
|
||||
TERM_VAR = 6,
|
||||
TERM_ENDH = 7,
|
||||
TERM_ENDS = 8,
|
||||
TERM_FN = 256, /* terme fn() : > 256 */
|
||||
|
||||
#define VAR_ERR 0
|
||||
#define VAR_OK 1
|
||||
VAR_ERR = 0,
|
||||
VAR_OK = 1
|
||||
};
|
||||
|
||||
#define sNUM_ZERO_NEUF "0,100000,200000,300000,400000,500000,600000,700000,800000,900000;PSH0,PSH1,PSH2,PSH3,PSH4,PSH5,PSH6,PSH7,PSH8,PSH9"
|
||||
|
||||
env e;
|
||||
|
||||
Dynamic fichier; /* contient le/les fichiers sources en cours de traitement */
|
||||
Dynamic token; /* contient les tokens suite au decodage lex d'une ligne */
|
||||
ent16 tok,tok2,tok3,tok4; /* token lu par la macro ci-dessous "nreg" */
|
||||
long n; /* indice en cours dans les token (parametre de la macro "nreg") */
|
||||
#define nreg(x) ((x)*4 > token.mLg ? 0 : *(ent16 *)(token.mPtr + (x)*4 - 4)) // maxi : 65535 regles...
|
||||
#define norig(x) ((x)*4 > token.mLg ? x : *(ent16 *)(token.mPtr + (x)*4 - 2)) // numero de sous-champ originel dans valex<1 2 3>
|
||||
|
||||
ent16 nreg(int x)
|
||||
{
|
||||
return ((x)*4 > token.mLg ? 0 : *(ent16 *)(token.mPtr + (x)*4 - 4));
|
||||
}
|
||||
|
||||
ent16 norig(int x)
|
||||
{
|
||||
return ((x)*4 > token.mLg ? x : *(ent16 *)(token.mPtr + (x)*4 - 2));
|
||||
}
|
||||
|
||||
Dynamic prio; /* pile des priorites dans les expressions, 0 = expr vide = erreur
|
||||
prio<iImbricPrio,iPrio> = priorite du niveau iPrio "," operateur du niveau iPrio (pour l'imbrication)
|
||||
@@ -67,13 +79,9 @@ Dynamic prio; /* pile des priorites dans les expressions, 0 = expr vide = erre
|
||||
long iPrio; /* indice en cours dans la pile prio, 0 pas d'expr en cours */
|
||||
long iImbriPrio; /* niveau d'imbrication des expressions, 1 la premiere expression ; donne l'attribut en cours de "prio" */
|
||||
|
||||
Dynamic src; /* pile des fichiers sources : sert a gerer les include et l'instruction INCL
|
||||
<1,x> = nom source ; <2,x> = nb lignes ; <3,x> = numlig en cours lors de l'include, pour restaurer au retour */
|
||||
long iSrc; /* indice dans la pile src, 1 = nom prog principal, 2 = nom include, etc. */
|
||||
int numlig; /* numero ligne de source en cours */
|
||||
int numatt; /* numero "attribut" (separateur \n) pour gestion des include */
|
||||
char * wsrc; /* pointeur sur la var d'env WSRC point de depart des sources */
|
||||
Dynamic wdir; /* contient les fichiers dans l'arborescence WSRC */
|
||||
Dynamic wdir; /* contient les repertoires dans l'arborescence WSRC */
|
||||
Dynamic srcdbg; /* contient les num lignes / nom des sources en gerant les "include" */
|
||||
|
||||
Dynamic instrNiv; /* en MV, <1> = type P/S/L/F/I <2> = id unique <3> = indice if/elseif */
|
||||
@@ -81,12 +89,6 @@ long numNiv; /* numero de niveau en cours */
|
||||
long idNiv; /* numero unique de chaque instruction qui cree un niveau */
|
||||
Dynamic label; /* label formatte selon le contexte (:i<niv>.<id>.<ind>, etc.) */
|
||||
|
||||
Dynamic interp; /* en mode "interpreter" : contient les instruction de la ligne de source courante */
|
||||
/* pour la gestion du mode interprete, macro pour simplifier le code */
|
||||
#define INSTR(e,x) {if(dynCtrl(e,&interp,interp.mLg+3,TRUE)==DYN_OK){*(short*)(interp.mPtr+interp.mLg)=(short)(1);*(interp.mPtr+interp.mLg+2)=*(char*)x;interp.mLg+=3;}}
|
||||
#define INSTR_D1(e,x,d) {if(dynCtrl(e,&interp,interp.mLg+4,TRUE)==DYN_OK){*(short*)(interp.mPtr+interp.mLg)=(short)(2);*(interp.mPtr+interp.mLg+2)=*(char*)x;*(interp.mPtr+interp.mLg+3)=(d&255);interp.mLg+=4;}}
|
||||
#define INSTR_D3(e,x,d) {if(dynCtrl(e,&interp,interp.mLg+6,TRUE)==DYN_OK){*(short*)(interp.mPtr+interp.mLg)=(short)(4);*(interp.mPtr+interp.mLg+2)=*(char*)x;*(interp.mPtr+interp.mLg+3)=((d>>16)&255);*(interp.mPtr+interp.mLg+4)=((d>>8)&255);*(interp.mPtr+interp.mLg+5)=(d&255);interp.mLg+=6;}}
|
||||
|
||||
Dynamic trav; /* variable de travail */
|
||||
Dynamic envers; /* variable de travail pour empiler les params a l'envers */
|
||||
Dynamic dercode;/* pour la gestion des variables de hash a gauche du signe " = " (methode variable() ) */
|
||||
@@ -121,15 +123,12 @@ static int clock_gettime_monotonic(struct timespec * tv)
|
||||
long init(env * e)
|
||||
{
|
||||
/* initialisations diverses */
|
||||
dynInit(e, &fichier, 0);
|
||||
dynInit(e, &prio, 0);
|
||||
dynInit(e, &label, 0);
|
||||
dynInit(e, &instrNiv, 0);
|
||||
dynInit(e, &src, 0);
|
||||
dynInit(e, &token, 0);
|
||||
dynInit(e, &trav, 0);
|
||||
dynInit(e, &envers, 0);
|
||||
dynInit(e, &interp, 0);
|
||||
dynInit(e, &dercode, 0);
|
||||
dynInit(e, &wdir, 0);
|
||||
dynInit(e, &srcdbg, 0);
|
||||
@@ -137,9 +136,7 @@ long init(env * e)
|
||||
iImbriPrio = 1;
|
||||
numNiv = 0;
|
||||
idNiv = 0;
|
||||
iSrc = 0;
|
||||
numlig = 0;
|
||||
numatt = 0;
|
||||
return OK; /* TODO controles */
|
||||
}
|
||||
|
||||
@@ -149,11 +146,8 @@ void fin(env * e)
|
||||
dynFree(e, &prio);
|
||||
dynFree(e, &label);
|
||||
dynFree(e, &instrNiv);
|
||||
dynFree(e, &src);
|
||||
dynFree(e, &fichier);
|
||||
dynFree(e, &token);
|
||||
dynFree(e, &envers);
|
||||
dynFree(e, &interp);
|
||||
dynFree(e, &dercode);
|
||||
dynFree(e, &wdir);
|
||||
dynFree(e, &srcdbg);
|
||||
@@ -199,11 +193,13 @@ struct {
|
||||
} r;
|
||||
/* les 2 fonctions fictives ci dessous doivent avoir un numero < 512 et > au max de "r" ci-dessus */
|
||||
/* servent a gerer la notation x{1,2}[3,4] */
|
||||
#define FN_FIELD 500
|
||||
#define FN_SUBSTR 501
|
||||
#define FN_SETSEP 502
|
||||
#define FN_SETFLD 503 // pour : let x{1,2] = ...}
|
||||
#define FN_SETSUBSTR 504 // pour : let x[x,y] ou x{1,2}[a,b]
|
||||
enum {
|
||||
FN_FIELD = 500,
|
||||
FN_SUBSTR = 501,
|
||||
FN_SETSEP = 502,
|
||||
FN_SETFLD = 503, // pour : let x{1,2] = ...}
|
||||
FN_SETSUBSTR = 504 // pour : let x[x,y] ou x{1,2}[a,b]
|
||||
};
|
||||
|
||||
void init_reg(env * e, Dynamic * regles, Dynamic * tmp)
|
||||
{
|
||||
@@ -373,7 +369,7 @@ long variable(env * e, Dynamic * resultat, Dynamic * valex, Dynamic * tmp, Dynam
|
||||
/* si *aGauche = 1 : permet de faire PHDE PIDE, sinon que PVAH PVAI (a droite du =) => mis a jour avec 2 si le dernier est bien PHDE/PIDE */
|
||||
/* renvoi VAR_OK ou VAR_ERR */
|
||||
tok = nreg(n);
|
||||
if(tok != r.ident)
|
||||
if(tok != r.ident && tok != r.this && tok != r.parent)
|
||||
return VAR_ERR;
|
||||
dynField(e, valex, tmp, 1, norig(n), cFM, cVM, 1);
|
||||
dynIconv(e, tmp, encours, "X");
|
||||
@@ -502,12 +498,14 @@ long terme(env * e, ent16 t, Dynamic * valex, Dynamic * tmp, Dynamic * encours)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define PRIO1 1
|
||||
#define PRIO2 2
|
||||
#define PRIO3 3
|
||||
#define PRIO4 4
|
||||
#define PRIO5 5
|
||||
#define PRIO0 6 // pseudo priorite => " , " => nouveau parametre (si fonction en cours)
|
||||
enum {
|
||||
PRIO1 = 1,
|
||||
PRIO2 = 2,
|
||||
PRIO3 = 3,
|
||||
PRIO4 = 4,
|
||||
PRIO5 = 5,
|
||||
PRIO0 = 6 // pseudo priorite => " , " => nouveau parametre (si fonction en cours)
|
||||
};
|
||||
|
||||
long tokprio(ent16 t)
|
||||
{
|
||||
@@ -825,9 +823,21 @@ long expr(env * e, Dynamic * resultat, Dynamic * valex, Dynamic * tmp, Dynamic *
|
||||
if(termType == TERM_NUM)
|
||||
{
|
||||
/* empiler le terme en assembleur <number> */
|
||||
dynConcatSz(e, resultat, "PSHC ", DYN_LGNONE);
|
||||
dynConcat(e, resultat, encours);
|
||||
/* recherche si constante de 0 à 9 pour instruction PSHx */
|
||||
dynLet(e, tmp, sNUM_ZERO_NEUF, DYN_LGNONE);
|
||||
long pos = dynLocateSz(e, tmp, encours->mPtr, ',', 1, ';');
|
||||
if(pos > 0)
|
||||
{
|
||||
dynField(e, tmp, encours, 2, pos, ';', ',', 1);
|
||||
dynConcat(e, resultat, encours);
|
||||
}
|
||||
else
|
||||
{
|
||||
dynConcatSz(e, resultat, "PSHC ", DYN_LGNONE);
|
||||
dynConcat(e, resultat, encours);
|
||||
}
|
||||
dynConcatSz(e, resultat, "\n", DYN_LGNONE);
|
||||
//printf("PSHC: %s\n", encours->mPtr);
|
||||
/* chercher ENDPAR */
|
||||
//termType = terme(e, tok, valex, tmp, encours);
|
||||
}
|
||||
@@ -958,51 +968,6 @@ long expr(env * e, Dynamic * resultat, Dynamic * valex, Dynamic * tmp, Dynamic *
|
||||
return 0; /* OK */
|
||||
}
|
||||
|
||||
long lire_source(env * e, char * ficsrc, Dynamic * tmp, Dynamic * elem)
|
||||
{
|
||||
/* si deja present, erreur (include recursif interdit) */
|
||||
long pos = dynLocateSz(e, &src, ficsrc, cVM, 1, cFM);
|
||||
if(pos > 0)
|
||||
return -4;
|
||||
/* */
|
||||
// TODO a revoir pour chercher dans les sous repertoires
|
||||
//dynLet(e, elem, wsrc, DYN_LGNONE);
|
||||
//if(elem->mLg > 0)
|
||||
// dynConcatSz(e, elem, e->path_sep, 1);
|
||||
//dynConcatSz(e, elem, ficsrc, DYN_LGNONE);
|
||||
//if(dynRead(e, tmp, ficsrc) != OK)
|
||||
// return -2;
|
||||
//
|
||||
long nb,dup;
|
||||
ScanDirectory(e, NULL, &wdir, ficsrc, tmp, &nb, &dup);
|
||||
if(nb < 1)
|
||||
return -2; // fichier pas trouve
|
||||
dynField(e, tmp, elem, 1, DYN_NONE, cFM, DYN_NONE, 1);
|
||||
if(dynRead(e, tmp, elem->mPtr) != OK)
|
||||
return -2;
|
||||
//
|
||||
/* source dans <tmp> */
|
||||
dynErase(e, tmp, "\r");
|
||||
long nblig = dynDcount(e, tmp, '\n', DYN_NONE, DYN_NONE);
|
||||
if(nblig == 0)
|
||||
{
|
||||
/* include vide : mettre une ligne vide au moins */
|
||||
dynLet(e, tmp, " ", 1);
|
||||
nblig = 1;
|
||||
}
|
||||
/* */
|
||||
iSrc++;
|
||||
// insertion de l'include
|
||||
dynIns(e, &fichier, numatt + 1, DYN_NONE, tmp, '\n', DYN_NONE);
|
||||
/* */
|
||||
dynStoreSz(e, &src, 2, iSrc, Int64ToSz(e, nblig, FALSE, 0), DYN_LGNONE, cFM, cVM);
|
||||
dynStoreSz(e, &src, 3, iSrc, Int64ToSz(e, numlig, FALSE, 0), DYN_LGNONE, cFM, cVM);
|
||||
dynLet(e, tmp, ficsrc, DYN_LGNONE);
|
||||
//dynField(e, tmp, elem, dynDcount(e, tmp, e->path_sep[0], DYN_NONE, DYN_NONE), DYN_NONE, e->path_sep[0], DYN_NONE, 1);
|
||||
dynStore(e, &src, 1, iSrc, tmp, cFM, cVM);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/* Gestion des niveaux dans les structures de W : begin/sub/loop/for/if */
|
||||
|
||||
@@ -1106,7 +1071,7 @@ int RechercheLoopForNiveau(env * e)
|
||||
// recherche niveau foreach ou loop : seuls blocs dans lesquels break/continue sont possibles
|
||||
for(long niv = numNiv; niv > 0; niv--)
|
||||
{
|
||||
dynExtractSubField(e, &instrNiv, 1, numNiv, &label); // <label> = type
|
||||
dynExtractSubField(e, &instrNiv, 1, niv, &label); // <label> = type
|
||||
if(*label.mPtr == 'L' || *label.mPtr == 'F')
|
||||
return niv;
|
||||
}
|
||||
@@ -1115,17 +1080,13 @@ int RechercheLoopForNiveau(env * e)
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic * encours)
|
||||
long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic * encours, Dynamic * file)
|
||||
{
|
||||
numlig++;
|
||||
numatt++;
|
||||
/* */
|
||||
dynSetLen(e, &interp, 0); // memorise dans mLg la prochaine position ou ecrire lg (sur 2 octets) = longueur !
|
||||
/* */
|
||||
if(valex->mLg == 0)
|
||||
return OK; /* ligne vide */
|
||||
/* */
|
||||
//int nbres = dynDcount(e, resultat, 10, DYN_NONE, DYN_NONE);
|
||||
int nbval = dynDcount(e, valex, cVM, 2, cFM);
|
||||
if(dynCtrl(e, &token, nbval * 4, FALSE) != DYN_OK)
|
||||
return DYN_ERR;
|
||||
@@ -1133,8 +1094,6 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
for(ent16 ival = 1; ival <= nbval; ival++)
|
||||
{
|
||||
/* suppression des tokens 1 et 2 (blanc et commentaire) */
|
||||
//dynField(e, valex, tmp, 2, ival, cFM, cVM, 1);
|
||||
//tok = dynToNum(e, tmp, DYN_FALSE, 0);
|
||||
tok = (ent16)dynExtractSubFieldAsNumber(e, valex, 2, ival, tmp);
|
||||
if(tok != r.blank && tok != r.comment)
|
||||
{
|
||||
@@ -1142,30 +1101,14 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
*(ent16 *)(token.mPtr + token.mLg + 2) = ival;
|
||||
dynSetLen(e, &token, token.mLg + 4);
|
||||
}
|
||||
/*{
|
||||
dynDel(e, valex, 1, ival, cFM, cVM, 1);
|
||||
dynDel(e, valex, 2, ival, cFM, cVM, 1);
|
||||
dynDel(e, valex, 3, ival, cFM, cVM, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(dynCtrl(e, &token, token.mLg + 2, TRUE) != DYN_OK)
|
||||
return DYN_ERR;
|
||||
if(token.mLg > 0)
|
||||
memcopie(token.mPtr + 2, token.mPtr, token.mLg);
|
||||
*(ent16 *)(token.mPtr) = tok;
|
||||
dynSetLen(e, &token, token.mLg + 2);
|
||||
}*/
|
||||
}
|
||||
/* */
|
||||
//if(numlig==38) {for(int i=1;i<=token.mLg/4;i++) printf("%d,",nreg(i)); printf("\n");}
|
||||
/* debut d'analyse des tokens de la ligne de source w */
|
||||
long aGauche = 0;
|
||||
dynSetLen(e, encours, 0);
|
||||
n = 1;
|
||||
if((tok = nreg(n)) == 0 || token.mLg == 0)
|
||||
return OK; /* blancs et/ou commentaire seuls */
|
||||
// field(valex, n) a ete remplace par field(valex, norig(n))
|
||||
if(numNiv == -1)
|
||||
{
|
||||
dynField(e, valex, tmp, 3, norig(n), cFM, cVM, 1);
|
||||
@@ -1195,8 +1138,7 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
dynConcatSz(e, resultat, "BACK\nBEXC\nVERS ", DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, Int64ToSz(e, WVERS, FALSE, 0), DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, "\nINCL ", DYN_LGNONE);
|
||||
dynField(e, &src, tmp, 1, 1, cFM, cVM, 1);
|
||||
dynConcat(e, resultat, tmp);
|
||||
dynConcat(e, resultat, file);
|
||||
dynConcatSz(e, resultat, "\nSDBG ", DYN_LGNONE);
|
||||
dynConcat(e, resultat, &srcdbg);
|
||||
//dynConcatSz(e, resultat, "\nSRCL ", DYN_LGNONE);
|
||||
@@ -1234,8 +1176,7 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
dynConcatSz(e, resultat, "LIBR\nBEXC\nVERS ", DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, Int64ToSz(e, WVERS, FALSE, 0), DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, "\nINCL ", DYN_LGNONE);
|
||||
dynField(e, &src, tmp, 1, 1, cFM, cVM, 1);
|
||||
dynConcat(e, resultat, tmp);
|
||||
dynConcat(e, resultat, file);
|
||||
dynConcatSz(e, resultat, "\nSDBG ", DYN_LGNONE);
|
||||
dynConcat(e, resultat, &srcdbg); // FDE A tester TODO 02/08/2025
|
||||
dynConcatSz(e, resultat, "\n", 1);
|
||||
@@ -1364,22 +1305,24 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
if(encours->mLg < 1 || encours->mLg > 255)
|
||||
{
|
||||
dynField(e, valex, tmp, 3, norig(n), cFM, cVM, 1);
|
||||
printf("Erreur ligne %dc%s : fichier include incorrect\n", numlig, tmp->mPtr);
|
||||
printf("Erreur ligne %dc%s : longueur fichier include incorrect\n", numlig, tmp->mPtr);
|
||||
return DYN_ERR; /* TODO numeroter les erreurs */
|
||||
}
|
||||
if(lire_source(e, encours->mPtr, tmp, tmp) != OK)
|
||||
// include ne doit pas inclure de separateur de chemin, ni .. (est deja fait dans GetSource lors du ScanDirectory)
|
||||
if(dynIndexSz(e, encours, "..", 2, 1) != DYN_NOTFOUND ||
|
||||
dynIndexSz(e, encours, e->path_sep, 1, 1) != DYN_NOTFOUND )
|
||||
{
|
||||
dynField(e, valex, tmp, 3, norig(n), cFM, cVM, 1);
|
||||
printf("Erreur ligne %dc%s : lecture fichier include ko\n", numlig, tmp->mPtr);
|
||||
printf("Erreur ligne %dc%s : nom fichier include incorrect\n", numlig, tmp->mPtr);
|
||||
return DYN_ERR; /* TODO numeroter les erreurs */
|
||||
}
|
||||
// include deja mis dans <source>, mis ici pour info dans le compile
|
||||
dynConcatSz(e, resultat, "SRCL ", DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, Int64ToSz(e, numlig, FALSE, 0), DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, "\nINCL ", DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, encours->mPtr, DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, "\n", 1);
|
||||
/* */
|
||||
numlig = 0;
|
||||
return OK;
|
||||
}
|
||||
/* -------------------------------------------------------------------------------------- */
|
||||
@@ -1415,7 +1358,8 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
printf("Erreur ligne %dc%s : numero exception throw incorrect\n", numlig, tmp->mPtr);
|
||||
return DYN_ERR; /* TODO numeroter les erreurs */
|
||||
}
|
||||
if(numb < NUM_FACTEUR || numb > 0xFFFFFF)
|
||||
numb /= NUM_FACTEUR;
|
||||
if(numb < 1 || numb > 0xFFFFFF)
|
||||
{
|
||||
dynField(e, valex, tmp, 3, norig(n), cFM, cVM, 1);
|
||||
printf("Erreur ligne %dc%s : numero exception throw hors limite\n", numlig, tmp->mPtr);
|
||||
@@ -1424,7 +1368,7 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
dynConcatSz(e, resultat, "SRCL ", 5);
|
||||
dynConcatSz(e, resultat, Int64ToSz(e, numlig, FALSE, 0), DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, "\nTHRW ", 6);
|
||||
dynConcatSz(e, resultat, encours->mPtr, DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, Int64ToSz(e, numb, FALSE, 0), DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, "\n", 1);
|
||||
return OK;
|
||||
}
|
||||
@@ -1499,7 +1443,8 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
printf("Erreur ligne %dc%s : numero part incorrect\n", numlig, tmp->mPtr);
|
||||
return DYN_ERR; /* TODO numeroter les erreurs */
|
||||
}
|
||||
if(numb < 0 || numb > 255)
|
||||
numb /= NUM_FACTEUR;
|
||||
if(numb < 1 || numb > 255)
|
||||
{
|
||||
dynField(e, valex, tmp, 3, norig(n), cFM, cVM, 1);
|
||||
printf("Erreur ligne %dc%s : numero part hors limite\n", numlig, tmp->mPtr);
|
||||
@@ -1508,7 +1453,7 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
dynConcatSz(e, resultat, "SRCL ", 5);
|
||||
dynConcatSz(e, resultat, Int64ToSz(e, numlig, FALSE, 0), DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, "\nPART ", 6);
|
||||
dynConcatSz(e, resultat, encours->mPtr, DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, Int64ToSz(e, numb, FALSE, 0), DYN_LGNONE);
|
||||
dynConcatSz(e, resultat, "\n", 1);
|
||||
return OK;
|
||||
}
|
||||
@@ -2613,61 +2558,20 @@ long parse(env * e, Dynamic * valex, Dynamic * resultat, Dynamic * tmp, Dynamic
|
||||
return DYN_ERR;
|
||||
}
|
||||
|
||||
/* ***************************************************************************************************** */
|
||||
/* mode interprete */
|
||||
ent64 idecode(env * e, pointeur code, short lg)
|
||||
{
|
||||
/* IDEE : dans parse, preparer 2 resultats : 1 pour l'assembleur en mode compile et
|
||||
1 pour le mode interprete, pour enchainer les "idecode" si pas d'erreur,
|
||||
resultat interprete remis a zero a chaque nouvelle ligne, puis
|
||||
execution avec remove/idecode et gestion exception
|
||||
Attention aux adresses de SUB et LIBR : garder le mInternal du source !
|
||||
(exception de type "script incorrect" en plus ?)
|
||||
*/
|
||||
return OK; // en attendant
|
||||
}
|
||||
/* idecode est dans langage.c ; dans le wiki, mettre la transformation des instructions quand compile et interprete
|
||||
car selon les instructions, cela peut etre different ! */
|
||||
|
||||
int interprete(env * e)
|
||||
{
|
||||
/* interprete le code de la ligne en cours */
|
||||
/* renvoi un code indiquant comment continuer :
|
||||
0 : lire la ligne suivante
|
||||
1 : chercher le ENDP/ENDL du meme niveau
|
||||
2 : chercher le ENDS du meme niveau
|
||||
3 : chercher le EXCE du meme niveau
|
||||
*/
|
||||
if(!e->interpreter) return 0; /* securite */
|
||||
/* Les donnes etant en binaire, on ecrit d'abord la longueur sur 2 octets puis les octets */
|
||||
short lg = 0;
|
||||
for(int pos = 0;pos < interp.mLg; pos += lg)
|
||||
{
|
||||
lg = *(short *)(interp.ptr + pos);
|
||||
pos += 2;
|
||||
/* gerer les cas particuliers : do library, etc. */
|
||||
if(idecode(e, interp.ptr + pos, lg) != OK) ;
|
||||
}
|
||||
INSTR(e, IS_PROG)
|
||||
INSTR_D1(e, IS_PART, 1)
|
||||
INSTR_D3(e, IS_BEXC, 0)
|
||||
INSTR(e, IS_ENDP)
|
||||
return 0;
|
||||
}
|
||||
/* ***************************************************************************************************** */
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
Dynamic valex, ligne, resultat, elem1, elem2, elem3, regles;
|
||||
int ret = 0, lg;
|
||||
Dynamic valex, ligne, resultat, source, tmp, file, regles, arg, wsrc, wlib, encours;
|
||||
int ret = 0;
|
||||
/* */
|
||||
/* avis de licence */
|
||||
printf("W language Copyright 2024,2025 lanisys.fr\n");
|
||||
printf("This program comes with ABSOLUTELY NO WARRANTY;\nThis is free software, and you are welcome to redistribute it\nunder certain conditions (GPL-3.0-or-later)\n\n");
|
||||
/* argument : fichier w a convertir en assembleur w */
|
||||
if(argc != 2)
|
||||
if(argc < 2)
|
||||
{
|
||||
printf("Usage: genw <fichier.w>\n");
|
||||
printf("Usage: lwc [-WSRC:<path>] [-WLIB:<path>] <file.w>\n");
|
||||
exit(-1);
|
||||
}
|
||||
/* */
|
||||
@@ -2682,73 +2586,95 @@ int main(int argc, char * argv[])
|
||||
dynInit(&e, &valex, 0);
|
||||
dynInit(&e, &ligne, 0);
|
||||
dynInit(&e, &resultat, 0);
|
||||
dynInit(&e, &elem1, 0);
|
||||
dynInit(&e, &elem2, 0);
|
||||
dynInit(&e, &elem3, 0);
|
||||
dynInit(&e, &source, 0);
|
||||
dynInit(&e, &tmp, 0);
|
||||
dynInit(&e, &file, 0);
|
||||
dynInit(&e, ®les, 0);
|
||||
dynInit(&e, &arg, 0);
|
||||
dynInit(&e, &wsrc, 0);
|
||||
dynInit(&e, &wlib, 0);
|
||||
dynInit(&e, &encours, 0);
|
||||
/* */
|
||||
lg = strlen(argv[1]);
|
||||
if(lg < 3)
|
||||
GetArgs(&e, argc, argv, &arg);
|
||||
dynExtractField(&e, &arg, 4, &wsrc);
|
||||
dynExtractField(&e, &arg, 5, &wlib);
|
||||
dynExtractSubField(&e, &arg, 2, 1, &file); // file = fichier.w a compiler
|
||||
/* */
|
||||
for(;;)
|
||||
{
|
||||
printf("Nom de fichier incorrect\n");
|
||||
ret = -2;
|
||||
}
|
||||
else if(argv[1][lg-1] != 'w' && argv[1][lg-2] != '.')
|
||||
{
|
||||
printf("Nom de fichier incorrect\n");
|
||||
ret = -2;
|
||||
}
|
||||
else if( ! (wsrc = getenv("WSRC")))
|
||||
{
|
||||
printf("Variable d'environnement WSRC introuvable\n");
|
||||
ret = -6;
|
||||
}
|
||||
else
|
||||
{
|
||||
long nb,dup;
|
||||
ScanDirectory(&e, wsrc, &wdir, NULL, &elem1, &nb, &dup); // init
|
||||
if(file.mLg < 3)
|
||||
{
|
||||
printf("Nom de fichier incorrect\n");
|
||||
ret = -2;
|
||||
break;
|
||||
}
|
||||
if(file.mPtr[file.mLg - 1] != 'w' && file.mPtr[file.mLg - 2] != '.')
|
||||
{
|
||||
printf("Nom de fichier incorrect\n");
|
||||
ret = -2;
|
||||
break;
|
||||
}
|
||||
if(wsrc.mLg == 0)
|
||||
{
|
||||
printf("Variable d'environnement WSRC non definie\n");
|
||||
ret = -6;
|
||||
break;
|
||||
}
|
||||
if(wlib.mLg == 0)
|
||||
{
|
||||
printf("Variable d'environnement WLIB non definie\n");
|
||||
ret = -6;
|
||||
break;
|
||||
}
|
||||
//
|
||||
if((ret = lire_source(&e, argv[1], &elem1, &elem2)) != OK)
|
||||
long nb,dup;
|
||||
if( ScanDirectory(&e, wsrc.mPtr, &wdir, NULL, &source, &nb, &dup) != 1) // init : inutile de rappeler ScanDirectory avec arg4 = NULL
|
||||
{
|
||||
printf("Erreur d'acces au fichier '%s'\n", argv[1]);
|
||||
printf("Erreur d'acces aux fichiers/repertoires de %s\n", wsrc.mPtr);
|
||||
ret = -3;
|
||||
break;
|
||||
}
|
||||
else
|
||||
//
|
||||
if((ret = GetSource(&e, &wdir, file.mPtr, &source, &srcdbg)))
|
||||
{
|
||||
GetSource(&e, wsrc, argv[1], &elem1, &srcdbg);
|
||||
//#ifdef WINLIB
|
||||
//if(lire_regles_lex(&e, ®les, "C:\\Users\\Poupougne42\\source\\repos\\win_w_src\\lex\\wlex") != DYN_OK) // A parametrer
|
||||
//#else
|
||||
//if(lire_regles_lex(&e, ®les, "/etc/wlanguage/wlex") != DYN_OK) // au lieu de lex/wlex
|
||||
//#endif
|
||||
if(lire_regles_lex(&e, ®les, "wlex") != DYN_OK)
|
||||
{
|
||||
printf("Erreur d'acces aux regles lex de w '%s'\n", "wlex");
|
||||
ret = -4;
|
||||
}
|
||||
else
|
||||
init_reg(&e, ®les, &elem1);
|
||||
printf("Fichier en entree/include inconnu ou en double, ou include en double/recursif => non autorise, code %d\n", ret);
|
||||
ret = -7;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(ret == 0)
|
||||
{
|
||||
long nbSrcdbg = dynDcount(&e, &srcdbg, cVM, META_GLOBAL_LN, cFM);
|
||||
if(wsrc.mPtr[wsrc.mLg - 1] != e.path_sep[0])
|
||||
dynConcatSz(&e, &wsrc, e.path_sep, 1); // ajoute le / si absent a la fin
|
||||
dynStore(&e, &srcdbg, META_WSRC, DYN_NONE, &wsrc, cFM, DYN_NONE);
|
||||
//
|
||||
if(lire_regles_lex(&e, ®les, "wlex") != DYN_OK)
|
||||
{
|
||||
printf("Erreur d'acces aux regles lex de w '%s'\n", "wlex");
|
||||
ret = -4;
|
||||
break;
|
||||
}
|
||||
init_reg(&e, ®les, &tmp);
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* resultat contient l'assembleur wa du source en entree */
|
||||
dynRemove(&e, &fichier, NULL, 0, DYN_TRUE);
|
||||
while(dynRemove(&e, &fichier, &ligne, 10, DYN_FALSE) > -1 && ret == 0)
|
||||
long currentLevel = 1, level = 0;
|
||||
dynRemove(&e, &source, NULL, 0, DYN_TRUE);
|
||||
while(dynRemove(&e, &source, &ligne, 10, DYN_FALSE) > -1 && ret == 0)
|
||||
{
|
||||
lex(&e, ®les, &ligne, &valex);
|
||||
/* */
|
||||
ret = parse(&e, &valex, &resultat, &elem1, &elem2);
|
||||
ret = parse(&e, &valex, &resultat, &tmp, &encours, &file);
|
||||
/* */
|
||||
dynField(&e, &src, &elem1, 2, iSrc, cFM, cVM, 1);
|
||||
if(ret == 0 && iSrc > 1 && numlig >= dynToNum(&e, &elem1, FALSE, 0))
|
||||
if(ret == 0)
|
||||
{
|
||||
/* descendre d'un niveau de source */
|
||||
dynDel(&e, &src, 1, iSrc, cFM, cVM, 1);
|
||||
dynField(&e, &src, &elem1, 3, iSrc, cFM, cVM, 1);
|
||||
numlig = dynToNum(&e, &elem1, FALSE, 0);
|
||||
dynConcatSz(&e, &resultat, "INCL\n", 5); /* inutile en mode interprete */
|
||||
iSrc--;
|
||||
dynFmtNumber(&e, numlig, &tmp, 'R', '0', 8);
|
||||
long pos = dynSortLocateSz(&e, &srcdbg, tmp.mPtr, cVM, DYN_SORT_ASC, META_GLOBAL_LN, cFM);
|
||||
if(pos < 0)
|
||||
pos = abs(pos) - 1;
|
||||
if(pos > nbSrcdbg)
|
||||
pos = nbSrcdbg;
|
||||
level = dynFieldAsNumber(&e, &srcdbg, META_LEVEL, pos, cFM, cVM);
|
||||
if(level < currentLevel)
|
||||
dynConcatSz(&e, &resultat, "INCL\n", 5); /* juste informatif, en lisant le compile ; la gestion passe par _srcdbg */
|
||||
currentLevel = level;
|
||||
}
|
||||
}
|
||||
/* */
|
||||
@@ -2760,25 +2686,32 @@ int main(int argc, char * argv[])
|
||||
if(ret == 0)
|
||||
{
|
||||
printf("Result : OK, lines=%d\n", numlig);
|
||||
dynLet(&e, &elem1, argv[1], DYN_LGNONE);
|
||||
dynConcatSz(&e, &elem1, "a", 1);
|
||||
dynWrite(&e, &resultat, elem1.mPtr);
|
||||
/* */
|
||||
if(wlib.mPtr[wlib.mLg - 1] != e.path_sep[0])
|
||||
dynConcatSz(&e, &wlib, e.path_sep, 1);
|
||||
dynConcat(&e, &wlib, &file);
|
||||
dynConcatSz(&e, &wlib, "a", 1);
|
||||
dynWrite(&e, &resultat, wlib.mPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
dynField(&e, &fichier, &elem1, numlig, DYN_NONE, 10, DYN_NONE, 1);
|
||||
printf("Result : error %d line %d => %s\n", ret, numlig, elem1.mPtr);
|
||||
dynField(&e, &source, &ligne, numlig, DYN_NONE, 10, DYN_NONE, 1);
|
||||
printf("Result : error %d line %d => %s\n", ret, numlig, ligne.mPtr);
|
||||
}
|
||||
/* */
|
||||
break;
|
||||
}
|
||||
fin(&e);
|
||||
dynFree(&e, &valex);
|
||||
dynFree(&e, &ligne);
|
||||
dynFree(&e, &resultat);
|
||||
dynFree(&e, &elem1);
|
||||
dynFree(&e, &elem2);
|
||||
dynFree(&e, &elem3);
|
||||
dynFree(&e, &source);
|
||||
dynFree(&e, &tmp);
|
||||
dynFree(&e, &file);
|
||||
dynFree(&e, ®les);
|
||||
dynFree(&e, &arg);
|
||||
dynFree(&e, &wsrc);
|
||||
dynFree(&e, &wlib);
|
||||
dynFree(&e, &encours);
|
||||
/* */
|
||||
if(clock_gettime_monotonic(&ts) != -1)
|
||||
lap = ts.tv_sec * 1000000 + (ts.tv_nsec / 1000) - lap;
|
||||
@@ -2791,3 +2724,4 @@ int main(int argc, char * argv[])
|
||||
printf("(%llu s)\n", lap/1000000);
|
||||
exit(ret);
|
||||
}
|
||||
|
||||
@@ -25,9 +25,19 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "langage.h"
|
||||
#include "dynamic.h"
|
||||
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
/* met a jour le minimum de <env> pour pouvoir utiliser <dynamic.h> sans erreur... */
|
||||
void init_env(env * e)
|
||||
WAPIDECL void init_env(env * e)
|
||||
{
|
||||
int i,j,k;
|
||||
/* endianess */
|
||||
@@ -55,7 +65,7 @@ void init_env(env * e)
|
||||
e->sep_subfield = '\xFD'; // cVM
|
||||
}
|
||||
|
||||
char * copy_nom(env * e, const char * s)
|
||||
WAPIDECL char * copy_nom(env * e, const char * s)
|
||||
{
|
||||
e->nom64[0] = 0;
|
||||
e->nom64[1] = 0;
|
||||
@@ -66,7 +76,7 @@ char * copy_nom(env * e, const char * s)
|
||||
return e->nom;
|
||||
}
|
||||
|
||||
int modFnIs(env * e, const char * fn, int lg)
|
||||
WAPIDECL int modFnIs(env * e, const char * fn, int lg)
|
||||
{
|
||||
// modifier l'endroit ou e->fn est mis a jour : verif fn64[0 1 2] est bien remis a zero avant la maj
|
||||
ent64 f[3];
|
||||
@@ -81,7 +91,7 @@ int modFnIs(env * e, const char * fn, int lg)
|
||||
/* fonctions wrapper au cas ou on aurait besoin de ne plus utiliser certaines */
|
||||
/* fonctions standards (malloc, etc.) */
|
||||
|
||||
void * memalloc(env * e, ent64 taille)
|
||||
WAPIDECL void * memalloc(env * e, ent64 taille)
|
||||
{
|
||||
void * ptr;
|
||||
taille += sizeof(ent64);
|
||||
@@ -109,7 +119,7 @@ void * memalloc(env * e, ent64 taille)
|
||||
}
|
||||
}
|
||||
|
||||
void memfree(env * e, void * ptr)
|
||||
WAPIDECL void memfree(env * e, void * ptr)
|
||||
{
|
||||
if(ptr != NULL)
|
||||
{
|
||||
@@ -129,7 +139,7 @@ void memfree(env * e, void * ptr)
|
||||
}
|
||||
}
|
||||
|
||||
void memcopie(void * dst, void * src, long nb)
|
||||
WAPIDECL void memcopie(void * dst, void * src, long nb)
|
||||
{
|
||||
if(dst == src || nb <= 0)
|
||||
return;
|
||||
@@ -147,7 +157,55 @@ void memcopie(void * dst, void * src, long nb)
|
||||
// for (char *p=src, *q=dst; --n>=0; ) q[n]=p[n]; // fin au debut
|
||||
}
|
||||
|
||||
void hex(pointeur ch, int lg)
|
||||
WAPIDECL void dynPrintfSz(env * e, const char * format, char * valeur)
|
||||
{
|
||||
dynConcatSz(e, &e->printf, (char *)format, DYN_LGNONE);
|
||||
if(valeur)
|
||||
dynChange(e, &e->printf, PRINTF_MARK, valeur, DYN_ALL);
|
||||
}
|
||||
|
||||
WAPIDECL void dynPrintfInt64(env * e, const char * format, ent64s valeur, long nb)
|
||||
{
|
||||
dynConcatSz(e, &e->printf, (char *)format, DYN_LGNONE);
|
||||
dynChange(e, &e->printf, PRINTF_MARK, Int64ToSz(e, valeur, DYN_TRUE, nb), DYN_ALL);
|
||||
}
|
||||
|
||||
WAPIDECL void dynPrintfHex(env * e, const char * format, ent64 valeur, long nb)
|
||||
{
|
||||
static char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||
char conv[17] = "0000000000000000";
|
||||
conv[16] = 0;
|
||||
dynConcatSz(e, &e->printf, (char *)format, DYN_LGNONE);
|
||||
int i;
|
||||
for(i = 15; i >=0 && valeur != 0; i--, valeur /= 16)
|
||||
conv[i] = hex[valeur % 16];
|
||||
//
|
||||
if(nb > 0 && nb < 17)
|
||||
nb = 16 - nb;
|
||||
else
|
||||
nb = i + 1;
|
||||
dynChange(e, &e->printf, PRINTF_MARK, conv + nb, DYN_ALL);
|
||||
}
|
||||
|
||||
WAPIDECL void dynPrintfConcatHexSz(env * e, char * valeur, long lg)
|
||||
{
|
||||
static char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||
char car[3] = {0};
|
||||
for(long i = 0; i < lg; i++)
|
||||
{
|
||||
car[0] = hex[((unsigned char)valeur[i]) >> 4];
|
||||
car[1] = hex[((unsigned char)valeur[i]) & 15];
|
||||
dynConcatSz(e, &e->printf, car, 2);
|
||||
if(i % 32 == 31 && i < lg - 1)
|
||||
dynConcatSz(e, &e->printf, "\n ", 4);
|
||||
else if(i % 8 == 7 && i < lg - 1)
|
||||
dynConcatSz(e, &e->printf, " | ", 3);
|
||||
else
|
||||
dynConcatSz(e, &e->printf, " ", 1);
|
||||
}
|
||||
}
|
||||
|
||||
WAPIDECL void hex(pointeur ch, int lg)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
@@ -167,7 +225,7 @@ void hex(pointeur ch, int lg)
|
||||
printf(" > %s\n", a);
|
||||
}
|
||||
|
||||
void hex2(char * ch, int lg, int nbpl)
|
||||
WAPIDECL void hex2(char * ch, int lg, int nbpl)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
@@ -210,12 +268,18 @@ void hex2(char * ch, int lg, int nbpl)
|
||||
printf(" (%6d) %s\n", i, a);
|
||||
}
|
||||
|
||||
void hex3(const char * p, long lg)
|
||||
WAPIDECL void hex3(const char * p, long lg)
|
||||
{
|
||||
static char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
|
||||
// affiche en hexa la chaine sur une ligne
|
||||
printf("=> ");
|
||||
for(long i = 0; i < lg; i++)
|
||||
{
|
||||
printf("%c%c ", hex[((unsigned char)p[i]) >> 4], hex[((unsigned char)p[i]) & 15]);
|
||||
if(i % 32 == 31 && i < lg - 1)
|
||||
printf("\n ");
|
||||
else if(i % 8 == 7 && i < lg - 1)
|
||||
printf(" | ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
@@ -23,23 +23,30 @@
|
||||
#ifndef GLOBAL_H
|
||||
#define GLOBAL_H
|
||||
|
||||
#include "apidecl.h"
|
||||
|
||||
void init_env(env * e);
|
||||
WAPIDECL void init_env(env * e);
|
||||
|
||||
char * copy_nom(env * e, const char * s);
|
||||
int modFnIs(env * e, const char * fn, int lg);
|
||||
WAPIDECL char * copy_nom(env * e, const char * s);
|
||||
WAPIDECL int modFnIs(env * e, const char * fn, int lg);
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* fonctions wrapper au cas ou on aurait besoin de ne plus utiliser certaines */
|
||||
/* fonctions standards (malloc, etc.) */
|
||||
|
||||
void * memalloc(env * e, ent64 taille);
|
||||
void memfree(env * e, void * ptr);
|
||||
void memcopie(void * dst, void * src, long nb);
|
||||
WAPIDECL void * memalloc(env * e, ent64 taille);
|
||||
WAPIDECL void memfree(env * e, void * ptr);
|
||||
WAPIDECL void memcopie(void * dst, void * src, long nb);
|
||||
|
||||
void hex(pointeur ch, int lg);
|
||||
void hex2(char * ch, int lg, int nbpl);
|
||||
void hex3(const char * p, long lg);
|
||||
#define PRINTF_MARK "\1"
|
||||
WAPIDECL void dynPrintfSz(env * e, const char * format, char * valeur);
|
||||
WAPIDECL void dynPrintfInt64(env * e, const char * format, ent64s valeur, long nb);
|
||||
WAPIDECL void dynPrintfHex(env * e, const char * format, ent64 valeur, long nb);
|
||||
WAPIDECL void dynPrintfConcatHexSz(env * e, char * valeur, long lg); // equiv hex3
|
||||
|
||||
WAPIDECL void hex(pointeur ch, int lg);
|
||||
WAPIDECL void hex2(char * ch, int lg, int nbpl);
|
||||
WAPIDECL void hex3(const char * p, long lg);
|
||||
|
||||
/* ************************************ */
|
||||
#endif
|
||||
@@ -301,13 +301,12 @@ void encodageMD4(char * entree, ent64 longueur, char * sortie)
|
||||
sortie[32] = 0;
|
||||
}
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
modEtat * p_etat;
|
||||
long exc = OK;
|
||||
@@ -333,7 +332,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(strncmp(e->fn, "init", 4) == 0)
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
@@ -346,7 +345,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//*** code specifique ici
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
// liberation specifique au module avant arret process
|
||||
if(p_etat != NULL)
|
||||
@@ -355,7 +354,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
memfree(e, p_etat);
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param1->type == VAR_DYNAMIC)
|
||||
@@ -365,7 +364,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
else if(strncmp(e->fn, "error", 5) == 0)
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
@@ -379,7 +378,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "MD2", 3) == 0)
|
||||
else if(modFnIs(e, "MD2", 3))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
// pour les vars en sortie, forcer le chgt de type si besoin ?
|
||||
@@ -393,7 +392,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "MD4", 3) == 0)
|
||||
else if(modFnIs(e, "MD4", 3))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
// pour les vars en sortie, forcer le chgt de type si besoin ?
|
||||
|
||||
+27
-11
@@ -28,6 +28,15 @@
|
||||
#include "var.h"
|
||||
#include "hashtable.h"
|
||||
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
// =============== PRIVATE ========================================================================
|
||||
|
||||
static entry * calc_entry(char * val, var * varht)
|
||||
@@ -74,7 +83,7 @@ static entry * calc_entry(char * val, var * varht)
|
||||
|
||||
// =============== PUBLIC ========================================================================
|
||||
|
||||
void hashtable_do(env * e, int action, var * varht, char * nom, var ** v)
|
||||
WAPIDECL void hashtable_do(env * e, int action, var * varht, char * nom, var ** v)
|
||||
{
|
||||
/* READ renvoi le ptr sur la var (ne fait pas une copie de la var)
|
||||
WRITE copie la var (si pas trouve ou trouve mais pointeurs differents)
|
||||
@@ -176,12 +185,12 @@ void hashtable_do(env * e, int action, var * varht, char * nom, var ** v)
|
||||
}
|
||||
}
|
||||
|
||||
var * hashtable_lastitemwritten(var * varht)
|
||||
WAPIDECL var * hashtable_lastitemwritten(var * varht)
|
||||
{
|
||||
return ((entry *)varht->ptr)->pvar;
|
||||
}
|
||||
|
||||
void hashtable_select(env * e, var * varht)
|
||||
WAPIDECL void hashtable_select(env * e, var * varht)
|
||||
{
|
||||
/* les 4 variables necessaires seront mises dans le groupe 0, premiere entree (celle servant au chainage) */
|
||||
/* dans la variable (content, inutilise) : */
|
||||
@@ -197,7 +206,7 @@ void hashtable_select(env * e, var * varht)
|
||||
pvar->ptr = (pointeur)(pentry+1); /* pentry */
|
||||
}
|
||||
|
||||
int hashtable_next(env * e, var * varht, char * nom, var ** v)
|
||||
WAPIDECL int hashtable_next(env * e, var * varht, char * nom, var ** v)
|
||||
{
|
||||
var * pvar;
|
||||
entry * pentry;
|
||||
@@ -236,7 +245,7 @@ int hashtable_next(env * e, var * varht, char * nom, var ** v)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void hashtable_free_ovf(env *e, var * varht)
|
||||
WAPIDECL void hashtable_free_ovf(env *e, var * varht)
|
||||
{
|
||||
/* libere les overflow de la hash table */
|
||||
/* pour chaque entree, chainage avant puis liberation en revenant en arriere */
|
||||
@@ -259,7 +268,7 @@ void hashtable_free_ovf(env *e, var * varht)
|
||||
/* reste a liberer le bloc primaire de la hashtable */
|
||||
}
|
||||
|
||||
void hashtable_clear(env * e, var * varht)
|
||||
WAPIDECL void hashtable_clear(env * e, var * varht)
|
||||
{
|
||||
var * pvar;
|
||||
int suivrepar = TRUE;
|
||||
@@ -275,7 +284,7 @@ void hashtable_clear(env * e, var * varht)
|
||||
hashtable_select(e, varht);
|
||||
}
|
||||
|
||||
long hashtable_count(env *e, var * varht)
|
||||
WAPIDECL long hashtable_count(env *e, var * varht)
|
||||
{
|
||||
long nb = 0;
|
||||
var * pvar;
|
||||
@@ -288,7 +297,7 @@ long hashtable_count(env *e, var * varht)
|
||||
return nb;
|
||||
}
|
||||
|
||||
void hashtable_printdebug(env * e, var * varht, int detail)
|
||||
WAPIDECL void hashtable_printdebug(env * e, var * varht, int detail)
|
||||
{
|
||||
entry * pentry; /* pointe sur une entree */
|
||||
entry * pchain; /* pointe sur la premiere du groupe, servant au chainage */
|
||||
@@ -303,7 +312,14 @@ void hashtable_printdebug(env * e, var * varht, int detail)
|
||||
varht = (var *)varht->ptr; /* travailler avec la var pointee ! */
|
||||
if(varht->type != VAR_HASHTABLE && varht->type != VAR_OBJECT)
|
||||
return;
|
||||
printf("hashtable modulo=%lld separateur=%lld (n=%lld)\n", varht->modulo, varht->separateur, varht->separateur/sizeof(entry));
|
||||
if(e->demon)
|
||||
{
|
||||
dynPrintfInt64(e, "hashtable modulo=" PRINTF_MARK " separateur=", varht->modulo, 0);
|
||||
dynPrintfInt64(e, PRINTF_MARK " (n=", varht->separateur, 0);
|
||||
dynPrintfInt64(e, PRINTF_MARK ")\n", varht->separateur/sizeof(entry), 0);
|
||||
}
|
||||
else
|
||||
printf("hashtable modulo=%lld separateur=%lld (n=%lld)\n", varht->modulo, varht->separateur, varht->separateur/sizeof(entry));
|
||||
/* */
|
||||
occ = 0;
|
||||
tot = 0;
|
||||
@@ -341,7 +357,7 @@ void hashtable_printdebug(env * e, var * varht, int detail)
|
||||
else
|
||||
printf("%c", e->var_car[pentry->content.type % 10]);
|
||||
/* */
|
||||
if(varht->type == VAR_OBJECT && strncmp((char *)&pentry->nom1, "_class", 6) == 0 && ! ptrClass)
|
||||
if(varht->type == VAR_OBJECT && strncmp((char *)&pentry->nom1, GUV_CLASS, 6) == 0 && ! ptrClass)
|
||||
ptrClass = pentry->content.mPtr;
|
||||
/* */
|
||||
occ += sizeof(entry);
|
||||
@@ -355,7 +371,7 @@ void hashtable_printdebug(env * e, var * varht, int detail)
|
||||
pchain = (entry *)((ent64)pchain_first + varht->separateur);
|
||||
}
|
||||
if(ptrClass)
|
||||
printf("_class : %s\n", ptrClass);
|
||||
printf("%s : %s\n", GUV_CLASS, ptrClass);
|
||||
printf("taille totale=%lld, occupee=%lld (taux %lld%%), nb item=%lld\n", tot, occ, occ * 100 / tot, nb);
|
||||
}
|
||||
|
||||
|
||||
+10
-8
@@ -23,15 +23,17 @@
|
||||
#ifndef HASHTABLE_H
|
||||
#define HASHTABLE_H
|
||||
|
||||
void hashtable_do(env * e, int action, var * varht, char * nom, var ** v);
|
||||
void hashtable_select(env * e, var * varht);
|
||||
int hashtable_next(env * e, var * varht, char * nom, var ** v);
|
||||
void hashtable_free_ovf(env *e, var * varht);
|
||||
void hashtable_clear(env *e, var * varht);
|
||||
long hashtable_count(env *e, var * varht);
|
||||
var * hashtable_lastitemwritten(var * varht);
|
||||
#include "apidecl.h"
|
||||
|
||||
void hashtable_printdebug(env * e, var * varht, int detail);
|
||||
WAPIDECL void hashtable_do(env * e, int action, var * varht, char * nom, var ** v);
|
||||
WAPIDECL void hashtable_select(env * e, var * varht);
|
||||
WAPIDECL int hashtable_next(env * e, var * varht, char * nom, var ** v);
|
||||
WAPIDECL void hashtable_free_ovf(env *e, var * varht);
|
||||
WAPIDECL void hashtable_clear(env *e, var * varht);
|
||||
WAPIDECL long hashtable_count(env *e, var * varht);
|
||||
WAPIDECL var * hashtable_lastitemwritten(var * varht);
|
||||
|
||||
WAPIDECL void hashtable_printdebug(env * e, var * varht, int detail);
|
||||
|
||||
/* ********************************************** */
|
||||
#endif
|
||||
@@ -1,3 +1,25 @@
|
||||
/* **********************************************
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
W language is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version (GPL-3.0-or-later).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
********************************************** */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "langage.h"
|
||||
@@ -29,32 +51,34 @@ typedef struct
|
||||
|
||||
/* mettre ici les codes d'erreurs specifiques au module */
|
||||
/* codes a passer a la fonction setError */
|
||||
#define EXMODJSON_MEM 106
|
||||
#define EXMODJSON_DECODE_INCORRECT_CHAR 101
|
||||
#define EXMODJSON_DECODE_KEYWORD_TRUE_EXPECTED 102
|
||||
#define EXMODJSON_DECODE_KEYWORD_FALSE_EXPECTED 103
|
||||
#define EXMODJSON_DECODE_KEYWORD_NULL_EXPECTED 104
|
||||
#define EXMODJSON_DECODE_INCORRECT_CHAR_IN_NUMBER 105
|
||||
#define EXMODJSON_DECODE_UNTERMINATED_STRING 107
|
||||
#define EXMODJSON_DECODE_UNEXPECTED_TOKEN_START_OBJECT 108
|
||||
#define EXMODJSON_DECODE_UNEXPECTED_TOKEN_START_ARRAY 109
|
||||
#define EXMODJSON_DECODE_UNEXPECTED_KEY 110
|
||||
#define EXMODJSON_DECODE_UNEXPECTED_VALUE 111
|
||||
#define EXMODJSON_DECODE_UNEXPECTED_TOKEN_NEXT 112
|
||||
#define EXMODJSON_DECODE_UNEXPECTED_TOKEN_END_OBJECT 113
|
||||
#define EXMODJSON_DECODE_UNEXPECTED_TOKEN_END_ARRAY 114
|
||||
#define EXMODJSON_DECODE_UNEXPECTED_ENDOFJSON 115
|
||||
enum {
|
||||
EXMODJSON_MEM = 106,
|
||||
EXMODJSON_DECODE_INCORRECT_CHAR = 101,
|
||||
EXMODJSON_DECODE_KEYWORD_TRUE_EXPECTED = 102,
|
||||
EXMODJSON_DECODE_KEYWORD_FALSE_EXPECTED = 103,
|
||||
EXMODJSON_DECODE_KEYWORD_NULL_EXPECTED = 104,
|
||||
EXMODJSON_DECODE_INCORRECT_CHAR_IN_NUMBER = 105,
|
||||
EXMODJSON_DECODE_UNTERMINATED_STRING = 107,
|
||||
EXMODJSON_DECODE_UNEXPECTED_TOKEN_START_OBJECT = 108,
|
||||
EXMODJSON_DECODE_UNEXPECTED_TOKEN_START_ARRAY = 109,
|
||||
EXMODJSON_DECODE_UNEXPECTED_KEY = 110,
|
||||
EXMODJSON_DECODE_UNEXPECTED_VALUE = 111,
|
||||
EXMODJSON_DECODE_UNEXPECTED_TOKEN_NEXT = 112,
|
||||
EXMODJSON_DECODE_UNEXPECTED_TOKEN_END_OBJECT = 113,
|
||||
EXMODJSON_DECODE_UNEXPECTED_TOKEN_END_ARRAY = 114,
|
||||
EXMODJSON_DECODE_UNEXPECTED_ENDOFJSON = 115
|
||||
};
|
||||
|
||||
/*
|
||||
Le decodage a besoin de mEncodeCle mEncodeValeur et la position de l'erreur si erreur (3 parametres ; en entree la position le flag "NoDQuote"). L'erreur est le code retour.
|
||||
L'encodage a besoin de mEncode, mId, flag NoDQuote (3 parametres)
|
||||
*/
|
||||
|
||||
int jsonInit(env * e, modContextJson * ctx);
|
||||
int jsonEnd(env * e, modContextJson * ctx);
|
||||
int jsonDecode(env * e, modContextJson * ctx, var * param1, var * param2, var * param3);
|
||||
int jsonPrint(env * e, modContextJson * ctx, var * param1, var * param2, var * param3);
|
||||
int jsonTreeFetch(env * e, modContextJson * ctx, var * param1, var * param2, var * param3);
|
||||
WAPIDECL int jsonInit(env * e, modContextJson * ctx);
|
||||
WAPIDECL int jsonEnd(env * e, modContextJson * ctx);
|
||||
WAPIDECL int jsonDecode(env * e, modContextJson * ctx, var * param1, var * param2, var * param3);
|
||||
WAPIDECL int jsonPrint(env * e, modContextJson * ctx, var * param1, var * param2, var * param3);
|
||||
WAPIDECL int jsonTreeFetch(env * e, modContextJson * ctx, var * param1, var * param2, var * param3);
|
||||
|
||||
/*
|
||||
|
||||
|
||||
@@ -43,13 +43,12 @@ static int setError(modEtat * p, int err)
|
||||
return err == OK ? OK : EX_MODERR;
|
||||
}
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
/* TODO : gestion des 3 parametres (au lieu d'un seul) */
|
||||
modEtat * p_etat;
|
||||
@@ -73,7 +72,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(strncmp(e->fn, "init", 4) == 0)
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
@@ -87,7 +86,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
exc = setError(p_etat, jsonInit(e, &p_etat->jsonCtx));
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
//*** code specifique ici
|
||||
exc = setError(p_etat, jsonEnd(e, &p_etat->jsonCtx));
|
||||
@@ -95,7 +94,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
if(p_etat != NULL)
|
||||
memfree(e, p_etat);
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
@@ -110,7 +109,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "error", 5) == 0)
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
@@ -126,7 +125,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "decode", 6) == 0)
|
||||
else if(modFnIs(e, "decode", 6))
|
||||
{
|
||||
if(param1 == NULL || param2 == NULL || param3 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
@@ -141,7 +140,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "print", 5) == 0)
|
||||
else if(modFnIs(e, "print", 5))
|
||||
{
|
||||
if(param1 == NULL || param2 == NULL || param3 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
@@ -154,7 +153,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
exc = setError(p_etat, jsonPrint(e, &p_etat->jsonCtx, param1, param2, param3));
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "treeFetch", 9) == 0)
|
||||
else if(modFnIs(e, "treeFetch", 9))
|
||||
{
|
||||
if(param1 == NULL || param2 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
|
||||
+53
-19
@@ -1,3 +1,25 @@
|
||||
/* **********************************************
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
W language is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version (GPL-3.0-or-later).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
********************************************** */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@@ -7,8 +29,16 @@
|
||||
#include "var.h"
|
||||
#include "hashtable.h"
|
||||
|
||||
#define LF 10
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------ */
|
||||
#define CAR_DQUOTE '"'
|
||||
#define CAR_MARQUE_CLE ':'
|
||||
#define CAR_DEBUT_OBJET '{'
|
||||
@@ -25,23 +55,27 @@
|
||||
#define STR_FIN_TABLEAU "]"
|
||||
#define STR_SUIVANT ","
|
||||
|
||||
#define DEBUT_FICHIER 0
|
||||
#define VALEUR_CHAINE 1
|
||||
#define VALEUR_NOMBRE 2
|
||||
#define VALEUR_CLE 3
|
||||
#define DEBUT_OBJET 4
|
||||
#define FIN_OBJET 5
|
||||
#define DEBUT_TABLEAU 6
|
||||
#define FIN_TABLEAU 7
|
||||
#define SUIVANT 8
|
||||
#define FIN_FICHIER 9
|
||||
enum {
|
||||
DEBUT_FICHIER = 0,
|
||||
VALEUR_CHAINE = 1,
|
||||
VALEUR_NOMBRE = 2,
|
||||
VALEUR_CLE = 3,
|
||||
DEBUT_OBJET = 4,
|
||||
FIN_OBJET = 5,
|
||||
DEBUT_TABLEAU = 6,
|
||||
FIN_TABLEAU = 7,
|
||||
SUIVANT = 8,
|
||||
FIN_FICHIER = 9,
|
||||
|
||||
#define ENCODE_OK 1
|
||||
#define ENCODE_ERREUR 0
|
||||
ENCODE_OK = 1,
|
||||
ENCODE_ERREUR = 0,
|
||||
|
||||
LF = 10
|
||||
};
|
||||
|
||||
/* =================================================================================== */
|
||||
|
||||
/* --------- JSON C --------- */
|
||||
/* --------- PRIVATE --------- */
|
||||
static void ConcatValue(env * e, modContextJson * ctx, char c)
|
||||
{
|
||||
char car[2];
|
||||
@@ -611,7 +645,7 @@ static int GetNextTreeFetch(env * e, treefetch * tree)
|
||||
*/
|
||||
|
||||
/* =================== PUBLIC ========================== */
|
||||
int jsonInit(env * e, modContextJson * ctx)
|
||||
WAPIDECL int jsonInit(env * e, modContextJson * ctx)
|
||||
{
|
||||
int cr = OK;
|
||||
//cr += dynInit(e, &ctx->mKeyList, DYN_LGMIN);
|
||||
@@ -636,7 +670,7 @@ int jsonInit(env * e, modContextJson * ctx)
|
||||
return (cr == OK ? OK : EXMODJSON_MEM);
|
||||
}
|
||||
|
||||
int jsonEnd(env * e, modContextJson * ctx)
|
||||
WAPIDECL int jsonEnd(env * e, modContextJson * ctx)
|
||||
{
|
||||
//dynFree(e, &ctx->mKeyList);
|
||||
//dynFree(e, &ctx->mCurrentKey);
|
||||
@@ -648,19 +682,19 @@ int jsonEnd(env * e, modContextJson * ctx)
|
||||
return OK;
|
||||
}
|
||||
|
||||
int jsonDecode(env * e, modContextJson * ctx, var * param1, var * param2, var * param3)
|
||||
WAPIDECL int jsonDecode(env * e, modContextJson * ctx, var * param1, var * param2, var * param3)
|
||||
{
|
||||
return Decode(e, ctx, param1->mPtr, param2, param3);
|
||||
}
|
||||
|
||||
int jsonPrint(env * e, modContextJson * ctx, var * param1, var * param2, var * param3)
|
||||
WAPIDECL int jsonPrint(env * e, modContextJson * ctx, var * param1, var * param2, var * param3)
|
||||
{
|
||||
char value[4] = " : \0", path = '/', index = '@';
|
||||
//
|
||||
return MakePrintable(e, ctx, param1, param2, param3, path, index, value);
|
||||
}
|
||||
|
||||
int jsonTreeFetch(env * e, modContextJson * ctx, var * param1, var * param2, var * param3)
|
||||
WAPIDECL int jsonTreeFetch(env * e, modContextJson * ctx, var * param1, var * param2, var * param3)
|
||||
{
|
||||
// KeyList, CurrentKey, Name, Value, DecodeCle, DecodeValue; // Dynamic
|
||||
// KeyField, KeyItem, KeyCount, ItemCount, Id, Parent, IdKey, ParentKey, ValuePresent; // Number
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024 lanisys.fr
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
@@ -23,16 +23,20 @@
|
||||
#ifndef LANGAGE_H
|
||||
#define LANGAGE_H
|
||||
|
||||
#define VERSION 1 // version "max" gere du pcode => version du "langage"
|
||||
enum {
|
||||
VERSION = 1 // version "max" gere du pcode => version du "langage"
|
||||
};
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define W_LITTLE_ENDIAN 1
|
||||
#define W_BIG_ENDIAN 0
|
||||
#define W_DEFAULT_ENDIAN 2 // celle de la plateforme d'execution
|
||||
enum {
|
||||
W_LITTLE_ENDIAN = 1,
|
||||
W_BIG_ENDIAN = 0,
|
||||
W_DEFAULT_ENDIAN = 2 // celle de la plateforme d'execution
|
||||
};
|
||||
|
||||
typedef unsigned char octet;
|
||||
typedef octet * pointeur; /* et pas "void *" ... */
|
||||
@@ -73,25 +77,27 @@ typedef ent64s number; /* 8 octets signes, virgule fixe */
|
||||
|
||||
/* les variables ne sont pas typees : elles peuvent changer de type au fur et a mesure des affectations */
|
||||
/* type 0 indique que l'emplacement n'a pas ete utilise encore : place disponible */
|
||||
#define VAR_NULL 1 /* variable declaree mais pas encore affectee d'une valeur */
|
||||
#define VAR_NUMBER 2 /* et @number */
|
||||
#define VAR_SUBROUTINE 3
|
||||
#define VAR_PARAM 4 /* adresse de la "vraie" variable, 1 seul niveau d'indirection, travail toujours sur la var "pointee" */
|
||||
#define VAR_DYNAMIC 5 /* et @string */
|
||||
#define VAR_HASHTABLE 6
|
||||
#define VAR_OBJECT 7 /* idem hashtable mais en objet : seule diff. element "_class" cree dans la table (interne) */
|
||||
#define VAR_BUFFER 8 /* usage interne : pile calcul + pile appel sub (autre ? buffer circulaire ptr read/write) */
|
||||
#define VAR_NB 8
|
||||
#define VAR_EMPTY 0 /* retour @empty */
|
||||
enum {
|
||||
VAR_NULL = 1, /* variable declaree mais pas encore affectee d'une valeur */
|
||||
VAR_NUMBER = 2, /* et @number */
|
||||
VAR_SUBROUTINE = 3,
|
||||
VAR_PARAM = 4, /* adresse de la "vraie" variable, 1 seul niveau d'indirection, travail toujours sur la var "pointee" */
|
||||
VAR_DYNAMIC = 5, /* et @string */
|
||||
VAR_HASHTABLE = 6,
|
||||
VAR_OBJECT = 7, /* idem hashtable mais en objet : seule diff. element "_class" cree dans la table (interne) */
|
||||
VAR_BUFFER = 8, /* usage interne : pile calcul + pile appel sub (autre ? buffer circulaire ptr read/write) */
|
||||
VAR_NB = 8,
|
||||
VAR_EMPTY = 0, /* retour @empty */
|
||||
|
||||
#define VAR_UNDECLARED -1
|
||||
VAR_UNDECLARED = -1,
|
||||
|
||||
#define CP_WIN1252 1252
|
||||
#define CP_8859_1 28591
|
||||
#define CP_8859_15 28605
|
||||
#define CP_UTF8 65001
|
||||
WCP_WIN1252 = 1252,
|
||||
WCP_8859_1 = 28591,
|
||||
WCP_8859_15 = 28605,
|
||||
WCP_UTF8 = 65001,
|
||||
|
||||
#define CP_DEFAULT CP_WIN1252 // UTF8 ??
|
||||
WCP_DEFAULT = WCP_WIN1252 // UTF8 ??
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
//union {
|
||||
@@ -163,8 +169,6 @@ typedef struct {
|
||||
v->ptr v->ptr v->misc
|
||||
*/
|
||||
|
||||
#define BUF_LGMINBLOC 16384 /* multiple de 32 sinon pile d'elements 8 et 16 octets KO, lgmax message = lg buffer / 32 (512 octets ici) */
|
||||
|
||||
typedef struct {
|
||||
/* buffer servant de stack pour number et string */
|
||||
number num; /* nombre si str == NULL */
|
||||
@@ -187,62 +191,67 @@ typedef struct {
|
||||
/* vrai buffer read = position a lire dans les donnees (a ajouter a ptr) ou prochaine position a ecrire (pile calcul et appel) */
|
||||
/* vrai buffer write = position a ecrire dans les donnees (a ajouter a ptr) ; si READ=WRITE : vide ! ou utilise en interne si pile */
|
||||
|
||||
#define OID_MAX 9999999999999999ll /* pour que l'OID reste sur 16 chiffres : 16 neufs ici */
|
||||
#define OID_MAX 999999999999999ll /* pour que l'OID reste sur 16 chiffres : 15 neufs ici, pour qu'un oid commence toujours par 0 ! */
|
||||
#define OID_MIN 100ll /* demarrage a 100 pour eviter les nombres trop petits */
|
||||
|
||||
#define CLASS_BASE "Base" /* classe mere de toutes les classes */
|
||||
|
||||
#define MAX_PARAM 8 /* nb maxi de parametres d'une sub/methode */
|
||||
enum {
|
||||
BUF_LGMINBLOC = 16384, /* multiple de 32 sinon pile d'elements 8 et 16 octets KO, lgmax message = lg buffer / 32 (512 octets ici) */
|
||||
MAX_PARAM = 8, /* nb maxi de parametres d'une sub/methode */
|
||||
|
||||
#define HASH_READ 1
|
||||
#define HASH_DELETE 2
|
||||
#define HASH_WRITE 3
|
||||
HASH_READ = 1,
|
||||
HASH_DELETE = 2,
|
||||
HASH_WRITE = 3,
|
||||
|
||||
#define NOK -1 /* quand pas une exception */
|
||||
NOK = -1 /* quand pas une exception */
|
||||
};
|
||||
//
|
||||
// 000 a 999 : erreur systeme
|
||||
// 1000 a 9999 : reserve aux modules systeme
|
||||
// 1000 a 1099 : module "db"
|
||||
//
|
||||
#define OK 0
|
||||
#define EX_DIV0 1 /* exceptions */
|
||||
#define EX_MEM 2 /* memalloc ko */
|
||||
#define EX_BUFOVF 3 /* depassement de capacite du buffer */
|
||||
#define EX_IO 4 /* erreur d'entree/sortie (leture fichier...) */
|
||||
#define EX_END 5 /* adresse du code hors prog/sub */
|
||||
#define EX_LGNOM 6 /* lg nom variable incorrecte (de 1 a 24 inclus) */
|
||||
#define EX_TYPVAR 7 /* type variable non attendu */
|
||||
#define EX_NULLOCAL 8 /* hashtable locale null et pas dans le code "global" */
|
||||
#define EX_NOVAR 9 /* nom de variable inconnu */
|
||||
#define EX_MODOPEN 10 /* erreur ouverture module (dlopen) */
|
||||
#define EX_MODDSYM 11 /* fonction execModule non trouvee dans le module (dsym) */
|
||||
#define EX_NOSTACK 12 /* dans ENDS, pas de var _stack trouve pour revenir a l'appelant */
|
||||
#define EX_NAVAR 13 /* la variable n'est pas du bon type / not available */
|
||||
#define EX_NOADVAR 14 /* pointeur ad_var non renseigne pour l'instruction qui en a besoin */
|
||||
#define EX_NAVERS 15 /* version de pcode non prise en charge par le "compilateur" */
|
||||
#define EX_MODNAME 16 /* le nom d'appel du module est incorrect */
|
||||
#define EX_DYNERR 17 /* erreur dans la manipulation des chaines */
|
||||
#define EX_MODFUNC 18 /* le code function du module est inconnu */
|
||||
#define EX_MODPARAM 19 /* le parametre donne au module est incorrect */
|
||||
#define EX_MODETAT 20 /* l'etat interne du module est incorrect */
|
||||
#define EX_MODERR 21 /* erreur specifique au module */
|
||||
#define EX_NOTNUM 22 /* erreur de conversion de chaine en number */
|
||||
#define EX_NOCLASS 23 /* la classe n'a pas ete trouvee dans la hash globale */
|
||||
#define EX_CMDLINE_ARG 24 /* erreur dans les parametres de la ligne de commande */
|
||||
#define EX_PCODE 25 /* pcode "binaire" incorrect : ne commence pas par PROG, library ne commence pas par LIBR, etc.*/
|
||||
#define EX_NOENVVAR 26 /* WBIN et/ou WSRC non defini en var d'environnement ou non passe en parametre de la ligne de commande */
|
||||
#define EX_EXCEPTNUM 27 /* code except ne tient pas sur 8 bits : ko pour retour shell */
|
||||
#define EX_BINVAR_KO 28 /* variable _bin de g non trouvee */
|
||||
#define EX_ENVVAR_KO 29 /* variable _env de g non trouvee */
|
||||
#define EX_BINADDRVAR_KO 30 /* variable _binaddr de g non trouvee */
|
||||
#define EX_CREATEHASH 31 /* erreur de creation de hashtable (memoire) */
|
||||
#define EX_FIELD_KO 32 /* erreur lors de dynField (memoire ou param incorrect) */
|
||||
#define EX_SUBSTR_KO 33 /* erreur lors de dynSubstr (memoire ou param incorrect) */
|
||||
#define EX_SEP_INCORRECT 34 /* separateurs incorrects dans setsep (0 interdit) */
|
||||
#define EX_FORMAT_KO 35 /* erreur de parametre (type format ou longueur incorrects) */
|
||||
#define EX_INSERT_KO 36 /* erreur de parametre ou memoire dans insert() */
|
||||
#define EX_REMOVE_KO 37 /* erreur de parametre ou memoire dans remove() */
|
||||
#define EXNB 37 /* MEMO !!!! */
|
||||
enum {
|
||||
OK = 0,
|
||||
EX_DIV0 = 1, /* exceptions */
|
||||
EX_MEM = 2, /* memalloc ko */
|
||||
EX_BUFOVF = 3, /* depassement de capacite du buffer */
|
||||
EX_IO = 4,/* erreur d'entree/sortie (leture fichier...) */
|
||||
EX_END = 5, /* adresse du code hors prog/sub */
|
||||
EX_LGNOM = 6, /* lg nom variable incorrecte (de 1 a 24 inclus) */
|
||||
EX_TYPVAR = 7, /* type variable non attendu */
|
||||
EX_NULLOCAL = 8, /* hashtable locale null et pas dans le code "global" */
|
||||
EX_NOVAR = 9, /* nom de variable inconnu */
|
||||
EX_MODOPEN = 10, /* erreur ouverture module (dlopen) */
|
||||
EX_MODDSYM = 11, /* fonction execModule non trouvee dans le module (dsym) */
|
||||
EX_NOSTACK = 12, /* dans ENDS, pas de var _stack trouve pour revenir a l'appelant */
|
||||
EX_NAVAR = 13, /* la variable n'est pas du bon type / not available */
|
||||
EX_NOADVAR = 14, /* pointeur ad_var non renseigne pour l'instruction qui en a besoin */
|
||||
EX_NAVERS = 15, /* version de pcode non prise en charge par le "compilateur" */
|
||||
EX_MODNAME = 16, /* le nom d'appel du module est incorrect */
|
||||
EX_DYNERR = 17, /* erreur dans la manipulation des chaines */
|
||||
EX_MODFUNC = 18, /* le code function du module est inconnu */
|
||||
EX_MODPARAM = 19, /* le parametre donne au module est incorrect */
|
||||
EX_MODETAT = 20, /* l'etat interne du module est incorrect */
|
||||
EX_MODERR = 21, /* erreur specifique au module */
|
||||
EX_NOTNUM = 22, /* erreur de conversion de chaine en number */
|
||||
EX_NOCLASS = 23, /* la classe n'a pas ete trouvee dans la hash globale */
|
||||
EX_CMDLINE_ARG = 24, /* erreur dans les parametres de la ligne de commande */
|
||||
EX_PCODE = 25, /* pcode "binaire" incorrect : ne commence pas par PROG, library ne commence pas par LIBR, etc.*/
|
||||
EX_NOENVVAR = 26, /* WBIN et/ou WSRC non defini en var d'environnement ou non passe en parametre de la ligne de commande */
|
||||
EX_EXCEPTNUM = 27, /* code except ne tient pas sur 8 bits : ko pour retour shell */
|
||||
EX_BINVAR_KO = 28, /* variable _bin de g non trouvee */
|
||||
EX_ENVVAR_KO = 29, /* variable _env de g non trouvee */
|
||||
EX_BINADDRVAR_KO = 30, /* variable _binaddr de g non trouvee */
|
||||
EX_CREATEHASH = 31, /* erreur de creation de hashtable (memoire) */
|
||||
EX_FIELD_KO = 32, /* erreur lors de dynField (memoire ou param incorrect) */
|
||||
EX_SUBSTR_KO = 33, /* erreur lors de dynSubstr (memoire ou param incorrect) */
|
||||
EX_SEP_INCORRECT = 34, /* separateurs incorrects dans setsep (0 interdit) */
|
||||
EX_FORMAT_KO = 35, /* erreur de parametre (type format ou longueur incorrects) */
|
||||
EX_INSERT_KO = 36, /* erreur de parametre ou memoire dans insert() */
|
||||
EX_REMOVE_KO = 37, /* erreur de parametre ou memoire dans remove() */
|
||||
EXNB = 37 /* MEMO !!!! */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/* environnement global */
|
||||
@@ -267,6 +276,8 @@ typedef struct {
|
||||
var v; /* variable servant en interne */
|
||||
var * ad_var; /* permet de recuperer l'adresse d'une var entre 2 instructions */
|
||||
var * ad_var_hash; /* dans les enchainements PVAR/PVAH-PVAI, donne l'adresse de la hash possédant la "derniere" variable */
|
||||
var * ad_var_obj; /* dans une affectation let ou do sub, donne l'objet concerne si objet, pour lire les membres (hors sub) -> pour creer this */
|
||||
var * ad_var_class; /* donne l'objet de la classe mere de l'objet courant, objet Base si objet de classe Base */
|
||||
/* */
|
||||
ent64 exception; /* exception courante (di) ; 0 ok, si # 0, levee d'une exception et saut au code qui le traite, 0 a chaque debut de fonction */
|
||||
ent64 except_ex; /* dans bloc except, code erreur ayant genere l'exception ; a mettre a 0 a chaque debut de methode sauf si appel depuis le bloc except ! */
|
||||
@@ -283,6 +294,8 @@ typedef struct {
|
||||
var debugreglelex;
|
||||
var debugcmd;
|
||||
var debugvalex;
|
||||
var printf;
|
||||
void * debugCtxShm; /* pour le debug des process phantom */
|
||||
/* */
|
||||
octet bin_comp; /* indique si les binaires lus sont compresses (1) et si oui, avec une cle (2), 0 RAS */
|
||||
octet demon; /* 1 si prog lance en demon, 0 sinon (lu par @demon) */
|
||||
@@ -329,18 +342,31 @@ typedef struct {
|
||||
char var_car[VAR_NB + 1]; /* lettre caracteristique de chaque type (printdebug) */
|
||||
} env;
|
||||
|
||||
#define CMP_EQ 1
|
||||
#define CMP_NE 2
|
||||
#define CMP_LT 3
|
||||
#define CMP_GT 4
|
||||
#define CMP_LE 5
|
||||
#define CMP_GE 6
|
||||
enum {
|
||||
CMP_EQ = 1,
|
||||
CMP_NE = 2,
|
||||
CMP_LT = 3,
|
||||
CMP_GT = 4,
|
||||
CMP_LE = 5,
|
||||
CMP_GE = 6,
|
||||
CMP_AND = 7,
|
||||
CMP_OR = 8,
|
||||
CMP_NOT = 9
|
||||
};
|
||||
|
||||
#define CMP_AND 7
|
||||
#define CMP_OR 8
|
||||
#define CMP_NOT 9
|
||||
#define GUV_CLASS "_class"
|
||||
#define GUV_BINADDR "_binaddr"
|
||||
#define GUV_LOCAL "_local"
|
||||
#define GUV_ENV "_env"
|
||||
#define GUV_ARG "_arg"
|
||||
#define GUV_ARGBACK "_argback"
|
||||
#define GUV_SRCDBG "_srcdbg"
|
||||
#define GUV_PROG "_prog"
|
||||
#define GUV_STACK "_stack"
|
||||
#define GUV_BIN "_bin"
|
||||
#define GUV_WDIR "_wdir"
|
||||
|
||||
#define VARSYS "@varnull,@varnumber,@varsubroutine,@varparam,@vardynamic,@varhashtable,@varobject,@varbuffer,@false,@true,@forcount,@kill,@fork,@exceptstr,@exceptline,@except,@part,@line,@os,@vers,@verw,@demon,@endian,@file,@arg,@pi,@fm,@vm,@svm,@tm,@currfm,@currvm,@number,@dynamic,@empty,@trim,@left,@right,@center,@surround;1,2,3,4,5,6,7,8,10,11,12,13,14,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,40,41,42,50,51,52,53,54"
|
||||
#define VARSYS "@varnull,@varnumber,@varsubroutine,@varparam,@vardynamic,@varhashtable,@varobject,@varbuffer,@false,@true,@forcount,@kill,@fork,@prog,@exceptstr,@exceptline,@except,@part,@line,@os,@vers,@verw,@demon,@endian,@file,@arg,@pi,@fm,@vm,@svm,@tm,@currfm,@currvm,@number,@dynamic,@empty,@trim,@left,@right,@center,@surround;1,2,3,4,5,6,7,8,10,11,12,13,14,15,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,40,41,42,50,51,52,53,54"
|
||||
|
||||
#include "global.h"
|
||||
|
||||
|
||||
@@ -1,3 +1,25 @@
|
||||
/* **********************************************
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
W language is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version (GPL-3.0-or-later).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
********************************************** */
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "langage.h"
|
||||
@@ -7,8 +29,10 @@
|
||||
tester avec alloc (size 20) !! TODO
|
||||
*/
|
||||
|
||||
#define MAX_ENTRY 3838 // 4096 - 258
|
||||
#define SIZE_ENTRY (124 + sizeof(int)) // TODO : voir la meilleure taille 91 sur fichier binaire de 130 Ko... !!! tester avec 20...
|
||||
enum {
|
||||
MAX_ENTRY = 3838, // 4096 - 258
|
||||
SIZE_ENTRY = (124 + sizeof(int)) // TODO : voir la meilleure taille 91 sur fichier binaire de 130 Ko... !!! tester avec 20...
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
octet Dict[MAX_ENTRY * SIZE_ENTRY]; // dictionnaire en cours
|
||||
@@ -24,7 +48,7 @@ typedef struct {
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
void initLzw(env * e, modContextLzw * cl);
|
||||
void freeLzw(env * e, modContextLzw * cl);
|
||||
long setLzw(env * e, var * clair, modContextLzw * cl, int type);
|
||||
long getLzw(env * e, var * comp, modContextLzw * cl, int type);
|
||||
WAPIDECL void initLzw(env * e, modContextLzw * cl);
|
||||
WAPIDECL void freeLzw(env * e, modContextLzw * cl);
|
||||
WAPIDECL long setLzw(env * e, var * clair, modContextLzw * cl, int type);
|
||||
WAPIDECL long getLzw(env * e, var * comp, modContextLzw * cl, int type);
|
||||
@@ -2,7 +2,7 @@
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024 lanisys.fr
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
@@ -34,14 +34,6 @@ typedef struct {
|
||||
int error; // dernier code erreur specifique au module
|
||||
//*** a completer selon le besoin du module
|
||||
modContextLzw cl;
|
||||
|
||||
/*var dict; // de type dynamic, dictionnaire en cours
|
||||
var code; // de type dynamic, contient le code/decode en cours
|
||||
var w; // de type dynamic, contient la chaine en cours d'analyse
|
||||
long prec; // dernier code trouve dans le dict
|
||||
long posDict;// position en cours du code dans dict + 256 (dernier)
|
||||
long bits; // nb de bits en cours (codage/decodage)
|
||||
long reste; // bits restant a traiter lors du decodage (nb bits dans pe->code.mInternal) */
|
||||
} modEtat;
|
||||
|
||||
/* mettre ici les codes d'erreurs specifiques au module */
|
||||
@@ -55,17 +47,12 @@ static int setError(modEtat * p, int err)
|
||||
return err == OK ? OK : EX_MODERR;
|
||||
}
|
||||
|
||||
//long set(env * e, var * clair, modEtat * pe, int type);
|
||||
//long get(env * e, var * code, modEtat * pe, int type);
|
||||
//long setV2(env * e, var * clair, modEtat * pe, int type);
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
/* TODO : gestion des 3 parametres (au lieu d'un seul) */
|
||||
modEtat * p_etat;
|
||||
@@ -81,7 +68,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(strncmp(e->fn, "init", 4) == 0)
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
@@ -98,7 +85,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
//dynInit(e, &p_etat->w, 256);
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
// liberation specifique au module avant arret process
|
||||
if(p_etat != NULL)
|
||||
@@ -111,7 +98,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
memfree(e, p_etat);
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param->type == VAR_DYNAMIC)
|
||||
@@ -121,7 +108,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
else if(strncmp(e->fn, "error", 5) == 0)
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
@@ -135,7 +122,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "set", 3) == 0)
|
||||
else if(modFnIs(e, "set", 3))
|
||||
{
|
||||
/* compression du clair de param, en une fois */
|
||||
/* sinon utiliser : setinit, setnext, setend */
|
||||
@@ -151,7 +138,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "get", 3) == 0)
|
||||
else if(modFnIs(e, "get", 3))
|
||||
{
|
||||
/* decompression du code de param, en une fois */
|
||||
/* sinon utiliser getinit, getnext, getend */
|
||||
|
||||
@@ -1,22 +1,41 @@
|
||||
/* **********************************************
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
W language is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version (GPL-3.0-or-later).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
********************************************** */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "lzw.h"
|
||||
|
||||
void initLzw(env * e, modContextLzw * cl)
|
||||
{
|
||||
cl->allocEntry = 0;
|
||||
dynInit(e, &cl->code, 4096);
|
||||
dynInit(e, &cl->w, 256);
|
||||
}
|
||||
|
||||
void freeLzw(env * e, modContextLzw * cl)
|
||||
{
|
||||
dynFree(e, &cl->code);
|
||||
dynFree(e, &cl->w);
|
||||
}
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
/* ***** PRIVATE *************** */
|
||||
static void InitDict(env * e, modContextLzw * cl)
|
||||
{
|
||||
cl->posDict = 0; // prochaine entree
|
||||
@@ -124,9 +143,21 @@ static void ecrireCode(env * e, modContextLzw * cl, long num)
|
||||
cl->code.mInternal = b; /* nb bits libres restant */
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
/* ***** PUBLIC *************** */
|
||||
WAPIDECL void initLzw(env * e, modContextLzw * cl)
|
||||
{
|
||||
cl->allocEntry = 0;
|
||||
dynInit(e, &cl->code, 4096);
|
||||
dynInit(e, &cl->w, 256);
|
||||
}
|
||||
|
||||
long setLzw(env * e, var * clair, modContextLzw * cl, int type)
|
||||
WAPIDECL void freeLzw(env * e, modContextLzw * cl)
|
||||
{
|
||||
dynFree(e, &cl->code);
|
||||
dynFree(e, &cl->w);
|
||||
}
|
||||
|
||||
WAPIDECL long setLzw(env * e, var * clair, modContextLzw * cl, int type)
|
||||
{
|
||||
/* codage lzw, type = 1 : premier appel, 2 : appel suivant, 3 : dernier appel, type = 0 : un seul appel pour tout */
|
||||
if(type == 1 || type == 0)
|
||||
@@ -198,7 +229,7 @@ long setLzw(env * e, var * clair, modContextLzw * cl, int type)
|
||||
|
||||
/* - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
long getLzw(env * e, var * comp, modContextLzw * cl, int type)
|
||||
WAPIDECL long getLzw(env * e, var * comp, modContextLzw * cl, int type)
|
||||
{
|
||||
long v; /* code en cours de decodage */
|
||||
long masque[8] = {0, 1, 3, 7, 15, 31, 63, 127};
|
||||
|
||||
@@ -44,6 +44,12 @@ static int setError(modEtat * p, int err)
|
||||
return EX_MODERR;
|
||||
}
|
||||
|
||||
#ifndef UNIX
|
||||
#define WLIBDECL __declspec(dllexport)
|
||||
#else
|
||||
#define WLIBDECL
|
||||
#endif
|
||||
|
||||
#ifndef UNIX
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
|
||||
@@ -1,27 +1,50 @@
|
||||
/* **********************************************
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
W language is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version (GPL-3.0-or-later).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
********************************************** */
|
||||
#include "lzw.h"
|
||||
|
||||
/* ******* constantes ********** */
|
||||
#define PDFFMT_A4P 1 /* A4 portrait */
|
||||
#define PDFFMT_A4L 2 /* A4 paysage ("landscape") */
|
||||
#define PDFFMT_A3P 3 /* A3 portrait */
|
||||
#define PDFFMT_A3L 4 /* A3 paysage */
|
||||
|
||||
#define PDFFONT_COURIER 1
|
||||
#define PDFFONT_COURIER_BOLD 2
|
||||
#define PDFFONT_COURIER_BOLDOBLIQUE 3
|
||||
#define PDFFONT_COURIER_OBLIQUE 4
|
||||
#define PDFFONT_HELVETICA 5
|
||||
#define PDFFONT_HELVETICA_BOLD 6
|
||||
#define PDFFONT_HELVETICA_BOLDOBLIQUE 7
|
||||
#define PDFFONT_HELVETICA_OBLIQUE 8
|
||||
#define PDFFONT_TIMES_ROMAN 9
|
||||
#define PDFFONT_TIMES_BOLD 10
|
||||
#define PDFFONT_TIMES_ITALIC 11
|
||||
#define PDFFONT_TIMES_BOLDITALIC 12
|
||||
#define PDFFONT_SYMBOL 13
|
||||
#define PDFFONT_ZAPFDINGBATS 14
|
||||
#define PDFFONT_NB 14
|
||||
enum {
|
||||
PDFFMT_A4P = 1, /* A4 portrait */
|
||||
PDFFMT_A4L = 2, /* A4 paysage ("landscape") */
|
||||
PDFFMT_A3P = 3, /* A3 portrait */
|
||||
PDFFMT_A3L = 4, /* A3 paysage */
|
||||
|
||||
PDFFONT_COURIER = 1,
|
||||
PDFFONT_COURIER_BOLD = 2,
|
||||
PDFFONT_COURIER_BOLDOBLIQUE = 3,
|
||||
PDFFONT_COURIER_OBLIQUE = 4,
|
||||
PDFFONT_HELVETICA = 5,
|
||||
PDFFONT_HELVETICA_BOLD = 6,
|
||||
PDFFONT_HELVETICA_BOLDOBLIQUE = 7,
|
||||
PDFFONT_HELVETICA_OBLIQUE = 8,
|
||||
PDFFONT_TIMES_ROMAN = 9,
|
||||
PDFFONT_TIMES_BOLD = 10,
|
||||
PDFFONT_TIMES_ITALIC = 11,
|
||||
PDFFONT_TIMES_BOLDITALIC = 12,
|
||||
PDFFONT_SYMBOL = 13,
|
||||
PDFFONT_ZAPFDINGBATS = 14,
|
||||
PDFFONT_NB = 14
|
||||
};
|
||||
|
||||
/* ***** MACRO ****/
|
||||
#define RGB(r,g,b) (((((r&255)<<8)+(g&255))<<8)+(b&255))
|
||||
@@ -49,14 +72,18 @@ typedef struct
|
||||
|
||||
modContextLzw mCtxLzw; /* gestion compression page lzw */
|
||||
|
||||
Dynamic mTmp1, mTmp2; /* temporaire pour le traitement */
|
||||
Dynamic mTmp1, mTmp2, mTmp3; /* temporaire pour le traitement */
|
||||
} modContextPdf;
|
||||
|
||||
void initPdf(env * e, modContextPdf * ctxPdf);
|
||||
void freePdf(env * e, modContextPdf * ctxPdf);
|
||||
int newPdf(env * e, modContextPdf * ctxPdf, Dynamic * titre, long nb_page, long format, Dynamic * fonts);
|
||||
int endPdf(env * e, modContextPdf * ctxPdf);
|
||||
int setPdfPage(env * e, modContextPdf * ctxPdf, int compression);
|
||||
int setPdfText(env * e, modContextPdf * ctxPdf, long x, long y, long w, long h, long font, long taille, long couleur, Dynamic * txt);
|
||||
int setPdfGraph(env * e, modContextPdf * ctxPdf, char type, long x, long y, long w, long h, long coul_trait, long coul_rempl, long epaisseur, long pointille);
|
||||
int setPdfImage(env * e, modContextPdf * ctxPdf, long x, long y, long img);
|
||||
WAPIDECL void initPdf(env * e, modContextPdf * ctxPdf);
|
||||
WAPIDECL void freePdf(env * e, modContextPdf * ctxPdf);
|
||||
WAPIDECL int newPdf(env * e, modContextPdf * ctxPdf, Dynamic * titre, long nb_page, long format, Dynamic * fonts);
|
||||
WAPIDECL int endPdf(env * e, modContextPdf * ctxPdf);
|
||||
WAPIDECL Dynamic * getPdf(env * e, modContextPdf * ctxPdf);
|
||||
WAPIDECL int setPdfPage(env * e, modContextPdf * ctxPdf, int compression);
|
||||
WAPIDECL int setPdfText(env * e, modContextPdf * ctxPdf, long x, long y, long w, long h, long font, long taille, long couleur, Dynamic * txt);
|
||||
WAPIDECL int setPdfGraph(env * e, modContextPdf * ctxPdf, char type, long x, long y, long w, long h, long coul_trait, long coul_rempl, long epaisseur, long pointille);
|
||||
WAPIDECL int setPdfImage(env * e, modContextPdf * ctxPdf, long x, long y, long img);
|
||||
WAPIDECL int pdfDeleteImage(env * e, modContextPdf * ctxPdf, long img);
|
||||
WAPIDECL int pdfLoadImageBmp(env * e, modContextPdf * ctxPdf, Dynamic * fichier);
|
||||
WAPIDECL int pdfList(env * e, modContextPdf * ctxPdf, Dynamic * titre, Dynamic * lignes, long format);
|
||||
@@ -50,13 +50,12 @@ static int setError(modEtat * p, int err)
|
||||
return err == OK ? OK : EX_MODERR;
|
||||
}
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
modEtat * p_etat;
|
||||
long exc = OK;
|
||||
@@ -147,13 +146,21 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
{
|
||||
// lire les infos necessaires a la creation d'un nouveau doc. pdf :
|
||||
// titre, nb pages, format, fontes utilisees
|
||||
var * titre, * fontes;
|
||||
var * titre, * fontes, * nbPage, * format;
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Titre"), &titre);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Fontes"), &fontes);
|
||||
if(titre && fontes)
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Pages"), &nbPage);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Format"), &format);
|
||||
if(titre && fontes && nbPage && format)
|
||||
{
|
||||
if(titre->type == VAR_DYNAMIC && fontes->type == VAR_DYNAMIC)
|
||||
exc = setError(p_etat, ! newPdf(e, &p_etat->cp, titre, 1, PDFFMT_A4P, fontes));
|
||||
if(titre->type == VAR_DYNAMIC && fontes->type == VAR_DYNAMIC && nbPage->type == VAR_NUMBER && format->type == VAR_NUMBER)
|
||||
{
|
||||
number nnbPage, nformat;
|
||||
if( var_conv_num(e, nbPage, &nnbPage) && var_conv_num(e, format, &nformat) )
|
||||
exc = setError(p_etat, ! newPdf(e, &p_etat->cp, titre, nnbPage / NUM_FACTEUR, nformat / NUM_FACTEUR, fontes));
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
@@ -202,7 +209,157 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
else
|
||||
{
|
||||
// ajouter le texte
|
||||
exc = setError(p_etat, ! setPdfText(e, &p_etat->cp, 100, 900, 300, 300, 1, 10, 0, param2));
|
||||
var * x, * y, * w, * h; // cadre englobant
|
||||
var * fonte, * taille, * couleur;
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "X"), &x);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Y"), &y);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "W"), &w);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "H"), &h);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Fonte"), &fonte);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Taille"), &taille);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Couleur"), &couleur);
|
||||
if(x && y && w && h && fonte && taille && couleur)
|
||||
{
|
||||
number nx, ny, nw, nh, nfonte, ntaille, ncouleur;
|
||||
if( var_conv_num(e, x, &nx) && var_conv_num(e, y, &ny) && var_conv_num(e, w, &nw) && var_conv_num(e, h, &nh) &&
|
||||
var_conv_num(e, fonte, &nfonte) && var_conv_num(e, taille, &ntaille) && var_conv_num(e, couleur, &ncouleur) )
|
||||
exc = setError(p_etat, ! setPdfText(e, &p_etat->cp, nx / NUM_FACTEUR, ny / NUM_FACTEUR, nw / NUM_FACTEUR, nh / NUM_FACTEUR,
|
||||
nfonte / NUM_FACTEUR, ntaille / NUM_FACTEUR, ncouleur / NUM_FACTEUR, param2)); // param2 = texte
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(modFnIs(e, "delImage", 8))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else if(param1->type != VAR_NUMBER && param1->type != VAR_DYNAMIC)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
number indice;
|
||||
if(var_conv_num(e, param1, &indice))
|
||||
exc = setError(p_etat, ! pdfDeleteImage(e, &p_etat->cp, indice / NUM_FACTEUR));
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(modFnIs(e, "addGraph", 8))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else if(param1->type != VAR_HASHTABLE)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
// ajouter l'element graphique
|
||||
var * x, * y, * w, * h; // cadre englobant
|
||||
var * couleurTrait, * couleurRemplissage, * epaisseur, * pointille, * type;
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "X"), &x);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Y"), &y);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "W"), &w);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "H"), &h);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "CouleurTrait"), &couleurTrait);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "CouleurRemplissage"), &couleurRemplissage);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "EpaisseurTrait"), &epaisseur);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Pointille"), &pointille);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Type"), &type);
|
||||
if(x && y && w && h && couleurTrait && couleurRemplissage && epaisseur && pointille && type)
|
||||
{
|
||||
number nx, ny, nw, nh, ntrait, nrempl, nepais, npoint;
|
||||
if( var_conv_num(e, x, &nx) && var_conv_num(e, y, &ny) && var_conv_num(e, w, &nw) && var_conv_num(e, h, &nh) &&
|
||||
type->type == VAR_DYNAMIC && var_conv_num(e, couleurTrait, &ntrait) && var_conv_num(e, couleurRemplissage, &nrempl) &&
|
||||
var_conv_num(e, epaisseur, &nepais) && var_conv_num(e, pointille, &npoint) )
|
||||
exc = setError(p_etat, ! setPdfGraph(e, &p_etat->cp, *type->mPtr, nx / NUM_FACTEUR, ny / NUM_FACTEUR, nw / NUM_FACTEUR, nh / NUM_FACTEUR,
|
||||
ntrait / NUM_FACTEUR, nrempl / NUM_FACTEUR, nepais / NUM_FACTEUR, npoint / NUM_FACTEUR));
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(modFnIs(e, "addImage", 8))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else if(param1->type != VAR_HASHTABLE)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
// ajouter l'element graphique
|
||||
var * x, * y, * img; // cadre englobant et n° image
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "X"), &x);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Y"), &y);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Image"), &img);
|
||||
if(x && y && img)
|
||||
{
|
||||
number nx, ny, nimg;
|
||||
if( var_conv_num(e, x, &nx) && var_conv_num(e, y, &ny) && var_conv_num(e, img, &nimg) )
|
||||
exc = setError(p_etat, ! setPdfImage(e, &p_etat->cp, nx / NUM_FACTEUR, ny / NUM_FACTEUR, nimg / NUM_FACTEUR));
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(modFnIs(e, "loadImage", 9))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else if(param1->type != VAR_DYNAMIC)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
exc = setError(p_etat, ! pdfLoadImageBmp(e, &p_etat->cp, param1));
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(modFnIs(e, "listing", 7))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else if(param1 == NULL || param2 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else if(param1->type != VAR_HASHTABLE || param2->type != VAR_DYNAMIC)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
var * titre, * format;
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Titre"), &titre);
|
||||
hashtable_do(e, HASH_READ, param1, copy_nom(e, "Format"), &format);
|
||||
if(titre && format)
|
||||
{
|
||||
if(titre->type == VAR_DYNAMIC && format->type == VAR_NUMBER)
|
||||
{
|
||||
int cr = pdfList(e, &p_etat->cp, titre, param2, format->num / NUM_FACTEUR);
|
||||
if(cr)
|
||||
{
|
||||
var_let(e, param2, getPdf(e, &p_etat->cp), FALSE, FALSE);
|
||||
}
|
||||
exc = setError(p_etat, ! cr);
|
||||
}
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
else
|
||||
exc = EX_MODPARAM;
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
|
||||
@@ -1,6 +1,36 @@
|
||||
/* **********************************************
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
W language is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version (GPL-3.0-or-later).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
********************************************** */
|
||||
#include "pdf.h"
|
||||
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
//
|
||||
// creation fichier PDF
|
||||
//
|
||||
@@ -133,8 +163,10 @@
|
||||
|
||||
#include "stdio.h"
|
||||
|
||||
#define PDF_CONV1 72000
|
||||
#define PDF_CONV2 2540
|
||||
enum {
|
||||
PDF_CONV1 = 72000,
|
||||
PDF_CONV2 = 2540
|
||||
};
|
||||
/* valeur en dixieme de mm * CONV11 / CONV2 = valeur en unites pdf x 100 (72 dpi = 72 points par pouce ; 1 pouce = 25.4) */
|
||||
|
||||
/* PRIVATE *****************************************************/
|
||||
@@ -221,8 +253,27 @@ static int fmtc(env * e, Dynamic * res, long coul)
|
||||
return cr;
|
||||
}
|
||||
|
||||
static void convertHexaRGBToBinLzw(env * e, modContextPdf * ctxPdf)
|
||||
{
|
||||
// ctxPdf->mTmp1 contient les donnees en entree, et ctxPdf->mTmp2 en sortie le lzw binaire
|
||||
// conversion de mTmp1 RGB hexa en binaire dans mTmp2
|
||||
dynSetLen(e, &ctxPdf->mTmp2, 0);
|
||||
long i, nb = ctxPdf->mTmp1.mLg / 6; // RRGGBB = 6 octets
|
||||
octet * p = ctxPdf->mTmp1.ptr;
|
||||
char res[4] = {0};
|
||||
for(i = 0; i < nb; i++, p += 6)
|
||||
{
|
||||
dynConvertCharHexaToChar(*p, *(p+1), res);
|
||||
dynConvertCharHexaToChar(*(p+2), *(p+3), res + 1);
|
||||
dynConvertCharHexaToChar(*(p+4), *(p+5), res + 2);
|
||||
dynConcatSz(e, &ctxPdf->mTmp2, res, 3);
|
||||
}
|
||||
// compression lzw de e->mTmp2
|
||||
setLzw(e, &ctxPdf->mTmp2, &ctxPdf->mCtxLzw, 0);
|
||||
}
|
||||
|
||||
/* PUBLIC ************************************************************************/
|
||||
void initPdf(env * e, modContextPdf * ctxPdf)
|
||||
WAPIDECL void initPdf(env * e, modContextPdf * ctxPdf)
|
||||
{
|
||||
ctxPdf->mLmarg = 100; /* dixieme de mm ( = 1 cm ici) */
|
||||
ctxPdf->mRmarg = 100;
|
||||
@@ -235,32 +286,35 @@ void initPdf(env * e, modContextPdf * ctxPdf)
|
||||
dynInit(e, &ctxPdf->mFont, 256);
|
||||
dynInit(e, &ctxPdf->mTmp1, 1024);
|
||||
dynInit(e, &ctxPdf->mTmp2, 1024);
|
||||
dynInit(e, &ctxPdf->mTmp3, 1024);
|
||||
dynInit(e, &ctxPdf->mPage, 4096);
|
||||
dynInit(e, &ctxPdf->mPdf, 8192);
|
||||
ctxPdf->mPdf.type = VAR_DYNAMIC;
|
||||
dynInit(e, &ctxPdf->mXref, 1024);
|
||||
dynInit(e, &ctxPdf->mImg, 2048);
|
||||
/* nom des fontes standards */
|
||||
dynLet(e, &ctxPdf->mFont, "Courier,Courier-Bold,Courier-BoldOblique,Courier-Oblique,Helvetica,Helvetica-Bold,Helvetica-BoldOblique,Helvetica-Oblique,Times-Roman,Times-Bold,Times-Italic,Times-BoldItalic,Symbol,ZapfDingbats", DYN_LGNONE);
|
||||
dynLet(e, &ctxPdf->mFont, "Courier,Courier-Bold,Courier-BoldOblique,Courier-Oblique,Helvetica,Helvetica-Bold,Helvetica-BoldOblique,Helvetica-Oblique,"
|
||||
"Times-Roman,Times-Bold,Times-Italic,Times-BoldItalic,Symbol,ZapfDingbats", DYN_LGNONE);
|
||||
dynConvert(e, &ctxPdf->mFont, ",", sFM);
|
||||
//
|
||||
initLzw(e, &ctxPdf->mCtxLzw);
|
||||
}
|
||||
|
||||
void freePdf(env * e, modContextPdf * ctxPdf)
|
||||
WAPIDECL void freePdf(env * e, modContextPdf * ctxPdf)
|
||||
{
|
||||
freeLzw(e, &ctxPdf->mCtxLzw);
|
||||
/* */
|
||||
dynFree(e, &ctxPdf->mFont);
|
||||
dynFree(e, &ctxPdf->mTmp1);
|
||||
dynFree(e, &ctxPdf->mTmp2);
|
||||
dynFree(e, &ctxPdf->mTmp3);
|
||||
dynFree(e, &ctxPdf->mPage);
|
||||
dynFree(e, &ctxPdf->mPdf);
|
||||
dynFree(e, &ctxPdf->mXref);
|
||||
dynFree(e, &ctxPdf->mImg);
|
||||
}
|
||||
|
||||
int newPdf(env * e, modContextPdf * ctxPdf, Dynamic * titre, long nb_page, long format, Dynamic * fonts)
|
||||
WAPIDECL int newPdf(env * e, modContextPdf * ctxPdf, Dynamic * titre, long nb_page, long format, Dynamic * fonts)
|
||||
{
|
||||
long i, j, cpt, nbp;
|
||||
long nb_img, nb_obj_entete, nb_font, nb_obj_fixe = 3;
|
||||
@@ -319,7 +373,10 @@ int newPdf(env * e, modContextPdf * ctxPdf, Dynamic * titre, long nb_page, long
|
||||
dynConcatSz(e, &ctxPdf->mPdf, "2 0 obj << /Producer (WPDF) /Author (WPDF) /Title (", DYN_LGNONE);
|
||||
dynConcat(e, &ctxPdf->mPdf, &ctxPdf->mTmp1); /* titre "echape" */
|
||||
dynConcatSz(e, &ctxPdf->mPdf, ") /CreationDate (", DYN_LGNONE);
|
||||
dynConcatSz(e, &ctxPdf->mPdf, "20000101140000", DYN_LGNONE); // TODO date courante YMDhms dynOconv(e, ...)
|
||||
dynSetLen(e, &ctxPdf->mTmp1, 0); // empty => oconv will convert time of the day
|
||||
dynOconv(e, &ctxPdf->mTmp1, &ctxPdf->mTmp2, "DYMDhms");
|
||||
dynConcat(e, &ctxPdf->mPdf, &ctxPdf->mTmp2);
|
||||
//dynConcatSz(e, &ctxPdf->mPdf, "20000101140000", DYN_LGNONE); // TODO date courante YMDhms dynOconv(e, ...) en TU
|
||||
dynConcatSz(e, &ctxPdf->mPdf, ") >> endobj\r\n", DYN_LGNONE);
|
||||
setXref(e, ctxPdf);
|
||||
// liste des pages
|
||||
@@ -365,11 +422,15 @@ int newPdf(env * e, modContextPdf * ctxPdf, Dynamic * titre, long nb_page, long
|
||||
dynConcat(e, &ctxPdf->mPdf, &ctxPdf->mTmp1);
|
||||
dynConcatSz(e, &ctxPdf->mXref, " 0 0 ", DYN_LGNONE);
|
||||
dynConcat(e, &ctxPdf->mXref, &ctxPdf->mTmp1);
|
||||
dynConcatSz(e, &ctxPdf->mPdf," /BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter /ASCIIHexDecode /Length ", DYN_LGNONE); // TODO remplacer /ASCIIHexDecode par /LZW...
|
||||
dynConcatSz(e, &ctxPdf->mPdf," /BitsPerComponent 8 /ColorSpace /DeviceRGB /Filter /LZWDecode /Length ", DYN_LGNONE); // TODO remplacer /ASCIIHexDecode par /LZWDecode
|
||||
dynField(e, &ctxPdf->mImg, &ctxPdf->mTmp1, i, 3, cFM, cVM, 1); // vm1 = larg (w) VM2 = haut (h) VM3 = bitmap 32bpp hexa RGBRGBRGBRGB
|
||||
dynConcatSz(e, &ctxPdf->mPdf, Int64ToSz(e, ctxPdf->mTmp1.mLg, FALSE, 0), DYN_LGNONE);
|
||||
convertHexaRGBToBinLzw(e, ctxPdf);
|
||||
dynConcatSz(e, &ctxPdf->mPdf, Int64ToSz(e, ctxPdf->mTmp2.mLg, FALSE, 0), DYN_LGNONE);
|
||||
dynConcatSz(e, &ctxPdf->mPdf, " >>\r\nstream\r\n", DYN_LGNONE);
|
||||
dynConcat(e, &ctxPdf->mPdf, &ctxPdf->mTmp1);
|
||||
dynConcat(e, &ctxPdf->mPdf, &ctxPdf->mTmp2);
|
||||
//dynConcatSz(e, &ctxPdf->mPdf, Int64ToSz(e, ctxPdf->mTmp1.mLg, FALSE, 0), DYN_LGNONE);
|
||||
//dynConcatSz(e, &ctxPdf->mPdf, " >>\r\nstream\r\n", DYN_LGNONE);
|
||||
//dynConcat(e, &ctxPdf->mPdf, &ctxPdf->mTmp1);
|
||||
dynConcatSz(e, &ctxPdf->mPdf,"\r\nendstream\r\nendobj\r\n", DYN_LGNONE);
|
||||
}
|
||||
/* definition de chaque page */
|
||||
@@ -409,7 +470,7 @@ int newPdf(env * e, modContextPdf * ctxPdf, Dynamic * titre, long nb_page, long
|
||||
return cr;
|
||||
}
|
||||
|
||||
int endPdf(env * e, modContextPdf * ctxPdf)
|
||||
WAPIDECL int endPdf(env * e, modContextPdf * ctxPdf)
|
||||
{
|
||||
long i, nb; /* nb xref */
|
||||
setXref(e, ctxPdf);
|
||||
@@ -422,7 +483,7 @@ int endPdf(env * e, modContextPdf * ctxPdf)
|
||||
dynConcatSz(e, &ctxPdf->mPdf, "\r\n0000000000 65535 f\r\n", DYN_LGNONE);
|
||||
else
|
||||
{
|
||||
dynField(e, &ctxPdf->mXref, &ctxPdf->mTmp1, i, DYN_NONE, cFM, DYN_NONE, 1);
|
||||
dynField(e, &ctxPdf->mXref, &ctxPdf->mTmp1, i, 1, cFM, cVM, 1); // VM1 a cause des images (x et y dans xref<x,2>...)
|
||||
dynConcat(e, &ctxPdf->mPdf, &ctxPdf->mTmp1);
|
||||
dynConcatSz(e, &ctxPdf->mPdf, " 00000 n\r\n", DYN_LGNONE);
|
||||
}
|
||||
@@ -435,12 +496,12 @@ int endPdf(env * e, modContextPdf * ctxPdf)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Dynamic * getPdf(env * e, modContextPdf * ctxPdf)
|
||||
WAPIDECL Dynamic * getPdf(env * e, modContextPdf * ctxPdf)
|
||||
{
|
||||
return &ctxPdf->mPdf;
|
||||
}
|
||||
|
||||
int setPdfPage(env * e, modContextPdf * ctxPdf, int compression)
|
||||
WAPIDECL int setPdfPage(env * e, modContextPdf * ctxPdf, int compression)
|
||||
{
|
||||
int cr = TRUE;
|
||||
/* compression = 0 : pas de compression LZW */
|
||||
@@ -475,7 +536,7 @@ int setPdfPage(env * e, modContextPdf * ctxPdf, int compression)
|
||||
return cr;
|
||||
}
|
||||
|
||||
int setPdfText(env * e, modContextPdf * ctxPdf, long x, long y, long w, long h, long font, long taille, long couleur, Dynamic * txt)
|
||||
WAPIDECL int setPdfText(env * e, modContextPdf * ctxPdf, long x, long y, long w, long h, long font, long taille, long couleur, Dynamic * txt)
|
||||
{
|
||||
int cr = TRUE;
|
||||
/* x,y,w,h en mm, font de 1 a PDF_FONT_NB, couleur avec RGB(r,g,b) */
|
||||
@@ -495,7 +556,7 @@ int setPdfText(env * e, modContextPdf * ctxPdf, long x, long y, long w, long h,
|
||||
return cr;
|
||||
}
|
||||
|
||||
int setPdfGraph(env * e, modContextPdf * ctxPdf, char type, long x, long y, long w, long h, long coul_trait, long coul_rempl, long epaisseur, long pointille)
|
||||
WAPIDECL int setPdfGraph(env * e, modContextPdf * ctxPdf, char type, long x, long y, long w, long h, long coul_trait, long coul_rempl, long epaisseur, long pointille)
|
||||
{
|
||||
int cr = TRUE;
|
||||
/* x,y,w,h en mm, font de 1 a PDF_FONT_NB, coul_trait/coul_rempl avec RGB(r,g,b), epaisseur et pointille de 0 a 9 */
|
||||
@@ -549,7 +610,7 @@ int setPdfGraph(env * e, modContextPdf * ctxPdf, char type, long x, long y, long
|
||||
return cr;
|
||||
}
|
||||
|
||||
int setPdfImage(env * e, modContextPdf * ctxPdf, long x, long y, long img)
|
||||
WAPIDECL int setPdfImage(env * e, modContextPdf * ctxPdf, long x, long y, long img)
|
||||
{
|
||||
int cr = TRUE;
|
||||
/* x,y en mm, image numero <img> */
|
||||
@@ -567,121 +628,123 @@ int setPdfImage(env * e, modContextPdf * ctxPdf, long x, long y, long img)
|
||||
return cr;
|
||||
}
|
||||
|
||||
/* debug TODO ---------------------------------------- */
|
||||
//int pdfChargeImageRGB(env * e, Dynamic * pixel)
|
||||
WAPIDECL int pdfDeleteImage(env * e, modContextPdf * ctxPdf, long img)
|
||||
{
|
||||
// delete image number <img>, if 0 delete all
|
||||
if(img > 0)
|
||||
dynDel(e, &ctxPdf->mImg, img, DYN_NONE, cFM, DYN_NONE, 1);
|
||||
else
|
||||
dynSetLen(e, &ctxPdf->mImg, 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//int pdfLoadImageRGB(env * e, Dynamic * pixel)
|
||||
//{
|
||||
// /* TODO png, jpeg,... en amont*/
|
||||
// return TRUE;
|
||||
//}
|
||||
//
|
||||
//int pdfChargeImageBmp(env * e, char * fichier)
|
||||
//{
|
||||
// long bpp, larg, haut, offset, par_ligne;
|
||||
// char * p; /* pour simplifier le code... */
|
||||
// long i, j, pos;
|
||||
// /* lecture fichier */
|
||||
// if(!ctxPdf->mTmp1.read(fichier))
|
||||
// return FALSE;
|
||||
// // controle du bitmap avant memorisation
|
||||
// p = ctxPdf->mTmp1.getPtr();
|
||||
// if(p[0] != 'B' && p[1] != 'M')
|
||||
// return FALSE; /* pas un fichier .bmp */
|
||||
// //
|
||||
// bpp = p[28];
|
||||
// if(bpp != 24 && bpp != 32)
|
||||
// return FALSE; /* uniquement les fichiers bmp encodes en 24bpp ou 32bpp */
|
||||
// bpp = bpp >> 3;
|
||||
// /* */
|
||||
// offset = (p[11]<<8) + p[10];
|
||||
// larg = (p[19]<<8) + p[18];
|
||||
// haut = (p[23]<<8) + p[22];
|
||||
// par_ligne = larg * bpp; /* nb octets par ligne */
|
||||
// if((par_ligne&3) != 0)
|
||||
// par_ligne += (4 - (par_ligne&3));
|
||||
// /* la bitmap en hexa fera une taille de larg*haut*3*2 */
|
||||
// if(!ctxPdf->mImg.ctrl(ctxPdf->mImg.getLen() + larg * haut * 6 + 13, TRUE)) /* 13: inclut largeur/hauteur et séparateurs FM VM */
|
||||
// return FALSE;
|
||||
// //
|
||||
// if(ctxPdf->mImg.getLen() != 0)
|
||||
// {
|
||||
// ctxPdf->mImg.concat(sFM);
|
||||
// }
|
||||
// ctxPdf->mImg.concat(larg, "%ld" sVM);
|
||||
// ctxPdf->mImg.concat(haut, "%ld" sVM);
|
||||
// // boucle sur chaque pixel
|
||||
// for(i = haut-1; i >= 0; i--)
|
||||
// for(j = 0; j < larg; j++)
|
||||
// {
|
||||
// pos = offset + j*bpp + i*par_ligne;
|
||||
// ctxPdf->mImg.concat( (((p[pos+2]<<8)+p[pos+1])<<8)+p[pos], "%6X");
|
||||
// }
|
||||
// return TRUE;
|
||||
//}
|
||||
//
|
||||
//int pdfList(env * e, char * titre, Dynamic & lignes, long format, long compression)
|
||||
//{
|
||||
// long nbPage, nbLig, nbLigPage, nbColPage;
|
||||
// long iPage, iLig, iPos;
|
||||
// long tmp;
|
||||
// // enchaine automatiquement les fonctions pour creer un pdf de type "listing" (log ou programme)
|
||||
// // police Courrier taille 9 en A4 =>
|
||||
// // paysage : 60 lignes 145 colonnes
|
||||
// // portrait : 87 lignes 99 colonnes
|
||||
// if(format == PDF_A4P)
|
||||
// {
|
||||
// // portrait
|
||||
// nbLigPage = 87;
|
||||
// nbColPage = 99;
|
||||
// }
|
||||
// else if(format == PDF_A4L)
|
||||
// {
|
||||
// // paysage (Landscape)
|
||||
// nbLigPage = 60;
|
||||
// nbColPage = 145;
|
||||
// }
|
||||
// else
|
||||
// return FALSE; // format non pris en charge
|
||||
// //
|
||||
// lignes.erase("\r");
|
||||
// nbLig = lignes.dcount(10); // \n
|
||||
// if(nbLig == 0)
|
||||
// nbPage = 1;
|
||||
// else
|
||||
// nbPage = (nbLig - 1) / nbLigPage + 1;
|
||||
// //
|
||||
// if(!ctxPdf->nouveau(titre, nbPage, format))
|
||||
// return FALSE; // erreur
|
||||
// //
|
||||
// iPos = 1;
|
||||
// for(iPage = 1; iPage <= nbPage; iPage++)
|
||||
// {
|
||||
// //if(logo_societe(mLarg * 10 / mRatio - 20, mHaut * 10 / mRatio - 20))
|
||||
// // ctxPdf->mPage.concat(mTmp1);
|
||||
// ctxPdf->mPage.concat("BT /F1 9 Tf ");
|
||||
// ctxPdf->mPage.concat(ctxPdf->mRatio * mLmarg / 100, "%ld.");
|
||||
// ctxPdf->mPage.concat(ctxPdf->mRatio * mLmarg % 100, "%ld ");
|
||||
// tmp = mHaut * 10 - (ctxPdf->mRatio * mHmarg);
|
||||
// ctxPdf->mPage.concat(tmp / 100, "%ld.");
|
||||
// ctxPdf->mPage.concat(tmp % 100, "%ld");
|
||||
// ctxPdf->mPage.concat(" Td 9 TL\r\n");
|
||||
// //
|
||||
// for(iLig = 1; iLig <= nbLigPage && iPos <= nbLig; iLig++)
|
||||
// {
|
||||
// lignes.field(10, iPos++, mTmp1); // 10 = \n
|
||||
// mTmp1.substr(0, nbColPage, mTmp2); // tronque au nb de colonnes max
|
||||
// ctxPdf->echap_txt(mTmp1, mTmp2.getPtr());
|
||||
// ctxPdf->mPage.concat("(");
|
||||
// ctxPdf->mPage.concat(mTmp1);
|
||||
// ctxPdf->mPage.concat(") '\r\n");
|
||||
// }
|
||||
// //
|
||||
// ctxPdf->mPage.concat("ET\r\n");
|
||||
// //
|
||||
// if(!ctxPdf->page(compression))
|
||||
// return FALSE; // erreur
|
||||
// }
|
||||
// //
|
||||
// return ctxPdf->termine();
|
||||
//}
|
||||
|
||||
/* ******************************************************** */
|
||||
WAPIDECL int pdfLoadImageBmp(env * e, modContextPdf * ctxPdf, Dynamic * fichier)
|
||||
{
|
||||
long bpp, larg, haut, offset, par_ligne;
|
||||
octet * p; /* pour simplifier le code... */
|
||||
long i, j, pos, ind;
|
||||
/* lecture fichier */
|
||||
if(!fichier)
|
||||
return FALSE;
|
||||
if(fichier->type != VAR_DYNAMIC)
|
||||
return FALSE;
|
||||
// controle du bitmap avant memorisation
|
||||
p = fichier->ptr;
|
||||
if(p[0] != 'B' && p[1] != 'M')
|
||||
return FALSE; /* pas un fichier .bmp */
|
||||
//
|
||||
bpp = p[28];
|
||||
if(bpp != 24 && bpp != 32)
|
||||
return FALSE; /* uniquement les fichiers bmp encodes en 24bpp ou 32bpp */
|
||||
bpp = bpp >> 3;
|
||||
/* */
|
||||
offset = (p[11] << 8) + p[10];
|
||||
larg = (p[19] << 8) + p[18];
|
||||
haut = (p[23] << 8) + p[22];
|
||||
par_ligne = larg * bpp; /* nb octets par ligne */
|
||||
if((par_ligne & 3) != 0)
|
||||
par_ligne += (4 - (par_ligne & 3));
|
||||
/* la bitmap en hexa fera une taille de larg*haut*3*2 */
|
||||
ind = dynDcount(e, &ctxPdf->mImg, cFM, DYN_NONE, DYN_NONE) + 1;
|
||||
dynStoreNumber(e, &ctxPdf->mImg, ind, 1, larg, cFM, cVM);
|
||||
dynStoreNumber(e, &ctxPdf->mImg, ind, 2, haut, cFM, cVM);
|
||||
dynConcatSz(e, &ctxPdf->mImg, sVM, 1);
|
||||
// boucle sur chaque pixel
|
||||
for(i = haut-1; i >= 0; i--)
|
||||
for(j = 0; j < larg; j++)
|
||||
{
|
||||
pos = offset + j * bpp + i * par_ligne;
|
||||
dynConcatSz(e, &ctxPdf->mImg, dynConvertCharToCharHexa(p[pos + 2]), 2);
|
||||
dynConcatSz(e, &ctxPdf->mImg, dynConvertCharToCharHexa(p[pos + 1]), 2);
|
||||
dynConcatSz(e, &ctxPdf->mImg, dynConvertCharToCharHexa(p[pos]), 2);
|
||||
}
|
||||
//printf("Image:\n%s\nlarg:%ld haut:%ld bpp:%ld ind:%ld parligne:%ld lenfichier:%lld\n", ctxPdf->mImg.mPtr, larg, haut, bpp, ind, par_ligne, fichier->mLg);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
WAPIDECL int pdfList(env * e, modContextPdf * ctxPdf, Dynamic * titre, Dynamic * lignes, long format)
|
||||
{
|
||||
// enchaine automatiquement les fonctions pour creer un pdf de type "listing" (log ou programme)
|
||||
// police Courrier taille 9 en A4 =>
|
||||
// paysage : 60 lignes 145 colonnes
|
||||
// portrait : 87 lignes 99 colonnes
|
||||
long nbLigPage, nbColPage;
|
||||
if(format == PDFFMT_A4P)
|
||||
{
|
||||
// portrait
|
||||
nbLigPage = 87;
|
||||
nbColPage = 99;
|
||||
}
|
||||
else if(format == PDFFMT_A4L)
|
||||
{
|
||||
// paysage (Landscape)
|
||||
nbLigPage = 60;
|
||||
nbColPage = 145;
|
||||
}
|
||||
else
|
||||
return FALSE; // format non pris en charge
|
||||
//
|
||||
long nbPage, nbLig;
|
||||
dynErase(e, lignes, "\r");
|
||||
nbLig = dynDcount(e, lignes, 10, DYN_NONE, DYN_NONE); // \n
|
||||
if(nbLig == 0)
|
||||
nbPage = 1;
|
||||
else
|
||||
nbPage = (nbLig - 1) / nbLigPage + 1;
|
||||
//
|
||||
dynLet(e, &ctxPdf->mTmp3, "Courier", DYN_LGNONE);
|
||||
if( ! newPdf(e, ctxPdf, titre, nbPage, format, &ctxPdf->mTmp3))
|
||||
return FALSE;
|
||||
//
|
||||
long iPage, iLigPage, iLigTotal = 1;
|
||||
for(iPage = 1; iPage <= nbPage; iPage++)
|
||||
{
|
||||
dynConcatSz(e, &ctxPdf->mPage, "BT /F1 9 Tf ", 12); // Fonte 1 = Courier (/F1)
|
||||
fmt2(e, &ctxPdf->mPage, ctxPdf->mLmarg, ctxPdf->mHaut - ctxPdf->mHmarg);
|
||||
dynConcatSz(e, &ctxPdf->mPage, " Td 9 TL\r\n", DYN_LGNONE);
|
||||
//
|
||||
for(iLigPage = 1; iLigPage <= nbLigPage && iLigTotal <= nbLig; iLigPage++)
|
||||
{
|
||||
dynField(e, lignes, &ctxPdf->mTmp1, iLigTotal++, DYN_NONE, 10, DYN_NONE, 1);
|
||||
if(ctxPdf->mTmp1.mLg > nbColPage)
|
||||
dynSetLen(e, &ctxPdf->mTmp1, nbColPage);
|
||||
pdfEchap(e, &ctxPdf->mTmp2, &ctxPdf->mTmp1);
|
||||
dynConcatSz(e, &ctxPdf->mPage, "(", 1);
|
||||
dynConcatSz(e, &ctxPdf->mPage, ctxPdf->mTmp2.mPtr, ctxPdf->mTmp2.mLg);
|
||||
dynConcatSz(e, &ctxPdf->mPage, ") '\r\n", DYN_LGNONE);
|
||||
}
|
||||
dynConcatSz(e, &ctxPdf->mPage, "ET\r\n", DYN_LGNONE);
|
||||
//
|
||||
if( ! setPdfPage(e, ctxPdf, 1)) // compression forcee, mettre un param ?
|
||||
return FALSE;
|
||||
}
|
||||
return endPdf(e, ctxPdf);
|
||||
}
|
||||
|
||||
/* ******************************************************** */
|
||||
+13
-12
@@ -28,8 +28,10 @@
|
||||
#include "langage.h"
|
||||
#include "dynamic.h"
|
||||
|
||||
#define RAND_STATE_COUNT 624
|
||||
#define RAND_PERIOD 397
|
||||
enum {
|
||||
RAND_STATE_COUNT = 624,
|
||||
RAND_PERIOD = 397
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int error; // dernier code erreur specifique au module
|
||||
@@ -84,13 +86,12 @@ static int setError(modEtat * p, int err)
|
||||
return EX_MODERR;
|
||||
}
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
/* TODO : gestion des 3 parametres (au lieu d'un seul) */
|
||||
modEtat * p_etat;
|
||||
@@ -114,7 +115,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(strncmp(e->fn, "init", 4) == 0)
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
@@ -129,7 +130,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
//*** code specifique ici
|
||||
//
|
||||
@@ -137,7 +138,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
if(p_etat != NULL)
|
||||
memfree(e, p_etat);
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
@@ -152,7 +153,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "error", 5) == 0)
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
@@ -168,7 +169,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "setSeed", 7) == 0)
|
||||
else if(modFnIs(e, "setSeed", 7))
|
||||
{
|
||||
if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
@@ -180,7 +181,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "get", 3) == 0)
|
||||
else if(modFnIs(e, "get", 3))
|
||||
{
|
||||
if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
|
||||
@@ -26,17 +26,56 @@
|
||||
|
||||
// TODO version windows
|
||||
#ifdef UNIX
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#else
|
||||
#include "windows.h" // pour les fonctions FindFile...
|
||||
#include "windows.h" // pour les fonctions FindFile...
|
||||
#endif
|
||||
|
||||
#include "langage.h"
|
||||
#include "dynamic.h"
|
||||
#include "rep.h"
|
||||
|
||||
long ScanDirectory(env * e, const char * path, Dynamic * directory, const char * fileToSearch, Dynamic * fileFound, long * fileFoundCount, long * duplicateCount)
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
/* ******** PRIVATE ********************* */
|
||||
static int GetInclude(env * e, Dynamic * line, Dynamic * includeFilename)
|
||||
{
|
||||
// check that the <line> is a include w statement. If not, return zero, else
|
||||
// return in <includeFilename> the name of the include file
|
||||
// separators are 9 and 32 (tab and space) and ";"" for the optional end of line comment
|
||||
char * p = line->mPtr, * q;
|
||||
while(*p && (*p == 9 || *p == 32)) p++;
|
||||
if(*p++ != 'i') return 0;
|
||||
if(*p++ != 'n') return 0;
|
||||
if(*p++ != 'c') return 0;
|
||||
if(*p++ != 'l') return 0;
|
||||
if(*p++ != 'u') return 0;
|
||||
if(*p++ != 'd') return 0;
|
||||
if(*p++ != 'e') return 0;
|
||||
if(*p != 9 && *p != 32) return 0;
|
||||
p++;
|
||||
while(*p && (*p == 9 || *p == 32)) p++;
|
||||
if(*p != '\'' && *p != '"') return 0;
|
||||
q = p + 1; // *p is the first char of include filename , including ' or ", and that chra must bi found at the end of the file
|
||||
while(*q && (*q != *p)) q++;
|
||||
if(*q != *p) return 0; // *q must be the same ' or " that begins filename
|
||||
long lg = q - p - 1;
|
||||
if(lg < 1) return 0;
|
||||
dynLet(e, includeFilename, p + 1, lg);
|
||||
dynSetLen(e, includeFilename, lg); // to be sure that \0 ends the filename
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ******** PUBLIC ********************* */
|
||||
WAPIDECL long ScanDirectory(env * e, const char * path, Dynamic * directory, const char * fileToSearch, Dynamic * fileFound, long * fileFoundCount, long * duplicateCount)
|
||||
{
|
||||
if(!e || !directory || !fileFound || !fileFoundCount || !duplicateCount)
|
||||
return 0; // error
|
||||
@@ -81,9 +120,10 @@ long ScanDirectory(env * e, const char * path, Dynamic * directory, const char *
|
||||
#ifdef UNIX
|
||||
if((dir = opendir(workPath.mPtr)) == NULL)
|
||||
{
|
||||
// TODO ?! exit or continue to next item ?
|
||||
dynFree(e, &workPath);
|
||||
return 0;
|
||||
// continue to next item (no access right for example for this directory, etc.)
|
||||
//dynFree(e, &workPath);
|
||||
//return 0;
|
||||
continue;
|
||||
}
|
||||
while ((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
@@ -129,9 +169,10 @@ long ScanDirectory(env * e, const char * path, Dynamic * directory, const char *
|
||||
dynConcatSz(e, &workPath, "\\*", DYN_LGNONE); /* sinon ko... */
|
||||
if((hFind = FindFirstFile(workPath.mPtr, &FindFileData)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
// TODO ?! exit or continue to next item ?
|
||||
dynFree(e, &workPath);
|
||||
return 0;
|
||||
// continue to next item (no access right for example for this directory, etc.)
|
||||
//dynFree(e, &workPath);
|
||||
//return 0;
|
||||
continue;
|
||||
}
|
||||
dynSetLen(e, &workPath, workPath.mLg - 2); // enlever \* mis a la fin...
|
||||
for(int cr = -1;cr != 0;)
|
||||
@@ -188,62 +229,47 @@ long ScanDirectory(env * e, const char * path, Dynamic * directory, const char *
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int GetInclude(env * e, Dynamic * line, Dynamic * includeFilename)
|
||||
{
|
||||
// check that the <line> is a include w statement. If not, return zero, else
|
||||
// return in <includeFilename> the name of the include file
|
||||
// separators are 9 and 32 (tab and space) and ";"" for the optional end of line comment
|
||||
char * p = line->mPtr, * q;
|
||||
while(*p && (*p == 9 || *p == 32)) p++;
|
||||
if(*p++ != 'i') return 0;
|
||||
if(*p++ != 'n') return 0;
|
||||
if(*p++ != 'c') return 0;
|
||||
if(*p++ != 'l') return 0;
|
||||
if(*p++ != 'u') return 0;
|
||||
if(*p++ != 'd') return 0;
|
||||
if(*p++ != 'e') return 0;
|
||||
if(*p != 9 && *p != 32) return 0;
|
||||
p++;
|
||||
while(*p && (*p == 9 || *p == 32)) p++;
|
||||
q = p; // *p is the first char of include filename (except if *p is null)
|
||||
while(*q && (*q != 9 && *q != 32 && *q != ';')) q++;
|
||||
// *q is the last char of include filename
|
||||
if( (! *p) || *p == ';') return 0;
|
||||
if(*q == ';') q--;
|
||||
// find it : copy do includeFilename
|
||||
long lg = q - p + 1;
|
||||
dynLet(e, includeFilename, p, lg);
|
||||
dynSetLen(e, includeFilename, lg); // to be sure that \0 ends the filename
|
||||
dynErase(e, includeFilename, "'\"");
|
||||
return 1;
|
||||
}
|
||||
|
||||
long GetSource(env * e, const char * wsrc, const char * filename, Dynamic * source, Dynamic * meta)
|
||||
WAPIDECL long GetSource(env * e, Dynamic * directory, const char * filename, Dynamic * source, Dynamic * meta)
|
||||
{
|
||||
int cr = 0;
|
||||
char cLF = 10;
|
||||
char sLF[2] = {"\n"};
|
||||
char sCR[2] = {"\r"};
|
||||
dynSetLen(e, source, 0);
|
||||
dynSetLen(e, meta, 0);
|
||||
//
|
||||
Dynamic directory, fileFound, line, include, tmp;
|
||||
dynInit(e, &directory, DYN_LGMIN);
|
||||
Dynamic fileFound, line, include, filenameFound;
|
||||
dynInit(e, &fileFound, DYN_LGMIN);
|
||||
dynInit(e, &line, DYN_LGMIN);
|
||||
dynInit(e, &include, DYN_LGMIN);
|
||||
dynInit(e, &tmp, DYN_LGMIN);
|
||||
dynInit(e, &filenameFound, DYN_LGMIN);
|
||||
//
|
||||
long fileCount, dup;
|
||||
for(;;)
|
||||
{
|
||||
if(dynRead(e, source, (char *)filename) != DYN_OK)
|
||||
if( ScanDirectory(e, NULL, directory, filename, &fileFound, &fileCount, &dup) != 1)
|
||||
{
|
||||
cr = 1;
|
||||
break;
|
||||
if( ! ScanDirectory(e, wsrc, &directory, NULL, &fileFound, &fileCount, &dup))
|
||||
}
|
||||
if(fileCount != 1)
|
||||
{
|
||||
cr = 2;
|
||||
break;
|
||||
}
|
||||
if(dynRead(e, source, fileFound.mPtr) != DYN_OK)
|
||||
{
|
||||
cr = 3;
|
||||
break;
|
||||
}
|
||||
dynErase(e, source, sCR);
|
||||
//
|
||||
long level = 1, current = 1;
|
||||
dynStoreSz(e, meta, 1, DYN_NONE, "00000001", 8, cFM, DYN_NONE);
|
||||
dynStoreSz(e, meta, 2, DYN_NONE, (char *)filename, DYN_LGNONE, cFM, DYN_NONE);
|
||||
dynStoreSz(e, meta, 3, DYN_NONE, (char *)filename, DYN_LGNONE, cFM, DYN_NONE);
|
||||
long treeLevel = 1, currentLevel = 1, level = 0, nbMeta = 1;
|
||||
dynStoreSz(e, meta, META_GLOBAL_LN, DYN_NONE, "00000001", 8, cFM, DYN_NONE);
|
||||
dynStoreSz(e, meta, META_FILENAME, DYN_NONE, fileFound.mPtr, DYN_LGNONE, cFM, DYN_NONE);
|
||||
dynStoreSz(e, meta, META_LOCAL_LN, DYN_NONE, "1", DYN_LGNONE, cFM, DYN_NONE);
|
||||
dynStoreNumber(e, meta, META_LEVEL, DYN_NONE, currentLevel, cFM, DYN_NONE);
|
||||
dynStoreSz(e, meta, META_FILETREE, DYN_NONE, (char *)filename, DYN_LGNONE, cFM, DYN_NONE);
|
||||
// foreach source line
|
||||
long numberOfLines = dynDcount(e, source, cLF, DYN_NONE, DYN_NONE);
|
||||
long numLine = 1;
|
||||
@@ -253,99 +279,117 @@ long GetSource(env * e, const char * wsrc, const char * filename, Dynamic * sour
|
||||
numLine++;
|
||||
if(GetInclude(e, &line, &include))
|
||||
{
|
||||
//printf("include: %s\n", include.mPtr);
|
||||
if(ScanDirectory(e, NULL, &directory, include.mPtr, &fileFound, &fileCount, &dup))
|
||||
if(ScanDirectory(e, NULL, directory, include.mPtr, &fileFound, &fileCount, &dup))
|
||||
{
|
||||
//printf("nb found %ld: %s\n", fileCount, fileFound.mPtr);
|
||||
if(fileCount == 1)
|
||||
{
|
||||
// memo include file tree to avoid cyclic includes and get meta data
|
||||
// 2 memos : one for call tree, and one for the map of files/number of lines
|
||||
// call tree =>
|
||||
// meta<3> = file tree, multi-valued filenames
|
||||
// meta<5> = file tree, multi-valued filenames (temporary, during GetSource)
|
||||
// meta data =>
|
||||
// meta<1> = beginning number of line
|
||||
// meta<1> = beginning line number, global
|
||||
// meta<2> = filename
|
||||
// meta<3> = local line number
|
||||
// meta<4> = level
|
||||
//
|
||||
// if filename already presents in file tree, error (ignore include)
|
||||
if(dynLocateSz(e, meta, fileFound.mPtr, cVM, 3, cFM) > 0)
|
||||
continue;
|
||||
// insert include file after include's line
|
||||
dynRead(e, &include, fileFound.mPtr);
|
||||
if(include.mLg == 0)
|
||||
continue; // don't insert empty file
|
||||
// suppress last character if LF : prevent blank line in result
|
||||
if(include.mPtr[include.mLg - 1] == cLF)
|
||||
dynSetLen(e, &include, include.mLg - 1);
|
||||
//
|
||||
// TODO : insert ENDINCLUDE pseudo code at the end of inserted include ? or only when generating pcode ! see with assembler.c
|
||||
dynIns(e, source, numLine, DYN_NONE, &include, cLF, DYN_NONE);
|
||||
long nbInclude = dynDcount(e, &include, cLF, DYN_NONE, DYN_NONE);
|
||||
numberOfLines = dynDcount(e, source, cLF, DYN_NONE, DYN_NONE);
|
||||
//printf("inc ok %s nbinclude %ld nbline %ld current %ld\n", fileFound.mPtr, nbInclude, numberOfLines, numLine);
|
||||
// put in <include> the line number formatted 00000000 and split current block in three
|
||||
dynFmtNumber(e, numLine, &include, 'R', '0', 8);
|
||||
long pos = abs(dynSortLocateSz(e, meta, include.mPtr, cVM, DYN_SORT_ASC, 1, cFM));
|
||||
dynIns(e, meta, 1, pos, &include, cFM, cVM);
|
||||
dynIns(e, meta, 2, pos, &fileFound, cFM, cVM);
|
||||
//
|
||||
//dynExtractSubField(e, meta, 2, pos - 1, &include); // ko si separateurs changent...
|
||||
dynField(e, meta, &include, 2, pos - 1, cFM, cVM, 1);
|
||||
dynIns(e, meta, 2, pos + 1, &include, cFM, cVM);
|
||||
dynFmtNumber(e, numLine + nbInclude, &include, 'R', '0', 8);
|
||||
dynIns(e, meta, 1, pos + 1, &include, cFM, cVM);
|
||||
//
|
||||
// adjust starting line of next blocks
|
||||
long nbMeta = dynDcount(e, meta, cVM, 2, cFM);
|
||||
for(long cpt = pos + 2; cpt <= nbMeta; cpt++)
|
||||
dynField(e, &fileFound, &filenameFound, dynDcount(e, &fileFound, e->path_sep[0], DYN_NONE, DYN_NONE), DYN_NONE, e->path_sep[0], DYN_NONE, 1); // extract filename from full path
|
||||
if(dynLocateSz(e, meta, filenameFound.mPtr, cVM, META_FILETREE, cFM) > 0)
|
||||
{
|
||||
//long num = dynExtractSubFieldAsNumber(e, meta, 1, cpt, &include) + nbInclude;
|
||||
long num = dynFieldAsNumber(e, meta, 1, cpt, cFM, cVM) + nbInclude;
|
||||
dynFmtNumber(e, num, &include, 'R', '0', 8);
|
||||
dynStore(e, meta, 1, cpt, &include, cFM, cVM);
|
||||
cr = 4;
|
||||
break;
|
||||
}
|
||||
// insert include file after include's line
|
||||
if(include.mLg == 0) // don't insert empty file (else, local line number calculus wouldn't be correct), add one space instead
|
||||
{
|
||||
dynLet(e, &include, " ", 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
dynErase(e, &include, sCR);
|
||||
if(include.mPtr[include.mLg - 1] != cLF)
|
||||
dynConcatSz(e, &include, sLF, 1); // add empty final line if there's not, else meta would have double same global line (if last line is include's line)
|
||||
}
|
||||
//
|
||||
dynStore(e, meta, 3, ++level, &fileFound, cFM, cVM);
|
||||
current++;
|
||||
dynIns(e, source, numLine, DYN_NONE, &include, cLF, DYN_NONE);
|
||||
long nbInclude = dynDcount(e, &include, cLF, DYN_NONE, DYN_NONE);
|
||||
numberOfLines = dynDcount(e, source, cLF, DYN_NONE, DYN_NONE); // extending scope
|
||||
//
|
||||
// put in <include> the line number formatted 00000000 and split current block in three
|
||||
dynFmtNumber(e, numLine, &include, 'R', '0', 8);
|
||||
long pos = abs(dynSortLocateSz(e, meta, include.mPtr, cVM, DYN_SORT_ASC, META_GLOBAL_LN, cFM));
|
||||
dynIns(e, meta, META_GLOBAL_LN, pos, &include, cFM, cVM);
|
||||
dynIns(e, meta, META_FILENAME, pos, &fileFound, cFM, cVM);
|
||||
dynInsSz(e, meta, META_LOCAL_LN, pos, "1", 1, cFM, cVM);
|
||||
level = dynFieldAsNumber(e, meta, META_LEVEL, pos - 1, cFM, cVM);
|
||||
dynInsNumber(e, meta, META_LEVEL, pos, level + 1, cFM, cVM);
|
||||
currentLevel = level + 1;
|
||||
//
|
||||
dynField(e, meta, &include, 2, pos - 1, cFM, cVM, 1);
|
||||
dynIns(e, meta, META_FILENAME, pos + 1, &include, cFM, cVM);
|
||||
dynFmtNumber(e, numLine + nbInclude, &include, 'R', '0', 8);
|
||||
dynIns(e, meta, META_GLOBAL_LN, pos + 1, &include, cFM, cVM);
|
||||
long global = dynFieldAsNumber(e, meta, META_GLOBAL_LN, pos - 1, cFM, cVM);
|
||||
long local = dynFieldAsNumber(e, meta, META_LOCAL_LN, pos - 1, cFM, cVM);
|
||||
dynInsNumber(e, meta, META_LOCAL_LN, pos + 1, numLine - global + local, cFM, cVM);
|
||||
dynInsNumber(e, meta, META_LEVEL, pos + 1, level, cFM, cVM);
|
||||
//
|
||||
// adjust starting line of next blocks
|
||||
nbMeta = dynDcount(e, meta, cVM, META_FILENAME, cFM);
|
||||
for(long cpt = pos + 2; cpt <= nbMeta; cpt++)
|
||||
{
|
||||
global = dynFieldAsNumber(e, meta, META_GLOBAL_LN, cpt, cFM, cVM);
|
||||
dynFmtNumber(e, global + nbInclude, &include, 'R', '0', 8);
|
||||
dynStore(e, meta, META_GLOBAL_LN, cpt, &include, cFM, cVM);
|
||||
}
|
||||
//
|
||||
dynStore(e, meta, META_FILETREE, ++treeLevel, &filenameFound, cFM, cVM);
|
||||
}
|
||||
else
|
||||
{
|
||||
cr = 5; // if fileCount <> 1, error (multiple included include not autorized, or not found when filename includes dot or path separator char)
|
||||
break;
|
||||
}
|
||||
// if fileCount > 1, error (ignore include)
|
||||
}
|
||||
// if error while searching for the include file, error (ignore include)
|
||||
else
|
||||
{
|
||||
cr = 6; // if error while searching for the include file, error
|
||||
break;
|
||||
}
|
||||
}
|
||||
// delete last file in call tree when changing of file
|
||||
// dynSetAsNumber(e, &tmp, numLine);
|
||||
//dynFmt(e, &tmp, &include, 'R', '0', 8); // TODO dynFmtNumber
|
||||
dynFmtNumber(e, numLine, &include, 'R', '0', 8);
|
||||
long pos = dynSortLocateSz(e, meta, include.mPtr, cVM, DYN_SORT_ASC, 1, cFM);
|
||||
if(pos != current && level > 0)
|
||||
{
|
||||
current = pos;
|
||||
dynDel(e, meta, 3, level--, cFM, cVM, 1);
|
||||
}
|
||||
long pos = dynSortLocateSz(e, meta, include.mPtr, cVM, DYN_SORT_ASC, META_GLOBAL_LN, cFM);
|
||||
if(pos < 0)
|
||||
pos = abs(pos) - 1;
|
||||
if(pos > nbMeta)
|
||||
pos = nbMeta;
|
||||
level = dynFieldAsNumber(e, meta, META_LEVEL, pos, cFM, cVM);
|
||||
if(level < currentLevel)
|
||||
dynDel(e, meta, META_FILETREE, treeLevel--, cFM, cVM, 1);
|
||||
currentLevel = level;
|
||||
}
|
||||
dynDel(e, meta, 3, DYN_NONE, cFM, DYN_NONE, 1);
|
||||
cr = 1;
|
||||
dynDel(e, meta, META_FILETREE, DYN_NONE, cFM, DYN_NONE, 1);
|
||||
break;
|
||||
}
|
||||
//
|
||||
dynFree(e, &directory);
|
||||
dynFree(e, &fileFound);
|
||||
dynFree(e, &line);
|
||||
dynFree(e, &include);
|
||||
dynFree(e, &tmp);
|
||||
dynFree(e, &filenameFound);
|
||||
return cr;
|
||||
}
|
||||
|
||||
void GetFile(env * e, long lineNumber, Dynamic * meta, int indice, Dynamic * fileFound)
|
||||
WAPIDECL void GetFile(env * e, long lineNumber, Dynamic * meta, int indice, Dynamic * fileFound, long * ficLine)
|
||||
{
|
||||
indice *= 2;
|
||||
indice = (indice - 1) * META_NB;
|
||||
dynFmtNumber(e, lineNumber, fileFound, 'R', '0', 8);
|
||||
long pos = dynSortLocateSz(e, meta, fileFound->mPtr, cVM, DYN_SORT_ASC, indice - 1, cFM);
|
||||
long pos = dynSortLocateSz(e, meta, fileFound->mPtr, cVM, DYN_SORT_ASC, indice + META_GLOBAL_LN, cFM);
|
||||
if(pos < 0)
|
||||
{
|
||||
pos = abs(pos) - 1;
|
||||
if(pos < 1) pos = 1; // securite
|
||||
}
|
||||
dynSetLen(e, fileFound, 0);
|
||||
dynField(e, meta, fileFound, indice, pos, cFM, cVM, 1);
|
||||
//
|
||||
*ficLine = lineNumber - dynFieldAsNumber(e, meta, indice + META_GLOBAL_LN, pos, cFM, cVM) + dynFieldAsNumber(e, meta, indice + META_LOCAL_LN, pos, cFM, cVM);
|
||||
dynField(e, meta, fileFound, indice + META_FILENAME, pos, cFM, cVM, 1);
|
||||
}
|
||||
@@ -23,10 +23,22 @@
|
||||
#ifndef REP_H
|
||||
#define REP_H
|
||||
|
||||
long ScanDirectory(env * e, const char * path, Dynamic * directory, const char * fileToSearch, Dynamic * fileFound, long * fileFoundCount, long * duplicateCount);
|
||||
long GetSource(env * e, const char * wsrc, const char * filename, Dynamic * source, Dynamic * meta);
|
||||
#include "apidecl.h"
|
||||
|
||||
void GetFile(env * e, long lineNumber, Dynamic * meta, int indice, Dynamic * fileFound);
|
||||
enum {
|
||||
META_GLOBAL_LN = 1,
|
||||
META_FILENAME = 2,
|
||||
META_LOCAL_LN = 3,
|
||||
META_LEVEL = 4,
|
||||
META_FILETREE = 5,
|
||||
META_WSRC = 5,
|
||||
META_NB = 5
|
||||
};
|
||||
|
||||
WAPIDECL long ScanDirectory(env * e, const char * path, Dynamic * directory, const char * fileToSearch, Dynamic * fileFound, long * fileFoundCount, long * duplicateCount);
|
||||
WAPIDECL long GetSource(env * e, Dynamic * directory, const char * filename, Dynamic * source, Dynamic * meta);
|
||||
|
||||
WAPIDECL void GetFile(env * e, long lineNumber, Dynamic * meta, int indice, Dynamic * fileFound, long * ficLine);
|
||||
|
||||
/* ********************************************** */
|
||||
#endif
|
||||
@@ -25,11 +25,11 @@
|
||||
#include <string.h>
|
||||
|
||||
#ifndef WINLIB
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "langage.h"
|
||||
@@ -38,6 +38,12 @@
|
||||
typedef int key_t;
|
||||
#endif
|
||||
|
||||
/* codes a passer a la fonction setError */
|
||||
enum {
|
||||
EXMOD_BUFFER_INIT = 1,
|
||||
EXMOD_BUFFER_WRITE = 2
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
// proprietaire
|
||||
key_t cle;
|
||||
@@ -46,8 +52,10 @@ typedef struct {
|
||||
var * buffer;
|
||||
#ifndef WINLIB
|
||||
int handle;
|
||||
int semId;
|
||||
#else
|
||||
HANDLE handle;
|
||||
char semDesti[25]; // 23 cars + '#' + \0 (different desti sinon ko sous windows)
|
||||
#endif
|
||||
// destinataire
|
||||
char desti[24]; // 23 cars + \0
|
||||
@@ -55,7 +63,7 @@ typedef struct {
|
||||
var * message;
|
||||
} modContextShm;
|
||||
|
||||
void initShm(env * e, modContextShm * ctx);
|
||||
void freeShm(env * e, modContextShm * ctx);
|
||||
void readShm(env * e, modContextShm * ctx);
|
||||
void writeShm(env * e, modContextShm * ctx);
|
||||
WAPIDECL void initShm(env * e, modContextShm * ctx);
|
||||
WAPIDECL void freeShm(env * e, modContextShm * ctx);
|
||||
WAPIDECL long readShm(env * e, modContextShm * ctx);
|
||||
WAPIDECL long writeShm(env * e, modContextShm * ctx);
|
||||
@@ -2,7 +2,7 @@
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024 lanisys.fr
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "langage.h"
|
||||
#include "dynamic.h"
|
||||
#include "hashtable.h"
|
||||
|
||||
#include "shm.h"
|
||||
|
||||
@@ -37,10 +38,6 @@ typedef struct {
|
||||
|
||||
} modEtat;
|
||||
|
||||
/* mettre ici les codes d'erreurs specifiques au module */
|
||||
/* codes a passer a la fonction setError */
|
||||
#define EXMOD_xxx 1
|
||||
|
||||
static int setError(modEtat * p, int err)
|
||||
{
|
||||
if(p != NULL)
|
||||
@@ -48,25 +45,32 @@ static int setError(modEtat * p, int err)
|
||||
return err == OK ? OK : EX_MODERR;
|
||||
}
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
/* TODO : gestion des 3 parametres (au lieu d'un seul) */
|
||||
/* gestion des 3 parametres (au lieu d'un seul) */
|
||||
modEtat * p_etat;
|
||||
long exc = OK;
|
||||
// init/end/vers/error sont obligatoires pour tout module
|
||||
// - - - - - - - - - - - - - - - - - - - -
|
||||
if(param == NULL || etat == NULL)
|
||||
if(etat == NULL)
|
||||
return EX_MODPARAM;
|
||||
else
|
||||
p_etat = (modEtat *)(*etat); /* evite de la faire a chaque fonction */
|
||||
if(param->type == VAR_PARAM)
|
||||
param = (var *)param->ptr; /* evite de le faire a chaque fonction */
|
||||
//
|
||||
if(param1 != NULL)
|
||||
if(param1->type == VAR_PARAM)
|
||||
param1 = (var *)param1->ptr; /* evite de le faire a chaque fonction */
|
||||
if(param2 != NULL)
|
||||
if(param2->type == VAR_PARAM)
|
||||
param2 = (var *)param2->ptr; /* evite de le faire a chaque fonction */
|
||||
if(param3 != NULL)
|
||||
if(param3->type == VAR_PARAM)
|
||||
param3 = (var *)param3->ptr; /* evite de le faire a chaque fonction */
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
@@ -81,6 +85,16 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
p_etat = (modEtat *)(*etat);
|
||||
p_etat->error = 0;
|
||||
//*** code specifique ici
|
||||
var * prog;
|
||||
hashtable_do(e, HASH_READ, &e->g, copy_nom(e, GUV_PROG), &prog);
|
||||
// maj ctx avec _prog et taille
|
||||
*((ent64 *)(p_etat->cs.nom)) = 0;
|
||||
*(((ent64 *)(p_etat->cs.nom)) + 1) = 0;
|
||||
*(((ent64 *)(p_etat->cs.nom)) + 2) = 0;
|
||||
if(prog && prog->type == VAR_DYNAMIC && prog->mLg < 24)
|
||||
strncpy(p_etat->cs.nom, prog->mPtr, prog->mLg);
|
||||
p_etat->cs.taille = 4000;
|
||||
//
|
||||
initShm(e, &p_etat->cs);
|
||||
}
|
||||
}
|
||||
@@ -97,10 +111,10 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param->type == VAR_DYNAMIC)
|
||||
dynLet(e, param, "1", 1); //*** version en alpha
|
||||
else if(param->type == VAR_NUMBER)
|
||||
param->num = NUM_UN; //*** version en numerique
|
||||
if(param1->type == VAR_DYNAMIC)
|
||||
dynLet(e, param1, "1", 1); //*** version en alpha
|
||||
else if(param1->type == VAR_NUMBER)
|
||||
param1->num = NUM_UN; //*** version en numerique
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
@@ -111,22 +125,48 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
exc = EX_MODETAT;
|
||||
else
|
||||
{
|
||||
if(param->type == VAR_NUMBER)
|
||||
param->num = (ent64)(NUM_FACTEUR * p_etat->error);
|
||||
if(param1->type == VAR_NUMBER)
|
||||
param1->num = (ent64)(NUM_FACTEUR * p_etat->error);
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(modFnIs(e, "xxx", 3))
|
||||
else if(modFnIs(e, "get", 3))
|
||||
{
|
||||
//*** coder les autres fonctions ici de la meme maniere, au a mettre au debut !
|
||||
exc = setError(p_etat, EXMOD_xxx);
|
||||
if(!param1)
|
||||
exc = EX_MODPARAM;
|
||||
else if(param1->type != VAR_DYNAMIC)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
p_etat->cs.message = param1;
|
||||
exc = setError(p_etat, readShm(e, &p_etat->cs));
|
||||
// param1 vide si rien a lire
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(modFnIs(e, "set", 3))
|
||||
{
|
||||
if(!param1 || !param2)
|
||||
exc = EX_MODPARAM;
|
||||
else if(param1->type != VAR_DYNAMIC || param2->type != VAR_DYNAMIC)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
*((ent64 *)(p_etat->cs.desti)) = 0;
|
||||
*(((ent64 *)(p_etat->cs.desti)) + 1) = 0;
|
||||
*(((ent64 *)(p_etat->cs.desti)) + 2) = 0;
|
||||
if(param1->mLg < 24)
|
||||
strncpy(p_etat->cs.desti, param1->mPtr, param1->mLg);
|
||||
p_etat->cs.message = param2;
|
||||
exc = setError(p_etat, writeShm(e, &p_etat->cs));
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else
|
||||
{
|
||||
exc = EX_MODFUNC; // fonction non prise en charge
|
||||
exc = setError(p_etat, EX_MODFUNC); // fonction non prise en charge
|
||||
}
|
||||
//
|
||||
return exc;
|
||||
|
||||
@@ -23,10 +23,29 @@
|
||||
#include "shm.h"
|
||||
|
||||
#include "buffer.h"
|
||||
#include <errno.h>
|
||||
|
||||
#define SHM_MIN_SIZE 1000
|
||||
#ifndef WINLIB
|
||||
#include <sys/types.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/sem.h>
|
||||
#endif
|
||||
|
||||
/* PRIVATE */
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
/* ---------------------------------------------------- */
|
||||
enum {
|
||||
NBSEM = 1
|
||||
};
|
||||
|
||||
/* ****** PRIVATE ************************ */
|
||||
static key_t Hash32(const char * cle, int lg)
|
||||
{
|
||||
// lg multiple de 4 et > 0
|
||||
@@ -58,36 +77,55 @@ static key_t Hash32(const char * cle, int lg)
|
||||
return (key_t)h;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------- */
|
||||
|
||||
void initShm(env * e, modContextShm * ctx)
|
||||
/* ****** PUBLIC ************************ */
|
||||
WAPIDECL void initShm(env * e, modContextShm * ctx)
|
||||
{
|
||||
#ifndef WINLIB
|
||||
ctx->buffer = NULL;
|
||||
ctx->handle = -1;
|
||||
ctx->semId = -1;
|
||||
// creer la sharedmemory du process, pour lecture
|
||||
if(ctx->taille < SHM_MIN_SIZE)
|
||||
return; // erreur buffer trop petit
|
||||
// ne pas controler la taille, sera fait par 'shmget'
|
||||
// calculer la cle a partir du nom du prog (ctx->nom)
|
||||
ctx->cle = Hash32(ctx->nom, 24); // chaine de 23 cars + \0
|
||||
ctx->cle = Hash32(ctx->nom, 24); // chaine de 23 cars max + \0 de fin
|
||||
// securite : supprimer un eventuel reliquat d'un ancien shm ? Faire un appel externe pas systematique, que le createur, (ou mettre un flag)
|
||||
//shmctl(ctx->cle, IPC_RMID, NULL);
|
||||
// creer le buffer
|
||||
ctx->handle = shmget(ctx->cle, ctx->taille, IPC_CREAT | IPC_EXCL | 0x666); // < 0 si ko
|
||||
ctx->handle = shmget(ctx->cle, ctx->taille, IPC_CREAT | IPC_EXCL | 0666); // < 0 si ko
|
||||
if(ctx->handle < 0)
|
||||
return; // erreur creation sharedmemory
|
||||
// lire le pointeur
|
||||
ctx->buffer = (var *)shmat(ctx->handle, NULL, 0);
|
||||
if( ! ctx->buffer)
|
||||
if(ctx->buffer == (var *)(-1))
|
||||
{
|
||||
shmctl(ctx->handle, IPC_RMID, NULL);
|
||||
ctx->buffer = NULL;
|
||||
ctx->handle = -1;
|
||||
return; // erreur recup pointeur
|
||||
}
|
||||
// creer le semaphore pour les writers
|
||||
ctx->semId = semget(ctx->cle, NBSEM, IPC_CREAT | IPC_EXCL | 0666); // < 0 si ko
|
||||
if(ctx->semId < 0)
|
||||
{
|
||||
freeShm(e, ctx); // erreur
|
||||
return;
|
||||
}
|
||||
// init semaphore
|
||||
unsigned short table[NBSEM];
|
||||
table[0] = 1;
|
||||
if(semctl(ctx->semId, 0, SETALL, table) < 0)
|
||||
{
|
||||
freeShm(e, ctx); // erreur
|
||||
return;
|
||||
}
|
||||
#else
|
||||
ctx->buffer = NULL;
|
||||
ctx->handle = NULL;
|
||||
strncpy(ctx->semDesti, ctx->desti, 24);
|
||||
ctx->semDesti[24] = 0;
|
||||
ctx->semDesti[strlen(ctx->desti)] = '#';
|
||||
// creer la sharedmemory du process, pour lecture
|
||||
if(ctx->taille < SHM_MIN_SIZE)
|
||||
return; // erreur buffer trop petit
|
||||
// ne pas controler la taille, sera fait par 'CreateFileMapping'
|
||||
// la cle est directement le nom
|
||||
// creer le buffer
|
||||
ctx->handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, ctx->taille, ctx->nom); // NULL si ko, attention au \0 de fin de ctx->nom
|
||||
@@ -97,6 +135,7 @@ void initShm(env * e, modContextShm * ctx)
|
||||
if( ! ctx->buffer)
|
||||
{
|
||||
CloseHandle(ctx->handle);
|
||||
ctx->buffer = NULL;
|
||||
ctx->handle = NULL;
|
||||
return; // erreur recup pointeur
|
||||
}
|
||||
@@ -105,71 +144,118 @@ void initShm(env * e, modContextShm * ctx)
|
||||
ctx->buffer->lgmax = ctx->taille - sizeof(var);
|
||||
ctx->buffer->read = 0;
|
||||
ctx->buffer->write = 0;
|
||||
ctx->buffer->ptr = (pointeur)ctx->buffer + sizeof(var); // le contenu est a la suite de l'entete de la variable
|
||||
ctx->buffer->ptr = NULL; // NULL signifie que le contenu est a la suite de l'entete de la variable (utilise uniquement ici avec les IPC)
|
||||
}
|
||||
|
||||
void freeShm(env * e, modContextShm * ctx)
|
||||
WAPIDECL void freeShm(env * e, modContextShm * ctx)
|
||||
{
|
||||
#ifndef WINLIB
|
||||
if(ctx->buffer)
|
||||
shmdt(ctx->buffer);
|
||||
if(ctx->handle >= 0)
|
||||
shmctl(ctx->handle, IPC_RMID, NULL);
|
||||
if(ctx->semId >= 0)
|
||||
semctl(ctx->semId, IPC_RMID, 0);
|
||||
ctx->buffer = NULL;
|
||||
ctx->handle = -1;
|
||||
ctx->semId = -1;
|
||||
#else
|
||||
if(ctx->buffer)
|
||||
UnmapViewOfFile(ctx->buffer);
|
||||
if(ctx->handle >= 0)
|
||||
CloseHandle(ctx->handle); // verif que bien detruit
|
||||
ctx->buffer = NULL;
|
||||
ctx->handle = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void readShm(env * e, modContextShm * ctx)
|
||||
WAPIDECL long readShm(env * e, modContextShm * ctx)
|
||||
{
|
||||
#ifndef WINLIB
|
||||
if( ! ctx->buffer || ctx->handle < 0)
|
||||
return EXMOD_BUFFER_INIT;
|
||||
#else
|
||||
if( ! ctx->buffer || ! ctx->handle)
|
||||
return EXMOD_BUFFER_INIT;
|
||||
#endif
|
||||
buffer_read(e, ctx->buffer, ctx->message);
|
||||
// e->exception != OK si exception en lecture (que EX_MEM) ! vide si rien a lire (Dynamic)
|
||||
return e->exception;
|
||||
}
|
||||
|
||||
void writeShm(env * e, modContextShm * ctx)
|
||||
WAPIDECL long writeShm(env * e, modContextShm * ctx)
|
||||
{
|
||||
// TODO gestion verrou !
|
||||
#ifndef WINLIB
|
||||
// calculer la cle a partir du nom du prog (ctx->nom)
|
||||
key_t cle = Hash32(ctx->desti, 24); // chaine de 23 cars + \0
|
||||
// acceder au buffer
|
||||
int handle = shmget(cle, 0, 0);
|
||||
if(handle < 0)
|
||||
return; // erreur access
|
||||
return EXMOD_BUFFER_WRITE; // erreur access
|
||||
// lire le pointeur
|
||||
var * buffer = (var *)shmat(handle, NULL, 0);
|
||||
if( ! buffer)
|
||||
return; // seul le ptr se libere
|
||||
if(buffer == (var *)(-1))
|
||||
return EXMOD_BUFFER_WRITE; // seul le ptr se libere
|
||||
// prendre le verrou (semaphore) pour ecrire, avec attente
|
||||
int semId = semget(cle, NBSEM, 0);
|
||||
if(semId < 0)
|
||||
{
|
||||
shmdt(buffer);
|
||||
return EXMOD_BUFFER_WRITE;
|
||||
}
|
||||
struct sembuf bufw;
|
||||
bufw.sem_num = 0;
|
||||
bufw.sem_op = -1; // prendre
|
||||
bufw.sem_flg = SEM_UNDO; // | IPC_NOWAIT ?
|
||||
if(semop(semId, &bufw, 1) < 0)
|
||||
{
|
||||
shmdt(buffer);
|
||||
return EXMOD_BUFFER_WRITE;
|
||||
}
|
||||
// EcrireBuffer
|
||||
buffer_write(e, buffer, ctx->message);
|
||||
// e->exception != OK si exception en ecriture (que EX_BUFOVF) !
|
||||
// liberer le verrou
|
||||
bufw.sem_op = 1; // liberer
|
||||
semop(semId, &bufw, 1);
|
||||
// ne liberer que le ptr sous unix
|
||||
shmdt(buffer);
|
||||
#else
|
||||
// la cle est directement le destinataire
|
||||
HANDLE handle = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, ctx->desti); // attention au \0 de fin
|
||||
if( ! handle)
|
||||
return; // erreur access
|
||||
return EXMOD_BUFFER_WRITE; // erreur access
|
||||
// lire le pointeur
|
||||
var * buffer = (var *)MapViewOfFile(handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
||||
if( ! buffer)
|
||||
{
|
||||
CloseHandle(handle);
|
||||
return; // erreur recup pointeur
|
||||
return EXMOD_BUFFER_WRITE; // erreur recup pointeur
|
||||
}
|
||||
// prendre le verrou (semaphore) pour ecrire, avec attente
|
||||
HANDLE hSem = CreateSemaphore(NULL, 1, 1, ctx->semDesti); // NULL si erreur
|
||||
if( ! hSem)
|
||||
{
|
||||
UnmapViewOfFile(buffer);
|
||||
CloseHandle(handle);
|
||||
return EXMOD_BUFFER_WRITE; // erreur recup pointeur
|
||||
}
|
||||
if(WaitForSingleObject(hSem, 0) != WAIT_OBJECT_0) // retour WAIT_OBJECT_0 si ok, WAIT_TIMEOUT ou autre si pas dispo ou erreur ; 0 = timeout en secondes
|
||||
{
|
||||
ReleaseSemaphore(hSem, 1, NULL);
|
||||
UnmapViewOfFile(buffer);
|
||||
CloseHandle(handle);
|
||||
return EXMOD_BUFFER_WRITE; // erreur recup pointeur
|
||||
}
|
||||
// EcrireBuffer
|
||||
buffer_write(e, buffer, ctx->message);
|
||||
// e->exception != OK si exception en ecriture (que EX_BUFOVF) !
|
||||
// liberer le verrou
|
||||
ReleaseSemaphore(hSem, 1, NULL);
|
||||
// liberations
|
||||
UnmapViewOfFile(buffer);
|
||||
CloseHandle(handle);
|
||||
#endif
|
||||
return e->exception;
|
||||
}
|
||||
|
||||
/*
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg); DispatchMessage(&msg);
|
||||
}
|
||||
*/
|
||||
@@ -2,7 +2,7 @@
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024 lanisys.fr
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
@@ -29,13 +29,13 @@
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef UNIX
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netdb.h>
|
||||
#else
|
||||
#include "windows.h"
|
||||
#include "windows.h"
|
||||
#endif
|
||||
|
||||
#include "langage.h"
|
||||
@@ -63,13 +63,12 @@ static int setError(modEtat * p, int err)
|
||||
return EX_MODERR;
|
||||
}
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
/* TODO : gestion des 3 parametres (au lieu d'un seul) */
|
||||
modEtat * p_etat;
|
||||
@@ -86,7 +85,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(strncmp(e->fn, "init", 4) == 0)
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
@@ -101,7 +100,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
p_etat->mServeur = 0;
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
// liberation specifique au module avant arret process
|
||||
p_etat = (modEtat *)(*etat);
|
||||
@@ -114,7 +113,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
memfree(e, p_etat);
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param->type == VAR_DYNAMIC)
|
||||
@@ -124,7 +123,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
else if(strncmp(e->fn, "error", 5) == 0)
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
@@ -138,7 +137,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "server", 6) == 0)
|
||||
else if(modFnIs(e, "server", 6))
|
||||
{
|
||||
/* cree un point d'entree serveur */
|
||||
if(p_etat == NULL)
|
||||
@@ -244,7 +243,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "connect", 7) == 0)
|
||||
else if(modFnIs(e, "connect", 7))
|
||||
{
|
||||
char ** tParam;
|
||||
/* connexion a un serveur */
|
||||
@@ -347,7 +346,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "arret", 5) == 0)
|
||||
else if(modFnIs(e, "arret", 5))
|
||||
{
|
||||
/* arret connexion cliente ou serveur */
|
||||
if(p_etat != NULL)
|
||||
@@ -358,7 +357,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "attente", 7) == 0)
|
||||
else if(modFnIs(e, "attente", 7))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -404,7 +403,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "get", 3) == 0)
|
||||
else if(modFnIs(e, "get", 3))
|
||||
{
|
||||
long nblu = 0, arg = 1, flagInProgress = 0, pas = 16000, would_block;
|
||||
/* lecture sur la connexion */
|
||||
@@ -446,7 +445,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "set", 3) == 0)
|
||||
else if(modFnIs(e, "set", 3))
|
||||
{
|
||||
long nb , pos = 0, lg, would_block;
|
||||
/* ecriture sur la connexion */
|
||||
@@ -481,7 +480,7 @@ extern long execModule(env * e, var * param, var * param2, var * param3, void **
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "accept", 6) == 0)
|
||||
else if(modFnIs(e, "accept", 6))
|
||||
{
|
||||
/* ecriture sur la connexion */
|
||||
if(p_etat == NULL)
|
||||
|
||||
+42
-39
@@ -26,17 +26,17 @@
|
||||
#include <string.h>
|
||||
|
||||
#ifdef UNIX
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
#include "windows.h" // TODO ici
|
||||
#include "windows.h" // TODO ici
|
||||
#endif
|
||||
|
||||
#include "langage.h"
|
||||
@@ -49,13 +49,15 @@ typedef struct {
|
||||
|
||||
/* mettre ici les codes d'erreurs specifiques au module */
|
||||
/* codes a passer a la fonction setError */
|
||||
#define EXMOD_SYSTEM_FICTMP 1
|
||||
#define EXMOD_SYSTEM_UNKNOWNVARENV 2
|
||||
#define EXMOD_SYSTEM_SETENV 3
|
||||
#define EXMOD_SYSTEM_UNSETENV 4
|
||||
#define EXMOD_SYSTEM_GETHOST 5
|
||||
#define EXMOD_SYSTEM_UNAME 6
|
||||
#define EXMOD_SYSTEM_FORK 7
|
||||
enum {
|
||||
EXMOD_SYSTEM_FICTMP = 1,
|
||||
EXMOD_SYSTEM_UNKNOWNVARENV = 2,
|
||||
EXMOD_SYSTEM_SETENV = 3,
|
||||
EXMOD_SYSTEM_UNSETENV = 4,
|
||||
EXMOD_SYSTEM_GETHOST = 5,
|
||||
EXMOD_SYSTEM_UNAME = 6,
|
||||
EXMOD_SYSTEM_FORK = 7
|
||||
};
|
||||
|
||||
static int setError(modEtat * p, int err)
|
||||
{
|
||||
@@ -64,13 +66,12 @@ static int setError(modEtat * p, int err)
|
||||
return EX_MODERR;
|
||||
}
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
modEtat * p_etat;
|
||||
long exc = OK;
|
||||
@@ -100,7 +101,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(strncmp(e->fn, "init", 4) == 0)
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
@@ -113,7 +114,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//*** code specifique ici
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
// liberation specifique au module avant arret process
|
||||
if(p_etat != NULL)
|
||||
@@ -122,7 +123,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
memfree(e, p_etat);
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param1->type == VAR_DYNAMIC)
|
||||
@@ -132,7 +133,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
else if(strncmp(e->fn, "error", 5) == 0)
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
@@ -146,7 +147,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "execute", 7) == 0)
|
||||
else if(modFnIs(e, "execute", 7))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
// execute(command, returning, capturing)
|
||||
@@ -184,10 +185,12 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
{
|
||||
if(flagCapturing)
|
||||
{
|
||||
dynIns(e, &e->int_dynamic, 1, DYN_NONE, param3, '>', DYN_NONE);
|
||||
cr = system(param1->mPtr);
|
||||
dynSetAs(e, param3, param1);
|
||||
dynIns(e, param3, 1 + dynDcount(e, param3, '>', DYN_NONE, DYN_NONE), DYN_NONE, &e->int_dynamic, '>', DYN_NONE);
|
||||
cr = system(param3->mPtr);
|
||||
dynRead(e, param3, e->int_dynamic.mPtr);
|
||||
// TODO : purge fichier temp ?
|
||||
// purge fichier temp
|
||||
remove(e->int_dynamic.mPtr); // pbm windows ?!
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -198,7 +201,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "getEnv", 6) == 0)
|
||||
else if(modFnIs(e, "getEnv", 6))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
/* utilisation de dynRead qui fait le travail */
|
||||
@@ -223,7 +226,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "createEnv", 9) == 0)
|
||||
else if(modFnIs(e, "createEnv", 9))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
// setEnv(nom, valeur, overwritting)
|
||||
@@ -258,7 +261,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "updateEnv", 9) == 0)
|
||||
else if(modFnIs(e, "updateEnv", 9))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
// setEnv(nom, valeur, overwritting)
|
||||
@@ -286,7 +289,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "deleteEnv", 9) == 0)
|
||||
else if(modFnIs(e, "deleteEnv", 9))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
// setEnv(nom, valeur, overwritting)
|
||||
@@ -312,7 +315,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "getOS", 5) == 0)
|
||||
else if(modFnIs(e, "getOS", 5))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
// uname() donne les infos
|
||||
@@ -341,7 +344,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "getHostname", 5) == 0)
|
||||
else if(modFnIs(e, "getHostname", 11))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
// uname() donne les infos
|
||||
@@ -424,7 +427,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "fork", 4) == 0)
|
||||
else if(modFnIs(e, "fork", 4))
|
||||
{
|
||||
p_etat->error = 0;
|
||||
#ifndef UNIX
|
||||
@@ -446,7 +449,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
#endif
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "wait", 4) == 0)
|
||||
else if(modFnIs(e, "wait", 4))
|
||||
{
|
||||
#ifndef UNIX
|
||||
// faire differemment sous windows : pas de wait dispo ? WaitForSingleObject()
|
||||
@@ -457,7 +460,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
#endif
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "kill", 4) == 0)
|
||||
else if(modFnIs(e, "kill", 4))
|
||||
{
|
||||
#ifndef UNIX
|
||||
// faire differemment sous windows : pas de kill dispo ?
|
||||
@@ -466,7 +469,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
#endif
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "sleep", 5) == 0)
|
||||
else if(modFnIs(e, "sleep", 5))
|
||||
{
|
||||
#ifdef WINLIB
|
||||
if(param1->type != VAR_NUMBER)
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
/* **********************************************
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
W language is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version (GPL-3.0-or-later).
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
********************************************** */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "langage.h"
|
||||
#include "dynamic.h"
|
||||
|
||||
typedef struct {
|
||||
int error; // dernier code erreur specifique au module
|
||||
//*** a completer selon le besoin du module
|
||||
} modEtat;
|
||||
|
||||
/* mettre ici les codes d'erreurs specifiques au module */
|
||||
/* codes a passer a la fonction setError */
|
||||
#define EXMOD_xxx 1
|
||||
|
||||
static int setError(modEtat * p, int err)
|
||||
{
|
||||
if(p != NULL)
|
||||
p->error = err;
|
||||
return EX_MODERR;
|
||||
}
|
||||
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
/* TODO : gestion des 3 parametres (au lieu d'un seul) */
|
||||
modEtat * p_etat;
|
||||
long exc = OK;
|
||||
// init/end/vers/error sont obligatoires pour tout module
|
||||
// - - - - - - - - - - - - - - - - - - - -
|
||||
if(etat == NULL)
|
||||
return EX_MODPARAM;
|
||||
else
|
||||
p_etat = (modEtat *)(*etat); /* evite de la faire a chaque fonction */
|
||||
//
|
||||
if(param1 != NULL)
|
||||
if(param1->type == VAR_PARAM)
|
||||
param1 = (var *)param1->ptr; /* evite de le faire a chaque fonction */
|
||||
if(param2 != NULL)
|
||||
if(param2->type == VAR_PARAM)
|
||||
param2 = (var *)param2->ptr; /* evite de le faire a chaque fonction */
|
||||
if(param3 != NULL)
|
||||
if(param3->type == VAR_PARAM)
|
||||
param3 = (var *)param3->ptr; /* evite de le faire a chaque fonction */
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
if(*etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else
|
||||
{
|
||||
p_etat = (modEtat *)(*etat);
|
||||
p_etat->error = 0;
|
||||
//*** code specifique ici
|
||||
//
|
||||
}
|
||||
}
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
//*** code specifique ici
|
||||
//
|
||||
// liberation specifique au module avant arret process
|
||||
if(p_etat != NULL)
|
||||
memfree(e, p_etat);
|
||||
}
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param1->type == VAR_DYNAMIC)
|
||||
dynLet(e, param1, "1", 1); //*** version en alpha
|
||||
else if(param1->type == VAR_NUMBER)
|
||||
param1->num = NUM_UN; //*** version en numerique
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
}
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
else if(param1 == NULL)
|
||||
exc = EX_MODPARAM;
|
||||
else
|
||||
{
|
||||
if(param1->type == VAR_NUMBER)
|
||||
param1->num = (ent64)(NUM_FACTEUR * p_etat->error);
|
||||
else
|
||||
exc = EX_MODPARAM; // bad type of parameter
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(modFnIs(e, "xxx", 3))
|
||||
{
|
||||
//*** coder les autres fonctions ici de la meme maniere, au a mettre au debut !
|
||||
exc = setError(p_etat, EXMOD_xxx);
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else
|
||||
{
|
||||
setError(p_etat, 0); // evite un warning de compil
|
||||
exc = EX_MODFUNC; // fonction non prise en charge
|
||||
}
|
||||
//
|
||||
return exc;
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
__ __ __
|
||||
\ \/ \/ / W language
|
||||
\ /\ /
|
||||
\/ \/ Copyright 2024 lanisys.fr
|
||||
\/ \/ Copyright 2024,2025 lanisys.fr
|
||||
|
||||
This file is part of W language.
|
||||
|
||||
@@ -51,11 +51,13 @@ typedef struct {
|
||||
|
||||
/* mettre ici les codes d'erreurs specifiques au module */
|
||||
/* codes a passer a la fonction setError */
|
||||
#define EXMOD_GETCLOCK 1
|
||||
#define EXMOD_PARAMNUM 2
|
||||
#define EXMOD_FORMAT_KO 3
|
||||
#define EXMOD_JETLAG_KO 4
|
||||
#define EXMOD_DURATION_GETCLOCK 5
|
||||
enum {
|
||||
EXMOD_GETCLOCK = 1,
|
||||
EXMOD_PARAMNUM = 2,
|
||||
EXMOD_FORMAT_KO = 3,
|
||||
EXMOD_JETLAG_KO = 4,
|
||||
EXMOD_DURATION_GETCLOCK = 5
|
||||
};
|
||||
|
||||
static int setError(modEtat * p, int err)
|
||||
{
|
||||
@@ -300,13 +302,12 @@ static void FormatTm(env * e, modEtat * p_etat, const char * format, time_t dhm,
|
||||
}
|
||||
/* fonctions locales au module FIN */
|
||||
|
||||
#ifndef UNIX
|
||||
#ifdef WINLIB
|
||||
/* Sous Windows, export de la fonction de base au sein d'une DLL : 1 module = 1 DLL */
|
||||
__declspec(dllexport) long execModule(env * , var * , var * , var * , void ** );
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#else
|
||||
extern long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
#endif
|
||||
|
||||
long execModule(env * e, var * param1, var * param2, var * param3, void ** etat)
|
||||
{
|
||||
/* TODO : gestion des 3 parametres (au lieu d'un seul) */
|
||||
modEtat * p_etat;
|
||||
@@ -329,7 +330,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
//
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
/* les 4 fonctions suivantes doivent toujours exister dans chaque module */
|
||||
if(strncmp(e->fn, "init", 4) == 0)
|
||||
if(modFnIs(e, "init", 4))
|
||||
{
|
||||
// alloc ptr sur zone memoire pour memoriser l'etat du module
|
||||
*etat = memalloc(e, sizeof(modEtat));
|
||||
@@ -346,7 +347,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
dynInit(e, &p_etat->valNum, DYN_LGMIN);
|
||||
}
|
||||
}
|
||||
else if(strncmp(e->fn, "end", 3) == 0)
|
||||
else if(modFnIs(e, "end", 3))
|
||||
{
|
||||
// liberation specifique au module avant arret process
|
||||
if(p_etat != NULL)
|
||||
@@ -355,7 +356,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
dynFree(e, &p_etat->horodate);
|
||||
dynFree(e, &p_etat->valNum);
|
||||
}
|
||||
else if(strncmp(e->fn, "vers", 4) == 0)
|
||||
else if(modFnIs(e, "vers", 4))
|
||||
{
|
||||
// renvoie la version du module/plugins
|
||||
if(param1 == NULL)
|
||||
@@ -367,7 +368,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
else
|
||||
exc = EX_MODPARAM; // variable en parametre du mauvais type
|
||||
}
|
||||
else if(strncmp(e->fn, "error", 5) == 0)
|
||||
else if(modFnIs(e, "error", 5))
|
||||
{
|
||||
// renvoie la derniere erreur specifique au module
|
||||
if(p_etat == NULL)
|
||||
@@ -383,7 +384,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ============================================================================================= */
|
||||
else if(strncmp(e->fn, "startChrono", 11) == 0)
|
||||
else if(modFnIs(e, "startChrono", 11))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -401,7 +402,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "lapChrono", 9) == 0)
|
||||
else if(modFnIs(e, "lapChrono", 9))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -420,7 +421,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "setUTC", 6) == 0)
|
||||
else if(modFnIs(e, "setUTC", 6))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -448,7 +449,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "setLocal", 8) == 0)
|
||||
else if(modFnIs(e, "setLocal", 8))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -483,7 +484,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "setNowLocal", 11) == 0)
|
||||
else if(modFnIs(e, "setNowLocal", 11))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -511,7 +512,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "setNowUTC", 9) == 0)
|
||||
else if(modFnIs(e, "setNowUTC", 9))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -533,7 +534,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "set", 3) == 0)
|
||||
else if(modFnIs(e, "set", 3))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -566,7 +567,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "getUTC", 6) == 0)
|
||||
else if(modFnIs(e, "getUTC", 6))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -586,7 +587,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "getLocal", 8) == 0)
|
||||
else if(modFnIs(e, "getLocal", 8))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -612,7 +613,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "get", 3) == 0)
|
||||
else if(modFnIs(e, "get", 3))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -635,7 +636,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "alarmUTCHM", 16) == 0)
|
||||
else if(modFnIs(e, "alarmUTCHM", 10))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
@@ -673,7 +674,7 @@ extern long execModule(env * e, var * param1, var * param2, var * param3, void *
|
||||
}
|
||||
}
|
||||
/* ----------------------------------------------------------------------------------------------- */
|
||||
else if(strncmp(e->fn, "alarmLocalHM", 18) == 0)
|
||||
else if(modFnIs(e, "alarmLocalHM", 12))
|
||||
{
|
||||
if(p_etat == NULL)
|
||||
exc = EX_MODETAT;
|
||||
|
||||
@@ -29,7 +29,16 @@
|
||||
#include "var.h"
|
||||
#include "hashtable.h"
|
||||
|
||||
void var_init(env * e, var * v, octet type, ent64 mod_lg, ent64 sep_lgm, pointeur pf)
|
||||
// force exporting
|
||||
#ifdef WINLIB
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL __declspec(dllexport)
|
||||
#else
|
||||
#undef WAPIDECL
|
||||
#define WAPIDECL
|
||||
#endif
|
||||
|
||||
WAPIDECL void var_init(env * e, var * v, octet type, ent64 mod_lg, ent64 sep_lgm, pointeur pf)
|
||||
{
|
||||
/* ne pas regarder le type precedent : ecraser ! */
|
||||
if(v == NULL)
|
||||
@@ -55,7 +64,7 @@ void var_init(env * e, var * v, octet type, ent64 mod_lg, ent64 sep_lgm, pointeu
|
||||
v->lg = 0;
|
||||
v->lgmax = sep_lgm;
|
||||
v->ptr[0] = 0;
|
||||
v->codePage = CP_DEFAULT;
|
||||
v->codePage = WCP_DEFAULT;
|
||||
}
|
||||
break;
|
||||
case VAR_BUFFER:
|
||||
@@ -102,7 +111,7 @@ void var_init(env * e, var * v, octet type, ent64 mod_lg, ent64 sep_lgm, pointeu
|
||||
}
|
||||
}
|
||||
|
||||
void var_ctrl_param(env * e, var * v)
|
||||
WAPIDECL void var_ctrl_param(env * e, var * v)
|
||||
{
|
||||
/* controle que la var "v", si de type PARAM, pointe sur une var toujours existante... */
|
||||
if(v->type != VAR_PARAM)
|
||||
@@ -111,7 +120,25 @@ void var_ctrl_param(env * e, var * v)
|
||||
/* dans le cas : hash, puis var de hash, puis clear hash : quid de la var de hash : ras car c'est une copie ! */
|
||||
}
|
||||
|
||||
void var_free(env * e, var * v, int suivre_par)
|
||||
WAPIDECL int var_conv_num(env * e, var * v, number * num)
|
||||
{
|
||||
if(!v || !num)
|
||||
return FALSE;
|
||||
if(v->type == VAR_PARAM)
|
||||
v = (var *)v->ptr;
|
||||
if(v->type == VAR_NUMBER)
|
||||
{
|
||||
*num = v->num;
|
||||
return TRUE;
|
||||
}
|
||||
if(v->type != VAR_DYNAMIC)
|
||||
return FALSE;
|
||||
/* convertir si string, en number */
|
||||
*num = dynToNumber(e, v);
|
||||
return(v->mInternal == DYN_OK);
|
||||
}
|
||||
|
||||
WAPIDECL void var_free(env * e, var * v, int suivre_par)
|
||||
{
|
||||
var * pvar;
|
||||
/* */
|
||||
@@ -149,7 +176,7 @@ void var_free(env * e, var * v, int suivre_par)
|
||||
v->type = VAR_NULL;
|
||||
}
|
||||
|
||||
void var_let(env * e, var * let, var * v, int suivre_let, int suivre_v)
|
||||
WAPIDECL void var_let(env * e, var * let, var * v, int suivre_let, int suivre_v)
|
||||
{
|
||||
var * pvar;
|
||||
/* tient compte de la valeur precedente de la var ; suivre_let/suivre_v = TRUE pour travailler avec la var pointee */
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
#ifndef VAR_H
|
||||
#define VAR_H
|
||||
|
||||
void var_init(env * e, var * v, octet type, ent64 mod_lg, ent64 sep_lgm, pointeur pf);
|
||||
void var_ctrl_param(env * e, var * v);
|
||||
void var_free(env * e, var * v, int suivre_par);
|
||||
void var_let(env * e, var * let, var * v, int suivre_let, int suivre_v);
|
||||
#include "apidecl.h"
|
||||
|
||||
WAPIDECL void var_init(env * e, var * v, octet type, ent64 mod_lg, ent64 sep_lgm, pointeur pf);
|
||||
WAPIDECL void var_ctrl_param(env * e, var * v);
|
||||
WAPIDECL int var_conv_num(env * e, var * v, number * num);
|
||||
WAPIDECL void var_free(env * e, var * v, int suivre_par);
|
||||
WAPIDECL void var_let(env * e, var * let, var * v, int suivre_let, int suivre_v);
|
||||
|
||||
/* ********************************************** */
|
||||
#endif
|
||||
Reference in new issue
Block a user