"Fossies" - the Fresh Open Source Software Archive

Member "gambas-3.16.3/main/gbx/gbx_subr_misc.c" (7 Sep 2021, 7502 Bytes) of package /linux/misc/gambas-3.16.3.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "gbx_subr_misc.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.16.2_vs_3.16.3.

    1 /***************************************************************************
    2 
    3   gbx_subr_misc.c
    4 
    5   (c) 2000-2017 BenoƮt Minisini <g4mba5@gmail.com>
    6 
    7   This program is free software; you can redistribute it and/or modify
    8   it under the terms of the GNU General Public License as published by
    9   the Free Software Foundation; either version 2, or (at your option)
   10   any later version.
   11 
   12   This program is distributed in the hope that it will be useful,
   13   but WITHOUT ANY WARRANTY; without even the implied warranty of
   14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15   GNU General Public License for more details.
   16 
   17   You should have received a copy of the GNU General Public License
   18   along with this program; if not, write to the Free Software
   19   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
   20   MA 02110-1301, USA.
   21 
   22 ***************************************************************************/
   23 
   24 #include <sys/wait.h>
   25 #include <time.h>
   26 
   27 #include "gb_common.h"
   28 #include "gbx_subr.h"
   29 #include "gbx_class.h"
   30 #include "gambas.h"
   31 #include "gbx_eval.h"
   32 #include "gbx_date.h"
   33 #include "gbx_archive.h"
   34 
   35 #include "gbx_api.h"
   36 #include "gbx_c_collection.h"
   37 #include "gbx_c_process.h"
   38 #include "gbx_debug.h"
   39 #include "gbx_watch.h"
   40 #include "gbx_math.h"
   41 
   42 
   43 static EVAL_INTERFACE EVAL;
   44 static CCOLLECTION *eval_env;
   45 
   46 static void init_eval()
   47 {
   48     static bool init = FALSE;
   49     
   50     if (init)
   51         return;
   52         
   53     COMPONENT_load(COMPONENT_create("gb.eval"));
   54     LIBRARY_get_interface_by_name("gb.eval", EVAL_INTERFACE_VERSION, &EVAL);
   55     init = TRUE;
   56 }
   57 
   58 void SUBR_error(void)
   59 {
   60     SP->type = T_BOOLEAN;
   61     SP->_boolean.value = EXEC_got_error ? -1 : 0;
   62     SP++;
   63 }
   64 
   65 
   66 void SUBR_wait(ushort code)
   67 {
   68     SUBR_ENTER();
   69     
   70     code &= 0x1F;
   71     
   72     EXEC_set_native_error(FALSE);
   73     
   74     if (code == 0)
   75         GB_Wait(0);
   76     else if (code == 1)
   77     {
   78         int delay = (int)(SUBR_get_float(PARAM) * 1000 + 0.5);
   79         if (delay < 0)
   80             delay = 0;
   81         GB_Wait(delay);
   82     }
   83     else if (code == 2)
   84     {
   85         NPARAM = 0;
   86         GB_Wait(-1);
   87     }
   88 
   89     if (EXEC_has_native_error())
   90     {
   91         EXEC_set_native_error(FALSE);
   92         PROPAGATE();
   93     }
   94     
   95     SUBR_LEAVE_VOID();
   96 }
   97 
   98 
   99 void SUBR_sleep(ushort code)
  100 {
  101     SUBR_ENTER_PARAM(1);
  102 
  103     switch(code & 0x3F)
  104     {
  105         case 0: // Sleep
  106         {
  107             double wait;
  108             struct timespec rem;
  109 
  110             wait = SUBR_get_float(PARAM);
  111 
  112             rem.tv_sec = (time_t)(int)wait;
  113             rem.tv_nsec = (int)(frac(wait) * 1E9);
  114 
  115             while (nanosleep(&rem, &rem) < 0);
  116             break;
  117         }
  118         case 1: // Use
  119         {
  120             char *name = SUBR_get_string(PARAM);
  121             COMPONENT *comp = COMPONENT_find(name);
  122             if (!comp)
  123                 comp = COMPONENT_create(name);
  124 
  125             COMPONENT_load(comp);
  126             break;
  127         }
  128         case 2: // CheckExec
  129         {
  130             CPROCESS_check(PARAM->_object.object);
  131             break;
  132         }
  133     }
  134     
  135     SUBR_LEAVE();
  136 }
  137 
  138 static void error_subr_exec(CPROCESS *process)
  139 {
  140     OBJECT_UNREF(process);
  141 }
  142 
  143 void SUBR_exec(ushort code)
  144 {
  145     void *cmd;
  146     bool wait;
  147     int mode;
  148     CPROCESS *process;
  149     bool ret;
  150     bool shell;
  151     char *name;
  152     CARRAY *env;
  153 
  154     SUBR_ENTER_PARAM(4);
  155 
  156     shell = (code & 0x1F) != 0;
  157 
  158     if (shell)
  159         cmd = (void *)SUBR_get_string(PARAM);
  160     else
  161     {
  162         VALUE_conv_object(PARAM, (TYPE)CLASS_StringArray);
  163         cmd = (void *)(PARAM->_object.object);
  164     }
  165 
  166     if (!cmd)
  167         THROW(E_ARG);
  168 
  169     if (VALUE_is_null(&PARAM[1]))
  170         env = NULL;
  171     else
  172     {
  173         VALUE_conv_object(&PARAM[1], (TYPE)CLASS_StringArray);
  174         env = (PARAM[1]._object.object);
  175     }
  176     
  177     VALUE_conv_integer(&PARAM[2]);
  178     mode = PARAM[2]._integer.value;
  179     wait = mode & PM_WAIT;
  180 
  181     name = SUBR_get_string(&PARAM[3]);
  182 
  183     ret = TRUE; // !PCODE_is_void(code);
  184 
  185     if (shell)
  186         mode |= PM_SHELL;
  187 
  188     //STRING_ref(name); ## This should not be needed
  189     process = CPROCESS_create(mode, cmd, name, env);
  190     //STRING_unref(&name);
  191 
  192     if (wait)
  193     {
  194         OBJECT_REF(process);
  195 
  196         ON_ERROR_1(error_subr_exec, process)
  197         {
  198             CPROCESS_wait_for(process, 0);
  199         }
  200         END_ERROR
  201 
  202         if (!ret)
  203         {
  204             OBJECT_UNREF(process);
  205         }
  206         else if (!process->to_string)
  207         {
  208             OBJECT_UNREF_KEEP(process);
  209         }
  210     }
  211 
  212     if (ret)
  213     {
  214         if (process->to_string)
  215         {
  216             char *result = process->result;
  217             process->result = NULL;
  218             
  219             RELEASE_MANY(SP, NPARAM);
  220             
  221             SP->type = T_STRING;
  222             SP->_string.addr = result;
  223             SP->_string.start = 0;
  224             SP->_string.len = STRING_length(result);
  225             SP++;
  226 
  227             OBJECT_UNREF(process);
  228         }
  229         else
  230         {
  231             RETURN->_object.class = CLASS_Process;
  232             RETURN->_object.object = process;
  233             SUBR_LEAVE();
  234         }
  235     }
  236     else
  237     {
  238         SUBR_LEAVE_VOID();
  239     }
  240 }
  241 
  242 
  243 static bool get_value(const char *sym, int len, GB_VARIANT *value)
  244 {
  245     if (eval_env)
  246         if (!GB_CollectionGet(eval_env, sym, len, value))
  247             return FALSE;
  248 
  249     value->type = T_NULL;
  250     return TRUE;
  251 }
  252 
  253 void EVAL_string(char *expr)
  254 {
  255     int len;
  256     EXPRESSION *eval;
  257 
  258     init_eval();
  259     len = strlen(expr);
  260     eval_env = NULL;
  261     
  262     EVAL.New((void **)(void *)&eval, expr, len);
  263 
  264     if (EVAL.Compile(eval, FALSE))
  265     {
  266         GB_Error(eval->error);
  267         goto _ERROR;
  268     }
  269 
  270     if (!EVAL.Run(eval, get_value))
  271         goto _ERROR;
  272 
  273     goto _FREE;
  274 
  275 _ERROR:
  276     EVAL.Free((void **)(void *)&eval);
  277     PROPAGATE();
  278 
  279 _FREE:
  280     EVAL.Free((void **)(void *)&eval);
  281 
  282     VALUE_to_local_string(&TEMP, &expr, &len);
  283     STREAM_write(CSTREAM_TO_STREAM(CFILE_out), expr, len);
  284     STREAM_write_eol(CSTREAM_TO_STREAM(CFILE_out));
  285     STREAM_flush(CSTREAM_TO_STREAM(CFILE_out));
  286 }
  287 
  288 void SUBR_eval(ushort code)
  289 {
  290     char *expr;
  291     int len;
  292     EXPRESSION *eval;
  293 
  294     SUBR_ENTER();
  295 
  296     init_eval();
  297     SUBR_get_string_len(PARAM, &expr, &len);
  298 
  299     if (NPARAM == 2)
  300     {
  301         VALUE_conv_object(&PARAM[1], (TYPE)CLASS_Collection);
  302         eval_env = (CCOLLECTION *)(PARAM[1]._object.object);
  303     }
  304     else
  305         eval_env = NULL;
  306 
  307     EVAL.New((void **)(void *)&eval, expr, len);
  308 
  309     if (EVAL.Compile(eval, FALSE))
  310     {
  311         GB_Error(eval->error);
  312         goto _ERROR;
  313     }
  314 
  315     if (!EVAL.Run(eval, get_value))
  316         goto _ERROR;
  317 
  318     *RP = TEMP;
  319     TEMP.type = T_VOID;
  320     goto _FREE;
  321 
  322 _ERROR:
  323 
  324     EVAL.Free((void **)(void *)&eval);
  325     PROPAGATE();
  326 
  327 _FREE:
  328 
  329     EVAL.Free((void **)(void *)&eval);
  330     SUBR_LEAVE();
  331 }
  332 
  333 void SUBR_array(ushort code)
  334 {
  335     static bool reuse = FALSE;
  336 
  337     TYPE type;
  338     int i, j;
  339     CARRAY *array;
  340     bool next_reuse;
  341 
  342     SUBR_ENTER();
  343 
  344     next_reuse = code & CODE_CALL_VARIANT;
  345 
  346     if (reuse)
  347     {
  348         array = (CARRAY *)(PARAM[-1]._object.object);
  349         type = array->type;
  350     }
  351     else
  352     {
  353         type = SUBR_check_good_type(PARAM, NPARAM);
  354 
  355         if (type == T_NULL)
  356             type = T_OBJECT;
  357     }
  358 
  359     for (i = 0; i < NPARAM; i++)
  360         VALUE_conv(&PARAM[i], type);
  361 
  362     if (reuse)
  363     {
  364         j = array->count;
  365         CARRAY_resize(array, j + NPARAM);
  366     }
  367     else
  368     {
  369         j = 0;
  370         GB_ArrayNew(POINTER(&array), type, NPARAM);
  371         OBJECT_REF(array);
  372     }
  373 
  374     for (i = 0; i < NPARAM; i++, j++)
  375     {
  376         GB_Store(type, (GB_VALUE *)&PARAM[i], GB_ArrayGet(array, j));
  377         RELEASE(&PARAM[i]);
  378     }
  379 
  380     if (reuse)
  381     {
  382         SP = PARAM;
  383     }
  384     else
  385     {
  386         PARAM->_object.class = OBJECT_class(array); //CLASS_Array;
  387         PARAM->_object.object = array;
  388         SP = PARAM + 1;
  389     }
  390 
  391     reuse = next_reuse;
  392 }
  393 
  394 void SUBR_collection(ushort code)
  395 {
  396     static bool reuse = FALSE;
  397 
  398     int i;
  399     GB_COLLECTION col;
  400     char *key;
  401     int len;
  402     VALUE *vkey, *vval;
  403     bool next_reuse;
  404 
  405     SUBR_ENTER();
  406 
  407     next_reuse = code & CODE_CALL_VARIANT;
  408 
  409     if (reuse)
  410         col = (GB_COLLECTION)(PARAM[-1]._object.object);
  411     else
  412     {
  413         GB_CollectionNew(&col, GB_COMP_BINARY);
  414         OBJECT_REF(col);
  415     }
  416 
  417     for (i = 0; i < NPARAM; i += 2)
  418     {
  419         vkey = &PARAM[i];
  420         vval = vkey + 1;
  421         SUBR_get_string_len(vkey, &key, &len);
  422         VALUE_conv_variant(vval);
  423         if (GB_CollectionSet(col, key, len, (GB_VARIANT *)vval))
  424         {
  425             OBJECT_UNREF(col);
  426             THROW(E_VKEY);
  427         }
  428         RELEASE_STRING(&PARAM[i]);
  429         RELEASE(&PARAM[i + 1]);
  430     }
  431 
  432     if (reuse)
  433     {
  434         SP = PARAM;
  435     }
  436     else
  437     {
  438         PARAM->_object.class = OBJECT_class(col); //CLASS_Array;
  439         PARAM->_object.object = col;
  440         SP = PARAM + 1;
  441     }
  442 
  443     reuse = next_reuse;
  444 }
  445 
  446