~ubuntu-branches/debian/stretch/device-tree-compiler/stretch

« back to all changes in this revision

Viewing changes to checks.c

  • Committer: Package Import Robot
  • Author(s): Hector Oron
  • Date: 2011-11-22 12:23:38 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20111122122338-ljbxy6a31fqztakc
Tags: 1.3.0-1
* New upstream release. (Closes: #572945)
* New maintainer. (Closes: #649290)
* New VCS repository.
* Update homepage stanza (Closes: #497605)
* Update standards version.
* Compile with -fPIC. Fixes ftbfs on amd64.
* Use dpkg 1.0 format.
* Backport upstream fixes as patches until 2011-10-26.

Show diffs side-by-side

added added

removed removed

Lines of Context:
242
242
}
243
243
NODE_CHECK(duplicate_property_names, NULL, ERROR);
244
244
 
 
245
#define LOWERCASE       "abcdefghijklmnopqrstuvwxyz"
 
246
#define UPPERCASE       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
247
#define DIGITS          "0123456789"
 
248
#define PROPNODECHARS   LOWERCASE UPPERCASE DIGITS ",._+*#?-"
 
249
 
 
250
static void check_node_name_chars(struct check *c, struct node *dt,
 
251
                                  struct node *node)
 
252
{
 
253
        int n = strspn(node->name, c->data);
 
254
 
 
255
        if (n < strlen(node->name))
 
256
                FAIL(c, "Bad character '%c' in node %s",
 
257
                     node->name[n], node->fullpath);
 
258
}
 
259
NODE_CHECK(node_name_chars, PROPNODECHARS "@", ERROR);
 
260
 
 
261
static void check_node_name_format(struct check *c, struct node *dt,
 
262
                                   struct node *node)
 
263
{
 
264
        if (strchr(get_unitname(node), '@'))
 
265
                FAIL(c, "Node %s has multiple '@' characters in name",
 
266
                     node->fullpath);
 
267
}
 
268
NODE_CHECK(node_name_format, NULL, ERROR, &node_name_chars);
 
269
 
 
270
static void check_property_name_chars(struct check *c, struct node *dt,
 
271
                                      struct node *node, struct property *prop)
 
272
{
 
273
        int n = strspn(prop->name, c->data);
 
274
 
 
275
        if (n < strlen(prop->name))
 
276
                FAIL(c, "Bad character '%c' in property name \"%s\", node %s",
 
277
                     prop->name[n], prop->name, node->fullpath);
 
278
}
 
279
PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
 
280
 
 
281
#define DESCLABEL_FMT   "%s%s%s%s%s"
 
282
#define DESCLABEL_ARGS(node,prop,mark)          \
 
283
        ((mark) ? "value of " : ""),            \
 
284
        ((prop) ? "'" : ""), \
 
285
        ((prop) ? (prop)->name : ""), \
 
286
        ((prop) ? "' in " : ""), (node)->fullpath
 
287
 
 
288
static void check_duplicate_label(struct check *c, struct node *dt,
 
289
                                  const char *label, struct node *node,
 
290
                                  struct property *prop, struct marker *mark)
 
291
{
 
292
        struct node *othernode = NULL;
 
293
        struct property *otherprop = NULL;
 
294
        struct marker *othermark = NULL;
 
295
 
 
296
        othernode = get_node_by_label(dt, label);
 
297
 
 
298
        if (!othernode)
 
299
                otherprop = get_property_by_label(dt, label, &othernode);
 
300
        if (!othernode)
 
301
                othermark = get_marker_label(dt, label, &othernode,
 
302
                                               &otherprop);
 
303
 
 
304
        if (!othernode)
 
305
                return;
 
306
 
 
307
        if ((othernode != node) || (otherprop != prop) || (othermark != mark))
 
308
                FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT
 
309
                     " and " DESCLABEL_FMT,
 
310
                     label, DESCLABEL_ARGS(node, prop, mark),
 
311
                     DESCLABEL_ARGS(othernode, otherprop, othermark));
 
312
}
 
313
 
 
314
static void check_duplicate_label_node(struct check *c, struct node *dt,
 
315
                                       struct node *node)
 
316
{
 
317
        struct label *l;
 
318
 
 
319
        for_each_label(node->labels, l)
 
320
                check_duplicate_label(c, dt, l->label, node, NULL, NULL);
 
321
}
 
322
static void check_duplicate_label_prop(struct check *c, struct node *dt,
 
323
                                       struct node *node, struct property *prop)
 
324
{
 
325
        struct marker *m = prop->val.markers;
 
326
        struct label *l;
 
327
 
 
328
        for_each_label(prop->labels, l)
 
329
                check_duplicate_label(c, dt, l->label, node, prop, NULL);
 
330
 
 
331
        for_each_marker_of_type(m, LABEL)
 
332
                check_duplicate_label(c, dt, m->ref, node, prop, m);
 
333
}
 
334
CHECK(duplicate_label, NULL, check_duplicate_label_node,
 
335
      check_duplicate_label_prop, NULL, ERROR);
 
336
 
245
337
static void check_explicit_phandles(struct check *c, struct node *root,
246
 
                                          struct node *node)
 
338
                                    struct node *node, struct property *prop)
247
339
{
248
 
        struct property *prop;
 
340
        struct marker *m;
249
341
        struct node *other;
250
342
        cell_t phandle;
251
343
 
252
 
        prop = get_property(node, "linux,phandle");
253
 
        if (! prop)
254
 
                return; /* No phandle, that's fine */
 
344
        if (!streq(prop->name, "phandle")
 
345
            && !streq(prop->name, "linux,phandle"))
 
346
                return;
255
347
 
256
348
        if (prop->val.len != sizeof(cell_t)) {
257
 
                FAIL(c, "%s has bad length (%d) linux,phandle property",
258
 
                     node->fullpath, prop->val.len);
 
349
                FAIL(c, "%s has bad length (%d) %s property",
 
350
                     node->fullpath, prop->val.len, prop->name);
 
351
                return;
 
352
        }
 
353
 
 
354
        m = prop->val.markers;
 
355
        for_each_marker_of_type(m, REF_PHANDLE) {
 
356
                assert(m->offset == 0);
 
357
                if (node != get_node_by_ref(root, m->ref))
 
358
                        /* "Set this node's phandle equal to some
 
359
                         * other node's phandle".  That's nonsensical
 
360
                         * by construction. */ {
 
361
                        FAIL(c, "%s in %s is a reference to another node",
 
362
                             prop->name, node->fullpath);
 
363
                        return;
 
364
                }
 
365
                /* But setting this node's phandle equal to its own
 
366
                 * phandle is allowed - that means allocate a unique
 
367
                 * phandle for this node, even if it's not otherwise
 
368
                 * referenced.  The value will be filled in later, so
 
369
                 * no further checking for now. */
259
370
                return;
260
371
        }
261
372
 
262
373
        phandle = propval_cell(prop);
 
374
 
263
375
        if ((phandle == 0) || (phandle == -1)) {
264
 
                FAIL(c, "%s has invalid linux,phandle value 0x%x",
265
 
                     node->fullpath, phandle);
 
376
                FAIL(c, "%s has bad value (0x%x) in %s property",
 
377
                     node->fullpath, phandle, prop->name);
266
378
                return;
267
379
        }
268
380
 
 
381
        if (node->phandle && (node->phandle != phandle))
 
382
                FAIL(c, "%s has %s property which replaces existing phandle information",
 
383
                     node->fullpath, prop->name);
 
384
 
269
385
        other = get_node_by_phandle(root, phandle);
270
 
        if (other) {
 
386
        if (other && (other != node)) {
271
387
                FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
272
388
                     node->fullpath, phandle, other->fullpath);
273
389
                return;
275
391
 
276
392
        node->phandle = phandle;
277
393
}
278
 
NODE_CHECK(explicit_phandles, NULL, ERROR);
 
394
PROP_CHECK(explicit_phandles, NULL, ERROR);
279
395
 
280
396
static void check_name_properties(struct check *c, struct node *root,
281
397
                                  struct node *node)
282
398
{
283
 
        struct property *prop;
284
 
 
285
 
        prop = get_property(node, "name");
 
399
        struct property **pp, *prop = NULL;
 
400
 
 
401
        for (pp = &node->proplist; *pp; pp = &((*pp)->next))
 
402
                if (streq((*pp)->name, "name")) {
 
403
                        prop = *pp;
 
404
                        break;
 
405
                }
 
406
 
286
407
        if (!prop)
287
408
                return; /* No name property, that's fine */
288
409
 
289
410
        if ((prop->val.len != node->basenamelen+1)
290
 
            || (memcmp(prop->val.val, node->name, node->basenamelen) != 0))
 
411
            || (memcmp(prop->val.val, node->name, node->basenamelen) != 0)) {
291
412
                FAIL(c, "\"name\" property in %s is incorrect (\"%s\" instead"
292
413
                     " of base node name)", node->fullpath, prop->val.val);
 
414
        } else {
 
415
                /* The name property is correct, and therefore redundant.
 
416
                 * Delete it */
 
417
                *pp = prop->next;
 
418
                free(prop->name);
 
419
                data_free(prop->val);
 
420
                free(prop);
 
421
        }
293
422
}
294
423
CHECK_IS_STRING(name_is_string, "name", ERROR);
295
424
NODE_CHECK(name_properties, NULL, ERROR, &name_is_string);
301
430
static void fixup_phandle_references(struct check *c, struct node *dt,
302
431
                                     struct node *node, struct property *prop)
303
432
{
304
 
      struct marker *m = prop->val.markers;
305
 
      struct node *refnode;
306
 
      cell_t phandle;
307
 
 
308
 
      for_each_marker_of_type(m, REF_PHANDLE) {
309
 
              assert(m->offset + sizeof(cell_t) <= prop->val.len);
310
 
 
311
 
              refnode = get_node_by_ref(dt, m->ref);
312
 
              if (! refnode) {
313
 
                      FAIL(c, "Reference to non-existent node or label \"%s\"\n",
314
 
                           m->ref);
315
 
                      continue;
316
 
              }
317
 
 
318
 
              phandle = get_node_phandle(dt, refnode);
319
 
              *((cell_t *)(prop->val.val + m->offset)) = cpu_to_be32(phandle);
320
 
      }
 
433
        struct marker *m = prop->val.markers;
 
434
        struct node *refnode;
 
435
        cell_t phandle;
 
436
 
 
437
        for_each_marker_of_type(m, REF_PHANDLE) {
 
438
                assert(m->offset + sizeof(cell_t) <= prop->val.len);
 
439
 
 
440
                refnode = get_node_by_ref(dt, m->ref);
 
441
                if (! refnode) {
 
442
                        FAIL(c, "Reference to non-existent node or label \"%s\"\n",
 
443
                             m->ref);
 
444
                        continue;
 
445
                }
 
446
 
 
447
                phandle = get_node_phandle(dt, refnode);
 
448
                *((cell_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
 
449
        }
321
450
}
322
451
CHECK(phandle_references, NULL, NULL, fixup_phandle_references, NULL, ERROR,
323
452
      &duplicate_node_names, &explicit_phandles);
498
627
 
499
628
static struct check *check_table[] = {
500
629
        &duplicate_node_names, &duplicate_property_names,
 
630
        &node_name_chars, &node_name_format, &property_name_chars,
501
631
        &name_is_string, &name_properties,
 
632
 
 
633
        &duplicate_label,
 
634
 
502
635
        &explicit_phandles,
503
636
        &phandle_references, &path_references,
504
637