/* * Copyright (C) 2006, Intel Corporation * * This file is part of the Linux-ready Firmware Developer Kit * * This program file is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by the * Free Software Foundation;version 2.1 of the License. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program in a file named COPYING; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include static int current_ssdt; /* Which DSDT or SSDT table we're dealing with */ extern void load_dsdt_ssdts(); /* parses an iasl output line, returns the line no. that * the error or warning is referencing */ static int get_line_nr(char *line) { char *c; if (strlen(line)<10) return 0; c = strchr(line, '('); if (c) return strtoul(c+1, NULL, 10); else return 0; } /* find a certain line in the given dsdt table * that we represented in the linked-list (ssdt) */ static char *find_line(int nr) { GList *list; list = g_list_nth(ssdt[current_ssdt], nr-1); if(list->data) return (char *) list->data; else return NULL; } /* do_table() -- recompiles .dsl file with iasl, parses the output * and reports the results. * * Parameters * filename - name of table to compile with iasl (*.dsl) * Returns * void */ static void do_table(char *filename) { FILE *file; char line[4096]; char command[4096]; int errlineno; /* Compile the dsdt or ssdt .dsl with iasl */ sprintf(command, "/usr/share/LFDK/plugins/iasl -vi -vs -w3 %s", filename); /* analyse output of the iasl compiler */ file = popen(command,"r"); while (!feof(file)) { char *q; char *dsdt_line; int sev; int f; char *details; int skip = 100; char key[1024]; memset(line, 0, 4096); if (fgets(line, 4095, file)==NULL) break; /* only deal with lines that have the filename in it, the rest is program fluff */ sprintf(key, "%s(", filename); if (strstr(line,key)==NULL) continue; /* not a warning we really care about */ if (strstr(line, "Namespace object is not referenced")) continue; chop_newline(line); errlineno = get_line_nr(line); dsdt_line = find_line(errlineno); if (!dsdt_line) { printf("FATAL: line %i not found\n", errlineno); continue; } /* save the actual warning/error msg (after line no, 'warning', etc.) * we'll use it later in our test error reporting. */ q = strchr(line, '-'); if (!q) q=line; else if (strlen(q)>2) q+=2; sev = PASS; if (strstr(line, "Warning")) sev = WARN; if (strstr(line, "Warning 1")) sev = WARN; if (strstr(line, "Warning 2")) sev = INFO; if (strstr(line, "Error")) sev = FAIL; if (strstr(line, "Remark")) sev = INFO; /* Construct the details of the warning/err by also including * the prev. 5 lines and the next 4 lines from where this * occured. */ /* first go through and fix spacing by recording what's the least * amount of spaces you can afford to skip before displaying a line */ skip = 100; for (f = errlineno-5; f < errlineno+5; f++) { char *d2; int Q; d2 = find_line(f); if (!d2) continue; Q = space_count(d2); if (Q>> %s", &d2[skip]); if (d2 && f!=errlineno) details = scatprintf(details," | %s", &d2[skip]); } report_result("acpicompile", sev, q, details, NULL); free(details); } fclose(file); current_ssdt++; sprintf(line, "Tested table %s", filename); report_result("acpicompile", PASS, line, NULL, NULL); } /* do_test() -- main workhorse for this plugin. * * Parameters * void * Returns * void */ static void do_test(void) { struct stat before, after; int ret; int i; char filen[1024]; load_acpi_tables(); current_ssdt = 0; report_testrun_progress(20); do_table(WORKINGDIR "/DSDT.dsl"); report_testrun_progress(40); for (i=0; i