コード例 #1
0
ファイル: init.c プロジェクト: Avanznow/rtems
static void test_chain_first_and_last(void)
{
  rtems_chain_control   chain;
  rtems_chain_node      node1, node2;
  rtems_chain_node     *cnode;

  rtems_chain_initialize_empty( &chain );
  rtems_chain_append( &chain, &node1 );
  rtems_chain_insert( &node1, &node2 );

  puts( "INIT - Verify rtems_chain_is_first" );
  cnode = rtems_chain_first(&chain);  
  rtems_test_assert( rtems_chain_is_first( cnode ) );

  puts( "INIT - Verify rtems_chain_is_last" );
  cnode = rtems_chain_last(&chain);
  rtems_test_assert( rtems_chain_is_last( cnode ) );

  cnode = rtems_chain_get_first_unprotected( &chain );
  rtems_test_assert( cnode == &node1 );
  cnode = rtems_chain_first( &chain );
  rtems_test_assert( cnode == &node2 );
  cnode = rtems_chain_last( &chain );
  rtems_test_assert( cnode == &node2 );
}
コード例 #2
0
int
rtems_bsd_rc_conf_service_add(const char*               name,
                              const char*               control,
                              rtems_bsd_rc_conf_service entry)
{
  service* srv;
  char*    ctl = NULL;
  char*    s;
  char*    c;

  srv = malloc(sizeof(*srv));
  if (srv == NULL) {
    errno = ENOMEM;
    return -1;
  }

  memset(srv, 0, sizeof(*srv));

  srv->name = strdup(name);
  if (control != NULL) {
    ctl = strdup(control);
    srv->control = ctl;
  }
  srv->entry = entry;

  if (srv->name == NULL || (control != NULL && ctl == NULL)) {
    fprintf(stderr, "error: rc.conf: add service: no memory\n");
    free((void*) srv->control);
    free((void*) srv->name);
    free(srv);
    errno = ENOMEM;
    return -1;
  }

  if (control != NULL) {
    s = c = ctl;

    while (*c != '\0') {
      if (*c == ';') {
        *c = '\0';

        if (strncasecmp("before:", s, sizeof("before:") - 1) == 0) {
          if (srv->before == NULL) {
            srv->before = s + sizeof("before:") - 1;
            s = NULL;
          }
          else {
            fprintf(stderr, "error: rc.conf: add service: repeated 'before'\n");
            c = NULL;
          }
        }
        else if (strncasecmp("after:", s, sizeof("after:") - 1) == 0) {
          if (srv->after == NULL) {
            srv->after = s + sizeof("after:") - 1;
            s = NULL;
          }
          else {
            fprintf(stderr, "error: rc.conf: add service: repeated 'after'\n");
            c = NULL;
          }
        }
        else if (strncasecmp("require:", s, sizeof("require:") - 1) == 0) {
          if (srv->require == NULL) {
            srv->require = s + sizeof("require:") - 1;
            s = NULL;
          }
          else {
            fprintf(stderr, "error: rc.conf: add service: repeated 'require'\n");
            c = NULL;
          }
        }
        else {
          fprintf(stderr, "error: rc.conf: add service: unknown keyword: %s\n", s);
          c = NULL;
        }

        if (c == NULL) {
          free((void*) srv->control);
          free((void*) srv->name);
          free(srv);
          errno = EINVAL;
          return -1;
        }
      }
      else if (s == NULL) {
        s = c;
      }

      ++c;
    }

    if (s != NULL) {
      fprintf(stderr, "error: rc.conf: add service: no ';' found\n");
      free((void*) srv->control);
      free((void*) srv->name);
      free(srv);
      errno = EINVAL;
      return -1;
    }

    /*
     * Place on the services list. The node is removed before being inserted. If
     * there are competing positions the last position is used. As a result
     * handle 'after' before 'before'.
     */
    rtems_chain_prepend(&services, &srv->node);
  }
  else {
    /*
     * No control string, add the end.
     */
    rtems_chain_append(&services, &srv->node);
  }

  /*
   * After.
   */
  if (srv->after != NULL) {
    const char* cc = srv->after;
    while (*cc != '\0') {
      const char* cs = cc;
      size_t      l;
      while (*cc != ',' && *cc != '\0')
        ++cc;
      l = cc - cs;
      if (strncasecmp(cs, "last", l) == 0) {
        fprintf(stderr,
                "error: rc.conf: add service: 'last' in 'after': %s\n",
                control);
        rtems_chain_extract(&srv->node);
        free((void*) srv->control);
        free((void*) srv->name);
        free(srv);
        errno = EINVAL;
        return -1;
      }
      else if (strncasecmp(cs, "first", l) == 0) {
        /* already prepended */
      }
      else {
        rtems_chain_node* node = rtems_chain_first(&services);
        while (!rtems_chain_is_tail(&services, node)) {
          service* ss = (service*) node;
          if (ss != srv &&
              strlen(ss->name) == l && strncasecmp(ss->name, cs, l) == 0) {
            rtems_chain_extract(&srv->node);
            rtems_chain_insert(&ss->node, &srv->node);
            break;
          }
          node = rtems_chain_next(node);
        }
      }
    }
  }

  /*
   * Before.
   */
  if (srv->before != NULL) {
    const char* cc = srv->before;
    while (*cc != '\0') {
      const char* cs = cc;
      size_t      l;
      while (*cc != ',' && *cc != '\0')
        ++cc;
      l = cc - cs;
      if (strncasecmp(cs, "first", l) == 0) {
        fprintf(stderr, "error: rc.conf: add service: 'first' in 'before'\n");
        rtems_chain_extract(&srv->node);
        free((void*) srv->control);
        free((void*) srv->name);
        free(srv);
        errno = EINVAL;
        return -1;
      }
      else if (strncasecmp(cs, "last", l) == 0) {
        rtems_chain_extract(&srv->node);
        rtems_chain_append(&services, &srv->node);
      }
      else {
        rtems_chain_node* node = rtems_chain_first(&services);
        while (!rtems_chain_is_tail(&services, node)) {
          service* ss = (service*) node;
          if (strlen(ss->name) == l && strncasecmp(ss->name, cs, l) == 0) {
            rtems_chain_extract(&srv->node);
            if (rtems_chain_is_first(node))
              rtems_chain_prepend(&services, &srv->node);
            else {
              service* sp = (service*) rtems_chain_previous(node);
              rtems_chain_insert(&sp->node, &srv->node);
            }
            break;
          }
          node = rtems_chain_next(node);
        }
      }
    }
  }

  return 0;
}