attr.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <String.h>
  4. #include <auth.h>
  5. int
  6. _attrfmt(Fmt *fmt)
  7. {
  8. char *b, buf[1024], *ebuf;
  9. Attr *a;
  10. ebuf = buf+sizeof buf;
  11. b = buf;
  12. strcpy(buf, " ");
  13. for(a=va_arg(fmt->args, Attr*); a; a=a->next){
  14. if(a->name == nil)
  15. continue;
  16. switch(a->type){
  17. case AttrQuery:
  18. b = seprint(b, ebuf, " %q?", s_to_c(a->name));
  19. break;
  20. case AttrNameval:
  21. b = seprint(b, ebuf, " %q=%q", s_to_c(a->name), s_to_c(a->val));
  22. break;
  23. case AttrDefault:
  24. b = seprint(b, ebuf, " %q:=%q", s_to_c(a->name), s_to_c(a->val));
  25. break;
  26. }
  27. }
  28. return fmtstrcpy(fmt, buf+1);
  29. }
  30. Attr*
  31. _copyattr(Attr *a)
  32. {
  33. Attr **la, *na;
  34. na = nil;
  35. la = &na;
  36. for(; a; a=a->next){
  37. *la = _mkattr(a->type, s_to_c(a->name), s_to_c(a->val), nil);
  38. setmalloctag(*la, getcallerpc(&a));
  39. la = &(*la)->next;
  40. }
  41. *la = nil;
  42. return na;
  43. }
  44. Attr*
  45. _delattr(Attr *a, char *name)
  46. {
  47. Attr *fa;
  48. Attr **la;
  49. for(la=&a; *la; ){
  50. if(strcmp(s_to_c((*la)->name), name) == 0){
  51. fa = *la;
  52. *la = (*la)->next;
  53. fa->next = nil;
  54. _freeattr(fa);
  55. }else
  56. la=&(*la)->next;
  57. }
  58. return a;
  59. }
  60. Attr*
  61. _findattr(Attr *a, char *n)
  62. {
  63. for(; a; a=a->next)
  64. if(strcmp(s_to_c(a->name), n) == 0 && a->type != AttrQuery)
  65. return a;
  66. return nil;
  67. }
  68. void
  69. _freeattr(Attr *a)
  70. {
  71. Attr *anext;
  72. for(; a; a=anext){
  73. anext = a->next;
  74. s_free(a->name);
  75. s_free(a->val);
  76. a->name = (void*)~0;
  77. a->val = (void*)~0;
  78. a->next = (void*)~0;
  79. free(a);
  80. }
  81. }
  82. Attr*
  83. _mkattr(int type, char *name, char *val, Attr *next)
  84. {
  85. Attr *a;
  86. a = malloc(sizeof(*a));
  87. if(a==nil)
  88. sysfatal("_mkattr malloc: %r");
  89. a->type = type;
  90. a->name = s_copy(name);
  91. a->val = s_copy(val);
  92. a->next = next;
  93. setmalloctag(a, getcallerpc(&type));
  94. return a;
  95. }
  96. static Attr*
  97. cleanattr(Attr *a)
  98. {
  99. Attr *fa;
  100. Attr **la;
  101. for(la=&a; *la; ){
  102. if((*la)->type==AttrQuery && _findattr(a, s_to_c((*la)->name))){
  103. fa = *la;
  104. *la = (*la)->next;
  105. fa->next = nil;
  106. _freeattr(fa);
  107. }else
  108. la=&(*la)->next;
  109. }
  110. return a;
  111. }
  112. Attr*
  113. _parseattr(char *s)
  114. {
  115. char *p, *t, *tok[256];
  116. int i, ntok, type;
  117. Attr *a;
  118. s = strdup(s);
  119. if(s == nil)
  120. sysfatal("_parseattr strdup: %r");
  121. ntok = tokenize(s, tok, nelem(tok));
  122. a = nil;
  123. for(i=ntok-1; i>=0; i--){
  124. t = tok[i];
  125. if(p = strchr(t, '=')){
  126. *p++ = '\0';
  127. // if(p-2 >= t && p[-2] == ':'){
  128. // p[-2] = '\0';
  129. // type = AttrDefault;
  130. // }else
  131. type = AttrNameval;
  132. a = _mkattr(type, t, p, a);
  133. setmalloctag(a, getcallerpc(&s));
  134. }
  135. else if(t[strlen(t)-1] == '?'){
  136. t[strlen(t)-1] = '\0';
  137. a = _mkattr(AttrQuery, t, "", a);
  138. setmalloctag(a, getcallerpc(&s));
  139. }else{
  140. /* really a syntax error, but better to provide some indication */
  141. a = _mkattr(AttrNameval, t, "", a);
  142. setmalloctag(a, getcallerpc(&s));
  143. }
  144. }
  145. free(s);
  146. return cleanattr(a);
  147. }
  148. char*
  149. _str_findattr(Attr *a, char *n)
  150. {
  151. a = _findattr(a, n);
  152. if(a == nil)
  153. return nil;
  154. return s_to_c(a->val);
  155. }