⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sim_log.c

📁 tinyos2.0版本驱动
💻 C
字号:
// $Id: sim_log.c,v 1.6 2008/06/11 00:46:26 razvanm Exp $/** "Copyright (c) 2005 Stanford University. All rights reserved. * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose, without fee, and without written * agreement is hereby granted, provided that the above copyright * notice, the following two paragraphs and the author appear in all * copies of this software. * * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, * ENHANCEMENTS, OR MODIFICATIONS." *//** * The TOSSIM logging system. * * @author Phil Levis * @date   November 9 2005 */#include <sim_log.h>#include <stdio.h>#include <stdarg.h>#include <hashtable.h>#include <string.h>enum {  DEFAULT_CHANNEL_SIZE = 8};typedef struct sim_log_output {  int num;  FILE** files;} sim_log_output_t;typedef struct sim_log_channel {  const char* name;  int numOutputs;  int size;  FILE** outputs;} sim_log_channel_t;enum {  SIM_LOG_OUTPUT_COUNT = uniqueCount("TOSSIM.debug")};sim_log_output_t outputs[SIM_LOG_OUTPUT_COUNT];struct hashtable* channelTable = NULL;static unsigned int sim_log_hash(void* key);static int sim_log_eq(void* key1, void* key2);// First we count how many outputs there are,// then allocate a FILE** large enough and fill it in.// This FILE** might be larger than needed, because// the outputs of the channels might have redundancies.// E.g., if two channels A and B are both to stdout, then// you don't want a channel of "A,B" to be doubly printed// to stdout. So when the channel's FILE*s are copied// into the debug point output array, this checks// for redundancies by checking file descriptors.static void fillInOutput(int id, char* name) {  char* termination = name;  char* namePos = name;  int count = 0;  char* newName = (char*)malloc(strlen(name) + 1);  memset(newName, 0, strlen(name) + 1);  // Count the outputs  while (termination != NULL) {    sim_log_channel_t* channel;        termination = strrchr(namePos, ',');    // If we've reached the end, just copy to the end    if (termination == NULL) {      strcpy(newName, namePos);    }    // Otherwise, memcpy over and null terminate    else {      memcpy(newName, namePos, (termination - namePos));      newName[termination - namePos] = 0;    }        channel = hashtable_search(channelTable, namePos);    if (channel != NULL) {      count += channel->numOutputs;    }    namePos = termination + 1;  }  termination = name;  namePos = name;    // Allocate  outputs[id].files = (FILE**)malloc(sizeof(FILE*) * count);  outputs[id].num = 0;  // Fill it in  while (termination != NULL) {    sim_log_channel_t* channel;        termination = strrchr(namePos, ',');    // If we've reached the end, just copy to the end    if (termination == NULL) {      strcpy(newName, namePos);    }    // Otherwise, memcpy over and null terminate    else {      memcpy(newName, namePos, (termination - namePos));      newName[termination - namePos] = 0;    }        channel = hashtable_search(channelTable, namePos);    if (channel != NULL) {      int i, j;      for (i = 0; i < channel->numOutputs; i++) {	int duplicate = 0;	int outputCount = outputs[id].num;	// Check if we already have this file descriptor in the output	// set, and if so, ignore it.	for (j = 0; j < outputCount; j++) {	  if (fileno(outputs[id].files[j]) == fileno(channel->outputs[i])) {	    duplicate = 1;	    j = outputCount;	  }	}	if (!duplicate) {	  outputs[id].files[outputCount] = channel->outputs[i];	  outputs[id].num++;	}      }    }    namePos = termination + 1;  }}void sim_log_init() {  int i;  channelTable = create_hashtable(128, sim_log_hash, sim_log_eq);    for (i = 0; i < SIM_LOG_OUTPUT_COUNT; i++) {    outputs[i].num = 1;    outputs[i].files = (FILE**)malloc(sizeof(FILE*));    outputs[i].files[0] = fdopen(1, "w"); // STDOUT  }  }void sim_log_add_channel(char* name, FILE* file) {  sim_log_channel_t* channel;  channel = (sim_log_channel_t*)hashtable_search(channelTable, name);    // If there's no current entry, allocate one, initialize it,  // and insert it.  if (channel == NULL) {    char* newName = (char*)malloc(strlen(name) + 1);    strcpy(newName, name);    newName[strlen(name)] = 0;        channel = (sim_log_channel_t*)malloc(sizeof(sim_log_channel_t));    channel->name = newName;    channel->numOutputs = 0;    channel->size = DEFAULT_CHANNEL_SIZE;    channel->outputs = (FILE**)malloc(sizeof(FILE*) * channel->size);    memset(channel->outputs, 0, sizeof(FILE*) * channel->size);    hashtable_insert(channelTable, newName, channel);  }  // If the channel output table is full, double the size of  // channel->outputs.  if (channel->numOutputs == channel->size) {    FILE** newOutputs;    int newSize = channel->size * 2;        newOutputs = (FILE**)malloc(sizeof(FILE*) * newSize);    memcpy(newOutputs, channel->outputs, channel->size * sizeof(FILE**));    free(channel->outputs);    channel->outputs = newOutputs;    channel->size    = newSize;  }  channel->outputs[channel->numOutputs] = file;  channel->numOutputs++;  sim_log_commit_change();}bool sim_log_remove_channel(char* output, FILE* file) {  sim_log_channel_t* channel;  int i;  channel = (sim_log_channel_t*)hashtable_search(channelTable, output);    if (channel == NULL) {    return FALSE;  }  // Note: if a FILE* has duplicates, this removes all of them  for (i = 0; i < channel->numOutputs; i++) {    FILE* f = channel->outputs[i];    if (file == f) {      memcpy(&channel->outputs[i], &channel->outputs[i + 1], (channel->numOutputs) - (i + 1));      channel->outputs[channel->numOutputs - 1] = NULL;      channel->numOutputs--;    }  }    return TRUE;}  void sim_log_commit_change() {  int i;  for (i = 0; i < SIM_LOG_OUTPUT_COUNT; i++) {    if (outputs[i].files != NULL) {      outputs[i].num = 0;      free(outputs[i].files);      outputs[i].files = NULL;    }  }}void sim_log_debug(uint16_t id, char* string, const char* format, ...) {  va_list args;  int i;  if (outputs[id].files == NULL) {    fillInOutput(id, string);  }  for (i = 0; i < outputs[id].num; i++) {    FILE* file = outputs[id].files[i];    va_start(args, format);    fprintf(file, "DEBUG (%i): ", (int)sim_node());    vfprintf(file, format, args);     fflush(file);  }}void sim_log_error(uint16_t id, char* string, const char* format, ...) {  va_list args;  int i;  if (outputs[id].files == NULL) {    fillInOutput(id, string);  }  for (i = 0; i < outputs[id].num; i++) {    FILE* file = outputs[id].files[i];    va_start(args, format);    fprintf(file, "ERROR (%i): ", (int)sim_node());    vfprintf(file, format, args);    fflush(file);  }}void sim_log_debug_clear(uint16_t id, char* string, const char* format, ...) {  va_list args;  int i;  if (outputs[id].files == NULL) {    fillInOutput(id, string);  }  for (i = 0; i < outputs[id].num; i++) {    FILE* file = outputs[id].files[i];    va_start(args, format);    vfprintf(file, format, args);    fflush(file);  }}void sim_log_error_clear(uint16_t id, char* string, const char* format, ...) {  va_list args;  int i;  if (outputs[id].files == NULL) {    fillInOutput(id, string);  }  for (i = 0; i < outputs[id].num; i++) {    FILE* file = outputs[id].files[i];    va_start(args, format);    vfprintf(file, format, args);    fflush(file);  }}/* This is the sdbm algorithm, taken from   http://www.cs.yorku.ca/~oz/hash.html -pal */static unsigned int sim_log_hash(void* key) {  char* str = (char*)key;  unsigned int hashVal = 0;  int hashChar;    while ((hashChar = *str++))    hashVal = hashChar + (hashVal << 6) + (hashVal << 16) - hashVal;    return hashVal;}static int sim_log_eq(void* key1, void* key2) {  return strcmp((char*)key1, (char*)key2) == 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -