/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include "CommentStyle.h" #include "defines.h" #include "Strings.h" #include "WarningDialogManager.h" // // Buffer text during parsing rather than repeatedly doing a strcat, setLabel // for the save of efficiency. // char* CommentStyle::ParseBuffer = NUL(char*); int CommentStyle::ParseBufferNext = 0; int CommentStyle::ParseBufferSize = 0; void CommentStyle::InitParseBuffer(int estimated_size) { int required_size = estimated_size + 64; // // Get a new buffer if the old one is too small. // if (CommentStyle::ParseBufferSize < required_size) { if (CommentStyle::ParseBuffer) delete CommentStyle::ParseBuffer; CommentStyle::ParseBuffer = new char[required_size]; } CommentStyle::ParseBuffer[ CommentStyle::ParseBufferNext = 0 ] = '\0'; } void CommentStyle::AppendParseBuffer(const char* text) { ASSERT(text); int len = strlen(text); // // If out of space realloc the buffer. This should never be the case unless // code is added down the road for escaping special chars which could increase // the required size to more then strlen says. // int required_size = len + CommentStyle::ParseBufferNext; if (required_size >= CommentStyle::ParseBufferSize) { char* cp = new char[required_size + 128]; CommentStyle::ParseBufferSize = required_size = 128; strcpy (cp, CommentStyle::ParseBuffer); delete CommentStyle::ParseBuffer; CommentStyle::ParseBuffer = cp; } if (CommentStyle::ParseBufferNext) { CommentStyle::ParseBuffer[CommentStyle::ParseBufferNext++] = '\n'; CommentStyle::ParseBuffer[CommentStyle::ParseBufferNext] = '\0'; } char* cp = &CommentStyle::ParseBuffer[CommentStyle::ParseBufferNext]; strcpy (cp, text); CommentStyle::ParseBufferNext+= len; } #define NO_TEXT_SYMBOL "" // // format: // // annotation %s_begin: NO_TEXT_SYMBOL\n // // annotation %s: %s\n // // annotation %s_end: NO_TEXT_SYMBOL\n // boolean CommentStyle::printComment (FILE* f) { char begin_stmnt[64]; char end_stmnt[64]; sprintf (begin_stmnt, "%s_begin", this->getKeyword()); sprintf (end_stmnt, "%s_end", this->getKeyword()); const char* cp = this->getPrintableText(); if ((cp) && (cp[0])) { if (fprintf (f, " // annotation %s: %d\n", begin_stmnt, strlen(cp)) < 0) return FALSE; char* line_to_print = DuplicateString(cp); // // The constant PBS imposes a maximum line length. // # define PBS 256 char print_buf[PBS]; int line_len_exceeded = 0; int i = 0, next = 0; while (1) { print_buf[next] = line_to_print[i]; if (next == (PBS-2)) { print_buf[++next] = '\n'; line_len_exceeded++; } if (print_buf[next] == '\n') { print_buf[next] = '\0'; int j; boolean is_line_whitespace = TRUE; for (j=0; jgetKeyword(), print_buf) < 0) return FALSE; } else { if (fprintf (f, " // annotation %s: %s\n", this->getKeyword(), NO_TEXT_SYMBOL) < 0) return FALSE; } next = 0; } else if (print_buf[next] == '\0') { int j; boolean is_line_whitespace = TRUE; for (j=0; jgetKeyword(), print_buf) < 0) return FALSE; } else { if (fprintf (f, " // annotation %s: %s\n", this->getKeyword(), NO_TEXT_SYMBOL) < 0) return FALSE; } break; } else { next++; } i++; } if (line_len_exceeded) { WarningMessage ("%d lines of program annotation" "exceeded maximum length of %d", line_len_exceeded, PBS); } delete line_to_print; if (fprintf (f, " // annotation %s: %s\n", end_stmnt, NO_TEXT_SYMBOL) < 0) return FALSE; } return TRUE; } // // boolean CommentStyle::parseComment (const char *comment, const char *file, int l) { int items_parsed; char text[1024]; char font[64]; boolean retVal = FALSE; char begin_stmnt[64]; char end_stmnt[64]; sprintf (begin_stmnt, "%s_begin", this->getKeyword()); sprintf (end_stmnt, "%s_end", this->getKeyword()); // // As of 3.1.4, we want to print the text of the decorator on multiple lines // using statefullness already implemented in ControlPanel and now in Network // as well, with the addition of vpe pages. // if (EqualSubstring(" annotation",comment,11)) { char additional_text[256]; additional_text[0] = '\0'; char keyword[64]; items_parsed = sscanf (comment, " annotation %[^:]: %[^\n]", keyword, additional_text); if (items_parsed == 2) { // // Count leading spaces. // char* cp = strchr(comment, ':'); int leading_space = 0; cp+=2; char c = *cp; while ((c != '\n') && ((c == ' ')||(c == '\t'))) c = *(++cp), additional_text[leading_space++] = ' '; ASSERT(leading_space < 255); items_parsed = sscanf (comment, " annotation %[^:]: %[^\n]", keyword, &additional_text[leading_space]); ASSERT(items_parsed == 2); } if (items_parsed == 2) { if (EqualString(keyword, this->getKeyword())) { if (EqualString(additional_text, NO_TEXT_SYMBOL)) additional_text[0]='\t',additional_text[1]='\0'; else { } CommentStyle::AppendParseBuffer(additional_text); retVal = TRUE; } else if (EqualString(keyword, begin_stmnt)) { int str_size = 128; sscanf (additional_text, "%d", &str_size); CommentStyle::InitParseBuffer(str_size); retVal = TRUE; } else if (EqualString(keyword, end_stmnt)) { this->setPrintableText(CommentStyle::ParseBuffer); retVal = TRUE; } else { // // This comment was intended for a different CommentStyle object // } } else { WarningMessage ("Unrecognized text in LabelDecorator " "Comment (file %s, line %d)", file, l); } } return retVal; }