liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

parseopts.c (4021B)


      1 #include <unistd.h>
      2 #include <stdint.h>
      3 #include <string.h>
      4 #include <unistd.h>
      5 
      6 static int begins_with(char * str, char * prefix)
      7 {
      8 	while(*prefix) {
      9 		if(*str == '\0') return 0;
     10 		if(*str != *prefix) return 0;
     11 		str++;
     12 		prefix++;
     13 	}
     14 	return 1;
     15 }
     16 
     17 char * pr_u32(int32_t input) {
     18     static char buf[9];
     19     const char *digits = "0123456789abcdef";
     20     int i=0;
     21 
     22     buf[i] = digits[(input & 0xf0000000) >> 28];
     23     buf[i+1] = digits[(input & 0x0f000000) >> 24];
     24     if(buf[i] != '0' || buf[i+1] != '0') i+=2;
     25 
     26     buf[i] = digits[(input & 0x00f00000) >> 20];
     27     buf[i+1] = digits[(input & 0x000f0000) >> 16];
     28     if(buf[i] != '0' || buf[i+1] != '0') i+=2;
     29 
     30     buf[i] = digits[(input & 0x0000f000) >> 12];
     31     buf[i+1] = digits[(input & 0x00000f00) >> 8];
     32     if(buf[i] != '0' || buf[i+1] != '0') i+=2;
     33 
     34     buf[i] = digits[(input & 0x000000f0) >> 4];
     35     buf[i+1] = digits[(input & 0x0000000f)];
     36     i+=2;
     37 
     38     buf[i] ='\0';
     39     write(2, buf, i);
     40 
     41     return buf;
     42 }
     43 
     44 
     45 void parseopts(char * cmdline, char **root, char **rootfstype) {
     46     *root = 0;
     47     *rootfstype = 0;
     48 
     49     for(char *p = cmdline; *p; p++) {
     50 	if(begins_with(p, "root=")) {
     51 	    *root = p + strlen("root=");
     52 	    while(*p && (*p != ' ')) p++;
     53 
     54 	    if(*p) {
     55 		*p = '\0';
     56 		p++;
     57 	    };
     58 	};
     59 	if(begins_with(p, "rootfstype=")) {
     60 	    *rootfstype = p + strlen("rootfstype=");
     61 	    while(*p && (*p != ' ')) p++;
     62 	    if(*p) {
     63 		*p = '\0';
     64 		p++;
     65 	    };
     66 	};
     67     };
     68 }
     69 
     70 #ifdef TESTS
     71 #include <assert.h>
     72 #include <stdio.h>
     73 #include <stdlib.h>
     74 
     75 // cc -DTESTS  -o parseopts parseopts.c && ./parseopts
     76 
     77 #define die(fmt, ...) do { printf(fmt, __VA_ARGS__); exit(1); } while(0)
     78 #define S(x) #x
     79 #define expect_equal(actual, expected) \
     80     if(!actual || strcmp(actual, expected)) die("%d: expected \"%s\", got \"%s\"", __LINE__, expected, actual);
     81 
     82 
     83 int main()
     84 {
     85     char * root = "/dev/hda1";
     86     char * rootfstype = "xiafs";
     87     char *buf;
     88 
     89     // finds root= and rootfstype= options
     90     buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/ubi0_4 rootfstype=ubifs fw_devlink=off mtdparts=phram0:18M(rootfs) phram.phram=phram0,0x40400000,18874368,65536 root=/dev/mtdblock0 foo");
     91     parseopts(buf, &root, &rootfstype);
     92     expect_equal(root, "/dev/mtdblock0");
     93     expect_equal(rootfstype, "ubifs");
     94 
     95     // in case of duplicates, chooses the latter
     96     // also: works if the option is end of string
     97     buf = strdup("liminix console=ttyS0,115200 panic=10 oops=panic init=/bin/init loglevel=8 root=/dev/ubi0_4 rootfstype=ubifs fw_devlink=off mtdparts=phram0:18M(rootfs) phram.phram=phram0,0x40400000,18874368,65536 root=/dev/mtdblock0");
     98     parseopts(buf, &root, &rootfstype);
     99     expect_equal(root, "/dev/mtdblock0");
    100     expect_equal(rootfstype, "ubifs");
    101 
    102     // options may appear in either order
    103     buf = strdup("liminix fw_devlink=off root=/dev/hda1 rootfstype=ubifs  foo");
    104     parseopts(buf, &root, &rootfstype);
    105     expect_equal(root, "/dev/hda1");
    106     expect_equal(rootfstype, "ubifs");
    107 
    108     buf = strdup("liminix rootfstype=ubifs fw_devlink=off root=/dev/hda1 foo");
    109     parseopts(buf, &root, &rootfstype);
    110     expect_equal(rootfstype, "ubifs");
    111     expect_equal(root, "/dev/hda1");
    112 
    113     // provides NULL for missing options
    114     buf = strdup("liminix rufustype=ubifs fw_devlink=off foot=/dev/hda1");
    115     parseopts(buf, &root, &rootfstype);
    116     if(rootfstype) die("expected null rootfstype, got \"%s\"", rootfstype);
    117     if(root) die("expected null root, got \"%s\"", root);
    118 
    119     // provides empty strings for empty options
    120     buf = strdup("liminix rootfstype= fw_devlink=off root= /dev/hda1");
    121     parseopts(buf, &root, &rootfstype);
    122     if(strlen(rootfstype)) die("expected empty rootfstype, got \"%s\"", rootfstype);
    123     if(strlen(root)) die("expected null root, got \"%s\"", root);
    124 
    125     expect_equal("01", pr_u32(1));
    126     expect_equal("ab", pr_u32(0xab));
    127     expect_equal("0abc", pr_u32(0xabc));
    128     expect_equal("aabc", pr_u32(0xaabc));
    129     expect_equal("deadcafe", pr_u32(0xdeadcafe));
    130 }
    131 
    132 #endif