Răsfoiți Sursa

feat: 完善了信号处理机制

SongZihuan 4 ani în urmă
părinte
comite
58a39ee633
13 a modificat fișierele cu 75 adăugiri și 39 ștergeri
  1. 1 0
      include/grammar.h
  2. 3 1
      include/handler.h
  3. 1 0
      include/macro.h
  4. 0 1
      include/token.h
  5. 2 9
      main.c
  6. 5 4
      parser/__grammar.c
  7. 15 2
      parser/grammar.c
  8. 1 1
      parser/lexical.c
  9. 6 12
      parser/syntax.c
  10. 12 3
      signalhandler/handler.c
  11. 12 1
      src/run.c
  12. 11 2
      src/runfile.c
  13. 6 3
      src/virtualmath.c

+ 1 - 0
include/grammar.h

@@ -9,6 +9,7 @@ struct ParserMessage{
         syntax_error,
         command_list_error,
         lexical_error,
+        int_error,
     } status;
     char *status_message;
     char *file;

+ 3 - 1
include/handler.h

@@ -9,7 +9,9 @@ enum SignalType{
 
 typedef enum SignalType SignalType;
 extern volatile SignalType is_KeyInterrupt;
+extern volatile SignalType pm_KeyInterrupt;
 
-void resetHandler();
+void signalStopInter(int signum);;
+void signalStopPm(int signum);
 
 #endif //VIRTUALMATH_HANDLER_H

+ 1 - 0
include/macro.h

@@ -11,6 +11,7 @@
 #include <ctype.h>
 #include <setjmp.h>
 #include <signal.h>
+#include <unistd.h>
 
 // 布尔逻辑的定义
 #define bool int

+ 0 - 1
include/token.h

@@ -3,7 +3,6 @@
 
 #include <__macro.h>
 
-#define MATHER_ERROR_ -1
 #define MATHER_NUMBER 0
 #define MATHER_STRING 1
 #define MATHER_VAR 2

+ 2 - 9
main.c

@@ -1,9 +1,8 @@
 #include "__virtualmath.h"
-void signalStop(int signum);
-
 int main(int argc, char *argv[]) {
     Inter *inter = NULL;
-    signal(SIGINT, signalStop);
+    signal(SIGINT, SIG_IGN);
+
     if (setjmp(memVirtualMath_Env) == -1){
         fprintf(stderr, "ERROR: Fatal memory error encountered, May be caused by insufficient memory!\n");
         return 1;
@@ -23,12 +22,6 @@ int main(int argc, char *argv[]) {
     return 0;
 }
 
-
-void signalStop(int signum) {
-    if (is_KeyInterrupt == signal_reset)
-        is_KeyInterrupt = signal_appear;
-}
-
 /** TODO-szh List
  * 官方函数
  * 官方类

+ 5 - 4
parser/__grammar.c

@@ -134,12 +134,13 @@ void syntaxError(ParserMessage *pm, int status, long int line, int num, ...) {
 
 int readBackToken(ParserMessage *pm){
     Token *tmp = popNewToken(pm->tm);
-    if (tmp->token_type == -2){
-        freeToken(tmp, false);
+    int type = tmp->token_type;
+    if (type == -2)
         syntaxError(pm, lexical_error, tmp->line, 1, "lexical make some error");
-    }
+    else if (type == -3)
+        syntaxError(pm, int_error, tmp->line, 1, "KeyInterrupt");
     addBackToken(pm->tm->ts, tmp);
-    return tmp->token_type;
+    return type;
 }
 
 bool checkToken(ParserMessage *pm, int type){

+ 15 - 2
parser/grammar.c

@@ -35,10 +35,18 @@ void parserCommandList(PASERSSIGNATURE, bool global, bool is_one, Statement *st)
     bool should_break = false;
     char *command_message = global ? "ERROR from command list(get parserCommand)" : NULL;
     int save_enter = pm->tm->file->filter_data.enter;
+    void *bak = NULL;
+    fline line = 0;
+
+    pm_KeyInterrupt = signal_reset;
+    bak = signal(SIGINT, signalStopPm);
     pm->tm->file->filter_data.enter = 0;
+
     while (!should_break){
         token_type = readBackToken(pm);
-        if (token_type == MATHER_EOF){
+        if (token_type == -3 || token_type == -2)
+            goto return_;
+        else if (token_type == MATHER_EOF){
             delToken(pm);
             goto return_;
         }
@@ -51,7 +59,7 @@ void parserCommandList(PASERSSIGNATURE, bool global, bool is_one, Statement *st)
             int stop;
             if (!callChildToken(CALLPASERSSIGNATURE, parserCommand, COMMAND, &command_token, command_message, command_list_error))
                 goto return_;
-
+            line = command_token->line;
             stop = readBackToken(pm);
             if (stop == MATHER_ENTER) {
                 delToken(pm);
@@ -78,6 +86,11 @@ void parserCommandList(PASERSSIGNATURE, bool global, bool is_one, Statement *st)
         }
     }
     return_:
+    signal(SIGINT, bak);
+    if (pm_KeyInterrupt != signal_reset) {
+        pm_KeyInterrupt = signal_reset;
+        syntaxError(pm, int_error, line, 1, "KeyInterrupt");
+    }
     pm->tm->file->filter_data.enter = save_enter;
     return;
 }

+ 1 - 1
parser/lexical.c

@@ -10,7 +10,7 @@ int readChar(LexFile *file){
     if (file->back.is_back)
         file->back.is_back = false;
     else
-        file->back.p = getc(file->file);
+        file->back.p = fgetc(file->file);
     if (file->back.p == '\n')
         file->line++;
     return file->back.p;

+ 6 - 12
parser/syntax.c

@@ -244,9 +244,9 @@ int getMatherStatus(LexFile *file, LexMathers *mathers) {
     setupMathers(mathers);
     while (status == -1){
         p = readChar(file);
-        if (is_KeyInterrupt == signal_appear) {
-            is_KeyInterrupt = signal_check;
-            return -2;
+        if (pm_KeyInterrupt == signal_appear) {
+            pm_KeyInterrupt = signal_check;
+            return -3;
         }
 
         numberMather(p ,mathers->mathers[MATHER_NUMBER]);
@@ -370,17 +370,11 @@ int lexFilter(LexFile *file, int status){
 Token *getToken(LexFile *file, LexMathers *mathers) {
     int status = MATHER_SPACE;
     int filter;
-    Token *tmp = NULL;
 
     while ((filter = lexFilter(file, status)) == -1)
         status = getMatherStatus(file, mathers);
 
-    if (status == -2){
-        tmp = makeLexToken(MATHER_ERROR_, NULL, NULL, file->line);
-        goto return_;
-    }
-    tmp = makeLexToken(filter, mathers->mathers[status]->str, mathers->mathers[status]->second_str, file->line);
-
-    return_:
-    return tmp;
+    if (status == -2 || status == -3)
+        return makeLexToken(status, NULL, NULL, file->line);
+    return makeLexToken(filter, mathers->mathers[status]->str, mathers->mathers[status]->second_str, file->line);
 }

+ 12 - 3
signalhandler/handler.c

@@ -1,6 +1,15 @@
 #include "__virtualmath.h"
-volatile SignalType is_KeyInterrupt;
+volatile SignalType is_KeyInterrupt = signal_reset;
+volatile SignalType pm_KeyInterrupt = signal_reset;
 
-void resetHandler() {
-    is_KeyInterrupt = signal_reset;
+void signalStopInter(int signum) {
+    if (is_KeyInterrupt == signal_reset)
+        is_KeyInterrupt = signal_appear;
+    signal(signum, signalStopInter);
 }
+
+void signalStopPm(int signum) {
+    if (pm_KeyInterrupt == signal_reset)
+        pm_KeyInterrupt = signal_appear;
+    signal(signum, signalStopPm);
+}

+ 12 - 1
src/run.c

@@ -134,13 +134,16 @@ bool checkSignal(ResultType *type, fline line, char *file, INTER_FUNCTIONSIG_NOT
 ResultType iterStatement(INTER_FUNCTIONSIG) {
     Statement *base;
     ResultType type;
-    setResultCore(result);
+//    void *bak = NULL;
 
+    setResultCore(result);
     if (st == NULL){
         setResult(result, inter, belong);
         return result->type;
     }
 
+//    is_KeyInterrupt = signal_reset;
+//    signal(SIGINT, signalStopInter);
     do {
         base = st;
         if (checkSignal(&type, base->line, base->code_file, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong)))
@@ -172,7 +175,9 @@ ResultType iterStatement(INTER_FUNCTIONSIG) {
     if (type == not_return || type == restart_return)
         setResultOperationNone(result, inter, belong);
     result->node = base;
+
     gc_run(inter, var_list, 1, 0, 0, var_list);
+//    signal(SIGINT, bak);
     return result->type;
 }
 
@@ -186,12 +191,15 @@ ResultType globalIterStatement(Result *result, Inter *inter, Statement *st) {
     VarList *var_list = NULL;
     Statement *base;
     LinkValue *belong = inter->base_father;
+    void *bak = NULL;
 
     if (st == NULL){
         setResult(result, inter, belong);
         return result->type;
     }
 
+    is_KeyInterrupt = signal_reset;
+    bak = signal(SIGINT, signalStopInter);
     gc_addTmpLink(&belong->gc_status);
     do {
         base = st;
@@ -225,8 +233,11 @@ ResultType globalIterStatement(Result *result, Inter *inter, Statement *st) {
     if (type != error_return && type != function_return)
         setResultOperationNone(result, inter, belong);
     result->node = base;
+
     gc_freeTmpLink(&belong->gc_status);
     gc_run(inter, var_list, 1, 0, 0, var_list);
+
+    signal(SIGINT, bak);
     return result->type;
 }
 

+ 11 - 2
src/runfile.c

@@ -25,7 +25,11 @@ ResultType includeFile(INTER_FUNCTIONSIG) {
     new_st = makeStatement(0, file_dir);
     pm = makeParserMessage(file_dir);
     parserCommandList(pm, inter, true, false, new_st);
-    if (pm->status != success){
+    if (pm->status == int_error) {
+        setResultErrorSt(E_KeyInterrupt, "KeyInterrupt", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        goto return_;
+    }
+    else if (pm->status != success){
         setResultErrorSt(E_IncludeException, pm->status_message, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         goto return_;
     }
@@ -74,9 +78,14 @@ ResultType importFileCore(VarList **new_object, char **file_dir, INTER_FUNCTIONS
     pm = makeParserMessage(*file_dir);
     run_st = makeStatement(0, *file_dir);
     parserCommandList(pm, import_inter, true, false, run_st);
-    if (pm->status != success) {
+    if (pm->status == int_error) {
+        setResultErrorSt(E_KeyInterrupt, "KeyInterrupt", true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
         freeInter(import_inter, false);
+        goto return_;
+    }
+    else if (pm->status != success) {
         setResultErrorSt(E_TypeException, pm->status_message, true, st, CALL_INTER_FUNCTIONSIG_NOT_ST(var_list, result, belong));
+        freeInter(import_inter, false);
         goto return_;
     }
 

+ 6 - 3
src/virtualmath.c

@@ -19,6 +19,7 @@ void runCodeFile(Inter *inter, char *file[]) {
         }
     }
 }
+
 void runCodeStdin(Inter *inter) {
     Statement *pst = NULL;
     Result result;
@@ -29,6 +30,7 @@ void runCodeStdin(Inter *inter) {
         fprintf(stdout, ">>> ");
         if (runParser(NULL, inter, true, &pst)) {
             globalIterStatement(&result, inter, pst);
+
             if (result.type == error_return && !(should_break = is_quitExc(result.value, inter)))
                 printError(&result, inter, true);
             freeStatement(pst);
@@ -41,8 +43,8 @@ bool runParser(char *code_file, Inter *inter, bool is_one, Statement **st) {
     ParserMessage *pm = makeParserMessage(code_file);
     *st = makeStatement(0, (code_file == NULL) ? "stdin" : code_file);
     parserCommandList(pm, inter, true, is_one, *st);
-    if (is_KeyInterrupt != signal_reset) {
-        is_KeyInterrupt = signal_reset;
+
+    if (pm->status == int_error) {
         fprintf(stderr, "KeyInterrupt\n");
     } else if (pm->status != success)
         fprintf(stderr, "Syntax Error: %s\n", pm->status_message);
@@ -50,8 +52,9 @@ bool runParser(char *code_file, Inter *inter, bool is_one, Statement **st) {
         freeParserMessage(pm, true);
         return true;
     }
+
     freeStatement(*st);
-    *st = NULL;
     freeParserMessage(pm, true);
+    *st = NULL;
     return false;
 }