Beispiel #1
0
void			ft_pwd(char *line)
{
	char	**buf;
	int		i;

	i = -1;
	if (!(buf = ft_strsplim(line)))
		return ;
	while (buf[++i])
		buf[i] = (char *)c_call("ft_strtrim", buf[i]);
	if (buf[1] != '\0')
	{
		ft_putendl_fd("pwd: too many arguments", 2);
		ft_free_char2(buf);
		return ;
	}
	if (!(buf[0] = ft_strnew(2000)))
		return ;
	ft_putendl(getcwd(buf[0], 2000));
	ft_free_char2(buf);
}
Beispiel #2
0
static
int lazy_rec_eval(CLazyLinker * self, Py_ssize_t var_idx, PyObject*one, PyObject*zero)
{
  PyObject *rval = NULL;
  int verbose = 0;
  int err = 0;

  if (verbose) fprintf(stderr, "lazy_rec computing %i\n", (int)var_idx);

  if (self->var_computed[var_idx] || !self->var_has_owner[var_idx])
    return 0;

  Py_ssize_t owner_idx = self->var_owner[var_idx];

  // STEP 1: compute the pre-requirements of the node
  // Includes input nodes for non-lazy ops.
  for (int i = 0; i < self->node_n_prereqs[owner_idx]; ++i)
    {
      Py_ssize_t prereq_idx = self->node_prereqs[owner_idx][i];
      if (!self->var_computed[prereq_idx])
        {
          err = lazy_rec_eval(self, prereq_idx, one, zero);
          if (err) return err;
        }
      assert (self->var_computed[prereq_idx]);
    }

  // STEP 2: compute the node itself
  if (self->is_lazy[owner_idx])
    {
      // update the compute_map cells corresponding to the inputs of this thunk
      for (int i = 0; i < self->node_n_inputs[owner_idx]; ++i)
        {
          int in_idx = self->node_inputs[owner_idx][i];
          if (self->var_computed[in_idx])
            {
              Py_INCREF(one);
              err = PyList_SetItem(self->var_computed_cells[in_idx], 0, one);
            }
          else
            {
              Py_INCREF(zero);
              err = PyList_SetItem(self->var_computed_cells[in_idx], 0, zero);
            }
          if (err) goto fail;
        }

      rval = pycall(self, owner_idx, verbose);
      // refcounting - rval is new ref
      //TODO: to prevent infinite loops
      // - consider check that a thunk does not ask for an input that is already computed
      if (rval == NULL)
        {
          assert (PyErr_Occurred());
          err = 1;
          goto fail;
        }

      //update the computed-ness of any output cells
      for (int i = 0; i < self->node_n_outputs[owner_idx]; ++i)
        {
          int out_idx = self->node_outputs[owner_idx][i];
          PyObject * el_i = PyList_GetItem(self->var_computed_cells[out_idx], 0);
          Py_ssize_t N = PyNumber_AsSsize_t(el_i, PyExc_IndexError);
          if (PyErr_Occurred())
            {
              err = -1;
              goto pyfail;
            }
          assert (N==0 || N==1);
          self->var_computed[out_idx] = N;
        }
      if (!self->var_computed[var_idx])
        {
          /*
           * If self is not computed after the call, this means that some
           * inputs are needed.  Compute the ones on the returned list
           * and try to compute the current node again (with recursive call).
           * This allows a node to request more nodes more than once before
           * finally yielding a result.
           */
          if (!PyList_Check(rval))
            {
              //TODO: More helpful error to help find *which node* made this
              // bad thunk
              PyErr_SetString(PyExc_TypeError,
                              "lazy thunk should return a list");
              err = 1;
              goto pyfail;
            }

          if (!PyList_Size(rval))
            {
              PyErr_SetString(PyExc_ValueError,
                              "lazy thunk returned empty list without computing output");
              err = 1;
              goto pyfail;
            }

          for (int i = 0; i < PyList_Size(rval); ++i)
            {
              PyObject * el_i = PyList_GetItem(rval, i);
              Py_ssize_t N = PyNumber_AsSsize_t(el_i, PyExc_IndexError);
              if (PyErr_Occurred())
                {
                  err = 1;
                  goto pyfail;
                }
              assert (N <= self->node_n_inputs[owner_idx]);
              Py_ssize_t input_idx = self->node_inputs[owner_idx][N];
              err = lazy_rec_eval(self, input_idx, one, zero);
              if (err) goto pyfail;
            }

          Py_DECREF(rval);
          /*
           * We intentionally skip all the end-of-function processing
           * (mark outputs, GC) as it will be performed by the call
           * that actually manages to compute the result.
           */
          return lazy_rec_eval(self, var_idx, one, zero);
        }

      Py_DECREF(rval);
    }
  else //owner is not a lazy op. Ensure all intputs are evaluated.
    {
      // loop over inputs to owner
      // call lazy_rec_eval on each one that is not computed.
      // if there's an error, pass it up the stack
      for (int i = 0; i < self->node_n_inputs[owner_idx]; ++i)
        {
          Py_ssize_t input_idx = self->node_inputs[owner_idx][i];
          if (!self->var_computed[input_idx])
            {
              err = lazy_rec_eval(self, input_idx, one, zero);
              if (err) return err;
            }
          assert (self->var_computed[input_idx]);
        }

      // call the thunk for this owner.
      if (self->thunk_cptr_fn[owner_idx])
        {
          err = c_call(self, owner_idx, verbose);
          if (err) goto fail;
        }
      else
        {
          rval = pycall(self, owner_idx, verbose);
          //rval is new ref
          if (rval) //pycall returned normally (no exception)
            {
              if (rval == Py_None)
                {
                  Py_DECREF(rval); //ignore a return of None
                }
              else if (PyList_Check(rval))
                {
                  PyErr_SetString(PyExc_TypeError,
                                  "non-lazy thunk should return None, not list");
                  err = 1;
                  goto pyfail;
                }
              else // don't know what it returned, but it wasn't right.
                {
                  PyErr_SetObject(PyExc_TypeError, rval);
                  err = 1;
                  // We don't release rval since we put it in the error above
                  goto fail;
                }
            }
          else // pycall returned NULL (internal error)
            {
              err = 1;
              goto fail;
            }
        }
    }

  // loop over all outputs and mark them as computed
  for (int i = 0; i < self->node_n_outputs[owner_idx]; ++i)
    {
      self->var_computed[self->node_outputs[owner_idx][i]] = 1;
    }

  // Free vars that are not needed anymore
  if (self->allow_gc)
    {
      for (int i = 0; i < self->node_n_inputs[owner_idx]; ++i)
        {
          int cleanup = 1;
          Py_ssize_t i_idx = self->node_inputs[owner_idx][i];
          if (!self->var_has_owner[i_idx])
            continue;

          for (int j = 0; j < self->n_output_vars; ++j)
            {
              if (i_idx == self->output_vars[j])
                {
                  cleanup = 0;
                  break;
                }
            }
          if (!cleanup) continue;

          for (int j = 0; j < self->n_dependencies[i_idx]; ++j)
            {
              if (!self->var_computed[self->dependencies[i_idx][j]])
                {
                  cleanup = 0;
                  break;
                }
            }
          if (!cleanup) continue;

          Py_INCREF(Py_None);
          err = PyList_SetItem(self->var_value_cells[i_idx], 0, Py_None);
//See the Stack gc implementation for why we change it to 2 and not 0.
          self->var_computed[i_idx] = 2;
          if (err) goto fail;
        }
    }

  return 0;
 pyfail:
  Py_DECREF(rval);
 fail:
  set_position_of_error(self, owner_idx);
  return err;
}
Beispiel #3
0
int main(void)
{ 
    F f{};
    
    c_call(f.get_ptr());
}
Beispiel #4
0
int main(void)
{ 
    F f{};
    
    c_call(&(f.get_int()));
}